InterpAsm-armv7-a.S revision 750d110b62cef538e193b6f91f5239b0c4b63ef1
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 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 GET_INST_OPCODE(ip) @ extract opcode from rINST 868 GOTO_OPCODE(ip) @ jump to next instruction 869 870/* ------------------------------ */ 871 .balign 64 872.L_OP_MONITOR_EXIT: /* 0x1e */ 873/* File: armv5te/OP_MONITOR_EXIT.S */ 874 /* 875 * Unlock an object. 876 * 877 * Exceptions that occur when unlocking a monitor need to appear as 878 * if they happened at the following instruction. See the Dalvik 879 * instruction spec. 880 */ 881 /* monitor-exit vAA */ 882 mov r2, rINST, lsr #8 @ r2<- AA 883 EXPORT_PC() @ before fetch: export the PC 884 GET_VREG(r1, r2) @ r1<- vAA (object) 885 cmp r1, #0 @ null object? 886 beq 1f @ yes 887 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 888 bl dvmUnlockObject @ r0<- success for unlock(self, obj) 889 cmp r0, #0 @ failed? 890 FETCH_ADVANCE_INST(1) @ before throw: advance rPC, load rINST 891 beq common_exceptionThrown @ yes, exception is pending 892 GET_INST_OPCODE(ip) @ extract opcode from rINST 893 GOTO_OPCODE(ip) @ jump to next instruction 8941: 895 FETCH_ADVANCE_INST(1) @ advance before throw 896 b common_errNullObject 897 898/* ------------------------------ */ 899 .balign 64 900.L_OP_CHECK_CAST: /* 0x1f */ 901/* File: armv5te/OP_CHECK_CAST.S */ 902 /* 903 * Check to see if a cast from one class to another is allowed. 904 */ 905 /* check-cast vAA, class@BBBB */ 906 mov r3, rINST, lsr #8 @ r3<- AA 907 FETCH(r2, 1) @ r2<- BBBB 908 GET_VREG(r9, r3) @ r9<- object 909 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- pDvmDex 910 cmp r9, #0 @ is object null? 911 ldr r0, [r0, #offDvmDex_pResClasses] @ r0<- pDvmDex->pResClasses 912 beq .LOP_CHECK_CAST_okay @ null obj, cast always succeeds 913 ldr r1, [r0, r2, lsl #2] @ r1<- resolved class 914 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 915 cmp r1, #0 @ have we resolved this before? 916 beq .LOP_CHECK_CAST_resolve @ not resolved, do it now 917.LOP_CHECK_CAST_resolved: 918 cmp r0, r1 @ same class (trivial success)? 919 bne .LOP_CHECK_CAST_fullcheck @ no, do full check 920.LOP_CHECK_CAST_okay: 921 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 922 GET_INST_OPCODE(ip) @ extract opcode from rINST 923 GOTO_OPCODE(ip) @ jump to next instruction 924 925/* ------------------------------ */ 926 .balign 64 927.L_OP_INSTANCE_OF: /* 0x20 */ 928/* File: armv5te/OP_INSTANCE_OF.S */ 929 /* 930 * Check to see if an object reference is an instance of a class. 931 * 932 * Most common situation is a non-null object, being compared against 933 * an already-resolved class. 934 */ 935 /* instance-of vA, vB, class@CCCC */ 936 mov r3, rINST, lsr #12 @ r3<- B 937 mov r9, rINST, lsr #8 @ r9<- A+ 938 GET_VREG(r0, r3) @ r0<- vB (object) 939 and r9, r9, #15 @ r9<- A 940 cmp r0, #0 @ is object null? 941 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- pDvmDex 942 beq .LOP_INSTANCE_OF_store @ null obj, not an instance, store r0 943 FETCH(r3, 1) @ r3<- CCCC 944 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- pDvmDex->pResClasses 945 ldr r1, [r2, r3, lsl #2] @ r1<- resolved class 946 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 947 cmp r1, #0 @ have we resolved this before? 948 beq .LOP_INSTANCE_OF_resolve @ not resolved, do it now 949.LOP_INSTANCE_OF_resolved: @ r0=obj->clazz, r1=resolved class 950 cmp r0, r1 @ same class (trivial success)? 951 beq .LOP_INSTANCE_OF_trivial @ yes, trivial finish 952 b .LOP_INSTANCE_OF_fullcheck @ no, do full check 953 954/* ------------------------------ */ 955 .balign 64 956.L_OP_ARRAY_LENGTH: /* 0x21 */ 957/* File: armv6t2/OP_ARRAY_LENGTH.S */ 958 /* 959 * Return the length of an array. 960 */ 961 mov r1, rINST, lsr #12 @ r1<- B 962 ubfx r2, rINST, #8, #4 @ r2<- A 963 GET_VREG(r0, r1) @ r0<- vB (object ref) 964 cmp r0, #0 @ is object null? 965 beq common_errNullObject @ yup, fail 966 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 967 ldr r3, [r0, #offArrayObject_length] @ r3<- array length 968 GET_INST_OPCODE(ip) @ extract opcode from rINST 969 SET_VREG(r3, r2) @ vB<- length 970 GOTO_OPCODE(ip) @ jump to next instruction 971 972/* ------------------------------ */ 973 .balign 64 974.L_OP_NEW_INSTANCE: /* 0x22 */ 975/* File: armv5te/OP_NEW_INSTANCE.S */ 976 /* 977 * Create a new instance of a class. 978 */ 979 /* new-instance vAA, class@BBBB */ 980 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 981 FETCH(r1, 1) @ r1<- BBBB 982 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 983 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 984 EXPORT_PC() @ req'd for init, resolve, alloc 985 cmp r0, #0 @ already resolved? 986 beq .LOP_NEW_INSTANCE_resolve @ no, resolve it now 987.LOP_NEW_INSTANCE_resolved: @ r0=class 988 ldrb r1, [r0, #offClassObject_status] @ r1<- ClassStatus enum 989 cmp r1, #CLASS_INITIALIZED @ has class been initialized? 990 bne .LOP_NEW_INSTANCE_needinit @ no, init class now 991.LOP_NEW_INSTANCE_initialized: @ r0=class 992 mov r1, #ALLOC_DONT_TRACK @ flags for alloc call 993 bl dvmAllocObject @ r0<- new object 994 b .LOP_NEW_INSTANCE_finish @ continue 995 996/* ------------------------------ */ 997 .balign 64 998.L_OP_NEW_ARRAY: /* 0x23 */ 999/* File: armv5te/OP_NEW_ARRAY.S */ 1000 /* 1001 * Allocate an array of objects, specified with the array class 1002 * and a count. 1003 * 1004 * The verifier guarantees that this is an array class, so we don't 1005 * check for it here. 1006 */ 1007 /* new-array vA, vB, class@CCCC */ 1008 mov r0, rINST, lsr #12 @ r0<- B 1009 FETCH(r2, 1) @ r2<- CCCC 1010 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 1011 GET_VREG(r1, r0) @ r1<- vB (array length) 1012 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1013 cmp r1, #0 @ check length 1014 ldr r0, [r3, r2, lsl #2] @ r0<- resolved class 1015 bmi common_errNegativeArraySize @ negative length, bail 1016 cmp r0, #0 @ already resolved? 1017 EXPORT_PC() @ req'd for resolve, alloc 1018 bne .LOP_NEW_ARRAY_finish @ resolved, continue 1019 b .LOP_NEW_ARRAY_resolve @ do resolve now 1020 1021/* ------------------------------ */ 1022 .balign 64 1023.L_OP_FILLED_NEW_ARRAY: /* 0x24 */ 1024/* File: armv5te/OP_FILLED_NEW_ARRAY.S */ 1025 /* 1026 * Create a new array with elements filled from registers. 1027 * 1028 * for: filled-new-array, filled-new-array/range 1029 */ 1030 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1031 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1032 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 1033 FETCH(r1, 1) @ r1<- BBBB 1034 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1035 EXPORT_PC() @ need for resolve and alloc 1036 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 1037 mov r10, rINST, lsr #8 @ r10<- AA or BA 1038 cmp r0, #0 @ already resolved? 1039 bne .LOP_FILLED_NEW_ARRAY_continue @ yes, continue on 10408: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 1041 mov r2, #0 @ r2<- false 1042 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 1043 bl dvmResolveClass @ r0<- call(clazz, ref) 1044 cmp r0, #0 @ got null? 1045 beq common_exceptionThrown @ yes, handle exception 1046 b .LOP_FILLED_NEW_ARRAY_continue 1047 1048/* ------------------------------ */ 1049 .balign 64 1050.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */ 1051/* File: armv5te/OP_FILLED_NEW_ARRAY_RANGE.S */ 1052/* File: armv5te/OP_FILLED_NEW_ARRAY.S */ 1053 /* 1054 * Create a new array with elements filled from registers. 1055 * 1056 * for: filled-new-array, filled-new-array/range 1057 */ 1058 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1059 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1060 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 1061 FETCH(r1, 1) @ r1<- BBBB 1062 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1063 EXPORT_PC() @ need for resolve and alloc 1064 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 1065 mov r10, rINST, lsr #8 @ r10<- AA or BA 1066 cmp r0, #0 @ already resolved? 1067 bne .LOP_FILLED_NEW_ARRAY_RANGE_continue @ yes, continue on 10688: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 1069 mov r2, #0 @ r2<- false 1070 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 1071 bl dvmResolveClass @ r0<- call(clazz, ref) 1072 cmp r0, #0 @ got null? 1073 beq common_exceptionThrown @ yes, handle exception 1074 b .LOP_FILLED_NEW_ARRAY_RANGE_continue 1075 1076 1077/* ------------------------------ */ 1078 .balign 64 1079.L_OP_FILL_ARRAY_DATA: /* 0x26 */ 1080/* File: armv5te/OP_FILL_ARRAY_DATA.S */ 1081 /* fill-array-data vAA, +BBBBBBBB */ 1082 FETCH(r0, 1) @ r0<- bbbb (lo) 1083 FETCH(r1, 2) @ r1<- BBBB (hi) 1084 mov r3, rINST, lsr #8 @ r3<- AA 1085 orr r1, r0, r1, lsl #16 @ r1<- BBBBbbbb 1086 GET_VREG(r0, r3) @ r0<- vAA (array object) 1087 add r1, rPC, r1, lsl #1 @ r1<- PC + BBBBbbbb*2 (array data off.) 1088 EXPORT_PC(); 1089 bl dvmInterpHandleFillArrayData@ fill the array with predefined data 1090 cmp r0, #0 @ 0 means an exception is thrown 1091 beq common_exceptionThrown @ has exception 1092 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 1093 GET_INST_OPCODE(ip) @ extract opcode from rINST 1094 GOTO_OPCODE(ip) @ jump to next instruction 1095 1096/* ------------------------------ */ 1097 .balign 64 1098.L_OP_THROW: /* 0x27 */ 1099/* File: armv5te/OP_THROW.S */ 1100 /* 1101 * Throw an exception object in the current thread. 1102 */ 1103 /* throw vAA */ 1104 mov r2, rINST, lsr #8 @ r2<- AA 1105 GET_VREG(r1, r2) @ r1<- vAA (exception object) 1106 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 1107 EXPORT_PC() @ exception handler can throw 1108 cmp r1, #0 @ null object? 1109 beq common_errNullObject @ yes, throw an NPE instead 1110 @ bypass dvmSetException, just store it 1111 str r1, [r0, #offThread_exception] @ thread->exception<- obj 1112 b common_exceptionThrown 1113 1114/* ------------------------------ */ 1115 .balign 64 1116.L_OP_GOTO: /* 0x28 */ 1117/* File: armv5te/OP_GOTO.S */ 1118 /* 1119 * Unconditional branch, 8-bit offset. 1120 * 1121 * The branch distance is a signed code-unit offset, which we need to 1122 * double to get a byte offset. 1123 */ 1124 /* goto +AA */ 1125 mov r0, rINST, lsl #16 @ r0<- AAxx0000 1126 movs r9, r0, asr #24 @ r9<- ssssssAA (sign-extended) 1127 mov r9, r9, lsl #1 @ r9<- byte offset 1128 bmi common_backwardBranch @ backward branch, do periodic checks 1129#if defined(WITH_JIT) 1130 GET_JIT_PROF_TABLE(r0) 1131 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1132 cmp r0,#0 1133 bne common_updateProfile 1134 GET_INST_OPCODE(ip) @ extract opcode from rINST 1135 GOTO_OPCODE(ip) @ jump to next instruction 1136#else 1137 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1138 GET_INST_OPCODE(ip) @ extract opcode from rINST 1139 GOTO_OPCODE(ip) @ jump to next instruction 1140#endif 1141 1142/* ------------------------------ */ 1143 .balign 64 1144.L_OP_GOTO_16: /* 0x29 */ 1145/* File: armv5te/OP_GOTO_16.S */ 1146 /* 1147 * Unconditional branch, 16-bit offset. 1148 * 1149 * The branch distance is a signed code-unit offset, which we need to 1150 * double to get a byte offset. 1151 */ 1152 /* goto/16 +AAAA */ 1153 FETCH_S(r0, 1) @ r0<- ssssAAAA (sign-extended) 1154 movs r9, r0, asl #1 @ r9<- byte offset, check sign 1155 bmi common_backwardBranch @ backward branch, do periodic checks 1156#if defined(WITH_JIT) 1157 GET_JIT_PROF_TABLE(r0) 1158 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1159 cmp r0,#0 1160 bne common_updateProfile 1161 GET_INST_OPCODE(ip) @ extract opcode from rINST 1162 GOTO_OPCODE(ip) @ jump to next instruction 1163#else 1164 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1165 GET_INST_OPCODE(ip) @ extract opcode from rINST 1166 GOTO_OPCODE(ip) @ jump to next instruction 1167#endif 1168 1169/* ------------------------------ */ 1170 .balign 64 1171.L_OP_GOTO_32: /* 0x2a */ 1172/* File: armv5te/OP_GOTO_32.S */ 1173 /* 1174 * Unconditional branch, 32-bit offset. 1175 * 1176 * The branch distance is a signed code-unit offset, which we need to 1177 * double to get a byte offset. 1178 * 1179 * Unlike most opcodes, this one is allowed to branch to itself, so 1180 * our "backward branch" test must be "<=0" instead of "<0". The ORRS 1181 * instruction doesn't affect the V flag, so we need to clear it 1182 * explicitly. 1183 */ 1184 /* goto/32 +AAAAAAAA */ 1185 FETCH(r0, 1) @ r0<- aaaa (lo) 1186 FETCH(r1, 2) @ r1<- AAAA (hi) 1187 cmp ip, ip @ (clear V flag during stall) 1188 orrs r0, r0, r1, lsl #16 @ r0<- AAAAaaaa, check sign 1189 mov r9, r0, asl #1 @ r9<- byte offset 1190 ble common_backwardBranch @ backward branch, do periodic checks 1191#if defined(WITH_JIT) 1192 GET_JIT_PROF_TABLE(r0) 1193 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1194 cmp r0,#0 1195 bne common_updateProfile 1196 GET_INST_OPCODE(ip) @ extract opcode from rINST 1197 GOTO_OPCODE(ip) @ jump to next instruction 1198#else 1199 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1200 GET_INST_OPCODE(ip) @ extract opcode from rINST 1201 GOTO_OPCODE(ip) @ jump to next instruction 1202#endif 1203 1204/* ------------------------------ */ 1205 .balign 64 1206.L_OP_PACKED_SWITCH: /* 0x2b */ 1207/* File: armv5te/OP_PACKED_SWITCH.S */ 1208 /* 1209 * Handle a packed-switch or sparse-switch instruction. In both cases 1210 * we decode it and hand it off to a helper function. 1211 * 1212 * We don't really expect backward branches in a switch statement, but 1213 * they're perfectly legal, so we check for them here. 1214 * 1215 * for: packed-switch, sparse-switch 1216 */ 1217 /* op vAA, +BBBB */ 1218 FETCH(r0, 1) @ r0<- bbbb (lo) 1219 FETCH(r1, 2) @ r1<- BBBB (hi) 1220 mov r3, rINST, lsr #8 @ r3<- AA 1221 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 1222 GET_VREG(r1, r3) @ r1<- vAA 1223 add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 1224 bl dvmInterpHandlePackedSwitch @ r0<- code-unit branch offset 1225 movs r9, r0, asl #1 @ r9<- branch byte offset, check sign 1226 bmi common_backwardBranch @ backward branch, do periodic checks 1227 beq common_backwardBranch @ (want to use BLE but V is unknown) 1228#if defined(WITH_JIT) 1229 GET_JIT_PROF_TABLE(r0) 1230 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1231 cmp r0,#0 1232 bne common_updateProfile 1233 GET_INST_OPCODE(ip) @ extract opcode from rINST 1234 GOTO_OPCODE(ip) @ jump to next instruction 1235#else 1236 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1237 GET_INST_OPCODE(ip) @ extract opcode from rINST 1238 GOTO_OPCODE(ip) @ jump to next instruction 1239#endif 1240 1241/* ------------------------------ */ 1242 .balign 64 1243.L_OP_SPARSE_SWITCH: /* 0x2c */ 1244/* File: armv5te/OP_SPARSE_SWITCH.S */ 1245/* File: armv5te/OP_PACKED_SWITCH.S */ 1246 /* 1247 * Handle a packed-switch or sparse-switch instruction. In both cases 1248 * we decode it and hand it off to a helper function. 1249 * 1250 * We don't really expect backward branches in a switch statement, but 1251 * they're perfectly legal, so we check for them here. 1252 * 1253 * for: packed-switch, sparse-switch 1254 */ 1255 /* op vAA, +BBBB */ 1256 FETCH(r0, 1) @ r0<- bbbb (lo) 1257 FETCH(r1, 2) @ r1<- BBBB (hi) 1258 mov r3, rINST, lsr #8 @ r3<- AA 1259 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 1260 GET_VREG(r1, r3) @ r1<- vAA 1261 add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 1262 bl dvmInterpHandleSparseSwitch @ r0<- code-unit branch offset 1263 movs r9, r0, asl #1 @ r9<- branch byte offset, check sign 1264 bmi common_backwardBranch @ backward branch, do periodic checks 1265 beq common_backwardBranch @ (want to use BLE but V is unknown) 1266#if defined(WITH_JIT) 1267 GET_JIT_PROF_TABLE(r0) 1268 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1269 cmp r0,#0 1270 bne common_updateProfile 1271 GET_INST_OPCODE(ip) @ extract opcode from rINST 1272 GOTO_OPCODE(ip) @ jump to next instruction 1273#else 1274 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1275 GET_INST_OPCODE(ip) @ extract opcode from rINST 1276 GOTO_OPCODE(ip) @ jump to next instruction 1277#endif 1278 1279 1280/* ------------------------------ */ 1281 .balign 64 1282.L_OP_CMPL_FLOAT: /* 0x2d */ 1283/* File: arm-vfp/OP_CMPL_FLOAT.S */ 1284 /* 1285 * Compare two floating-point values. Puts 0, 1, or -1 into the 1286 * destination register based on the results of the comparison. 1287 * 1288 * int compare(x, y) { 1289 * if (x == y) { 1290 * return 0; 1291 * } else if (x > y) { 1292 * return 1; 1293 * } else if (x < y) { 1294 * return -1; 1295 * } else { 1296 * return -1; 1297 * } 1298 * } 1299 */ 1300 /* op vAA, vBB, vCC */ 1301 FETCH(r0, 1) @ r0<- CCBB 1302 mov r9, rINST, lsr #8 @ r9<- AA 1303 and r2, r0, #255 @ r2<- BB 1304 mov r3, r0, lsr #8 @ r3<- CC 1305 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1306 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1307 flds s0, [r2] @ s0<- vBB 1308 flds s1, [r3] @ s1<- vCC 1309 fcmpes s0, s1 @ compare (vBB, vCC) 1310 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1311 mvn r0, #0 @ r0<- -1 (default) 1312 GET_INST_OPCODE(ip) @ extract opcode from rINST 1313 fmstat @ export status flags 1314 movgt r0, #1 @ (greater than) r1<- 1 1315 moveq r0, #0 @ (equal) r1<- 0 1316 b .LOP_CMPL_FLOAT_finish @ argh 1317 1318 1319/* ------------------------------ */ 1320 .balign 64 1321.L_OP_CMPG_FLOAT: /* 0x2e */ 1322/* File: arm-vfp/OP_CMPG_FLOAT.S */ 1323 /* 1324 * Compare two floating-point values. Puts 0, 1, or -1 into the 1325 * destination register based on the results of the comparison. 1326 * 1327 * int compare(x, y) { 1328 * if (x == y) { 1329 * return 0; 1330 * } else if (x < y) { 1331 * return -1; 1332 * } else if (x > y) { 1333 * return 1; 1334 * } else { 1335 * return 1; 1336 * } 1337 * } 1338 */ 1339 /* op vAA, vBB, vCC */ 1340 FETCH(r0, 1) @ r0<- CCBB 1341 mov r9, rINST, lsr #8 @ r9<- AA 1342 and r2, r0, #255 @ r2<- BB 1343 mov r3, r0, lsr #8 @ r3<- CC 1344 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1345 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1346 flds s0, [r2] @ s0<- vBB 1347 flds s1, [r3] @ s1<- vCC 1348 fcmpes s0, s1 @ compare (vBB, vCC) 1349 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1350 mov r0, #1 @ r0<- 1 (default) 1351 GET_INST_OPCODE(ip) @ extract opcode from rINST 1352 fmstat @ export status flags 1353 mvnmi r0, #0 @ (less than) r1<- -1 1354 moveq r0, #0 @ (equal) r1<- 0 1355 b .LOP_CMPG_FLOAT_finish @ argh 1356 1357 1358/* ------------------------------ */ 1359 .balign 64 1360.L_OP_CMPL_DOUBLE: /* 0x2f */ 1361/* File: arm-vfp/OP_CMPL_DOUBLE.S */ 1362 /* 1363 * Compare two floating-point values. Puts 0, 1, or -1 into the 1364 * destination register based on the results of the comparison. 1365 * 1366 * int compare(x, y) { 1367 * if (x == y) { 1368 * return 0; 1369 * } else if (x > y) { 1370 * return 1; 1371 * } else if (x < y) { 1372 * return -1; 1373 * } else { 1374 * return -1; 1375 * } 1376 * } 1377 */ 1378 /* op vAA, vBB, vCC */ 1379 FETCH(r0, 1) @ r0<- CCBB 1380 mov r9, rINST, lsr #8 @ r9<- AA 1381 and r2, r0, #255 @ r2<- BB 1382 mov r3, r0, lsr #8 @ r3<- CC 1383 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1384 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1385 fldd d0, [r2] @ d0<- vBB 1386 fldd d1, [r3] @ d1<- vCC 1387 fcmped d0, d1 @ compare (vBB, vCC) 1388 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1389 mvn r0, #0 @ r0<- -1 (default) 1390 GET_INST_OPCODE(ip) @ extract opcode from rINST 1391 fmstat @ export status flags 1392 movgt r0, #1 @ (greater than) r1<- 1 1393 moveq r0, #0 @ (equal) r1<- 0 1394 b .LOP_CMPL_DOUBLE_finish @ argh 1395 1396 1397/* ------------------------------ */ 1398 .balign 64 1399.L_OP_CMPG_DOUBLE: /* 0x30 */ 1400/* File: arm-vfp/OP_CMPG_DOUBLE.S */ 1401 /* 1402 * Compare two floating-point values. Puts 0, 1, or -1 into the 1403 * destination register based on the results of the comparison. 1404 * 1405 * int compare(x, y) { 1406 * if (x == y) { 1407 * return 0; 1408 * } else if (x < y) { 1409 * return -1; 1410 * } else if (x > y) { 1411 * return 1; 1412 * } else { 1413 * return 1; 1414 * } 1415 * } 1416 */ 1417 /* op vAA, vBB, vCC */ 1418 FETCH(r0, 1) @ r0<- CCBB 1419 mov r9, rINST, lsr #8 @ r9<- AA 1420 and r2, r0, #255 @ r2<- BB 1421 mov r3, r0, lsr #8 @ r3<- CC 1422 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1423 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1424 fldd d0, [r2] @ d0<- vBB 1425 fldd d1, [r3] @ d1<- vCC 1426 fcmped d0, d1 @ compare (vBB, vCC) 1427 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1428 mov r0, #1 @ r0<- 1 (default) 1429 GET_INST_OPCODE(ip) @ extract opcode from rINST 1430 fmstat @ export status flags 1431 mvnmi r0, #0 @ (less than) r1<- -1 1432 moveq r0, #0 @ (equal) r1<- 0 1433 b .LOP_CMPG_DOUBLE_finish @ argh 1434 1435 1436/* ------------------------------ */ 1437 .balign 64 1438.L_OP_CMP_LONG: /* 0x31 */ 1439/* File: armv5te/OP_CMP_LONG.S */ 1440 /* 1441 * Compare two 64-bit values. Puts 0, 1, or -1 into the destination 1442 * register based on the results of the comparison. 1443 * 1444 * We load the full values with LDM, but in practice many values could 1445 * be resolved by only looking at the high word. This could be made 1446 * faster or slower by splitting the LDM into a pair of LDRs. 1447 * 1448 * If we just wanted to set condition flags, we could do this: 1449 * subs ip, r0, r2 1450 * sbcs ip, r1, r3 1451 * subeqs ip, r0, r2 1452 * Leaving { <0, 0, >0 } in ip. However, we have to set it to a specific 1453 * integer value, which we can do with 2 conditional mov/mvn instructions 1454 * (set 1, set -1; if they're equal we already have 0 in ip), giving 1455 * us a constant 5-cycle path plus a branch at the end to the 1456 * instruction epilogue code. The multi-compare approach below needs 1457 * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch 1458 * in the worst case (the 64-bit values are equal). 1459 */ 1460 /* cmp-long vAA, vBB, vCC */ 1461 FETCH(r0, 1) @ r0<- CCBB 1462 mov r9, rINST, lsr #8 @ r9<- AA 1463 and r2, r0, #255 @ r2<- BB 1464 mov r3, r0, lsr #8 @ r3<- CC 1465 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 1466 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 1467 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 1468 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 1469 cmp r1, r3 @ compare (vBB+1, vCC+1) 1470 blt .LOP_CMP_LONG_less @ signed compare on high part 1471 bgt .LOP_CMP_LONG_greater 1472 subs r1, r0, r2 @ r1<- r0 - r2 1473 bhi .LOP_CMP_LONG_greater @ unsigned compare on low part 1474 bne .LOP_CMP_LONG_less 1475 b .LOP_CMP_LONG_finish @ equal; r1 already holds 0 1476 1477/* ------------------------------ */ 1478 .balign 64 1479.L_OP_IF_EQ: /* 0x32 */ 1480/* File: armv6t2/OP_IF_EQ.S */ 1481/* File: armv6t2/bincmp.S */ 1482 /* 1483 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1484 * fragment that specifies the *reverse* comparison to perform, e.g. 1485 * for "if-le" you would use "gt". 1486 * 1487 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1488 */ 1489 /* if-cmp vA, vB, +CCCC */ 1490 mov r1, rINST, lsr #12 @ r1<- B 1491 ubfx r0, rINST, #8, #4 @ r0<- A 1492 GET_VREG(r3, r1) @ r3<- vB 1493 GET_VREG(r2, r0) @ r2<- vA 1494 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1495 cmp r2, r3 @ compare (vA, vB) 1496 bne 1f @ branch to 1 if comparison failed 1497 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1498 movs r9, r9, asl #1 @ convert to bytes, check sign 1499 bmi common_backwardBranch @ yes, do periodic checks 15001: 1501#if defined(WITH_JIT) 1502 GET_JIT_PROF_TABLE(r0) 1503 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1504 b common_testUpdateProfile 1505#else 1506 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1507 GET_INST_OPCODE(ip) @ extract opcode from rINST 1508 GOTO_OPCODE(ip) @ jump to next instruction 1509#endif 1510 1511 1512/* ------------------------------ */ 1513 .balign 64 1514.L_OP_IF_NE: /* 0x33 */ 1515/* File: armv6t2/OP_IF_NE.S */ 1516/* File: armv6t2/bincmp.S */ 1517 /* 1518 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1519 * fragment that specifies the *reverse* comparison to perform, e.g. 1520 * for "if-le" you would use "gt". 1521 * 1522 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1523 */ 1524 /* if-cmp vA, vB, +CCCC */ 1525 mov r1, rINST, lsr #12 @ r1<- B 1526 ubfx r0, rINST, #8, #4 @ r0<- A 1527 GET_VREG(r3, r1) @ r3<- vB 1528 GET_VREG(r2, r0) @ r2<- vA 1529 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1530 cmp r2, r3 @ compare (vA, vB) 1531 beq 1f @ branch to 1 if comparison failed 1532 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1533 movs r9, r9, asl #1 @ convert to bytes, check sign 1534 bmi common_backwardBranch @ yes, do periodic checks 15351: 1536#if defined(WITH_JIT) 1537 GET_JIT_PROF_TABLE(r0) 1538 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1539 b common_testUpdateProfile 1540#else 1541 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1542 GET_INST_OPCODE(ip) @ extract opcode from rINST 1543 GOTO_OPCODE(ip) @ jump to next instruction 1544#endif 1545 1546 1547/* ------------------------------ */ 1548 .balign 64 1549.L_OP_IF_LT: /* 0x34 */ 1550/* File: armv6t2/OP_IF_LT.S */ 1551/* File: armv6t2/bincmp.S */ 1552 /* 1553 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1554 * fragment that specifies the *reverse* comparison to perform, e.g. 1555 * for "if-le" you would use "gt". 1556 * 1557 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1558 */ 1559 /* if-cmp vA, vB, +CCCC */ 1560 mov r1, rINST, lsr #12 @ r1<- B 1561 ubfx r0, rINST, #8, #4 @ r0<- A 1562 GET_VREG(r3, r1) @ r3<- vB 1563 GET_VREG(r2, r0) @ r2<- vA 1564 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1565 cmp r2, r3 @ compare (vA, vB) 1566 bge 1f @ branch to 1 if comparison failed 1567 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1568 movs r9, r9, asl #1 @ convert to bytes, check sign 1569 bmi common_backwardBranch @ yes, do periodic checks 15701: 1571#if defined(WITH_JIT) 1572 GET_JIT_PROF_TABLE(r0) 1573 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1574 b common_testUpdateProfile 1575#else 1576 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1577 GET_INST_OPCODE(ip) @ extract opcode from rINST 1578 GOTO_OPCODE(ip) @ jump to next instruction 1579#endif 1580 1581 1582/* ------------------------------ */ 1583 .balign 64 1584.L_OP_IF_GE: /* 0x35 */ 1585/* File: armv6t2/OP_IF_GE.S */ 1586/* File: armv6t2/bincmp.S */ 1587 /* 1588 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1589 * fragment that specifies the *reverse* comparison to perform, e.g. 1590 * for "if-le" you would use "gt". 1591 * 1592 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1593 */ 1594 /* if-cmp vA, vB, +CCCC */ 1595 mov r1, rINST, lsr #12 @ r1<- B 1596 ubfx r0, rINST, #8, #4 @ r0<- A 1597 GET_VREG(r3, r1) @ r3<- vB 1598 GET_VREG(r2, r0) @ r2<- vA 1599 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1600 cmp r2, r3 @ compare (vA, vB) 1601 blt 1f @ branch to 1 if comparison failed 1602 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1603 movs r9, r9, asl #1 @ convert to bytes, check sign 1604 bmi common_backwardBranch @ yes, do periodic checks 16051: 1606#if defined(WITH_JIT) 1607 GET_JIT_PROF_TABLE(r0) 1608 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1609 b common_testUpdateProfile 1610#else 1611 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1612 GET_INST_OPCODE(ip) @ extract opcode from rINST 1613 GOTO_OPCODE(ip) @ jump to next instruction 1614#endif 1615 1616 1617/* ------------------------------ */ 1618 .balign 64 1619.L_OP_IF_GT: /* 0x36 */ 1620/* File: armv6t2/OP_IF_GT.S */ 1621/* File: armv6t2/bincmp.S */ 1622 /* 1623 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1624 * fragment that specifies the *reverse* comparison to perform, e.g. 1625 * for "if-le" you would use "gt". 1626 * 1627 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1628 */ 1629 /* if-cmp vA, vB, +CCCC */ 1630 mov r1, rINST, lsr #12 @ r1<- B 1631 ubfx r0, rINST, #8, #4 @ r0<- A 1632 GET_VREG(r3, r1) @ r3<- vB 1633 GET_VREG(r2, r0) @ r2<- vA 1634 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1635 cmp r2, r3 @ compare (vA, vB) 1636 ble 1f @ branch to 1 if comparison failed 1637 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1638 movs r9, r9, asl #1 @ convert to bytes, check sign 1639 bmi common_backwardBranch @ yes, do periodic checks 16401: 1641#if defined(WITH_JIT) 1642 GET_JIT_PROF_TABLE(r0) 1643 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1644 b common_testUpdateProfile 1645#else 1646 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1647 GET_INST_OPCODE(ip) @ extract opcode from rINST 1648 GOTO_OPCODE(ip) @ jump to next instruction 1649#endif 1650 1651 1652/* ------------------------------ */ 1653 .balign 64 1654.L_OP_IF_LE: /* 0x37 */ 1655/* File: armv6t2/OP_IF_LE.S */ 1656/* File: armv6t2/bincmp.S */ 1657 /* 1658 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1659 * fragment that specifies the *reverse* comparison to perform, e.g. 1660 * for "if-le" you would use "gt". 1661 * 1662 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1663 */ 1664 /* if-cmp vA, vB, +CCCC */ 1665 mov r1, rINST, lsr #12 @ r1<- B 1666 ubfx r0, rINST, #8, #4 @ r0<- A 1667 GET_VREG(r3, r1) @ r3<- vB 1668 GET_VREG(r2, r0) @ r2<- vA 1669 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1670 cmp r2, r3 @ compare (vA, vB) 1671 bgt 1f @ branch to 1 if comparison failed 1672 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1673 movs r9, r9, asl #1 @ convert to bytes, check sign 1674 bmi common_backwardBranch @ yes, do periodic checks 16751: 1676#if defined(WITH_JIT) 1677 GET_JIT_PROF_TABLE(r0) 1678 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1679 b common_testUpdateProfile 1680#else 1681 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1682 GET_INST_OPCODE(ip) @ extract opcode from rINST 1683 GOTO_OPCODE(ip) @ jump to next instruction 1684#endif 1685 1686 1687/* ------------------------------ */ 1688 .balign 64 1689.L_OP_IF_EQZ: /* 0x38 */ 1690/* File: armv5te/OP_IF_EQZ.S */ 1691/* File: armv5te/zcmp.S */ 1692 /* 1693 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1694 * fragment that specifies the *reverse* comparison to perform, e.g. 1695 * for "if-le" you would use "gt". 1696 * 1697 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1698 */ 1699 /* if-cmp vAA, +BBBB */ 1700 mov r0, rINST, lsr #8 @ r0<- AA 1701 GET_VREG(r2, r0) @ r2<- vAA 1702 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1703 cmp r2, #0 @ compare (vA, 0) 1704 bne 1f @ branch to 1 if comparison failed 1705 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1706 movs r9, r9, asl #1 @ convert to bytes, check sign 1707 bmi common_backwardBranch @ backward branch, do periodic checks 17081: 1709#if defined(WITH_JIT) 1710 GET_JIT_PROF_TABLE(r0) 1711 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1712 cmp r0,#0 1713 bne common_updateProfile 1714 GET_INST_OPCODE(ip) @ extract opcode from rINST 1715 GOTO_OPCODE(ip) @ jump to next instruction 1716#else 1717 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1718 GET_INST_OPCODE(ip) @ extract opcode from rINST 1719 GOTO_OPCODE(ip) @ jump to next instruction 1720#endif 1721 1722 1723/* ------------------------------ */ 1724 .balign 64 1725.L_OP_IF_NEZ: /* 0x39 */ 1726/* File: armv5te/OP_IF_NEZ.S */ 1727/* File: armv5te/zcmp.S */ 1728 /* 1729 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1730 * fragment that specifies the *reverse* comparison to perform, e.g. 1731 * for "if-le" you would use "gt". 1732 * 1733 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1734 */ 1735 /* if-cmp vAA, +BBBB */ 1736 mov r0, rINST, lsr #8 @ r0<- AA 1737 GET_VREG(r2, r0) @ r2<- vAA 1738 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1739 cmp r2, #0 @ compare (vA, 0) 1740 beq 1f @ branch to 1 if comparison failed 1741 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1742 movs r9, r9, asl #1 @ convert to bytes, check sign 1743 bmi common_backwardBranch @ backward branch, do periodic checks 17441: 1745#if defined(WITH_JIT) 1746 GET_JIT_PROF_TABLE(r0) 1747 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1748 cmp r0,#0 1749 bne common_updateProfile 1750 GET_INST_OPCODE(ip) @ extract opcode from rINST 1751 GOTO_OPCODE(ip) @ jump to next instruction 1752#else 1753 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1754 GET_INST_OPCODE(ip) @ extract opcode from rINST 1755 GOTO_OPCODE(ip) @ jump to next instruction 1756#endif 1757 1758 1759/* ------------------------------ */ 1760 .balign 64 1761.L_OP_IF_LTZ: /* 0x3a */ 1762/* File: armv5te/OP_IF_LTZ.S */ 1763/* File: armv5te/zcmp.S */ 1764 /* 1765 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1766 * fragment that specifies the *reverse* comparison to perform, e.g. 1767 * for "if-le" you would use "gt". 1768 * 1769 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1770 */ 1771 /* if-cmp vAA, +BBBB */ 1772 mov r0, rINST, lsr #8 @ r0<- AA 1773 GET_VREG(r2, r0) @ r2<- vAA 1774 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1775 cmp r2, #0 @ compare (vA, 0) 1776 bge 1f @ branch to 1 if comparison failed 1777 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1778 movs r9, r9, asl #1 @ convert to bytes, check sign 1779 bmi common_backwardBranch @ backward branch, do periodic checks 17801: 1781#if defined(WITH_JIT) 1782 GET_JIT_PROF_TABLE(r0) 1783 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1784 cmp r0,#0 1785 bne common_updateProfile 1786 GET_INST_OPCODE(ip) @ extract opcode from rINST 1787 GOTO_OPCODE(ip) @ jump to next instruction 1788#else 1789 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1790 GET_INST_OPCODE(ip) @ extract opcode from rINST 1791 GOTO_OPCODE(ip) @ jump to next instruction 1792#endif 1793 1794 1795/* ------------------------------ */ 1796 .balign 64 1797.L_OP_IF_GEZ: /* 0x3b */ 1798/* File: armv5te/OP_IF_GEZ.S */ 1799/* File: armv5te/zcmp.S */ 1800 /* 1801 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1802 * fragment that specifies the *reverse* comparison to perform, e.g. 1803 * for "if-le" you would use "gt". 1804 * 1805 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1806 */ 1807 /* if-cmp vAA, +BBBB */ 1808 mov r0, rINST, lsr #8 @ r0<- AA 1809 GET_VREG(r2, r0) @ r2<- vAA 1810 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1811 cmp r2, #0 @ compare (vA, 0) 1812 blt 1f @ branch to 1 if comparison failed 1813 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1814 movs r9, r9, asl #1 @ convert to bytes, check sign 1815 bmi common_backwardBranch @ backward branch, do periodic checks 18161: 1817#if defined(WITH_JIT) 1818 GET_JIT_PROF_TABLE(r0) 1819 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1820 cmp r0,#0 1821 bne common_updateProfile 1822 GET_INST_OPCODE(ip) @ extract opcode from rINST 1823 GOTO_OPCODE(ip) @ jump to next instruction 1824#else 1825 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1826 GET_INST_OPCODE(ip) @ extract opcode from rINST 1827 GOTO_OPCODE(ip) @ jump to next instruction 1828#endif 1829 1830 1831/* ------------------------------ */ 1832 .balign 64 1833.L_OP_IF_GTZ: /* 0x3c */ 1834/* File: armv5te/OP_IF_GTZ.S */ 1835/* File: armv5te/zcmp.S */ 1836 /* 1837 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1838 * fragment that specifies the *reverse* comparison to perform, e.g. 1839 * for "if-le" you would use "gt". 1840 * 1841 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1842 */ 1843 /* if-cmp vAA, +BBBB */ 1844 mov r0, rINST, lsr #8 @ r0<- AA 1845 GET_VREG(r2, r0) @ r2<- vAA 1846 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1847 cmp r2, #0 @ compare (vA, 0) 1848 ble 1f @ branch to 1 if comparison failed 1849 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1850 movs r9, r9, asl #1 @ convert to bytes, check sign 1851 bmi common_backwardBranch @ backward branch, do periodic checks 18521: 1853#if defined(WITH_JIT) 1854 GET_JIT_PROF_TABLE(r0) 1855 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1856 cmp r0,#0 1857 bne common_updateProfile 1858 GET_INST_OPCODE(ip) @ extract opcode from rINST 1859 GOTO_OPCODE(ip) @ jump to next instruction 1860#else 1861 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1862 GET_INST_OPCODE(ip) @ extract opcode from rINST 1863 GOTO_OPCODE(ip) @ jump to next instruction 1864#endif 1865 1866 1867/* ------------------------------ */ 1868 .balign 64 1869.L_OP_IF_LEZ: /* 0x3d */ 1870/* File: armv5te/OP_IF_LEZ.S */ 1871/* File: armv5te/zcmp.S */ 1872 /* 1873 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1874 * fragment that specifies the *reverse* comparison to perform, e.g. 1875 * for "if-le" you would use "gt". 1876 * 1877 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1878 */ 1879 /* if-cmp vAA, +BBBB */ 1880 mov r0, rINST, lsr #8 @ r0<- AA 1881 GET_VREG(r2, r0) @ r2<- vAA 1882 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1883 cmp r2, #0 @ compare (vA, 0) 1884 bgt 1f @ branch to 1 if comparison failed 1885 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1886 movs r9, r9, asl #1 @ convert to bytes, check sign 1887 bmi common_backwardBranch @ backward branch, do periodic checks 18881: 1889#if defined(WITH_JIT) 1890 GET_JIT_PROF_TABLE(r0) 1891 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1892 cmp r0,#0 1893 bne common_updateProfile 1894 GET_INST_OPCODE(ip) @ extract opcode from rINST 1895 GOTO_OPCODE(ip) @ jump to next instruction 1896#else 1897 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1898 GET_INST_OPCODE(ip) @ extract opcode from rINST 1899 GOTO_OPCODE(ip) @ jump to next instruction 1900#endif 1901 1902 1903/* ------------------------------ */ 1904 .balign 64 1905.L_OP_UNUSED_3E: /* 0x3e */ 1906/* File: armv5te/OP_UNUSED_3E.S */ 1907/* File: armv5te/unused.S */ 1908 bl common_abort 1909 1910 1911/* ------------------------------ */ 1912 .balign 64 1913.L_OP_UNUSED_3F: /* 0x3f */ 1914/* File: armv5te/OP_UNUSED_3F.S */ 1915/* File: armv5te/unused.S */ 1916 bl common_abort 1917 1918 1919/* ------------------------------ */ 1920 .balign 64 1921.L_OP_UNUSED_40: /* 0x40 */ 1922/* File: armv5te/OP_UNUSED_40.S */ 1923/* File: armv5te/unused.S */ 1924 bl common_abort 1925 1926 1927/* ------------------------------ */ 1928 .balign 64 1929.L_OP_UNUSED_41: /* 0x41 */ 1930/* File: armv5te/OP_UNUSED_41.S */ 1931/* File: armv5te/unused.S */ 1932 bl common_abort 1933 1934 1935/* ------------------------------ */ 1936 .balign 64 1937.L_OP_UNUSED_42: /* 0x42 */ 1938/* File: armv5te/OP_UNUSED_42.S */ 1939/* File: armv5te/unused.S */ 1940 bl common_abort 1941 1942 1943/* ------------------------------ */ 1944 .balign 64 1945.L_OP_UNUSED_43: /* 0x43 */ 1946/* File: armv5te/OP_UNUSED_43.S */ 1947/* File: armv5te/unused.S */ 1948 bl common_abort 1949 1950 1951/* ------------------------------ */ 1952 .balign 64 1953.L_OP_AGET: /* 0x44 */ 1954/* File: armv5te/OP_AGET.S */ 1955 /* 1956 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1957 * 1958 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1959 * instructions. We use a pair of FETCH_Bs instead. 1960 * 1961 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1962 */ 1963 /* op vAA, vBB, vCC */ 1964 FETCH_B(r2, 1, 0) @ r2<- BB 1965 mov r9, rINST, lsr #8 @ r9<- AA 1966 FETCH_B(r3, 1, 1) @ r3<- CC 1967 GET_VREG(r0, r2) @ r0<- vBB (array object) 1968 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1969 cmp r0, #0 @ null array object? 1970 beq common_errNullObject @ yes, bail 1971 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1972 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 1973 cmp r1, r3 @ compare unsigned index, length 1974 bcs common_errArrayIndex @ index >= length, bail 1975 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1976 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 1977 GET_INST_OPCODE(ip) @ extract opcode from rINST 1978 SET_VREG(r2, r9) @ vAA<- r2 1979 GOTO_OPCODE(ip) @ jump to next instruction 1980 1981/* ------------------------------ */ 1982 .balign 64 1983.L_OP_AGET_WIDE: /* 0x45 */ 1984/* File: armv5te/OP_AGET_WIDE.S */ 1985 /* 1986 * Array get, 64 bits. vAA <- vBB[vCC]. 1987 * 1988 * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD. 1989 */ 1990 /* aget-wide vAA, vBB, vCC */ 1991 FETCH(r0, 1) @ r0<- CCBB 1992 mov r9, rINST, lsr #8 @ r9<- AA 1993 and r2, r0, #255 @ r2<- BB 1994 mov r3, r0, lsr #8 @ r3<- CC 1995 GET_VREG(r0, r2) @ r0<- vBB (array object) 1996 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1997 cmp r0, #0 @ null array object? 1998 beq common_errNullObject @ yes, bail 1999 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2000 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 2001 cmp r1, r3 @ compare unsigned index, length 2002 bcc .LOP_AGET_WIDE_finish @ okay, continue below 2003 b common_errArrayIndex @ index >= length, bail 2004 @ May want to swap the order of these two branches depending on how the 2005 @ branch prediction (if any) handles conditional forward branches vs. 2006 @ unconditional forward branches. 2007 2008/* ------------------------------ */ 2009 .balign 64 2010.L_OP_AGET_OBJECT: /* 0x46 */ 2011/* File: armv5te/OP_AGET_OBJECT.S */ 2012/* File: armv5te/OP_AGET.S */ 2013 /* 2014 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2015 * 2016 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2017 * instructions. We use a pair of FETCH_Bs instead. 2018 * 2019 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2020 */ 2021 /* op vAA, vBB, vCC */ 2022 FETCH_B(r2, 1, 0) @ r2<- BB 2023 mov r9, rINST, lsr #8 @ r9<- AA 2024 FETCH_B(r3, 1, 1) @ r3<- CC 2025 GET_VREG(r0, r2) @ r0<- vBB (array object) 2026 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2027 cmp r0, #0 @ null array object? 2028 beq common_errNullObject @ yes, bail 2029 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2030 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 2031 cmp r1, r3 @ compare unsigned index, length 2032 bcs common_errArrayIndex @ index >= length, bail 2033 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2034 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2035 GET_INST_OPCODE(ip) @ extract opcode from rINST 2036 SET_VREG(r2, r9) @ vAA<- r2 2037 GOTO_OPCODE(ip) @ jump to next instruction 2038 2039 2040/* ------------------------------ */ 2041 .balign 64 2042.L_OP_AGET_BOOLEAN: /* 0x47 */ 2043/* File: armv5te/OP_AGET_BOOLEAN.S */ 2044/* File: armv5te/OP_AGET.S */ 2045 /* 2046 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2047 * 2048 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2049 * instructions. We use a pair of FETCH_Bs instead. 2050 * 2051 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2052 */ 2053 /* op vAA, vBB, vCC */ 2054 FETCH_B(r2, 1, 0) @ r2<- BB 2055 mov r9, rINST, lsr #8 @ r9<- AA 2056 FETCH_B(r3, 1, 1) @ r3<- CC 2057 GET_VREG(r0, r2) @ r0<- vBB (array object) 2058 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2059 cmp r0, #0 @ null array object? 2060 beq common_errNullObject @ yes, bail 2061 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2062 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2063 cmp r1, r3 @ compare unsigned index, length 2064 bcs common_errArrayIndex @ index >= length, bail 2065 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2066 ldrb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2067 GET_INST_OPCODE(ip) @ extract opcode from rINST 2068 SET_VREG(r2, r9) @ vAA<- r2 2069 GOTO_OPCODE(ip) @ jump to next instruction 2070 2071 2072/* ------------------------------ */ 2073 .balign 64 2074.L_OP_AGET_BYTE: /* 0x48 */ 2075/* File: armv5te/OP_AGET_BYTE.S */ 2076/* File: armv5te/OP_AGET.S */ 2077 /* 2078 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2079 * 2080 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2081 * instructions. We use a pair of FETCH_Bs instead. 2082 * 2083 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2084 */ 2085 /* op vAA, vBB, vCC */ 2086 FETCH_B(r2, 1, 0) @ r2<- BB 2087 mov r9, rINST, lsr #8 @ r9<- AA 2088 FETCH_B(r3, 1, 1) @ r3<- CC 2089 GET_VREG(r0, r2) @ r0<- vBB (array object) 2090 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2091 cmp r0, #0 @ null array object? 2092 beq common_errNullObject @ yes, bail 2093 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2094 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2095 cmp r1, r3 @ compare unsigned index, length 2096 bcs common_errArrayIndex @ index >= length, bail 2097 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2098 ldrsb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2099 GET_INST_OPCODE(ip) @ extract opcode from rINST 2100 SET_VREG(r2, r9) @ vAA<- r2 2101 GOTO_OPCODE(ip) @ jump to next instruction 2102 2103 2104/* ------------------------------ */ 2105 .balign 64 2106.L_OP_AGET_CHAR: /* 0x49 */ 2107/* File: armv5te/OP_AGET_CHAR.S */ 2108/* File: armv5te/OP_AGET.S */ 2109 /* 2110 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2111 * 2112 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2113 * instructions. We use a pair of FETCH_Bs instead. 2114 * 2115 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2116 */ 2117 /* op vAA, vBB, vCC */ 2118 FETCH_B(r2, 1, 0) @ r2<- BB 2119 mov r9, rINST, lsr #8 @ r9<- AA 2120 FETCH_B(r3, 1, 1) @ r3<- CC 2121 GET_VREG(r0, r2) @ r0<- vBB (array object) 2122 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2123 cmp r0, #0 @ null array object? 2124 beq common_errNullObject @ yes, bail 2125 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2126 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2127 cmp r1, r3 @ compare unsigned index, length 2128 bcs common_errArrayIndex @ index >= length, bail 2129 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2130 ldrh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2131 GET_INST_OPCODE(ip) @ extract opcode from rINST 2132 SET_VREG(r2, r9) @ vAA<- r2 2133 GOTO_OPCODE(ip) @ jump to next instruction 2134 2135 2136/* ------------------------------ */ 2137 .balign 64 2138.L_OP_AGET_SHORT: /* 0x4a */ 2139/* File: armv5te/OP_AGET_SHORT.S */ 2140/* File: armv5te/OP_AGET.S */ 2141 /* 2142 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2143 * 2144 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2145 * instructions. We use a pair of FETCH_Bs instead. 2146 * 2147 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2148 */ 2149 /* op vAA, vBB, vCC */ 2150 FETCH_B(r2, 1, 0) @ r2<- BB 2151 mov r9, rINST, lsr #8 @ r9<- AA 2152 FETCH_B(r3, 1, 1) @ r3<- CC 2153 GET_VREG(r0, r2) @ r0<- vBB (array object) 2154 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2155 cmp r0, #0 @ null array object? 2156 beq common_errNullObject @ yes, bail 2157 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2158 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2159 cmp r1, r3 @ compare unsigned index, length 2160 bcs common_errArrayIndex @ index >= length, bail 2161 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2162 ldrsh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2163 GET_INST_OPCODE(ip) @ extract opcode from rINST 2164 SET_VREG(r2, r9) @ vAA<- r2 2165 GOTO_OPCODE(ip) @ jump to next instruction 2166 2167 2168/* ------------------------------ */ 2169 .balign 64 2170.L_OP_APUT: /* 0x4b */ 2171/* File: armv5te/OP_APUT.S */ 2172 /* 2173 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2174 * 2175 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2176 * instructions. We use a pair of FETCH_Bs instead. 2177 * 2178 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2179 */ 2180 /* op vAA, vBB, vCC */ 2181 FETCH_B(r2, 1, 0) @ r2<- BB 2182 mov r9, rINST, lsr #8 @ r9<- AA 2183 FETCH_B(r3, 1, 1) @ r3<- CC 2184 GET_VREG(r0, r2) @ r0<- vBB (array object) 2185 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2186 cmp r0, #0 @ null array object? 2187 beq common_errNullObject @ yes, bail 2188 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2189 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 2190 cmp r1, r3 @ compare unsigned index, length 2191 bcs common_errArrayIndex @ index >= length, bail 2192 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2193 GET_VREG(r2, r9) @ r2<- vAA 2194 GET_INST_OPCODE(ip) @ extract opcode from rINST 2195 str r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2196 GOTO_OPCODE(ip) @ jump to next instruction 2197 2198/* ------------------------------ */ 2199 .balign 64 2200.L_OP_APUT_WIDE: /* 0x4c */ 2201/* File: armv5te/OP_APUT_WIDE.S */ 2202 /* 2203 * Array put, 64 bits. vBB[vCC] <- vAA. 2204 * 2205 * Arrays of long/double are 64-bit aligned, so it's okay to use STRD. 2206 */ 2207 /* aput-wide vAA, vBB, vCC */ 2208 FETCH(r0, 1) @ r0<- CCBB 2209 mov r9, rINST, lsr #8 @ r9<- AA 2210 and r2, r0, #255 @ r2<- BB 2211 mov r3, r0, lsr #8 @ r3<- CC 2212 GET_VREG(r0, r2) @ r0<- vBB (array object) 2213 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2214 cmp r0, #0 @ null array object? 2215 beq common_errNullObject @ yes, bail 2216 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2217 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 2218 cmp r1, r3 @ compare unsigned index, length 2219 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2220 bcc .LOP_APUT_WIDE_finish @ okay, continue below 2221 b common_errArrayIndex @ index >= length, bail 2222 @ May want to swap the order of these two branches depending on how the 2223 @ branch prediction (if any) handles conditional forward branches vs. 2224 @ unconditional forward branches. 2225 2226/* ------------------------------ */ 2227 .balign 64 2228.L_OP_APUT_OBJECT: /* 0x4d */ 2229/* File: armv5te/OP_APUT_OBJECT.S */ 2230 /* 2231 * Store an object into an array. vBB[vCC] <- vAA. 2232 */ 2233 /* op vAA, vBB, vCC */ 2234 FETCH(r0, 1) @ r0<- CCBB 2235 mov r9, rINST, lsr #8 @ r9<- AA 2236 and r2, r0, #255 @ r2<- BB 2237 mov r3, r0, lsr #8 @ r3<- CC 2238 GET_VREG(rINST, r2) @ rINST<- vBB (array object) 2239 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2240 cmp rINST, #0 @ null array object? 2241 GET_VREG(r9, r9) @ r9<- vAA 2242 beq common_errNullObject @ yes, bail 2243 ldr r3, [rINST, #offArrayObject_length] @ r3<- arrayObj->length 2244 add r10, rINST, r1, lsl #2 @ r10<- arrayObj + index*width 2245 cmp r1, r3 @ compare unsigned index, length 2246 bcc .LOP_APUT_OBJECT_finish @ we're okay, continue on 2247 b common_errArrayIndex @ index >= length, bail 2248 2249 2250/* ------------------------------ */ 2251 .balign 64 2252.L_OP_APUT_BOOLEAN: /* 0x4e */ 2253/* File: armv5te/OP_APUT_BOOLEAN.S */ 2254/* File: armv5te/OP_APUT.S */ 2255 /* 2256 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2257 * 2258 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2259 * instructions. We use a pair of FETCH_Bs instead. 2260 * 2261 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2262 */ 2263 /* op vAA, vBB, vCC */ 2264 FETCH_B(r2, 1, 0) @ r2<- BB 2265 mov r9, rINST, lsr #8 @ r9<- AA 2266 FETCH_B(r3, 1, 1) @ r3<- CC 2267 GET_VREG(r0, r2) @ r0<- vBB (array object) 2268 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2269 cmp r0, #0 @ null array object? 2270 beq common_errNullObject @ yes, bail 2271 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2272 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2273 cmp r1, r3 @ compare unsigned index, length 2274 bcs common_errArrayIndex @ index >= length, bail 2275 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2276 GET_VREG(r2, r9) @ r2<- vAA 2277 GET_INST_OPCODE(ip) @ extract opcode from rINST 2278 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2279 GOTO_OPCODE(ip) @ jump to next instruction 2280 2281 2282/* ------------------------------ */ 2283 .balign 64 2284.L_OP_APUT_BYTE: /* 0x4f */ 2285/* File: armv5te/OP_APUT_BYTE.S */ 2286/* File: armv5te/OP_APUT.S */ 2287 /* 2288 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2289 * 2290 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2291 * instructions. We use a pair of FETCH_Bs instead. 2292 * 2293 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2294 */ 2295 /* op vAA, vBB, vCC */ 2296 FETCH_B(r2, 1, 0) @ r2<- BB 2297 mov r9, rINST, lsr #8 @ r9<- AA 2298 FETCH_B(r3, 1, 1) @ r3<- CC 2299 GET_VREG(r0, r2) @ r0<- vBB (array object) 2300 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2301 cmp r0, #0 @ null array object? 2302 beq common_errNullObject @ yes, bail 2303 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2304 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2305 cmp r1, r3 @ compare unsigned index, length 2306 bcs common_errArrayIndex @ index >= length, bail 2307 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2308 GET_VREG(r2, r9) @ r2<- vAA 2309 GET_INST_OPCODE(ip) @ extract opcode from rINST 2310 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2311 GOTO_OPCODE(ip) @ jump to next instruction 2312 2313 2314/* ------------------------------ */ 2315 .balign 64 2316.L_OP_APUT_CHAR: /* 0x50 */ 2317/* File: armv5te/OP_APUT_CHAR.S */ 2318/* File: armv5te/OP_APUT.S */ 2319 /* 2320 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2321 * 2322 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2323 * instructions. We use a pair of FETCH_Bs instead. 2324 * 2325 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2326 */ 2327 /* op vAA, vBB, vCC */ 2328 FETCH_B(r2, 1, 0) @ r2<- BB 2329 mov r9, rINST, lsr #8 @ r9<- AA 2330 FETCH_B(r3, 1, 1) @ r3<- CC 2331 GET_VREG(r0, r2) @ r0<- vBB (array object) 2332 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2333 cmp r0, #0 @ null array object? 2334 beq common_errNullObject @ yes, bail 2335 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2336 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2337 cmp r1, r3 @ compare unsigned index, length 2338 bcs common_errArrayIndex @ index >= length, bail 2339 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2340 GET_VREG(r2, r9) @ r2<- vAA 2341 GET_INST_OPCODE(ip) @ extract opcode from rINST 2342 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2343 GOTO_OPCODE(ip) @ jump to next instruction 2344 2345 2346/* ------------------------------ */ 2347 .balign 64 2348.L_OP_APUT_SHORT: /* 0x51 */ 2349/* File: armv5te/OP_APUT_SHORT.S */ 2350/* File: armv5te/OP_APUT.S */ 2351 /* 2352 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2353 * 2354 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2355 * instructions. We use a pair of FETCH_Bs instead. 2356 * 2357 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2358 */ 2359 /* op vAA, vBB, vCC */ 2360 FETCH_B(r2, 1, 0) @ r2<- BB 2361 mov r9, rINST, lsr #8 @ r9<- AA 2362 FETCH_B(r3, 1, 1) @ r3<- CC 2363 GET_VREG(r0, r2) @ r0<- vBB (array object) 2364 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2365 cmp r0, #0 @ null array object? 2366 beq common_errNullObject @ yes, bail 2367 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2368 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2369 cmp r1, r3 @ compare unsigned index, length 2370 bcs common_errArrayIndex @ index >= length, bail 2371 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2372 GET_VREG(r2, r9) @ r2<- vAA 2373 GET_INST_OPCODE(ip) @ extract opcode from rINST 2374 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2375 GOTO_OPCODE(ip) @ jump to next instruction 2376 2377 2378/* ------------------------------ */ 2379 .balign 64 2380.L_OP_IGET: /* 0x52 */ 2381/* File: armv6t2/OP_IGET.S */ 2382 /* 2383 * General 32-bit instance field get. 2384 * 2385 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2386 */ 2387 /* op vA, vB, field@CCCC */ 2388 mov r0, rINST, lsr #12 @ r0<- B 2389 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2390 FETCH(r1, 1) @ r1<- field ref CCCC 2391 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2392 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2393 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2394 cmp r0, #0 @ is resolved entry null? 2395 bne .LOP_IGET_finish @ no, already resolved 23968: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2397 EXPORT_PC() @ resolve() could throw 2398 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2399 bl dvmResolveInstField @ r0<- resolved InstField ptr 2400 cmp r0, #0 2401 bne .LOP_IGET_finish 2402 b common_exceptionThrown 2403 2404/* ------------------------------ */ 2405 .balign 64 2406.L_OP_IGET_WIDE: /* 0x53 */ 2407/* File: armv6t2/OP_IGET_WIDE.S */ 2408 /* 2409 * Wide 32-bit instance field get. 2410 */ 2411 /* iget-wide vA, vB, field@CCCC */ 2412 mov r0, rINST, lsr #12 @ r0<- B 2413 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2414 FETCH(r1, 1) @ r1<- field ref CCCC 2415 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2416 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2417 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2418 cmp r0, #0 @ is resolved entry null? 2419 bne .LOP_IGET_WIDE_finish @ no, already resolved 24208: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2421 EXPORT_PC() @ resolve() could throw 2422 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2423 bl dvmResolveInstField @ r0<- resolved InstField ptr 2424 cmp r0, #0 2425 bne .LOP_IGET_WIDE_finish 2426 b common_exceptionThrown 2427 2428/* ------------------------------ */ 2429 .balign 64 2430.L_OP_IGET_OBJECT: /* 0x54 */ 2431/* File: armv5te/OP_IGET_OBJECT.S */ 2432/* File: armv5te/OP_IGET.S */ 2433 /* 2434 * General 32-bit instance field get. 2435 * 2436 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2437 */ 2438 /* op vA, vB, field@CCCC */ 2439 mov r0, rINST, lsr #12 @ r0<- B 2440 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2441 FETCH(r1, 1) @ r1<- field ref CCCC 2442 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2443 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2444 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2445 cmp r0, #0 @ is resolved entry null? 2446 bne .LOP_IGET_OBJECT_finish @ no, already resolved 24478: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2448 EXPORT_PC() @ resolve() could throw 2449 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2450 bl dvmResolveInstField @ r0<- resolved InstField ptr 2451 cmp r0, #0 2452 bne .LOP_IGET_OBJECT_finish 2453 b common_exceptionThrown 2454 2455 2456/* ------------------------------ */ 2457 .balign 64 2458.L_OP_IGET_BOOLEAN: /* 0x55 */ 2459/* File: armv5te/OP_IGET_BOOLEAN.S */ 2460@include "armv5te/OP_IGET.S" { "load":"ldrb", "sqnum":"1" } 2461/* File: armv5te/OP_IGET.S */ 2462 /* 2463 * General 32-bit instance field get. 2464 * 2465 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2466 */ 2467 /* op vA, vB, field@CCCC */ 2468 mov r0, rINST, lsr #12 @ r0<- B 2469 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2470 FETCH(r1, 1) @ r1<- field ref CCCC 2471 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2472 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2473 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2474 cmp r0, #0 @ is resolved entry null? 2475 bne .LOP_IGET_BOOLEAN_finish @ no, already resolved 24768: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2477 EXPORT_PC() @ resolve() could throw 2478 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2479 bl dvmResolveInstField @ r0<- resolved InstField ptr 2480 cmp r0, #0 2481 bne .LOP_IGET_BOOLEAN_finish 2482 b common_exceptionThrown 2483 2484 2485/* ------------------------------ */ 2486 .balign 64 2487.L_OP_IGET_BYTE: /* 0x56 */ 2488/* File: armv5te/OP_IGET_BYTE.S */ 2489@include "armv5te/OP_IGET.S" { "load":"ldrsb", "sqnum":"2" } 2490/* File: armv5te/OP_IGET.S */ 2491 /* 2492 * General 32-bit instance field get. 2493 * 2494 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2495 */ 2496 /* op vA, vB, field@CCCC */ 2497 mov r0, rINST, lsr #12 @ r0<- B 2498 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2499 FETCH(r1, 1) @ r1<- field ref CCCC 2500 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2501 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2502 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2503 cmp r0, #0 @ is resolved entry null? 2504 bne .LOP_IGET_BYTE_finish @ no, already resolved 25058: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2506 EXPORT_PC() @ resolve() could throw 2507 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2508 bl dvmResolveInstField @ r0<- resolved InstField ptr 2509 cmp r0, #0 2510 bne .LOP_IGET_BYTE_finish 2511 b common_exceptionThrown 2512 2513 2514/* ------------------------------ */ 2515 .balign 64 2516.L_OP_IGET_CHAR: /* 0x57 */ 2517/* File: armv5te/OP_IGET_CHAR.S */ 2518@include "armv5te/OP_IGET.S" { "load":"ldrh", "sqnum":"3" } 2519/* File: armv5te/OP_IGET.S */ 2520 /* 2521 * General 32-bit instance field get. 2522 * 2523 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2524 */ 2525 /* op vA, vB, field@CCCC */ 2526 mov r0, rINST, lsr #12 @ r0<- B 2527 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2528 FETCH(r1, 1) @ r1<- field ref CCCC 2529 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2530 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2531 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2532 cmp r0, #0 @ is resolved entry null? 2533 bne .LOP_IGET_CHAR_finish @ no, already resolved 25348: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2535 EXPORT_PC() @ resolve() could throw 2536 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2537 bl dvmResolveInstField @ r0<- resolved InstField ptr 2538 cmp r0, #0 2539 bne .LOP_IGET_CHAR_finish 2540 b common_exceptionThrown 2541 2542 2543/* ------------------------------ */ 2544 .balign 64 2545.L_OP_IGET_SHORT: /* 0x58 */ 2546/* File: armv5te/OP_IGET_SHORT.S */ 2547@include "armv5te/OP_IGET.S" { "load":"ldrsh", "sqnum":"4" } 2548/* File: armv5te/OP_IGET.S */ 2549 /* 2550 * General 32-bit instance field get. 2551 * 2552 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2553 */ 2554 /* op vA, vB, field@CCCC */ 2555 mov r0, rINST, lsr #12 @ r0<- B 2556 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2557 FETCH(r1, 1) @ r1<- field ref CCCC 2558 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2559 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2560 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2561 cmp r0, #0 @ is resolved entry null? 2562 bne .LOP_IGET_SHORT_finish @ no, already resolved 25638: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2564 EXPORT_PC() @ resolve() could throw 2565 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2566 bl dvmResolveInstField @ r0<- resolved InstField ptr 2567 cmp r0, #0 2568 bne .LOP_IGET_SHORT_finish 2569 b common_exceptionThrown 2570 2571 2572/* ------------------------------ */ 2573 .balign 64 2574.L_OP_IPUT: /* 0x59 */ 2575/* File: armv6t2/OP_IPUT.S */ 2576 /* 2577 * General 32-bit instance field put. 2578 * 2579 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 2580 */ 2581 /* op vA, vB, field@CCCC */ 2582 mov r0, rINST, lsr #12 @ r0<- B 2583 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2584 FETCH(r1, 1) @ r1<- field ref CCCC 2585 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2586 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2587 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2588 cmp r0, #0 @ is resolved entry null? 2589 bne .LOP_IPUT_finish @ no, already resolved 25908: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2591 EXPORT_PC() @ resolve() could throw 2592 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2593 bl dvmResolveInstField @ r0<- resolved InstField ptr 2594 cmp r0, #0 @ success? 2595 bne .LOP_IPUT_finish @ yes, finish up 2596 b common_exceptionThrown 2597 2598/* ------------------------------ */ 2599 .balign 64 2600.L_OP_IPUT_WIDE: /* 0x5a */ 2601/* File: armv6t2/OP_IPUT_WIDE.S */ 2602 /* iput-wide vA, vB, field@CCCC */ 2603 mov r0, rINST, lsr #12 @ r0<- B 2604 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2605 FETCH(r1, 1) @ r1<- field ref CCCC 2606 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2607 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2608 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2609 cmp r0, #0 @ is resolved entry null? 2610 bne .LOP_IPUT_WIDE_finish @ no, already resolved 26118: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2612 EXPORT_PC() @ resolve() could throw 2613 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2614 bl dvmResolveInstField @ r0<- resolved InstField ptr 2615 cmp r0, #0 @ success? 2616 bne .LOP_IPUT_WIDE_finish @ yes, finish up 2617 b common_exceptionThrown 2618 2619/* ------------------------------ */ 2620 .balign 64 2621.L_OP_IPUT_OBJECT: /* 0x5b */ 2622/* File: armv5te/OP_IPUT_OBJECT.S */ 2623 /* 2624 * 32-bit instance field put. 2625 * 2626 * for: iput-object, iput-object-volatile 2627 */ 2628 /* op vA, vB, field@CCCC */ 2629 mov r0, rINST, lsr #12 @ r0<- B 2630 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2631 FETCH(r1, 1) @ r1<- field ref CCCC 2632 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2633 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2634 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2635 cmp r0, #0 @ is resolved entry null? 2636 bne .LOP_IPUT_OBJECT_finish @ no, already resolved 26378: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2638 EXPORT_PC() @ resolve() could throw 2639 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2640 bl dvmResolveInstField @ r0<- resolved InstField ptr 2641 cmp r0, #0 @ success? 2642 bne .LOP_IPUT_OBJECT_finish @ yes, finish up 2643 b common_exceptionThrown 2644 2645/* ------------------------------ */ 2646 .balign 64 2647.L_OP_IPUT_BOOLEAN: /* 0x5c */ 2648/* File: armv5te/OP_IPUT_BOOLEAN.S */ 2649@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"1" } 2650/* File: armv5te/OP_IPUT.S */ 2651 /* 2652 * General 32-bit instance field put. 2653 * 2654 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2655 */ 2656 /* op vA, vB, field@CCCC */ 2657 mov r0, rINST, lsr #12 @ r0<- B 2658 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2659 FETCH(r1, 1) @ r1<- field ref CCCC 2660 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2661 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2662 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2663 cmp r0, #0 @ is resolved entry null? 2664 bne .LOP_IPUT_BOOLEAN_finish @ no, already resolved 26658: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2666 EXPORT_PC() @ resolve() could throw 2667 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2668 bl dvmResolveInstField @ r0<- resolved InstField ptr 2669 cmp r0, #0 @ success? 2670 bne .LOP_IPUT_BOOLEAN_finish @ yes, finish up 2671 b common_exceptionThrown 2672 2673 2674/* ------------------------------ */ 2675 .balign 64 2676.L_OP_IPUT_BYTE: /* 0x5d */ 2677/* File: armv5te/OP_IPUT_BYTE.S */ 2678@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"2" } 2679/* File: armv5te/OP_IPUT.S */ 2680 /* 2681 * General 32-bit instance field put. 2682 * 2683 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2684 */ 2685 /* op vA, vB, field@CCCC */ 2686 mov r0, rINST, lsr #12 @ r0<- B 2687 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2688 FETCH(r1, 1) @ r1<- field ref CCCC 2689 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2690 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2691 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2692 cmp r0, #0 @ is resolved entry null? 2693 bne .LOP_IPUT_BYTE_finish @ no, already resolved 26948: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2695 EXPORT_PC() @ resolve() could throw 2696 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2697 bl dvmResolveInstField @ r0<- resolved InstField ptr 2698 cmp r0, #0 @ success? 2699 bne .LOP_IPUT_BYTE_finish @ yes, finish up 2700 b common_exceptionThrown 2701 2702 2703/* ------------------------------ */ 2704 .balign 64 2705.L_OP_IPUT_CHAR: /* 0x5e */ 2706/* File: armv5te/OP_IPUT_CHAR.S */ 2707@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"3" } 2708/* File: armv5te/OP_IPUT.S */ 2709 /* 2710 * General 32-bit instance field put. 2711 * 2712 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2713 */ 2714 /* op vA, vB, field@CCCC */ 2715 mov r0, rINST, lsr #12 @ r0<- B 2716 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2717 FETCH(r1, 1) @ r1<- field ref CCCC 2718 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2719 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2720 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2721 cmp r0, #0 @ is resolved entry null? 2722 bne .LOP_IPUT_CHAR_finish @ no, already resolved 27238: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2724 EXPORT_PC() @ resolve() could throw 2725 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2726 bl dvmResolveInstField @ r0<- resolved InstField ptr 2727 cmp r0, #0 @ success? 2728 bne .LOP_IPUT_CHAR_finish @ yes, finish up 2729 b common_exceptionThrown 2730 2731 2732/* ------------------------------ */ 2733 .balign 64 2734.L_OP_IPUT_SHORT: /* 0x5f */ 2735/* File: armv5te/OP_IPUT_SHORT.S */ 2736@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"4" } 2737/* File: armv5te/OP_IPUT.S */ 2738 /* 2739 * General 32-bit instance field put. 2740 * 2741 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2742 */ 2743 /* op vA, vB, field@CCCC */ 2744 mov r0, rINST, lsr #12 @ r0<- B 2745 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2746 FETCH(r1, 1) @ r1<- field ref CCCC 2747 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2748 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2749 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2750 cmp r0, #0 @ is resolved entry null? 2751 bne .LOP_IPUT_SHORT_finish @ no, already resolved 27528: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2753 EXPORT_PC() @ resolve() could throw 2754 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2755 bl dvmResolveInstField @ r0<- resolved InstField ptr 2756 cmp r0, #0 @ success? 2757 bne .LOP_IPUT_SHORT_finish @ yes, finish up 2758 b common_exceptionThrown 2759 2760 2761/* ------------------------------ */ 2762 .balign 64 2763.L_OP_SGET: /* 0x60 */ 2764/* File: armv5te/OP_SGET.S */ 2765 /* 2766 * General 32-bit SGET handler. 2767 * 2768 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2769 */ 2770 /* op vAA, field@BBBB */ 2771 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2772 FETCH(r1, 1) @ r1<- field ref BBBB 2773 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2774 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2775 cmp r0, #0 @ is resolved entry null? 2776 beq .LOP_SGET_resolve @ yes, do resolve 2777.LOP_SGET_finish: @ field ptr in r0 2778 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2779 @ no-op @ acquiring load 2780 mov r2, rINST, lsr #8 @ r2<- AA 2781 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2782 SET_VREG(r1, r2) @ fp[AA]<- r1 2783 GET_INST_OPCODE(ip) @ extract opcode from rINST 2784 GOTO_OPCODE(ip) @ jump to next instruction 2785 2786/* ------------------------------ */ 2787 .balign 64 2788.L_OP_SGET_WIDE: /* 0x61 */ 2789/* File: armv5te/OP_SGET_WIDE.S */ 2790 /* 2791 * 64-bit SGET handler. 2792 */ 2793 /* sget-wide vAA, field@BBBB */ 2794 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2795 FETCH(r1, 1) @ r1<- field ref BBBB 2796 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2797 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2798 cmp r0, #0 @ is resolved entry null? 2799 beq .LOP_SGET_WIDE_resolve @ yes, do resolve 2800.LOP_SGET_WIDE_finish: 2801 mov r9, rINST, lsr #8 @ r9<- AA 2802 .if 0 2803 add r0, r0, #offStaticField_value @ r0<- pointer to data 2804 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 2805 .else 2806 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 2807 .endif 2808 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2809 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2810 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 2811 GET_INST_OPCODE(ip) @ extract opcode from rINST 2812 GOTO_OPCODE(ip) @ jump to next instruction 2813 2814/* ------------------------------ */ 2815 .balign 64 2816.L_OP_SGET_OBJECT: /* 0x62 */ 2817/* File: armv5te/OP_SGET_OBJECT.S */ 2818/* File: armv5te/OP_SGET.S */ 2819 /* 2820 * General 32-bit SGET handler. 2821 * 2822 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2823 */ 2824 /* op vAA, field@BBBB */ 2825 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2826 FETCH(r1, 1) @ r1<- field ref BBBB 2827 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2828 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2829 cmp r0, #0 @ is resolved entry null? 2830 beq .LOP_SGET_OBJECT_resolve @ yes, do resolve 2831.LOP_SGET_OBJECT_finish: @ field ptr in r0 2832 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2833 @ no-op @ acquiring load 2834 mov r2, rINST, lsr #8 @ r2<- AA 2835 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2836 SET_VREG(r1, r2) @ fp[AA]<- r1 2837 GET_INST_OPCODE(ip) @ extract opcode from rINST 2838 GOTO_OPCODE(ip) @ jump to next instruction 2839 2840 2841/* ------------------------------ */ 2842 .balign 64 2843.L_OP_SGET_BOOLEAN: /* 0x63 */ 2844/* File: armv5te/OP_SGET_BOOLEAN.S */ 2845/* File: armv5te/OP_SGET.S */ 2846 /* 2847 * General 32-bit SGET handler. 2848 * 2849 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2850 */ 2851 /* op vAA, field@BBBB */ 2852 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2853 FETCH(r1, 1) @ r1<- field ref BBBB 2854 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2855 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2856 cmp r0, #0 @ is resolved entry null? 2857 beq .LOP_SGET_BOOLEAN_resolve @ yes, do resolve 2858.LOP_SGET_BOOLEAN_finish: @ field ptr in r0 2859 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2860 @ no-op @ acquiring load 2861 mov r2, rINST, lsr #8 @ r2<- AA 2862 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2863 SET_VREG(r1, r2) @ fp[AA]<- r1 2864 GET_INST_OPCODE(ip) @ extract opcode from rINST 2865 GOTO_OPCODE(ip) @ jump to next instruction 2866 2867 2868/* ------------------------------ */ 2869 .balign 64 2870.L_OP_SGET_BYTE: /* 0x64 */ 2871/* File: armv5te/OP_SGET_BYTE.S */ 2872/* File: armv5te/OP_SGET.S */ 2873 /* 2874 * General 32-bit SGET handler. 2875 * 2876 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2877 */ 2878 /* op vAA, field@BBBB */ 2879 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2880 FETCH(r1, 1) @ r1<- field ref BBBB 2881 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2882 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2883 cmp r0, #0 @ is resolved entry null? 2884 beq .LOP_SGET_BYTE_resolve @ yes, do resolve 2885.LOP_SGET_BYTE_finish: @ field ptr in r0 2886 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2887 @ no-op @ acquiring load 2888 mov r2, rINST, lsr #8 @ r2<- AA 2889 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2890 SET_VREG(r1, r2) @ fp[AA]<- r1 2891 GET_INST_OPCODE(ip) @ extract opcode from rINST 2892 GOTO_OPCODE(ip) @ jump to next instruction 2893 2894 2895/* ------------------------------ */ 2896 .balign 64 2897.L_OP_SGET_CHAR: /* 0x65 */ 2898/* File: armv5te/OP_SGET_CHAR.S */ 2899/* File: armv5te/OP_SGET.S */ 2900 /* 2901 * General 32-bit SGET handler. 2902 * 2903 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2904 */ 2905 /* op vAA, field@BBBB */ 2906 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2907 FETCH(r1, 1) @ r1<- field ref BBBB 2908 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2909 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2910 cmp r0, #0 @ is resolved entry null? 2911 beq .LOP_SGET_CHAR_resolve @ yes, do resolve 2912.LOP_SGET_CHAR_finish: @ field ptr in r0 2913 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2914 @ no-op @ acquiring load 2915 mov r2, rINST, lsr #8 @ r2<- AA 2916 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2917 SET_VREG(r1, r2) @ fp[AA]<- r1 2918 GET_INST_OPCODE(ip) @ extract opcode from rINST 2919 GOTO_OPCODE(ip) @ jump to next instruction 2920 2921 2922/* ------------------------------ */ 2923 .balign 64 2924.L_OP_SGET_SHORT: /* 0x66 */ 2925/* File: armv5te/OP_SGET_SHORT.S */ 2926/* File: armv5te/OP_SGET.S */ 2927 /* 2928 * General 32-bit SGET handler. 2929 * 2930 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2931 */ 2932 /* op vAA, field@BBBB */ 2933 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2934 FETCH(r1, 1) @ r1<- field ref BBBB 2935 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2936 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2937 cmp r0, #0 @ is resolved entry null? 2938 beq .LOP_SGET_SHORT_resolve @ yes, do resolve 2939.LOP_SGET_SHORT_finish: @ field ptr in r0 2940 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2941 @ no-op @ acquiring load 2942 mov r2, rINST, lsr #8 @ r2<- AA 2943 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2944 SET_VREG(r1, r2) @ fp[AA]<- r1 2945 GET_INST_OPCODE(ip) @ extract opcode from rINST 2946 GOTO_OPCODE(ip) @ jump to next instruction 2947 2948 2949/* ------------------------------ */ 2950 .balign 64 2951.L_OP_SPUT: /* 0x67 */ 2952/* File: armv5te/OP_SPUT.S */ 2953 /* 2954 * General 32-bit SPUT handler. 2955 * 2956 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2957 */ 2958 /* op vAA, field@BBBB */ 2959 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2960 FETCH(r1, 1) @ r1<- field ref BBBB 2961 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2962 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2963 cmp r0, #0 @ is resolved entry null? 2964 beq .LOP_SPUT_resolve @ yes, do resolve 2965.LOP_SPUT_finish: @ field ptr in r0 2966 mov r2, rINST, lsr #8 @ r2<- AA 2967 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2968 GET_VREG(r1, r2) @ r1<- fp[AA] 2969 GET_INST_OPCODE(ip) @ extract opcode from rINST 2970 @ no-op @ releasing store 2971 str r1, [r0, #offStaticField_value] @ field<- vAA 2972 GOTO_OPCODE(ip) @ jump to next instruction 2973 2974/* ------------------------------ */ 2975 .balign 64 2976.L_OP_SPUT_WIDE: /* 0x68 */ 2977/* File: armv5te/OP_SPUT_WIDE.S */ 2978 /* 2979 * 64-bit SPUT handler. 2980 */ 2981 /* sput-wide vAA, field@BBBB */ 2982 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- DvmDex 2983 FETCH(r1, 1) @ r1<- field ref BBBB 2984 ldr r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields 2985 mov r9, rINST, lsr #8 @ r9<- AA 2986 ldr r2, [r0, r1, lsl #2] @ r2<- resolved StaticField ptr 2987 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2988 cmp r2, #0 @ is resolved entry null? 2989 beq .LOP_SPUT_WIDE_resolve @ yes, do resolve 2990.LOP_SPUT_WIDE_finish: @ field ptr in r2, AA in r9 2991 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2992 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 2993 GET_INST_OPCODE(r10) @ extract opcode from rINST 2994 .if 0 2995 add r2, r2, #offStaticField_value @ r2<- pointer to data 2996 bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2 2997 .else 2998 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 2999 .endif 3000 GOTO_OPCODE(r10) @ jump to next instruction 3001 3002/* ------------------------------ */ 3003 .balign 64 3004.L_OP_SPUT_OBJECT: /* 0x69 */ 3005/* File: armv5te/OP_SPUT_OBJECT.S */ 3006 /* 3007 * 32-bit SPUT handler for objects 3008 * 3009 * for: sput-object, sput-object-volatile 3010 */ 3011 /* op vAA, field@BBBB */ 3012 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3013 FETCH(r1, 1) @ r1<- field ref BBBB 3014 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3015 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3016 cmp r0, #0 @ is resolved entry null? 3017 bne .LOP_SPUT_OBJECT_finish @ no, continue 3018 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 3019 EXPORT_PC() @ resolve() could throw, so export now 3020 ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz 3021 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 3022 cmp r0, #0 @ success? 3023 bne .LOP_SPUT_OBJECT_finish @ yes, finish 3024 b common_exceptionThrown @ no, handle exception 3025 3026 3027/* ------------------------------ */ 3028 .balign 64 3029.L_OP_SPUT_BOOLEAN: /* 0x6a */ 3030/* File: armv5te/OP_SPUT_BOOLEAN.S */ 3031/* File: armv5te/OP_SPUT.S */ 3032 /* 3033 * General 32-bit SPUT handler. 3034 * 3035 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3036 */ 3037 /* op vAA, field@BBBB */ 3038 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3039 FETCH(r1, 1) @ r1<- field ref BBBB 3040 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3041 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3042 cmp r0, #0 @ is resolved entry null? 3043 beq .LOP_SPUT_BOOLEAN_resolve @ yes, do resolve 3044.LOP_SPUT_BOOLEAN_finish: @ field ptr in r0 3045 mov r2, rINST, lsr #8 @ r2<- AA 3046 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3047 GET_VREG(r1, r2) @ r1<- fp[AA] 3048 GET_INST_OPCODE(ip) @ extract opcode from rINST 3049 @ no-op @ releasing store 3050 str r1, [r0, #offStaticField_value] @ field<- vAA 3051 GOTO_OPCODE(ip) @ jump to next instruction 3052 3053 3054/* ------------------------------ */ 3055 .balign 64 3056.L_OP_SPUT_BYTE: /* 0x6b */ 3057/* File: armv5te/OP_SPUT_BYTE.S */ 3058/* File: armv5te/OP_SPUT.S */ 3059 /* 3060 * General 32-bit SPUT handler. 3061 * 3062 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3063 */ 3064 /* op vAA, field@BBBB */ 3065 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3066 FETCH(r1, 1) @ r1<- field ref BBBB 3067 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3068 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3069 cmp r0, #0 @ is resolved entry null? 3070 beq .LOP_SPUT_BYTE_resolve @ yes, do resolve 3071.LOP_SPUT_BYTE_finish: @ field ptr in r0 3072 mov r2, rINST, lsr #8 @ r2<- AA 3073 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3074 GET_VREG(r1, r2) @ r1<- fp[AA] 3075 GET_INST_OPCODE(ip) @ extract opcode from rINST 3076 @ no-op @ releasing store 3077 str r1, [r0, #offStaticField_value] @ field<- vAA 3078 GOTO_OPCODE(ip) @ jump to next instruction 3079 3080 3081/* ------------------------------ */ 3082 .balign 64 3083.L_OP_SPUT_CHAR: /* 0x6c */ 3084/* File: armv5te/OP_SPUT_CHAR.S */ 3085/* File: armv5te/OP_SPUT.S */ 3086 /* 3087 * General 32-bit SPUT handler. 3088 * 3089 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3090 */ 3091 /* op vAA, field@BBBB */ 3092 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3093 FETCH(r1, 1) @ r1<- field ref BBBB 3094 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3095 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3096 cmp r0, #0 @ is resolved entry null? 3097 beq .LOP_SPUT_CHAR_resolve @ yes, do resolve 3098.LOP_SPUT_CHAR_finish: @ field ptr in r0 3099 mov r2, rINST, lsr #8 @ r2<- AA 3100 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3101 GET_VREG(r1, r2) @ r1<- fp[AA] 3102 GET_INST_OPCODE(ip) @ extract opcode from rINST 3103 @ no-op @ releasing store 3104 str r1, [r0, #offStaticField_value] @ field<- vAA 3105 GOTO_OPCODE(ip) @ jump to next instruction 3106 3107 3108/* ------------------------------ */ 3109 .balign 64 3110.L_OP_SPUT_SHORT: /* 0x6d */ 3111/* File: armv5te/OP_SPUT_SHORT.S */ 3112/* File: armv5te/OP_SPUT.S */ 3113 /* 3114 * General 32-bit SPUT handler. 3115 * 3116 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3117 */ 3118 /* op vAA, field@BBBB */ 3119 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3120 FETCH(r1, 1) @ r1<- field ref BBBB 3121 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3122 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3123 cmp r0, #0 @ is resolved entry null? 3124 beq .LOP_SPUT_SHORT_resolve @ yes, do resolve 3125.LOP_SPUT_SHORT_finish: @ field ptr in r0 3126 mov r2, rINST, lsr #8 @ r2<- AA 3127 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3128 GET_VREG(r1, r2) @ r1<- fp[AA] 3129 GET_INST_OPCODE(ip) @ extract opcode from rINST 3130 @ no-op @ releasing store 3131 str r1, [r0, #offStaticField_value] @ field<- vAA 3132 GOTO_OPCODE(ip) @ jump to next instruction 3133 3134 3135/* ------------------------------ */ 3136 .balign 64 3137.L_OP_INVOKE_VIRTUAL: /* 0x6e */ 3138/* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3139 /* 3140 * Handle a virtual method call. 3141 * 3142 * for: invoke-virtual, invoke-virtual/range 3143 */ 3144 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3145 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3146 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3147 FETCH(r1, 1) @ r1<- BBBB 3148 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3149 FETCH(r10, 2) @ r10<- GFED or CCCC 3150 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3151 .if (!0) 3152 and r10, r10, #15 @ r10<- D (or stays CCCC) 3153 .endif 3154 cmp r0, #0 @ already resolved? 3155 EXPORT_PC() @ must export for invoke 3156 bne .LOP_INVOKE_VIRTUAL_continue @ yes, continue on 3157 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 3158 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3159 mov r2, #METHOD_VIRTUAL @ resolver method type 3160 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3161 cmp r0, #0 @ got null? 3162 bne .LOP_INVOKE_VIRTUAL_continue @ no, continue 3163 b common_exceptionThrown @ yes, handle exception 3164 3165/* ------------------------------ */ 3166 .balign 64 3167.L_OP_INVOKE_SUPER: /* 0x6f */ 3168/* File: armv5te/OP_INVOKE_SUPER.S */ 3169 /* 3170 * Handle a "super" method call. 3171 * 3172 * for: invoke-super, invoke-super/range 3173 */ 3174 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3175 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3176 FETCH(r10, 2) @ r10<- GFED or CCCC 3177 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3178 .if (!0) 3179 and r10, r10, #15 @ r10<- D (or stays CCCC) 3180 .endif 3181 FETCH(r1, 1) @ r1<- BBBB 3182 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3183 GET_VREG(r2, r10) @ r2<- "this" ptr 3184 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3185 cmp r2, #0 @ null "this"? 3186 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 3187 beq common_errNullObject @ null "this", throw exception 3188 cmp r0, #0 @ already resolved? 3189 ldr r9, [r9, #offMethod_clazz] @ r9<- method->clazz 3190 EXPORT_PC() @ must export for invoke 3191 bne .LOP_INVOKE_SUPER_continue @ resolved, continue on 3192 b .LOP_INVOKE_SUPER_resolve @ do resolve now 3193 3194/* ------------------------------ */ 3195 .balign 64 3196.L_OP_INVOKE_DIRECT: /* 0x70 */ 3197/* File: armv5te/OP_INVOKE_DIRECT.S */ 3198 /* 3199 * Handle a direct method call. 3200 * 3201 * (We could defer the "is 'this' pointer null" test to the common 3202 * method invocation code, and use a flag to indicate that static 3203 * calls don't count. If we do this as part of copying the arguments 3204 * out we could avoiding loading the first arg twice.) 3205 * 3206 * for: invoke-direct, invoke-direct/range 3207 */ 3208 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3209 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3210 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3211 FETCH(r1, 1) @ r1<- BBBB 3212 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3213 FETCH(r10, 2) @ r10<- GFED or CCCC 3214 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3215 .if (!0) 3216 and r10, r10, #15 @ r10<- D (or stays CCCC) 3217 .endif 3218 cmp r0, #0 @ already resolved? 3219 EXPORT_PC() @ must export for invoke 3220 GET_VREG(r2, r10) @ r2<- "this" ptr 3221 beq .LOP_INVOKE_DIRECT_resolve @ not resolved, do it now 3222.LOP_INVOKE_DIRECT_finish: 3223 cmp r2, #0 @ null "this" ref? 3224 bne common_invokeMethodNoRange @ no, continue on 3225 b common_errNullObject @ yes, throw exception 3226 3227/* ------------------------------ */ 3228 .balign 64 3229.L_OP_INVOKE_STATIC: /* 0x71 */ 3230/* File: armv5te/OP_INVOKE_STATIC.S */ 3231 /* 3232 * Handle a static method call. 3233 * 3234 * for: invoke-static, invoke-static/range 3235 */ 3236 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3237 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3238 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3239 FETCH(r1, 1) @ r1<- BBBB 3240 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3241 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3242 cmp r0, #0 @ already resolved? 3243 EXPORT_PC() @ must export for invoke 3244 bne common_invokeMethodNoRange @ yes, continue on 32450: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 3246 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3247 mov r2, #METHOD_STATIC @ resolver method type 3248 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3249 cmp r0, #0 @ got null? 3250 bne common_invokeMethodNoRange @ no, continue 3251 b common_exceptionThrown @ yes, handle exception 3252 3253/* ------------------------------ */ 3254 .balign 64 3255.L_OP_INVOKE_INTERFACE: /* 0x72 */ 3256/* File: armv5te/OP_INVOKE_INTERFACE.S */ 3257 /* 3258 * Handle an interface method call. 3259 * 3260 * for: invoke-interface, invoke-interface/range 3261 */ 3262 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3263 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3264 FETCH(r2, 2) @ r2<- FEDC or CCCC 3265 FETCH(r1, 1) @ r1<- BBBB 3266 .if (!0) 3267 and r2, r2, #15 @ r2<- C (or stays CCCC) 3268 .endif 3269 EXPORT_PC() @ must export for invoke 3270 GET_VREG(r0, r2) @ r0<- first arg ("this") 3271 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- methodClassDex 3272 cmp r0, #0 @ null obj? 3273 ldr r2, [rGLUE, #offGlue_method] @ r2<- method 3274 beq common_errNullObject @ yes, fail 3275 ldr r0, [r0, #offObject_clazz] @ r0<- thisPtr->clazz 3276 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3277 cmp r0, #0 @ failed? 3278 beq common_exceptionThrown @ yes, handle exception 3279 b common_invokeMethodNoRange @ jump to common handler 3280 3281/* ------------------------------ */ 3282 .balign 64 3283.L_OP_UNUSED_73: /* 0x73 */ 3284/* File: armv5te/OP_UNUSED_73.S */ 3285/* File: armv5te/unused.S */ 3286 bl common_abort 3287 3288 3289/* ------------------------------ */ 3290 .balign 64 3291.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */ 3292/* File: armv5te/OP_INVOKE_VIRTUAL_RANGE.S */ 3293/* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3294 /* 3295 * Handle a virtual method call. 3296 * 3297 * for: invoke-virtual, invoke-virtual/range 3298 */ 3299 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3300 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3301 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3302 FETCH(r1, 1) @ r1<- BBBB 3303 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3304 FETCH(r10, 2) @ r10<- GFED or CCCC 3305 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3306 .if (!1) 3307 and r10, r10, #15 @ r10<- D (or stays CCCC) 3308 .endif 3309 cmp r0, #0 @ already resolved? 3310 EXPORT_PC() @ must export for invoke 3311 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ yes, continue on 3312 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 3313 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3314 mov r2, #METHOD_VIRTUAL @ resolver method type 3315 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3316 cmp r0, #0 @ got null? 3317 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ no, continue 3318 b common_exceptionThrown @ yes, handle exception 3319 3320 3321/* ------------------------------ */ 3322 .balign 64 3323.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */ 3324/* File: armv5te/OP_INVOKE_SUPER_RANGE.S */ 3325/* File: armv5te/OP_INVOKE_SUPER.S */ 3326 /* 3327 * Handle a "super" method call. 3328 * 3329 * for: invoke-super, invoke-super/range 3330 */ 3331 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3332 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3333 FETCH(r10, 2) @ r10<- GFED or CCCC 3334 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3335 .if (!1) 3336 and r10, r10, #15 @ r10<- D (or stays CCCC) 3337 .endif 3338 FETCH(r1, 1) @ r1<- BBBB 3339 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3340 GET_VREG(r2, r10) @ r2<- "this" ptr 3341 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3342 cmp r2, #0 @ null "this"? 3343 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 3344 beq common_errNullObject @ null "this", throw exception 3345 cmp r0, #0 @ already resolved? 3346 ldr r9, [r9, #offMethod_clazz] @ r9<- method->clazz 3347 EXPORT_PC() @ must export for invoke 3348 bne .LOP_INVOKE_SUPER_RANGE_continue @ resolved, continue on 3349 b .LOP_INVOKE_SUPER_RANGE_resolve @ do resolve now 3350 3351 3352/* ------------------------------ */ 3353 .balign 64 3354.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */ 3355/* File: armv5te/OP_INVOKE_DIRECT_RANGE.S */ 3356/* File: armv5te/OP_INVOKE_DIRECT.S */ 3357 /* 3358 * Handle a direct method call. 3359 * 3360 * (We could defer the "is 'this' pointer null" test to the common 3361 * method invocation code, and use a flag to indicate that static 3362 * calls don't count. If we do this as part of copying the arguments 3363 * out we could avoiding loading the first arg twice.) 3364 * 3365 * for: invoke-direct, invoke-direct/range 3366 */ 3367 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3368 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3369 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3370 FETCH(r1, 1) @ r1<- BBBB 3371 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3372 FETCH(r10, 2) @ r10<- GFED or CCCC 3373 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3374 .if (!1) 3375 and r10, r10, #15 @ r10<- D (or stays CCCC) 3376 .endif 3377 cmp r0, #0 @ already resolved? 3378 EXPORT_PC() @ must export for invoke 3379 GET_VREG(r2, r10) @ r2<- "this" ptr 3380 beq .LOP_INVOKE_DIRECT_RANGE_resolve @ not resolved, do it now 3381.LOP_INVOKE_DIRECT_RANGE_finish: 3382 cmp r2, #0 @ null "this" ref? 3383 bne common_invokeMethodRange @ no, continue on 3384 b common_errNullObject @ yes, throw exception 3385 3386 3387/* ------------------------------ */ 3388 .balign 64 3389.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */ 3390/* File: armv5te/OP_INVOKE_STATIC_RANGE.S */ 3391/* File: armv5te/OP_INVOKE_STATIC.S */ 3392 /* 3393 * Handle a static method call. 3394 * 3395 * for: invoke-static, invoke-static/range 3396 */ 3397 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3398 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3399 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3400 FETCH(r1, 1) @ r1<- BBBB 3401 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3402 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3403 cmp r0, #0 @ already resolved? 3404 EXPORT_PC() @ must export for invoke 3405 bne common_invokeMethodRange @ yes, continue on 34060: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 3407 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3408 mov r2, #METHOD_STATIC @ resolver method type 3409 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3410 cmp r0, #0 @ got null? 3411 bne common_invokeMethodRange @ no, continue 3412 b common_exceptionThrown @ yes, handle exception 3413 3414 3415/* ------------------------------ */ 3416 .balign 64 3417.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */ 3418/* File: armv5te/OP_INVOKE_INTERFACE_RANGE.S */ 3419/* File: armv5te/OP_INVOKE_INTERFACE.S */ 3420 /* 3421 * Handle an interface method call. 3422 * 3423 * for: invoke-interface, invoke-interface/range 3424 */ 3425 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3426 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3427 FETCH(r2, 2) @ r2<- FEDC or CCCC 3428 FETCH(r1, 1) @ r1<- BBBB 3429 .if (!1) 3430 and r2, r2, #15 @ r2<- C (or stays CCCC) 3431 .endif 3432 EXPORT_PC() @ must export for invoke 3433 GET_VREG(r0, r2) @ r0<- first arg ("this") 3434 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- methodClassDex 3435 cmp r0, #0 @ null obj? 3436 ldr r2, [rGLUE, #offGlue_method] @ r2<- method 3437 beq common_errNullObject @ yes, fail 3438 ldr r0, [r0, #offObject_clazz] @ r0<- thisPtr->clazz 3439 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3440 cmp r0, #0 @ failed? 3441 beq common_exceptionThrown @ yes, handle exception 3442 b common_invokeMethodRange @ jump to common handler 3443 3444 3445/* ------------------------------ */ 3446 .balign 64 3447.L_OP_UNUSED_79: /* 0x79 */ 3448/* File: armv5te/OP_UNUSED_79.S */ 3449/* File: armv5te/unused.S */ 3450 bl common_abort 3451 3452 3453/* ------------------------------ */ 3454 .balign 64 3455.L_OP_UNUSED_7A: /* 0x7a */ 3456/* File: armv5te/OP_UNUSED_7A.S */ 3457/* File: armv5te/unused.S */ 3458 bl common_abort 3459 3460 3461/* ------------------------------ */ 3462 .balign 64 3463.L_OP_NEG_INT: /* 0x7b */ 3464/* File: armv6t2/OP_NEG_INT.S */ 3465/* File: armv6t2/unop.S */ 3466 /* 3467 * Generic 32-bit unary operation. Provide an "instr" line that 3468 * specifies an instruction that performs "result = op r0". 3469 * This could be an ARM instruction or a function call. 3470 * 3471 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3472 * int-to-byte, int-to-char, int-to-short 3473 */ 3474 /* unop vA, vB */ 3475 mov r3, rINST, lsr #12 @ r3<- B 3476 ubfx r9, rINST, #8, #4 @ r9<- A 3477 GET_VREG(r0, r3) @ r0<- vB 3478 @ optional op; may set condition codes 3479 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3480 rsb r0, r0, #0 @ r0<- op, r0-r3 changed 3481 GET_INST_OPCODE(ip) @ extract opcode from rINST 3482 SET_VREG(r0, r9) @ vAA<- r0 3483 GOTO_OPCODE(ip) @ jump to next instruction 3484 /* 8-9 instructions */ 3485 3486 3487/* ------------------------------ */ 3488 .balign 64 3489.L_OP_NOT_INT: /* 0x7c */ 3490/* File: armv6t2/OP_NOT_INT.S */ 3491/* File: armv6t2/unop.S */ 3492 /* 3493 * Generic 32-bit unary operation. Provide an "instr" line that 3494 * specifies an instruction that performs "result = op r0". 3495 * This could be an ARM instruction or a function call. 3496 * 3497 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3498 * int-to-byte, int-to-char, int-to-short 3499 */ 3500 /* unop vA, vB */ 3501 mov r3, rINST, lsr #12 @ r3<- B 3502 ubfx r9, rINST, #8, #4 @ r9<- A 3503 GET_VREG(r0, r3) @ r0<- vB 3504 @ optional op; may set condition codes 3505 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3506 mvn r0, r0 @ r0<- op, r0-r3 changed 3507 GET_INST_OPCODE(ip) @ extract opcode from rINST 3508 SET_VREG(r0, r9) @ vAA<- r0 3509 GOTO_OPCODE(ip) @ jump to next instruction 3510 /* 8-9 instructions */ 3511 3512 3513/* ------------------------------ */ 3514 .balign 64 3515.L_OP_NEG_LONG: /* 0x7d */ 3516/* File: armv6t2/OP_NEG_LONG.S */ 3517/* File: armv6t2/unopWide.S */ 3518 /* 3519 * Generic 64-bit unary operation. Provide an "instr" line that 3520 * specifies an instruction that performs "result = op r0/r1". 3521 * This could be an ARM instruction or a function call. 3522 * 3523 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3524 */ 3525 /* unop vA, vB */ 3526 mov r3, rINST, lsr #12 @ r3<- B 3527 ubfx r9, rINST, #8, #4 @ r9<- A 3528 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3529 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3530 ldmia r3, {r0-r1} @ r0/r1<- vAA 3531 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3532 rsbs r0, r0, #0 @ optional op; may set condition codes 3533 rsc r1, r1, #0 @ r0/r1<- op, r2-r3 changed 3534 GET_INST_OPCODE(ip) @ extract opcode from rINST 3535 stmia r9, {r0-r1} @ vAA<- r0/r1 3536 GOTO_OPCODE(ip) @ jump to next instruction 3537 /* 10-11 instructions */ 3538 3539 3540/* ------------------------------ */ 3541 .balign 64 3542.L_OP_NOT_LONG: /* 0x7e */ 3543/* File: armv6t2/OP_NOT_LONG.S */ 3544/* File: armv6t2/unopWide.S */ 3545 /* 3546 * Generic 64-bit unary operation. Provide an "instr" line that 3547 * specifies an instruction that performs "result = op r0/r1". 3548 * This could be an ARM instruction or a function call. 3549 * 3550 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3551 */ 3552 /* unop vA, vB */ 3553 mov r3, rINST, lsr #12 @ r3<- B 3554 ubfx r9, rINST, #8, #4 @ r9<- A 3555 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3556 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3557 ldmia r3, {r0-r1} @ r0/r1<- vAA 3558 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3559 mvn r0, r0 @ optional op; may set condition codes 3560 mvn r1, r1 @ r0/r1<- op, r2-r3 changed 3561 GET_INST_OPCODE(ip) @ extract opcode from rINST 3562 stmia r9, {r0-r1} @ vAA<- r0/r1 3563 GOTO_OPCODE(ip) @ jump to next instruction 3564 /* 10-11 instructions */ 3565 3566 3567/* ------------------------------ */ 3568 .balign 64 3569.L_OP_NEG_FLOAT: /* 0x7f */ 3570/* File: armv6t2/OP_NEG_FLOAT.S */ 3571/* File: armv6t2/unop.S */ 3572 /* 3573 * Generic 32-bit unary operation. Provide an "instr" line that 3574 * specifies an instruction that performs "result = op r0". 3575 * This could be an ARM instruction or a function call. 3576 * 3577 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3578 * int-to-byte, int-to-char, int-to-short 3579 */ 3580 /* unop vA, vB */ 3581 mov r3, rINST, lsr #12 @ r3<- B 3582 ubfx r9, rINST, #8, #4 @ r9<- A 3583 GET_VREG(r0, r3) @ r0<- vB 3584 @ optional op; may set condition codes 3585 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3586 add r0, r0, #0x80000000 @ r0<- op, r0-r3 changed 3587 GET_INST_OPCODE(ip) @ extract opcode from rINST 3588 SET_VREG(r0, r9) @ vAA<- r0 3589 GOTO_OPCODE(ip) @ jump to next instruction 3590 /* 8-9 instructions */ 3591 3592 3593/* ------------------------------ */ 3594 .balign 64 3595.L_OP_NEG_DOUBLE: /* 0x80 */ 3596/* File: armv6t2/OP_NEG_DOUBLE.S */ 3597/* File: armv6t2/unopWide.S */ 3598 /* 3599 * Generic 64-bit unary operation. Provide an "instr" line that 3600 * specifies an instruction that performs "result = op r0/r1". 3601 * This could be an ARM instruction or a function call. 3602 * 3603 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3604 */ 3605 /* unop vA, vB */ 3606 mov r3, rINST, lsr #12 @ r3<- B 3607 ubfx r9, rINST, #8, #4 @ r9<- A 3608 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3609 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3610 ldmia r3, {r0-r1} @ r0/r1<- vAA 3611 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3612 @ optional op; may set condition codes 3613 add r1, r1, #0x80000000 @ r0/r1<- op, r2-r3 changed 3614 GET_INST_OPCODE(ip) @ extract opcode from rINST 3615 stmia r9, {r0-r1} @ vAA<- r0/r1 3616 GOTO_OPCODE(ip) @ jump to next instruction 3617 /* 10-11 instructions */ 3618 3619 3620/* ------------------------------ */ 3621 .balign 64 3622.L_OP_INT_TO_LONG: /* 0x81 */ 3623/* File: armv6t2/OP_INT_TO_LONG.S */ 3624/* File: armv6t2/unopWider.S */ 3625 /* 3626 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3627 * that specifies an instruction that performs "result = op r0", where 3628 * "result" is a 64-bit quantity in r0/r1. 3629 * 3630 * For: int-to-long, int-to-double, float-to-long, float-to-double 3631 */ 3632 /* unop vA, vB */ 3633 mov r3, rINST, lsr #12 @ r3<- B 3634 ubfx r9, rINST, #8, #4 @ r9<- A 3635 GET_VREG(r0, r3) @ r0<- vB 3636 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3637 @ optional op; may set condition codes 3638 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3639 mov r1, r0, asr #31 @ r0<- op, r0-r3 changed 3640 GET_INST_OPCODE(ip) @ extract opcode from rINST 3641 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3642 GOTO_OPCODE(ip) @ jump to next instruction 3643 /* 9-10 instructions */ 3644 3645 3646/* ------------------------------ */ 3647 .balign 64 3648.L_OP_INT_TO_FLOAT: /* 0x82 */ 3649/* File: arm-vfp/OP_INT_TO_FLOAT.S */ 3650/* File: arm-vfp/funop.S */ 3651 /* 3652 * Generic 32-bit unary floating-point operation. Provide an "instr" 3653 * line that specifies an instruction that performs "s1 = op s0". 3654 * 3655 * for: int-to-float, float-to-int 3656 */ 3657 /* unop vA, vB */ 3658 mov r3, rINST, lsr #12 @ r3<- B 3659 mov r9, rINST, lsr #8 @ r9<- A+ 3660 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3661 flds s0, [r3] @ s0<- vB 3662 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3663 and r9, r9, #15 @ r9<- A 3664 fsitos s1, s0 @ s1<- op 3665 GET_INST_OPCODE(ip) @ extract opcode from rINST 3666 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3667 fsts s1, [r9] @ vA<- s1 3668 GOTO_OPCODE(ip) @ jump to next instruction 3669 3670 3671/* ------------------------------ */ 3672 .balign 64 3673.L_OP_INT_TO_DOUBLE: /* 0x83 */ 3674/* File: arm-vfp/OP_INT_TO_DOUBLE.S */ 3675/* File: arm-vfp/funopWider.S */ 3676 /* 3677 * Generic 32bit-to-64bit floating point unary operation. Provide an 3678 * "instr" line that specifies an instruction that performs "d0 = op s0". 3679 * 3680 * For: int-to-double, float-to-double 3681 */ 3682 /* unop vA, vB */ 3683 mov r3, rINST, lsr #12 @ r3<- B 3684 mov r9, rINST, lsr #8 @ r9<- A+ 3685 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3686 flds s0, [r3] @ s0<- vB 3687 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3688 and r9, r9, #15 @ r9<- A 3689 fsitod d0, s0 @ d0<- op 3690 GET_INST_OPCODE(ip) @ extract opcode from rINST 3691 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3692 fstd d0, [r9] @ vA<- d0 3693 GOTO_OPCODE(ip) @ jump to next instruction 3694 3695 3696/* ------------------------------ */ 3697 .balign 64 3698.L_OP_LONG_TO_INT: /* 0x84 */ 3699/* File: armv5te/OP_LONG_TO_INT.S */ 3700/* we ignore the high word, making this equivalent to a 32-bit reg move */ 3701/* File: armv5te/OP_MOVE.S */ 3702 /* for move, move-object, long-to-int */ 3703 /* op vA, vB */ 3704 mov r1, rINST, lsr #12 @ r1<- B from 15:12 3705 mov r0, rINST, lsr #8 @ r0<- A from 11:8 3706 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3707 GET_VREG(r2, r1) @ r2<- fp[B] 3708 and r0, r0, #15 3709 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 3710 SET_VREG(r2, r0) @ fp[A]<- r2 3711 GOTO_OPCODE(ip) @ execute next instruction 3712 3713 3714/* ------------------------------ */ 3715 .balign 64 3716.L_OP_LONG_TO_FLOAT: /* 0x85 */ 3717/* File: armv6t2/OP_LONG_TO_FLOAT.S */ 3718/* File: armv6t2/unopNarrower.S */ 3719 /* 3720 * Generic 64bit-to-32bit unary operation. Provide an "instr" line 3721 * that specifies an instruction that performs "result = op r0/r1", where 3722 * "result" is a 32-bit quantity in r0. 3723 * 3724 * For: long-to-float, double-to-int, double-to-float 3725 * 3726 * (This would work for long-to-int, but that instruction is actually 3727 * an exact match for OP_MOVE.) 3728 */ 3729 /* unop vA, vB */ 3730 mov r3, rINST, lsr #12 @ r3<- B 3731 ubfx r9, rINST, #8, #4 @ r9<- A 3732 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3733 ldmia r3, {r0-r1} @ r0/r1<- vB/vB+1 3734 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3735 @ optional op; may set condition codes 3736 bl __aeabi_l2f @ r0<- op, r0-r3 changed 3737 GET_INST_OPCODE(ip) @ extract opcode from rINST 3738 SET_VREG(r0, r9) @ vA<- r0 3739 GOTO_OPCODE(ip) @ jump to next instruction 3740 /* 9-10 instructions */ 3741 3742 3743/* ------------------------------ */ 3744 .balign 64 3745.L_OP_LONG_TO_DOUBLE: /* 0x86 */ 3746/* File: armv6t2/OP_LONG_TO_DOUBLE.S */ 3747/* File: armv6t2/unopWide.S */ 3748 /* 3749 * Generic 64-bit unary operation. Provide an "instr" line that 3750 * specifies an instruction that performs "result = op r0/r1". 3751 * This could be an ARM instruction or a function call. 3752 * 3753 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3754 */ 3755 /* unop vA, vB */ 3756 mov r3, rINST, lsr #12 @ r3<- B 3757 ubfx r9, rINST, #8, #4 @ r9<- A 3758 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3759 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3760 ldmia r3, {r0-r1} @ r0/r1<- vAA 3761 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3762 @ optional op; may set condition codes 3763 bl __aeabi_l2d @ r0/r1<- op, r2-r3 changed 3764 GET_INST_OPCODE(ip) @ extract opcode from rINST 3765 stmia r9, {r0-r1} @ vAA<- r0/r1 3766 GOTO_OPCODE(ip) @ jump to next instruction 3767 /* 10-11 instructions */ 3768 3769 3770/* ------------------------------ */ 3771 .balign 64 3772.L_OP_FLOAT_TO_INT: /* 0x87 */ 3773/* File: arm-vfp/OP_FLOAT_TO_INT.S */ 3774/* File: arm-vfp/funop.S */ 3775 /* 3776 * Generic 32-bit unary floating-point operation. Provide an "instr" 3777 * line that specifies an instruction that performs "s1 = op s0". 3778 * 3779 * for: int-to-float, float-to-int 3780 */ 3781 /* unop vA, vB */ 3782 mov r3, rINST, lsr #12 @ r3<- B 3783 mov r9, rINST, lsr #8 @ r9<- A+ 3784 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3785 flds s0, [r3] @ s0<- vB 3786 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3787 and r9, r9, #15 @ r9<- A 3788 ftosizs s1, s0 @ s1<- op 3789 GET_INST_OPCODE(ip) @ extract opcode from rINST 3790 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3791 fsts s1, [r9] @ vA<- s1 3792 GOTO_OPCODE(ip) @ jump to next instruction 3793 3794 3795/* ------------------------------ */ 3796 .balign 64 3797.L_OP_FLOAT_TO_LONG: /* 0x88 */ 3798/* File: armv6t2/OP_FLOAT_TO_LONG.S */ 3799@include "armv6t2/unopWider.S" {"instr":"bl __aeabi_f2lz"} 3800/* File: armv6t2/unopWider.S */ 3801 /* 3802 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3803 * that specifies an instruction that performs "result = op r0", where 3804 * "result" is a 64-bit quantity in r0/r1. 3805 * 3806 * For: int-to-long, int-to-double, float-to-long, float-to-double 3807 */ 3808 /* unop vA, vB */ 3809 mov r3, rINST, lsr #12 @ r3<- B 3810 ubfx r9, rINST, #8, #4 @ r9<- A 3811 GET_VREG(r0, r3) @ r0<- vB 3812 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3813 @ optional op; may set condition codes 3814 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3815 bl f2l_doconv @ r0<- op, r0-r3 changed 3816 GET_INST_OPCODE(ip) @ extract opcode from rINST 3817 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3818 GOTO_OPCODE(ip) @ jump to next instruction 3819 /* 9-10 instructions */ 3820 3821 3822 3823/* ------------------------------ */ 3824 .balign 64 3825.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */ 3826/* File: arm-vfp/OP_FLOAT_TO_DOUBLE.S */ 3827/* File: arm-vfp/funopWider.S */ 3828 /* 3829 * Generic 32bit-to-64bit floating point unary operation. Provide an 3830 * "instr" line that specifies an instruction that performs "d0 = op s0". 3831 * 3832 * For: int-to-double, float-to-double 3833 */ 3834 /* unop vA, vB */ 3835 mov r3, rINST, lsr #12 @ r3<- B 3836 mov r9, rINST, lsr #8 @ r9<- A+ 3837 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3838 flds s0, [r3] @ s0<- vB 3839 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3840 and r9, r9, #15 @ r9<- A 3841 fcvtds d0, s0 @ d0<- op 3842 GET_INST_OPCODE(ip) @ extract opcode from rINST 3843 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3844 fstd d0, [r9] @ vA<- d0 3845 GOTO_OPCODE(ip) @ jump to next instruction 3846 3847 3848/* ------------------------------ */ 3849 .balign 64 3850.L_OP_DOUBLE_TO_INT: /* 0x8a */ 3851/* File: arm-vfp/OP_DOUBLE_TO_INT.S */ 3852/* File: arm-vfp/funopNarrower.S */ 3853 /* 3854 * Generic 64bit-to-32bit unary floating point operation. Provide an 3855 * "instr" line that specifies an instruction that performs "s0 = op d0". 3856 * 3857 * For: double-to-int, double-to-float 3858 */ 3859 /* unop vA, vB */ 3860 mov r3, rINST, lsr #12 @ r3<- B 3861 mov r9, rINST, lsr #8 @ r9<- A+ 3862 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3863 fldd d0, [r3] @ d0<- vB 3864 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3865 and r9, r9, #15 @ r9<- A 3866 ftosizd s0, d0 @ s0<- op 3867 GET_INST_OPCODE(ip) @ extract opcode from rINST 3868 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3869 fsts s0, [r9] @ vA<- s0 3870 GOTO_OPCODE(ip) @ jump to next instruction 3871 3872 3873/* ------------------------------ */ 3874 .balign 64 3875.L_OP_DOUBLE_TO_LONG: /* 0x8b */ 3876/* File: armv6t2/OP_DOUBLE_TO_LONG.S */ 3877@include "armv6t2/unopWide.S" {"instr":"bl __aeabi_d2lz"} 3878/* File: armv6t2/unopWide.S */ 3879 /* 3880 * Generic 64-bit unary operation. Provide an "instr" line that 3881 * specifies an instruction that performs "result = op r0/r1". 3882 * This could be an ARM instruction or a function call. 3883 * 3884 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3885 */ 3886 /* unop vA, vB */ 3887 mov r3, rINST, lsr #12 @ r3<- B 3888 ubfx r9, rINST, #8, #4 @ r9<- A 3889 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3890 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3891 ldmia r3, {r0-r1} @ r0/r1<- vAA 3892 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3893 @ optional op; may set condition codes 3894 bl d2l_doconv @ r0/r1<- op, r2-r3 changed 3895 GET_INST_OPCODE(ip) @ extract opcode from rINST 3896 stmia r9, {r0-r1} @ vAA<- r0/r1 3897 GOTO_OPCODE(ip) @ jump to next instruction 3898 /* 10-11 instructions */ 3899 3900 3901 3902/* ------------------------------ */ 3903 .balign 64 3904.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */ 3905/* File: arm-vfp/OP_DOUBLE_TO_FLOAT.S */ 3906/* File: arm-vfp/funopNarrower.S */ 3907 /* 3908 * Generic 64bit-to-32bit unary floating point operation. Provide an 3909 * "instr" line that specifies an instruction that performs "s0 = op d0". 3910 * 3911 * For: double-to-int, double-to-float 3912 */ 3913 /* unop vA, vB */ 3914 mov r3, rINST, lsr #12 @ r3<- B 3915 mov r9, rINST, lsr #8 @ r9<- A+ 3916 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3917 fldd d0, [r3] @ d0<- vB 3918 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3919 and r9, r9, #15 @ r9<- A 3920 fcvtsd s0, d0 @ s0<- op 3921 GET_INST_OPCODE(ip) @ extract opcode from rINST 3922 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3923 fsts s0, [r9] @ vA<- s0 3924 GOTO_OPCODE(ip) @ jump to next instruction 3925 3926 3927/* ------------------------------ */ 3928 .balign 64 3929.L_OP_INT_TO_BYTE: /* 0x8d */ 3930/* File: armv6t2/OP_INT_TO_BYTE.S */ 3931/* File: armv6t2/unop.S */ 3932 /* 3933 * Generic 32-bit unary operation. Provide an "instr" line that 3934 * specifies an instruction that performs "result = op r0". 3935 * This could be an ARM instruction or a function call. 3936 * 3937 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3938 * int-to-byte, int-to-char, int-to-short 3939 */ 3940 /* unop vA, vB */ 3941 mov r3, rINST, lsr #12 @ r3<- B 3942 ubfx r9, rINST, #8, #4 @ r9<- A 3943 GET_VREG(r0, r3) @ r0<- vB 3944 @ optional op; may set condition codes 3945 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3946 sxtb r0, r0 @ r0<- op, r0-r3 changed 3947 GET_INST_OPCODE(ip) @ extract opcode from rINST 3948 SET_VREG(r0, r9) @ vAA<- r0 3949 GOTO_OPCODE(ip) @ jump to next instruction 3950 /* 8-9 instructions */ 3951 3952 3953/* ------------------------------ */ 3954 .balign 64 3955.L_OP_INT_TO_CHAR: /* 0x8e */ 3956/* File: armv6t2/OP_INT_TO_CHAR.S */ 3957/* File: armv6t2/unop.S */ 3958 /* 3959 * Generic 32-bit unary operation. Provide an "instr" line that 3960 * specifies an instruction that performs "result = op r0". 3961 * This could be an ARM instruction or a function call. 3962 * 3963 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3964 * int-to-byte, int-to-char, int-to-short 3965 */ 3966 /* unop vA, vB */ 3967 mov r3, rINST, lsr #12 @ r3<- B 3968 ubfx r9, rINST, #8, #4 @ r9<- A 3969 GET_VREG(r0, r3) @ r0<- vB 3970 @ optional op; may set condition codes 3971 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3972 uxth r0, r0 @ r0<- op, r0-r3 changed 3973 GET_INST_OPCODE(ip) @ extract opcode from rINST 3974 SET_VREG(r0, r9) @ vAA<- r0 3975 GOTO_OPCODE(ip) @ jump to next instruction 3976 /* 8-9 instructions */ 3977 3978 3979/* ------------------------------ */ 3980 .balign 64 3981.L_OP_INT_TO_SHORT: /* 0x8f */ 3982/* File: armv6t2/OP_INT_TO_SHORT.S */ 3983/* File: armv6t2/unop.S */ 3984 /* 3985 * Generic 32-bit unary operation. Provide an "instr" line that 3986 * specifies an instruction that performs "result = op r0". 3987 * This could be an ARM instruction or a function call. 3988 * 3989 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3990 * int-to-byte, int-to-char, int-to-short 3991 */ 3992 /* unop vA, vB */ 3993 mov r3, rINST, lsr #12 @ r3<- B 3994 ubfx r9, rINST, #8, #4 @ r9<- A 3995 GET_VREG(r0, r3) @ r0<- vB 3996 @ optional op; may set condition codes 3997 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3998 sxth r0, r0 @ r0<- op, r0-r3 changed 3999 GET_INST_OPCODE(ip) @ extract opcode from rINST 4000 SET_VREG(r0, r9) @ vAA<- r0 4001 GOTO_OPCODE(ip) @ jump to next instruction 4002 /* 8-9 instructions */ 4003 4004 4005/* ------------------------------ */ 4006 .balign 64 4007.L_OP_ADD_INT: /* 0x90 */ 4008/* File: armv5te/OP_ADD_INT.S */ 4009/* File: armv5te/binop.S */ 4010 /* 4011 * Generic 32-bit binary operation. Provide an "instr" line that 4012 * specifies an instruction that performs "result = r0 op r1". 4013 * This could be an ARM instruction or a function call. (If the result 4014 * comes back in a register other than r0, you can override "result".) 4015 * 4016 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4017 * vCC (r1). Useful for integer division and modulus. Note that we 4018 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4019 * handles it correctly. 4020 * 4021 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4022 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4023 * mul-float, div-float, rem-float 4024 */ 4025 /* binop vAA, vBB, vCC */ 4026 FETCH(r0, 1) @ r0<- CCBB 4027 mov r9, rINST, lsr #8 @ r9<- AA 4028 mov r3, r0, lsr #8 @ r3<- CC 4029 and r2, r0, #255 @ r2<- BB 4030 GET_VREG(r1, r3) @ r1<- vCC 4031 GET_VREG(r0, r2) @ r0<- vBB 4032 .if 0 4033 cmp r1, #0 @ is second operand zero? 4034 beq common_errDivideByZero 4035 .endif 4036 4037 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4038 @ optional op; may set condition codes 4039 add r0, r0, r1 @ r0<- op, r0-r3 changed 4040 GET_INST_OPCODE(ip) @ extract opcode from rINST 4041 SET_VREG(r0, r9) @ vAA<- r0 4042 GOTO_OPCODE(ip) @ jump to next instruction 4043 /* 11-14 instructions */ 4044 4045 4046/* ------------------------------ */ 4047 .balign 64 4048.L_OP_SUB_INT: /* 0x91 */ 4049/* File: armv5te/OP_SUB_INT.S */ 4050/* File: armv5te/binop.S */ 4051 /* 4052 * Generic 32-bit binary operation. Provide an "instr" line that 4053 * specifies an instruction that performs "result = r0 op r1". 4054 * This could be an ARM instruction or a function call. (If the result 4055 * comes back in a register other than r0, you can override "result".) 4056 * 4057 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4058 * vCC (r1). Useful for integer division and modulus. Note that we 4059 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4060 * handles it correctly. 4061 * 4062 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4063 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4064 * mul-float, div-float, rem-float 4065 */ 4066 /* binop vAA, vBB, vCC */ 4067 FETCH(r0, 1) @ r0<- CCBB 4068 mov r9, rINST, lsr #8 @ r9<- AA 4069 mov r3, r0, lsr #8 @ r3<- CC 4070 and r2, r0, #255 @ r2<- BB 4071 GET_VREG(r1, r3) @ r1<- vCC 4072 GET_VREG(r0, r2) @ r0<- vBB 4073 .if 0 4074 cmp r1, #0 @ is second operand zero? 4075 beq common_errDivideByZero 4076 .endif 4077 4078 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4079 @ optional op; may set condition codes 4080 sub r0, r0, r1 @ r0<- op, r0-r3 changed 4081 GET_INST_OPCODE(ip) @ extract opcode from rINST 4082 SET_VREG(r0, r9) @ vAA<- r0 4083 GOTO_OPCODE(ip) @ jump to next instruction 4084 /* 11-14 instructions */ 4085 4086 4087/* ------------------------------ */ 4088 .balign 64 4089.L_OP_MUL_INT: /* 0x92 */ 4090/* File: armv5te/OP_MUL_INT.S */ 4091/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 4092/* File: armv5te/binop.S */ 4093 /* 4094 * Generic 32-bit binary operation. Provide an "instr" line that 4095 * specifies an instruction that performs "result = r0 op r1". 4096 * This could be an ARM instruction or a function call. (If the result 4097 * comes back in a register other than r0, you can override "result".) 4098 * 4099 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4100 * vCC (r1). Useful for integer division and modulus. Note that we 4101 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4102 * handles it correctly. 4103 * 4104 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4105 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4106 * mul-float, div-float, rem-float 4107 */ 4108 /* binop vAA, vBB, vCC */ 4109 FETCH(r0, 1) @ r0<- CCBB 4110 mov r9, rINST, lsr #8 @ r9<- AA 4111 mov r3, r0, lsr #8 @ r3<- CC 4112 and r2, r0, #255 @ r2<- BB 4113 GET_VREG(r1, r3) @ r1<- vCC 4114 GET_VREG(r0, r2) @ r0<- vBB 4115 .if 0 4116 cmp r1, #0 @ is second operand zero? 4117 beq common_errDivideByZero 4118 .endif 4119 4120 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4121 @ optional op; may set condition codes 4122 mul r0, r1, r0 @ r0<- op, r0-r3 changed 4123 GET_INST_OPCODE(ip) @ extract opcode from rINST 4124 SET_VREG(r0, r9) @ vAA<- r0 4125 GOTO_OPCODE(ip) @ jump to next instruction 4126 /* 11-14 instructions */ 4127 4128 4129/* ------------------------------ */ 4130 .balign 64 4131.L_OP_DIV_INT: /* 0x93 */ 4132/* File: armv5te/OP_DIV_INT.S */ 4133/* File: armv5te/binop.S */ 4134 /* 4135 * Generic 32-bit binary operation. Provide an "instr" line that 4136 * specifies an instruction that performs "result = r0 op r1". 4137 * This could be an ARM instruction or a function call. (If the result 4138 * comes back in a register other than r0, you can override "result".) 4139 * 4140 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4141 * vCC (r1). Useful for integer division and modulus. Note that we 4142 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4143 * handles it correctly. 4144 * 4145 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4146 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4147 * mul-float, div-float, rem-float 4148 */ 4149 /* binop vAA, vBB, vCC */ 4150 FETCH(r0, 1) @ r0<- CCBB 4151 mov r9, rINST, lsr #8 @ r9<- AA 4152 mov r3, r0, lsr #8 @ r3<- CC 4153 and r2, r0, #255 @ r2<- BB 4154 GET_VREG(r1, r3) @ r1<- vCC 4155 GET_VREG(r0, r2) @ r0<- vBB 4156 .if 1 4157 cmp r1, #0 @ is second operand zero? 4158 beq common_errDivideByZero 4159 .endif 4160 4161 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4162 @ optional op; may set condition codes 4163 bl __aeabi_idiv @ r0<- op, r0-r3 changed 4164 GET_INST_OPCODE(ip) @ extract opcode from rINST 4165 SET_VREG(r0, r9) @ vAA<- r0 4166 GOTO_OPCODE(ip) @ jump to next instruction 4167 /* 11-14 instructions */ 4168 4169 4170/* ------------------------------ */ 4171 .balign 64 4172.L_OP_REM_INT: /* 0x94 */ 4173/* File: armv5te/OP_REM_INT.S */ 4174/* idivmod returns quotient in r0 and remainder in r1 */ 4175/* File: armv5te/binop.S */ 4176 /* 4177 * Generic 32-bit binary operation. Provide an "instr" line that 4178 * specifies an instruction that performs "result = r0 op r1". 4179 * This could be an ARM instruction or a function call. (If the result 4180 * comes back in a register other than r0, you can override "result".) 4181 * 4182 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4183 * vCC (r1). Useful for integer division and modulus. Note that we 4184 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4185 * handles it correctly. 4186 * 4187 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4188 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4189 * mul-float, div-float, rem-float 4190 */ 4191 /* binop vAA, vBB, vCC */ 4192 FETCH(r0, 1) @ r0<- CCBB 4193 mov r9, rINST, lsr #8 @ r9<- AA 4194 mov r3, r0, lsr #8 @ r3<- CC 4195 and r2, r0, #255 @ r2<- BB 4196 GET_VREG(r1, r3) @ r1<- vCC 4197 GET_VREG(r0, r2) @ r0<- vBB 4198 .if 1 4199 cmp r1, #0 @ is second operand zero? 4200 beq common_errDivideByZero 4201 .endif 4202 4203 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4204 @ optional op; may set condition codes 4205 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 4206 GET_INST_OPCODE(ip) @ extract opcode from rINST 4207 SET_VREG(r1, r9) @ vAA<- r1 4208 GOTO_OPCODE(ip) @ jump to next instruction 4209 /* 11-14 instructions */ 4210 4211 4212/* ------------------------------ */ 4213 .balign 64 4214.L_OP_AND_INT: /* 0x95 */ 4215/* File: armv5te/OP_AND_INT.S */ 4216/* File: armv5te/binop.S */ 4217 /* 4218 * Generic 32-bit binary operation. Provide an "instr" line that 4219 * specifies an instruction that performs "result = r0 op r1". 4220 * This could be an ARM instruction or a function call. (If the result 4221 * comes back in a register other than r0, you can override "result".) 4222 * 4223 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4224 * vCC (r1). Useful for integer division and modulus. Note that we 4225 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4226 * handles it correctly. 4227 * 4228 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4229 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4230 * mul-float, div-float, rem-float 4231 */ 4232 /* binop vAA, vBB, vCC */ 4233 FETCH(r0, 1) @ r0<- CCBB 4234 mov r9, rINST, lsr #8 @ r9<- AA 4235 mov r3, r0, lsr #8 @ r3<- CC 4236 and r2, r0, #255 @ r2<- BB 4237 GET_VREG(r1, r3) @ r1<- vCC 4238 GET_VREG(r0, r2) @ r0<- vBB 4239 .if 0 4240 cmp r1, #0 @ is second operand zero? 4241 beq common_errDivideByZero 4242 .endif 4243 4244 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4245 @ optional op; may set condition codes 4246 and r0, r0, r1 @ r0<- op, r0-r3 changed 4247 GET_INST_OPCODE(ip) @ extract opcode from rINST 4248 SET_VREG(r0, r9) @ vAA<- r0 4249 GOTO_OPCODE(ip) @ jump to next instruction 4250 /* 11-14 instructions */ 4251 4252 4253/* ------------------------------ */ 4254 .balign 64 4255.L_OP_OR_INT: /* 0x96 */ 4256/* File: armv5te/OP_OR_INT.S */ 4257/* File: armv5te/binop.S */ 4258 /* 4259 * Generic 32-bit binary operation. Provide an "instr" line that 4260 * specifies an instruction that performs "result = r0 op r1". 4261 * This could be an ARM instruction or a function call. (If the result 4262 * comes back in a register other than r0, you can override "result".) 4263 * 4264 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4265 * vCC (r1). Useful for integer division and modulus. Note that we 4266 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4267 * handles it correctly. 4268 * 4269 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4270 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4271 * mul-float, div-float, rem-float 4272 */ 4273 /* binop vAA, vBB, vCC */ 4274 FETCH(r0, 1) @ r0<- CCBB 4275 mov r9, rINST, lsr #8 @ r9<- AA 4276 mov r3, r0, lsr #8 @ r3<- CC 4277 and r2, r0, #255 @ r2<- BB 4278 GET_VREG(r1, r3) @ r1<- vCC 4279 GET_VREG(r0, r2) @ r0<- vBB 4280 .if 0 4281 cmp r1, #0 @ is second operand zero? 4282 beq common_errDivideByZero 4283 .endif 4284 4285 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4286 @ optional op; may set condition codes 4287 orr r0, r0, r1 @ r0<- op, r0-r3 changed 4288 GET_INST_OPCODE(ip) @ extract opcode from rINST 4289 SET_VREG(r0, r9) @ vAA<- r0 4290 GOTO_OPCODE(ip) @ jump to next instruction 4291 /* 11-14 instructions */ 4292 4293 4294/* ------------------------------ */ 4295 .balign 64 4296.L_OP_XOR_INT: /* 0x97 */ 4297/* File: armv5te/OP_XOR_INT.S */ 4298/* File: armv5te/binop.S */ 4299 /* 4300 * Generic 32-bit binary operation. Provide an "instr" line that 4301 * specifies an instruction that performs "result = r0 op r1". 4302 * This could be an ARM instruction or a function call. (If the result 4303 * comes back in a register other than r0, you can override "result".) 4304 * 4305 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4306 * vCC (r1). Useful for integer division and modulus. Note that we 4307 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4308 * handles it correctly. 4309 * 4310 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4311 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4312 * mul-float, div-float, rem-float 4313 */ 4314 /* binop vAA, vBB, vCC */ 4315 FETCH(r0, 1) @ r0<- CCBB 4316 mov r9, rINST, lsr #8 @ r9<- AA 4317 mov r3, r0, lsr #8 @ r3<- CC 4318 and r2, r0, #255 @ r2<- BB 4319 GET_VREG(r1, r3) @ r1<- vCC 4320 GET_VREG(r0, r2) @ r0<- vBB 4321 .if 0 4322 cmp r1, #0 @ is second operand zero? 4323 beq common_errDivideByZero 4324 .endif 4325 4326 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4327 @ optional op; may set condition codes 4328 eor r0, r0, r1 @ r0<- op, r0-r3 changed 4329 GET_INST_OPCODE(ip) @ extract opcode from rINST 4330 SET_VREG(r0, r9) @ vAA<- r0 4331 GOTO_OPCODE(ip) @ jump to next instruction 4332 /* 11-14 instructions */ 4333 4334 4335/* ------------------------------ */ 4336 .balign 64 4337.L_OP_SHL_INT: /* 0x98 */ 4338/* File: armv5te/OP_SHL_INT.S */ 4339/* File: armv5te/binop.S */ 4340 /* 4341 * Generic 32-bit binary operation. Provide an "instr" line that 4342 * specifies an instruction that performs "result = r0 op r1". 4343 * This could be an ARM instruction or a function call. (If the result 4344 * comes back in a register other than r0, you can override "result".) 4345 * 4346 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4347 * vCC (r1). Useful for integer division and modulus. Note that we 4348 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4349 * handles it correctly. 4350 * 4351 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4352 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4353 * mul-float, div-float, rem-float 4354 */ 4355 /* binop vAA, vBB, vCC */ 4356 FETCH(r0, 1) @ r0<- CCBB 4357 mov r9, rINST, lsr #8 @ r9<- AA 4358 mov r3, r0, lsr #8 @ r3<- CC 4359 and r2, r0, #255 @ r2<- BB 4360 GET_VREG(r1, r3) @ r1<- vCC 4361 GET_VREG(r0, r2) @ r0<- vBB 4362 .if 0 4363 cmp r1, #0 @ is second operand zero? 4364 beq common_errDivideByZero 4365 .endif 4366 4367 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4368 and r1, r1, #31 @ optional op; may set condition codes 4369 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 4370 GET_INST_OPCODE(ip) @ extract opcode from rINST 4371 SET_VREG(r0, r9) @ vAA<- r0 4372 GOTO_OPCODE(ip) @ jump to next instruction 4373 /* 11-14 instructions */ 4374 4375 4376/* ------------------------------ */ 4377 .balign 64 4378.L_OP_SHR_INT: /* 0x99 */ 4379/* File: armv5te/OP_SHR_INT.S */ 4380/* File: armv5te/binop.S */ 4381 /* 4382 * Generic 32-bit binary operation. Provide an "instr" line that 4383 * specifies an instruction that performs "result = r0 op r1". 4384 * This could be an ARM instruction or a function call. (If the result 4385 * comes back in a register other than r0, you can override "result".) 4386 * 4387 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4388 * vCC (r1). Useful for integer division and modulus. Note that we 4389 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4390 * handles it correctly. 4391 * 4392 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4393 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4394 * mul-float, div-float, rem-float 4395 */ 4396 /* binop vAA, vBB, vCC */ 4397 FETCH(r0, 1) @ r0<- CCBB 4398 mov r9, rINST, lsr #8 @ r9<- AA 4399 mov r3, r0, lsr #8 @ r3<- CC 4400 and r2, r0, #255 @ r2<- BB 4401 GET_VREG(r1, r3) @ r1<- vCC 4402 GET_VREG(r0, r2) @ r0<- vBB 4403 .if 0 4404 cmp r1, #0 @ is second operand zero? 4405 beq common_errDivideByZero 4406 .endif 4407 4408 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4409 and r1, r1, #31 @ optional op; may set condition codes 4410 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 4411 GET_INST_OPCODE(ip) @ extract opcode from rINST 4412 SET_VREG(r0, r9) @ vAA<- r0 4413 GOTO_OPCODE(ip) @ jump to next instruction 4414 /* 11-14 instructions */ 4415 4416 4417/* ------------------------------ */ 4418 .balign 64 4419.L_OP_USHR_INT: /* 0x9a */ 4420/* File: armv5te/OP_USHR_INT.S */ 4421/* File: armv5te/binop.S */ 4422 /* 4423 * Generic 32-bit binary operation. Provide an "instr" line that 4424 * specifies an instruction that performs "result = r0 op r1". 4425 * This could be an ARM instruction or a function call. (If the result 4426 * comes back in a register other than r0, you can override "result".) 4427 * 4428 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4429 * vCC (r1). Useful for integer division and modulus. Note that we 4430 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4431 * handles it correctly. 4432 * 4433 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4434 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4435 * mul-float, div-float, rem-float 4436 */ 4437 /* binop vAA, vBB, vCC */ 4438 FETCH(r0, 1) @ r0<- CCBB 4439 mov r9, rINST, lsr #8 @ r9<- AA 4440 mov r3, r0, lsr #8 @ r3<- CC 4441 and r2, r0, #255 @ r2<- BB 4442 GET_VREG(r1, r3) @ r1<- vCC 4443 GET_VREG(r0, r2) @ r0<- vBB 4444 .if 0 4445 cmp r1, #0 @ is second operand zero? 4446 beq common_errDivideByZero 4447 .endif 4448 4449 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4450 and r1, r1, #31 @ optional op; may set condition codes 4451 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 4452 GET_INST_OPCODE(ip) @ extract opcode from rINST 4453 SET_VREG(r0, r9) @ vAA<- r0 4454 GOTO_OPCODE(ip) @ jump to next instruction 4455 /* 11-14 instructions */ 4456 4457 4458/* ------------------------------ */ 4459 .balign 64 4460.L_OP_ADD_LONG: /* 0x9b */ 4461/* File: armv5te/OP_ADD_LONG.S */ 4462/* File: armv5te/binopWide.S */ 4463 /* 4464 * Generic 64-bit binary operation. Provide an "instr" line that 4465 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4466 * This could be an ARM instruction or a function call. (If the result 4467 * comes back in a register other than r0, you can override "result".) 4468 * 4469 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4470 * vCC (r1). Useful for integer division and modulus. 4471 * 4472 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4473 * xor-long, add-double, sub-double, mul-double, div-double, 4474 * rem-double 4475 * 4476 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4477 */ 4478 /* binop vAA, vBB, vCC */ 4479 FETCH(r0, 1) @ r0<- CCBB 4480 mov r9, rINST, lsr #8 @ r9<- AA 4481 and r2, r0, #255 @ r2<- BB 4482 mov r3, r0, lsr #8 @ r3<- CC 4483 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4484 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4485 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4486 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4487 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4488 .if 0 4489 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4490 beq common_errDivideByZero 4491 .endif 4492 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4493 4494 adds r0, r0, r2 @ optional op; may set condition codes 4495 adc r1, r1, r3 @ result<- op, r0-r3 changed 4496 GET_INST_OPCODE(ip) @ extract opcode from rINST 4497 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4498 GOTO_OPCODE(ip) @ jump to next instruction 4499 /* 14-17 instructions */ 4500 4501 4502/* ------------------------------ */ 4503 .balign 64 4504.L_OP_SUB_LONG: /* 0x9c */ 4505/* File: armv5te/OP_SUB_LONG.S */ 4506/* File: armv5te/binopWide.S */ 4507 /* 4508 * Generic 64-bit binary operation. Provide an "instr" line that 4509 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4510 * This could be an ARM instruction or a function call. (If the result 4511 * comes back in a register other than r0, you can override "result".) 4512 * 4513 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4514 * vCC (r1). Useful for integer division and modulus. 4515 * 4516 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4517 * xor-long, add-double, sub-double, mul-double, div-double, 4518 * rem-double 4519 * 4520 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4521 */ 4522 /* binop vAA, vBB, vCC */ 4523 FETCH(r0, 1) @ r0<- CCBB 4524 mov r9, rINST, lsr #8 @ r9<- AA 4525 and r2, r0, #255 @ r2<- BB 4526 mov r3, r0, lsr #8 @ r3<- CC 4527 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4528 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4529 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4530 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4531 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4532 .if 0 4533 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4534 beq common_errDivideByZero 4535 .endif 4536 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4537 4538 subs r0, r0, r2 @ optional op; may set condition codes 4539 sbc r1, r1, r3 @ result<- op, r0-r3 changed 4540 GET_INST_OPCODE(ip) @ extract opcode from rINST 4541 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4542 GOTO_OPCODE(ip) @ jump to next instruction 4543 /* 14-17 instructions */ 4544 4545 4546/* ------------------------------ */ 4547 .balign 64 4548.L_OP_MUL_LONG: /* 0x9d */ 4549/* File: armv5te/OP_MUL_LONG.S */ 4550 /* 4551 * Signed 64-bit integer multiply. 4552 * 4553 * Consider WXxYZ (r1r0 x r3r2) with a long multiply: 4554 * WX 4555 * x YZ 4556 * -------- 4557 * ZW ZX 4558 * YW YX 4559 * 4560 * The low word of the result holds ZX, the high word holds 4561 * (ZW+YX) + (the high overflow from ZX). YW doesn't matter because 4562 * it doesn't fit in the low 64 bits. 4563 * 4564 * Unlike most ARM math operations, multiply instructions have 4565 * restrictions on using the same register more than once (Rd and Rm 4566 * cannot be the same). 4567 */ 4568 /* mul-long vAA, vBB, vCC */ 4569 FETCH(r0, 1) @ r0<- CCBB 4570 and r2, r0, #255 @ r2<- BB 4571 mov r3, r0, lsr #8 @ r3<- CC 4572 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4573 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4574 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4575 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4576 mul ip, r2, r1 @ ip<- ZxW 4577 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 4578 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 4579 mov r0, rINST, lsr #8 @ r0<- AA 4580 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 4581 add r0, rFP, r0, lsl #2 @ r0<- &fp[AA] 4582 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4583 b .LOP_MUL_LONG_finish 4584 4585/* ------------------------------ */ 4586 .balign 64 4587.L_OP_DIV_LONG: /* 0x9e */ 4588/* File: armv5te/OP_DIV_LONG.S */ 4589/* File: armv5te/binopWide.S */ 4590 /* 4591 * Generic 64-bit binary operation. Provide an "instr" line that 4592 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4593 * This could be an ARM instruction or a function call. (If the result 4594 * comes back in a register other than r0, you can override "result".) 4595 * 4596 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4597 * vCC (r1). Useful for integer division and modulus. 4598 * 4599 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4600 * xor-long, add-double, sub-double, mul-double, div-double, 4601 * rem-double 4602 * 4603 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4604 */ 4605 /* binop vAA, vBB, vCC */ 4606 FETCH(r0, 1) @ r0<- CCBB 4607 mov r9, rINST, lsr #8 @ r9<- AA 4608 and r2, r0, #255 @ r2<- BB 4609 mov r3, r0, lsr #8 @ r3<- CC 4610 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4611 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4612 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4613 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4614 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4615 .if 1 4616 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4617 beq common_errDivideByZero 4618 .endif 4619 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4620 4621 @ optional op; may set condition codes 4622 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4623 GET_INST_OPCODE(ip) @ extract opcode from rINST 4624 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4625 GOTO_OPCODE(ip) @ jump to next instruction 4626 /* 14-17 instructions */ 4627 4628 4629/* ------------------------------ */ 4630 .balign 64 4631.L_OP_REM_LONG: /* 0x9f */ 4632/* File: armv5te/OP_REM_LONG.S */ 4633/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 4634/* File: armv5te/binopWide.S */ 4635 /* 4636 * Generic 64-bit binary operation. Provide an "instr" line that 4637 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4638 * This could be an ARM instruction or a function call. (If the result 4639 * comes back in a register other than r0, you can override "result".) 4640 * 4641 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4642 * vCC (r1). Useful for integer division and modulus. 4643 * 4644 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4645 * xor-long, add-double, sub-double, mul-double, div-double, 4646 * rem-double 4647 * 4648 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4649 */ 4650 /* binop vAA, vBB, vCC */ 4651 FETCH(r0, 1) @ r0<- CCBB 4652 mov r9, rINST, lsr #8 @ r9<- AA 4653 and r2, r0, #255 @ r2<- BB 4654 mov r3, r0, lsr #8 @ r3<- CC 4655 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4656 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4657 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4658 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4659 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4660 .if 1 4661 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4662 beq common_errDivideByZero 4663 .endif 4664 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4665 4666 @ optional op; may set condition codes 4667 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4668 GET_INST_OPCODE(ip) @ extract opcode from rINST 4669 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 4670 GOTO_OPCODE(ip) @ jump to next instruction 4671 /* 14-17 instructions */ 4672 4673 4674/* ------------------------------ */ 4675 .balign 64 4676.L_OP_AND_LONG: /* 0xa0 */ 4677/* File: armv5te/OP_AND_LONG.S */ 4678/* File: armv5te/binopWide.S */ 4679 /* 4680 * Generic 64-bit binary operation. Provide an "instr" line that 4681 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4682 * This could be an ARM instruction or a function call. (If the result 4683 * comes back in a register other than r0, you can override "result".) 4684 * 4685 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4686 * vCC (r1). Useful for integer division and modulus. 4687 * 4688 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4689 * xor-long, add-double, sub-double, mul-double, div-double, 4690 * rem-double 4691 * 4692 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4693 */ 4694 /* binop vAA, vBB, vCC */ 4695 FETCH(r0, 1) @ r0<- CCBB 4696 mov r9, rINST, lsr #8 @ r9<- AA 4697 and r2, r0, #255 @ r2<- BB 4698 mov r3, r0, lsr #8 @ r3<- CC 4699 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4700 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4701 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4702 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4703 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4704 .if 0 4705 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4706 beq common_errDivideByZero 4707 .endif 4708 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4709 4710 and r0, r0, r2 @ optional op; may set condition codes 4711 and r1, r1, r3 @ result<- op, r0-r3 changed 4712 GET_INST_OPCODE(ip) @ extract opcode from rINST 4713 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4714 GOTO_OPCODE(ip) @ jump to next instruction 4715 /* 14-17 instructions */ 4716 4717 4718/* ------------------------------ */ 4719 .balign 64 4720.L_OP_OR_LONG: /* 0xa1 */ 4721/* File: armv5te/OP_OR_LONG.S */ 4722/* File: armv5te/binopWide.S */ 4723 /* 4724 * Generic 64-bit binary operation. Provide an "instr" line that 4725 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4726 * This could be an ARM instruction or a function call. (If the result 4727 * comes back in a register other than r0, you can override "result".) 4728 * 4729 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4730 * vCC (r1). Useful for integer division and modulus. 4731 * 4732 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4733 * xor-long, add-double, sub-double, mul-double, div-double, 4734 * rem-double 4735 * 4736 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4737 */ 4738 /* binop vAA, vBB, vCC */ 4739 FETCH(r0, 1) @ r0<- CCBB 4740 mov r9, rINST, lsr #8 @ r9<- AA 4741 and r2, r0, #255 @ r2<- BB 4742 mov r3, r0, lsr #8 @ r3<- CC 4743 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4744 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4745 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4746 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4747 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4748 .if 0 4749 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4750 beq common_errDivideByZero 4751 .endif 4752 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4753 4754 orr r0, r0, r2 @ optional op; may set condition codes 4755 orr r1, r1, r3 @ result<- op, r0-r3 changed 4756 GET_INST_OPCODE(ip) @ extract opcode from rINST 4757 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4758 GOTO_OPCODE(ip) @ jump to next instruction 4759 /* 14-17 instructions */ 4760 4761 4762/* ------------------------------ */ 4763 .balign 64 4764.L_OP_XOR_LONG: /* 0xa2 */ 4765/* File: armv5te/OP_XOR_LONG.S */ 4766/* File: armv5te/binopWide.S */ 4767 /* 4768 * Generic 64-bit binary operation. Provide an "instr" line that 4769 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4770 * This could be an ARM instruction or a function call. (If the result 4771 * comes back in a register other than r0, you can override "result".) 4772 * 4773 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4774 * vCC (r1). Useful for integer division and modulus. 4775 * 4776 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4777 * xor-long, add-double, sub-double, mul-double, div-double, 4778 * rem-double 4779 * 4780 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4781 */ 4782 /* binop vAA, vBB, vCC */ 4783 FETCH(r0, 1) @ r0<- CCBB 4784 mov r9, rINST, lsr #8 @ r9<- AA 4785 and r2, r0, #255 @ r2<- BB 4786 mov r3, r0, lsr #8 @ r3<- CC 4787 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4788 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4789 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4790 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4791 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4792 .if 0 4793 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4794 beq common_errDivideByZero 4795 .endif 4796 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4797 4798 eor r0, r0, r2 @ optional op; may set condition codes 4799 eor r1, r1, r3 @ result<- op, r0-r3 changed 4800 GET_INST_OPCODE(ip) @ extract opcode from rINST 4801 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4802 GOTO_OPCODE(ip) @ jump to next instruction 4803 /* 14-17 instructions */ 4804 4805 4806/* ------------------------------ */ 4807 .balign 64 4808.L_OP_SHL_LONG: /* 0xa3 */ 4809/* File: armv5te/OP_SHL_LONG.S */ 4810 /* 4811 * Long integer shift. This is different from the generic 32/64-bit 4812 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4813 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4814 * 6 bits of the shift distance. 4815 */ 4816 /* shl-long vAA, vBB, vCC */ 4817 FETCH(r0, 1) @ r0<- CCBB 4818 mov r9, rINST, lsr #8 @ r9<- AA 4819 and r3, r0, #255 @ r3<- BB 4820 mov r0, r0, lsr #8 @ r0<- CC 4821 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4822 GET_VREG(r2, r0) @ r2<- vCC 4823 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4824 and r2, r2, #63 @ r2<- r2 & 0x3f 4825 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4826 4827 mov r1, r1, asl r2 @ r1<- r1 << r2 4828 rsb r3, r2, #32 @ r3<- 32 - r2 4829 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 4830 subs ip, r2, #32 @ ip<- r2 - 32 4831 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 4832 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4833 b .LOP_SHL_LONG_finish 4834 4835/* ------------------------------ */ 4836 .balign 64 4837.L_OP_SHR_LONG: /* 0xa4 */ 4838/* File: armv5te/OP_SHR_LONG.S */ 4839 /* 4840 * Long integer shift. This is different from the generic 32/64-bit 4841 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4842 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4843 * 6 bits of the shift distance. 4844 */ 4845 /* shr-long vAA, vBB, vCC */ 4846 FETCH(r0, 1) @ r0<- CCBB 4847 mov r9, rINST, lsr #8 @ r9<- AA 4848 and r3, r0, #255 @ r3<- BB 4849 mov r0, r0, lsr #8 @ r0<- CC 4850 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4851 GET_VREG(r2, r0) @ r2<- vCC 4852 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4853 and r2, r2, #63 @ r0<- r0 & 0x3f 4854 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4855 4856 mov r0, r0, lsr r2 @ r0<- r2 >> r2 4857 rsb r3, r2, #32 @ r3<- 32 - r2 4858 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 4859 subs ip, r2, #32 @ ip<- r2 - 32 4860 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 4861 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4862 b .LOP_SHR_LONG_finish 4863 4864/* ------------------------------ */ 4865 .balign 64 4866.L_OP_USHR_LONG: /* 0xa5 */ 4867/* File: armv5te/OP_USHR_LONG.S */ 4868 /* 4869 * Long integer shift. This is different from the generic 32/64-bit 4870 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4871 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4872 * 6 bits of the shift distance. 4873 */ 4874 /* ushr-long vAA, vBB, vCC */ 4875 FETCH(r0, 1) @ r0<- CCBB 4876 mov r9, rINST, lsr #8 @ r9<- AA 4877 and r3, r0, #255 @ r3<- BB 4878 mov r0, r0, lsr #8 @ r0<- CC 4879 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4880 GET_VREG(r2, r0) @ r2<- vCC 4881 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4882 and r2, r2, #63 @ r0<- r0 & 0x3f 4883 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4884 4885 mov r0, r0, lsr r2 @ r0<- r2 >> r2 4886 rsb r3, r2, #32 @ r3<- 32 - r2 4887 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 4888 subs ip, r2, #32 @ ip<- r2 - 32 4889 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 4890 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4891 b .LOP_USHR_LONG_finish 4892 4893/* ------------------------------ */ 4894 .balign 64 4895.L_OP_ADD_FLOAT: /* 0xa6 */ 4896/* File: arm-vfp/OP_ADD_FLOAT.S */ 4897/* File: arm-vfp/fbinop.S */ 4898 /* 4899 * Generic 32-bit floating-point operation. Provide an "instr" line that 4900 * specifies an instruction that performs "s2 = s0 op s1". Because we 4901 * use the "softfp" ABI, this must be an instruction, not a function call. 4902 * 4903 * For: add-float, sub-float, mul-float, div-float 4904 */ 4905 /* floatop vAA, vBB, vCC */ 4906 FETCH(r0, 1) @ r0<- CCBB 4907 mov r9, rINST, lsr #8 @ r9<- AA 4908 mov r3, r0, lsr #8 @ r3<- CC 4909 and r2, r0, #255 @ r2<- BB 4910 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4911 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4912 flds s1, [r3] @ s1<- vCC 4913 flds s0, [r2] @ s0<- vBB 4914 4915 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4916 fadds s2, s0, s1 @ s2<- op 4917 GET_INST_OPCODE(ip) @ extract opcode from rINST 4918 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4919 fsts s2, [r9] @ vAA<- s2 4920 GOTO_OPCODE(ip) @ jump to next instruction 4921 4922 4923/* ------------------------------ */ 4924 .balign 64 4925.L_OP_SUB_FLOAT: /* 0xa7 */ 4926/* File: arm-vfp/OP_SUB_FLOAT.S */ 4927/* File: arm-vfp/fbinop.S */ 4928 /* 4929 * Generic 32-bit floating-point operation. Provide an "instr" line that 4930 * specifies an instruction that performs "s2 = s0 op s1". Because we 4931 * use the "softfp" ABI, this must be an instruction, not a function call. 4932 * 4933 * For: add-float, sub-float, mul-float, div-float 4934 */ 4935 /* floatop vAA, vBB, vCC */ 4936 FETCH(r0, 1) @ r0<- CCBB 4937 mov r9, rINST, lsr #8 @ r9<- AA 4938 mov r3, r0, lsr #8 @ r3<- CC 4939 and r2, r0, #255 @ r2<- BB 4940 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4941 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4942 flds s1, [r3] @ s1<- vCC 4943 flds s0, [r2] @ s0<- vBB 4944 4945 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4946 fsubs s2, s0, s1 @ s2<- op 4947 GET_INST_OPCODE(ip) @ extract opcode from rINST 4948 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4949 fsts s2, [r9] @ vAA<- s2 4950 GOTO_OPCODE(ip) @ jump to next instruction 4951 4952 4953/* ------------------------------ */ 4954 .balign 64 4955.L_OP_MUL_FLOAT: /* 0xa8 */ 4956/* File: arm-vfp/OP_MUL_FLOAT.S */ 4957/* File: arm-vfp/fbinop.S */ 4958 /* 4959 * Generic 32-bit floating-point operation. Provide an "instr" line that 4960 * specifies an instruction that performs "s2 = s0 op s1". Because we 4961 * use the "softfp" ABI, this must be an instruction, not a function call. 4962 * 4963 * For: add-float, sub-float, mul-float, div-float 4964 */ 4965 /* floatop vAA, vBB, vCC */ 4966 FETCH(r0, 1) @ r0<- CCBB 4967 mov r9, rINST, lsr #8 @ r9<- AA 4968 mov r3, r0, lsr #8 @ r3<- CC 4969 and r2, r0, #255 @ r2<- BB 4970 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4971 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4972 flds s1, [r3] @ s1<- vCC 4973 flds s0, [r2] @ s0<- vBB 4974 4975 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4976 fmuls s2, s0, s1 @ s2<- op 4977 GET_INST_OPCODE(ip) @ extract opcode from rINST 4978 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4979 fsts s2, [r9] @ vAA<- s2 4980 GOTO_OPCODE(ip) @ jump to next instruction 4981 4982 4983/* ------------------------------ */ 4984 .balign 64 4985.L_OP_DIV_FLOAT: /* 0xa9 */ 4986/* File: arm-vfp/OP_DIV_FLOAT.S */ 4987/* File: arm-vfp/fbinop.S */ 4988 /* 4989 * Generic 32-bit floating-point operation. Provide an "instr" line that 4990 * specifies an instruction that performs "s2 = s0 op s1". Because we 4991 * use the "softfp" ABI, this must be an instruction, not a function call. 4992 * 4993 * For: add-float, sub-float, mul-float, div-float 4994 */ 4995 /* floatop vAA, vBB, vCC */ 4996 FETCH(r0, 1) @ r0<- CCBB 4997 mov r9, rINST, lsr #8 @ r9<- AA 4998 mov r3, r0, lsr #8 @ r3<- CC 4999 and r2, r0, #255 @ r2<- BB 5000 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5001 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5002 flds s1, [r3] @ s1<- vCC 5003 flds s0, [r2] @ s0<- vBB 5004 5005 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5006 fdivs s2, s0, s1 @ s2<- op 5007 GET_INST_OPCODE(ip) @ extract opcode from rINST 5008 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5009 fsts s2, [r9] @ vAA<- s2 5010 GOTO_OPCODE(ip) @ jump to next instruction 5011 5012 5013/* ------------------------------ */ 5014 .balign 64 5015.L_OP_REM_FLOAT: /* 0xaa */ 5016/* File: armv5te/OP_REM_FLOAT.S */ 5017/* EABI doesn't define a float remainder function, but libm does */ 5018/* File: armv5te/binop.S */ 5019 /* 5020 * Generic 32-bit binary operation. Provide an "instr" line that 5021 * specifies an instruction that performs "result = r0 op r1". 5022 * This could be an ARM instruction or a function call. (If the result 5023 * comes back in a register other than r0, you can override "result".) 5024 * 5025 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5026 * vCC (r1). Useful for integer division and modulus. Note that we 5027 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 5028 * handles it correctly. 5029 * 5030 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 5031 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 5032 * mul-float, div-float, rem-float 5033 */ 5034 /* binop vAA, vBB, vCC */ 5035 FETCH(r0, 1) @ r0<- CCBB 5036 mov r9, rINST, lsr #8 @ r9<- AA 5037 mov r3, r0, lsr #8 @ r3<- CC 5038 and r2, r0, #255 @ r2<- BB 5039 GET_VREG(r1, r3) @ r1<- vCC 5040 GET_VREG(r0, r2) @ r0<- vBB 5041 .if 0 5042 cmp r1, #0 @ is second operand zero? 5043 beq common_errDivideByZero 5044 .endif 5045 5046 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5047 @ optional op; may set condition codes 5048 bl fmodf @ r0<- op, r0-r3 changed 5049 GET_INST_OPCODE(ip) @ extract opcode from rINST 5050 SET_VREG(r0, r9) @ vAA<- r0 5051 GOTO_OPCODE(ip) @ jump to next instruction 5052 /* 11-14 instructions */ 5053 5054 5055/* ------------------------------ */ 5056 .balign 64 5057.L_OP_ADD_DOUBLE: /* 0xab */ 5058/* File: arm-vfp/OP_ADD_DOUBLE.S */ 5059/* File: arm-vfp/fbinopWide.S */ 5060 /* 5061 * Generic 64-bit double-precision floating point binary operation. 5062 * Provide an "instr" line that specifies an instruction that performs 5063 * "d2 = d0 op d1". 5064 * 5065 * for: add-double, sub-double, mul-double, div-double 5066 */ 5067 /* doubleop vAA, vBB, vCC */ 5068 FETCH(r0, 1) @ r0<- CCBB 5069 mov r9, rINST, lsr #8 @ r9<- AA 5070 mov r3, r0, lsr #8 @ r3<- CC 5071 and r2, r0, #255 @ r2<- BB 5072 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5073 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5074 fldd d1, [r3] @ d1<- vCC 5075 fldd d0, [r2] @ d0<- vBB 5076 5077 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5078 faddd d2, d0, d1 @ s2<- op 5079 GET_INST_OPCODE(ip) @ extract opcode from rINST 5080 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5081 fstd d2, [r9] @ vAA<- d2 5082 GOTO_OPCODE(ip) @ jump to next instruction 5083 5084 5085/* ------------------------------ */ 5086 .balign 64 5087.L_OP_SUB_DOUBLE: /* 0xac */ 5088/* File: arm-vfp/OP_SUB_DOUBLE.S */ 5089/* File: arm-vfp/fbinopWide.S */ 5090 /* 5091 * Generic 64-bit double-precision floating point binary operation. 5092 * Provide an "instr" line that specifies an instruction that performs 5093 * "d2 = d0 op d1". 5094 * 5095 * for: add-double, sub-double, mul-double, div-double 5096 */ 5097 /* doubleop vAA, vBB, vCC */ 5098 FETCH(r0, 1) @ r0<- CCBB 5099 mov r9, rINST, lsr #8 @ r9<- AA 5100 mov r3, r0, lsr #8 @ r3<- CC 5101 and r2, r0, #255 @ r2<- BB 5102 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5103 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5104 fldd d1, [r3] @ d1<- vCC 5105 fldd d0, [r2] @ d0<- vBB 5106 5107 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5108 fsubd d2, d0, d1 @ s2<- op 5109 GET_INST_OPCODE(ip) @ extract opcode from rINST 5110 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5111 fstd d2, [r9] @ vAA<- d2 5112 GOTO_OPCODE(ip) @ jump to next instruction 5113 5114 5115/* ------------------------------ */ 5116 .balign 64 5117.L_OP_MUL_DOUBLE: /* 0xad */ 5118/* File: arm-vfp/OP_MUL_DOUBLE.S */ 5119/* File: arm-vfp/fbinopWide.S */ 5120 /* 5121 * Generic 64-bit double-precision floating point binary operation. 5122 * Provide an "instr" line that specifies an instruction that performs 5123 * "d2 = d0 op d1". 5124 * 5125 * for: add-double, sub-double, mul-double, div-double 5126 */ 5127 /* doubleop vAA, vBB, vCC */ 5128 FETCH(r0, 1) @ r0<- CCBB 5129 mov r9, rINST, lsr #8 @ r9<- AA 5130 mov r3, r0, lsr #8 @ r3<- CC 5131 and r2, r0, #255 @ r2<- BB 5132 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5133 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5134 fldd d1, [r3] @ d1<- vCC 5135 fldd d0, [r2] @ d0<- vBB 5136 5137 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5138 fmuld d2, d0, d1 @ s2<- op 5139 GET_INST_OPCODE(ip) @ extract opcode from rINST 5140 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5141 fstd d2, [r9] @ vAA<- d2 5142 GOTO_OPCODE(ip) @ jump to next instruction 5143 5144 5145/* ------------------------------ */ 5146 .balign 64 5147.L_OP_DIV_DOUBLE: /* 0xae */ 5148/* File: arm-vfp/OP_DIV_DOUBLE.S */ 5149/* File: arm-vfp/fbinopWide.S */ 5150 /* 5151 * Generic 64-bit double-precision floating point binary operation. 5152 * Provide an "instr" line that specifies an instruction that performs 5153 * "d2 = d0 op d1". 5154 * 5155 * for: add-double, sub-double, mul-double, div-double 5156 */ 5157 /* doubleop vAA, vBB, vCC */ 5158 FETCH(r0, 1) @ r0<- CCBB 5159 mov r9, rINST, lsr #8 @ r9<- AA 5160 mov r3, r0, lsr #8 @ r3<- CC 5161 and r2, r0, #255 @ r2<- BB 5162 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5163 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5164 fldd d1, [r3] @ d1<- vCC 5165 fldd d0, [r2] @ d0<- vBB 5166 5167 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5168 fdivd d2, d0, d1 @ s2<- op 5169 GET_INST_OPCODE(ip) @ extract opcode from rINST 5170 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5171 fstd d2, [r9] @ vAA<- d2 5172 GOTO_OPCODE(ip) @ jump to next instruction 5173 5174 5175/* ------------------------------ */ 5176 .balign 64 5177.L_OP_REM_DOUBLE: /* 0xaf */ 5178/* File: armv5te/OP_REM_DOUBLE.S */ 5179/* EABI doesn't define a double remainder function, but libm does */ 5180/* File: armv5te/binopWide.S */ 5181 /* 5182 * Generic 64-bit binary operation. Provide an "instr" line that 5183 * specifies an instruction that performs "result = r0-r1 op r2-r3". 5184 * This could be an ARM instruction or a function call. (If the result 5185 * comes back in a register other than r0, you can override "result".) 5186 * 5187 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5188 * vCC (r1). Useful for integer division and modulus. 5189 * 5190 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 5191 * xor-long, add-double, sub-double, mul-double, div-double, 5192 * rem-double 5193 * 5194 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 5195 */ 5196 /* binop vAA, vBB, vCC */ 5197 FETCH(r0, 1) @ r0<- CCBB 5198 mov r9, rINST, lsr #8 @ r9<- AA 5199 and r2, r0, #255 @ r2<- BB 5200 mov r3, r0, lsr #8 @ r3<- CC 5201 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 5202 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 5203 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 5204 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 5205 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 5206 .if 0 5207 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5208 beq common_errDivideByZero 5209 .endif 5210 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5211 5212 @ optional op; may set condition codes 5213 bl fmod @ result<- op, r0-r3 changed 5214 GET_INST_OPCODE(ip) @ extract opcode from rINST 5215 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5216 GOTO_OPCODE(ip) @ jump to next instruction 5217 /* 14-17 instructions */ 5218 5219 5220/* ------------------------------ */ 5221 .balign 64 5222.L_OP_ADD_INT_2ADDR: /* 0xb0 */ 5223/* File: armv6t2/OP_ADD_INT_2ADDR.S */ 5224/* File: armv6t2/binop2addr.S */ 5225 /* 5226 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5227 * that specifies an instruction that performs "result = r0 op r1". 5228 * This could be an ARM instruction or a function call. (If the result 5229 * comes back in a register other than r0, you can override "result".) 5230 * 5231 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5232 * vCC (r1). Useful for integer division and modulus. 5233 * 5234 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5235 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5236 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5237 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5238 */ 5239 /* binop/2addr vA, vB */ 5240 mov r3, rINST, lsr #12 @ r3<- B 5241 ubfx r9, rINST, #8, #4 @ r9<- A 5242 GET_VREG(r1, r3) @ r1<- vB 5243 GET_VREG(r0, r9) @ r0<- vA 5244 .if 0 5245 cmp r1, #0 @ is second operand zero? 5246 beq common_errDivideByZero 5247 .endif 5248 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5249 5250 @ optional op; may set condition codes 5251 add r0, r0, r1 @ r0<- op, r0-r3 changed 5252 GET_INST_OPCODE(ip) @ extract opcode from rINST 5253 SET_VREG(r0, r9) @ vAA<- r0 5254 GOTO_OPCODE(ip) @ jump to next instruction 5255 /* 10-13 instructions */ 5256 5257 5258/* ------------------------------ */ 5259 .balign 64 5260.L_OP_SUB_INT_2ADDR: /* 0xb1 */ 5261/* File: armv6t2/OP_SUB_INT_2ADDR.S */ 5262/* File: armv6t2/binop2addr.S */ 5263 /* 5264 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5265 * that specifies an instruction that performs "result = r0 op r1". 5266 * This could be an ARM instruction or a function call. (If the result 5267 * comes back in a register other than r0, you can override "result".) 5268 * 5269 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5270 * vCC (r1). Useful for integer division and modulus. 5271 * 5272 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5273 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5274 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5275 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5276 */ 5277 /* binop/2addr vA, vB */ 5278 mov r3, rINST, lsr #12 @ r3<- B 5279 ubfx r9, rINST, #8, #4 @ r9<- A 5280 GET_VREG(r1, r3) @ r1<- vB 5281 GET_VREG(r0, r9) @ r0<- vA 5282 .if 0 5283 cmp r1, #0 @ is second operand zero? 5284 beq common_errDivideByZero 5285 .endif 5286 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5287 5288 @ optional op; may set condition codes 5289 sub r0, r0, r1 @ r0<- op, r0-r3 changed 5290 GET_INST_OPCODE(ip) @ extract opcode from rINST 5291 SET_VREG(r0, r9) @ vAA<- r0 5292 GOTO_OPCODE(ip) @ jump to next instruction 5293 /* 10-13 instructions */ 5294 5295 5296/* ------------------------------ */ 5297 .balign 64 5298.L_OP_MUL_INT_2ADDR: /* 0xb2 */ 5299/* File: armv6t2/OP_MUL_INT_2ADDR.S */ 5300/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 5301/* File: armv6t2/binop2addr.S */ 5302 /* 5303 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5304 * that specifies an instruction that performs "result = r0 op r1". 5305 * This could be an ARM instruction or a function call. (If the result 5306 * comes back in a register other than r0, you can override "result".) 5307 * 5308 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5309 * vCC (r1). Useful for integer division and modulus. 5310 * 5311 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5312 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5313 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5314 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5315 */ 5316 /* binop/2addr vA, vB */ 5317 mov r3, rINST, lsr #12 @ r3<- B 5318 ubfx r9, rINST, #8, #4 @ r9<- A 5319 GET_VREG(r1, r3) @ r1<- vB 5320 GET_VREG(r0, r9) @ r0<- vA 5321 .if 0 5322 cmp r1, #0 @ is second operand zero? 5323 beq common_errDivideByZero 5324 .endif 5325 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5326 5327 @ optional op; may set condition codes 5328 mul r0, r1, r0 @ r0<- op, r0-r3 changed 5329 GET_INST_OPCODE(ip) @ extract opcode from rINST 5330 SET_VREG(r0, r9) @ vAA<- r0 5331 GOTO_OPCODE(ip) @ jump to next instruction 5332 /* 10-13 instructions */ 5333 5334 5335/* ------------------------------ */ 5336 .balign 64 5337.L_OP_DIV_INT_2ADDR: /* 0xb3 */ 5338/* File: armv6t2/OP_DIV_INT_2ADDR.S */ 5339/* File: armv6t2/binop2addr.S */ 5340 /* 5341 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5342 * that specifies an instruction that performs "result = r0 op r1". 5343 * This could be an ARM instruction or a function call. (If the result 5344 * comes back in a register other than r0, you can override "result".) 5345 * 5346 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5347 * vCC (r1). Useful for integer division and modulus. 5348 * 5349 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5350 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5351 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5352 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5353 */ 5354 /* binop/2addr vA, vB */ 5355 mov r3, rINST, lsr #12 @ r3<- B 5356 ubfx r9, rINST, #8, #4 @ r9<- A 5357 GET_VREG(r1, r3) @ r1<- vB 5358 GET_VREG(r0, r9) @ r0<- vA 5359 .if 1 5360 cmp r1, #0 @ is second operand zero? 5361 beq common_errDivideByZero 5362 .endif 5363 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5364 5365 @ optional op; may set condition codes 5366 bl __aeabi_idiv @ r0<- op, r0-r3 changed 5367 GET_INST_OPCODE(ip) @ extract opcode from rINST 5368 SET_VREG(r0, r9) @ vAA<- r0 5369 GOTO_OPCODE(ip) @ jump to next instruction 5370 /* 10-13 instructions */ 5371 5372 5373/* ------------------------------ */ 5374 .balign 64 5375.L_OP_REM_INT_2ADDR: /* 0xb4 */ 5376/* File: armv6t2/OP_REM_INT_2ADDR.S */ 5377/* idivmod returns quotient in r0 and remainder in r1 */ 5378/* File: armv6t2/binop2addr.S */ 5379 /* 5380 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5381 * that specifies an instruction that performs "result = r0 op r1". 5382 * This could be an ARM instruction or a function call. (If the result 5383 * comes back in a register other than r0, you can override "result".) 5384 * 5385 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5386 * vCC (r1). Useful for integer division and modulus. 5387 * 5388 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5389 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5390 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5391 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5392 */ 5393 /* binop/2addr vA, vB */ 5394 mov r3, rINST, lsr #12 @ r3<- B 5395 ubfx r9, rINST, #8, #4 @ r9<- A 5396 GET_VREG(r1, r3) @ r1<- vB 5397 GET_VREG(r0, r9) @ r0<- vA 5398 .if 1 5399 cmp r1, #0 @ is second operand zero? 5400 beq common_errDivideByZero 5401 .endif 5402 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5403 5404 @ optional op; may set condition codes 5405 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 5406 GET_INST_OPCODE(ip) @ extract opcode from rINST 5407 SET_VREG(r1, r9) @ vAA<- r1 5408 GOTO_OPCODE(ip) @ jump to next instruction 5409 /* 10-13 instructions */ 5410 5411 5412/* ------------------------------ */ 5413 .balign 64 5414.L_OP_AND_INT_2ADDR: /* 0xb5 */ 5415/* File: armv6t2/OP_AND_INT_2ADDR.S */ 5416/* File: armv6t2/binop2addr.S */ 5417 /* 5418 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5419 * that specifies an instruction that performs "result = r0 op r1". 5420 * This could be an ARM instruction or a function call. (If the result 5421 * comes back in a register other than r0, you can override "result".) 5422 * 5423 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5424 * vCC (r1). Useful for integer division and modulus. 5425 * 5426 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5427 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5428 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5429 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5430 */ 5431 /* binop/2addr vA, vB */ 5432 mov r3, rINST, lsr #12 @ r3<- B 5433 ubfx r9, rINST, #8, #4 @ r9<- A 5434 GET_VREG(r1, r3) @ r1<- vB 5435 GET_VREG(r0, r9) @ r0<- vA 5436 .if 0 5437 cmp r1, #0 @ is second operand zero? 5438 beq common_errDivideByZero 5439 .endif 5440 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5441 5442 @ optional op; may set condition codes 5443 and r0, r0, r1 @ r0<- op, r0-r3 changed 5444 GET_INST_OPCODE(ip) @ extract opcode from rINST 5445 SET_VREG(r0, r9) @ vAA<- r0 5446 GOTO_OPCODE(ip) @ jump to next instruction 5447 /* 10-13 instructions */ 5448 5449 5450/* ------------------------------ */ 5451 .balign 64 5452.L_OP_OR_INT_2ADDR: /* 0xb6 */ 5453/* File: armv6t2/OP_OR_INT_2ADDR.S */ 5454/* File: armv6t2/binop2addr.S */ 5455 /* 5456 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5457 * that specifies an instruction that performs "result = r0 op r1". 5458 * This could be an ARM instruction or a function call. (If the result 5459 * comes back in a register other than r0, you can override "result".) 5460 * 5461 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5462 * vCC (r1). Useful for integer division and modulus. 5463 * 5464 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5465 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5466 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5467 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5468 */ 5469 /* binop/2addr vA, vB */ 5470 mov r3, rINST, lsr #12 @ r3<- B 5471 ubfx r9, rINST, #8, #4 @ r9<- A 5472 GET_VREG(r1, r3) @ r1<- vB 5473 GET_VREG(r0, r9) @ r0<- vA 5474 .if 0 5475 cmp r1, #0 @ is second operand zero? 5476 beq common_errDivideByZero 5477 .endif 5478 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5479 5480 @ optional op; may set condition codes 5481 orr r0, r0, r1 @ r0<- op, r0-r3 changed 5482 GET_INST_OPCODE(ip) @ extract opcode from rINST 5483 SET_VREG(r0, r9) @ vAA<- r0 5484 GOTO_OPCODE(ip) @ jump to next instruction 5485 /* 10-13 instructions */ 5486 5487 5488/* ------------------------------ */ 5489 .balign 64 5490.L_OP_XOR_INT_2ADDR: /* 0xb7 */ 5491/* File: armv6t2/OP_XOR_INT_2ADDR.S */ 5492/* File: armv6t2/binop2addr.S */ 5493 /* 5494 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5495 * that specifies an instruction that performs "result = r0 op r1". 5496 * This could be an ARM instruction or a function call. (If the result 5497 * comes back in a register other than r0, you can override "result".) 5498 * 5499 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5500 * vCC (r1). Useful for integer division and modulus. 5501 * 5502 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5503 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5504 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5505 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5506 */ 5507 /* binop/2addr vA, vB */ 5508 mov r3, rINST, lsr #12 @ r3<- B 5509 ubfx r9, rINST, #8, #4 @ r9<- A 5510 GET_VREG(r1, r3) @ r1<- vB 5511 GET_VREG(r0, r9) @ r0<- vA 5512 .if 0 5513 cmp r1, #0 @ is second operand zero? 5514 beq common_errDivideByZero 5515 .endif 5516 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5517 5518 @ optional op; may set condition codes 5519 eor r0, r0, r1 @ r0<- op, r0-r3 changed 5520 GET_INST_OPCODE(ip) @ extract opcode from rINST 5521 SET_VREG(r0, r9) @ vAA<- r0 5522 GOTO_OPCODE(ip) @ jump to next instruction 5523 /* 10-13 instructions */ 5524 5525 5526/* ------------------------------ */ 5527 .balign 64 5528.L_OP_SHL_INT_2ADDR: /* 0xb8 */ 5529/* File: armv6t2/OP_SHL_INT_2ADDR.S */ 5530/* File: armv6t2/binop2addr.S */ 5531 /* 5532 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5533 * that specifies an instruction that performs "result = r0 op r1". 5534 * This could be an ARM instruction or a function call. (If the result 5535 * comes back in a register other than r0, you can override "result".) 5536 * 5537 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5538 * vCC (r1). Useful for integer division and modulus. 5539 * 5540 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5541 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5542 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5543 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5544 */ 5545 /* binop/2addr vA, vB */ 5546 mov r3, rINST, lsr #12 @ r3<- B 5547 ubfx r9, rINST, #8, #4 @ r9<- A 5548 GET_VREG(r1, r3) @ r1<- vB 5549 GET_VREG(r0, r9) @ r0<- vA 5550 .if 0 5551 cmp r1, #0 @ is second operand zero? 5552 beq common_errDivideByZero 5553 .endif 5554 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5555 5556 and r1, r1, #31 @ optional op; may set condition codes 5557 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 5558 GET_INST_OPCODE(ip) @ extract opcode from rINST 5559 SET_VREG(r0, r9) @ vAA<- r0 5560 GOTO_OPCODE(ip) @ jump to next instruction 5561 /* 10-13 instructions */ 5562 5563 5564/* ------------------------------ */ 5565 .balign 64 5566.L_OP_SHR_INT_2ADDR: /* 0xb9 */ 5567/* File: armv6t2/OP_SHR_INT_2ADDR.S */ 5568/* File: armv6t2/binop2addr.S */ 5569 /* 5570 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5571 * that specifies an instruction that performs "result = r0 op r1". 5572 * This could be an ARM instruction or a function call. (If the result 5573 * comes back in a register other than r0, you can override "result".) 5574 * 5575 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5576 * vCC (r1). Useful for integer division and modulus. 5577 * 5578 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5579 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5580 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5581 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5582 */ 5583 /* binop/2addr vA, vB */ 5584 mov r3, rINST, lsr #12 @ r3<- B 5585 ubfx r9, rINST, #8, #4 @ r9<- A 5586 GET_VREG(r1, r3) @ r1<- vB 5587 GET_VREG(r0, r9) @ r0<- vA 5588 .if 0 5589 cmp r1, #0 @ is second operand zero? 5590 beq common_errDivideByZero 5591 .endif 5592 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5593 5594 and r1, r1, #31 @ optional op; may set condition codes 5595 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 5596 GET_INST_OPCODE(ip) @ extract opcode from rINST 5597 SET_VREG(r0, r9) @ vAA<- r0 5598 GOTO_OPCODE(ip) @ jump to next instruction 5599 /* 10-13 instructions */ 5600 5601 5602/* ------------------------------ */ 5603 .balign 64 5604.L_OP_USHR_INT_2ADDR: /* 0xba */ 5605/* File: armv6t2/OP_USHR_INT_2ADDR.S */ 5606/* File: armv6t2/binop2addr.S */ 5607 /* 5608 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5609 * that specifies an instruction that performs "result = r0 op r1". 5610 * This could be an ARM instruction or a function call. (If the result 5611 * comes back in a register other than r0, you can override "result".) 5612 * 5613 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5614 * vCC (r1). Useful for integer division and modulus. 5615 * 5616 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5617 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5618 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5619 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5620 */ 5621 /* binop/2addr vA, vB */ 5622 mov r3, rINST, lsr #12 @ r3<- B 5623 ubfx r9, rINST, #8, #4 @ r9<- A 5624 GET_VREG(r1, r3) @ r1<- vB 5625 GET_VREG(r0, r9) @ r0<- vA 5626 .if 0 5627 cmp r1, #0 @ is second operand zero? 5628 beq common_errDivideByZero 5629 .endif 5630 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5631 5632 and r1, r1, #31 @ optional op; may set condition codes 5633 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 5634 GET_INST_OPCODE(ip) @ extract opcode from rINST 5635 SET_VREG(r0, r9) @ vAA<- r0 5636 GOTO_OPCODE(ip) @ jump to next instruction 5637 /* 10-13 instructions */ 5638 5639 5640/* ------------------------------ */ 5641 .balign 64 5642.L_OP_ADD_LONG_2ADDR: /* 0xbb */ 5643/* File: armv6t2/OP_ADD_LONG_2ADDR.S */ 5644/* File: armv6t2/binopWide2addr.S */ 5645 /* 5646 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5647 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5648 * This could be an ARM instruction or a function call. (If the result 5649 * comes back in a register other than r0, you can override "result".) 5650 * 5651 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5652 * vCC (r1). Useful for integer division and modulus. 5653 * 5654 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5655 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5656 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5657 * rem-double/2addr 5658 */ 5659 /* binop/2addr vA, vB */ 5660 mov r1, rINST, lsr #12 @ r1<- B 5661 ubfx r9, rINST, #8, #4 @ r9<- A 5662 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5663 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5664 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5665 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5666 .if 0 5667 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5668 beq common_errDivideByZero 5669 .endif 5670 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5671 5672 adds r0, r0, r2 @ optional op; may set condition codes 5673 adc r1, r1, r3 @ result<- op, r0-r3 changed 5674 GET_INST_OPCODE(ip) @ extract opcode from rINST 5675 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5676 GOTO_OPCODE(ip) @ jump to next instruction 5677 /* 12-15 instructions */ 5678 5679 5680/* ------------------------------ */ 5681 .balign 64 5682.L_OP_SUB_LONG_2ADDR: /* 0xbc */ 5683/* File: armv6t2/OP_SUB_LONG_2ADDR.S */ 5684/* File: armv6t2/binopWide2addr.S */ 5685 /* 5686 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5687 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5688 * This could be an ARM instruction or a function call. (If the result 5689 * comes back in a register other than r0, you can override "result".) 5690 * 5691 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5692 * vCC (r1). Useful for integer division and modulus. 5693 * 5694 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5695 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5696 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5697 * rem-double/2addr 5698 */ 5699 /* binop/2addr vA, vB */ 5700 mov r1, rINST, lsr #12 @ r1<- B 5701 ubfx r9, rINST, #8, #4 @ r9<- A 5702 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5703 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5704 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5705 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5706 .if 0 5707 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5708 beq common_errDivideByZero 5709 .endif 5710 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5711 5712 subs r0, r0, r2 @ optional op; may set condition codes 5713 sbc r1, r1, r3 @ result<- op, r0-r3 changed 5714 GET_INST_OPCODE(ip) @ extract opcode from rINST 5715 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5716 GOTO_OPCODE(ip) @ jump to next instruction 5717 /* 12-15 instructions */ 5718 5719 5720/* ------------------------------ */ 5721 .balign 64 5722.L_OP_MUL_LONG_2ADDR: /* 0xbd */ 5723/* File: armv6t2/OP_MUL_LONG_2ADDR.S */ 5724 /* 5725 * Signed 64-bit integer multiply, "/2addr" version. 5726 * 5727 * See OP_MUL_LONG for an explanation. 5728 * 5729 * We get a little tight on registers, so to avoid looking up &fp[A] 5730 * again we stuff it into rINST. 5731 */ 5732 /* mul-long/2addr vA, vB */ 5733 mov r1, rINST, lsr #12 @ r1<- B 5734 ubfx r9, rINST, #8, #4 @ r9<- A 5735 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5736 add rINST, rFP, r9, lsl #2 @ rINST<- &fp[A] 5737 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5738 ldmia rINST, {r0-r1} @ r0/r1<- vAA/vAA+1 5739 mul ip, r2, r1 @ ip<- ZxW 5740 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 5741 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 5742 mov r0, rINST @ r0<- &fp[A] (free up rINST) 5743 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5744 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 5745 GET_INST_OPCODE(ip) @ extract opcode from rINST 5746 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 5747 GOTO_OPCODE(ip) @ jump to next instruction 5748 5749/* ------------------------------ */ 5750 .balign 64 5751.L_OP_DIV_LONG_2ADDR: /* 0xbe */ 5752/* File: armv6t2/OP_DIV_LONG_2ADDR.S */ 5753/* File: armv6t2/binopWide2addr.S */ 5754 /* 5755 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5756 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5757 * This could be an ARM instruction or a function call. (If the result 5758 * comes back in a register other than r0, you can override "result".) 5759 * 5760 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5761 * vCC (r1). Useful for integer division and modulus. 5762 * 5763 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5764 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5765 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5766 * rem-double/2addr 5767 */ 5768 /* binop/2addr vA, vB */ 5769 mov r1, rINST, lsr #12 @ r1<- B 5770 ubfx r9, rINST, #8, #4 @ r9<- A 5771 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5772 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5773 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5774 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5775 .if 1 5776 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5777 beq common_errDivideByZero 5778 .endif 5779 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5780 5781 @ optional op; may set condition codes 5782 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 5783 GET_INST_OPCODE(ip) @ extract opcode from rINST 5784 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5785 GOTO_OPCODE(ip) @ jump to next instruction 5786 /* 12-15 instructions */ 5787 5788 5789/* ------------------------------ */ 5790 .balign 64 5791.L_OP_REM_LONG_2ADDR: /* 0xbf */ 5792/* File: armv6t2/OP_REM_LONG_2ADDR.S */ 5793/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 5794/* File: armv6t2/binopWide2addr.S */ 5795 /* 5796 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5797 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5798 * This could be an ARM instruction or a function call. (If the result 5799 * comes back in a register other than r0, you can override "result".) 5800 * 5801 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5802 * vCC (r1). Useful for integer division and modulus. 5803 * 5804 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5805 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5806 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5807 * rem-double/2addr 5808 */ 5809 /* binop/2addr vA, vB */ 5810 mov r1, rINST, lsr #12 @ r1<- B 5811 ubfx r9, rINST, #8, #4 @ r9<- A 5812 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5813 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5814 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5815 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5816 .if 1 5817 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5818 beq common_errDivideByZero 5819 .endif 5820 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5821 5822 @ optional op; may set condition codes 5823 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 5824 GET_INST_OPCODE(ip) @ extract opcode from rINST 5825 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 5826 GOTO_OPCODE(ip) @ jump to next instruction 5827 /* 12-15 instructions */ 5828 5829 5830/* ------------------------------ */ 5831 .balign 64 5832.L_OP_AND_LONG_2ADDR: /* 0xc0 */ 5833/* File: armv6t2/OP_AND_LONG_2ADDR.S */ 5834/* File: armv6t2/binopWide2addr.S */ 5835 /* 5836 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5837 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5838 * This could be an ARM instruction or a function call. (If the result 5839 * comes back in a register other than r0, you can override "result".) 5840 * 5841 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5842 * vCC (r1). Useful for integer division and modulus. 5843 * 5844 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5845 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5846 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5847 * rem-double/2addr 5848 */ 5849 /* binop/2addr vA, vB */ 5850 mov r1, rINST, lsr #12 @ r1<- B 5851 ubfx r9, rINST, #8, #4 @ r9<- A 5852 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5853 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5854 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5855 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5856 .if 0 5857 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5858 beq common_errDivideByZero 5859 .endif 5860 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5861 5862 and r0, r0, r2 @ optional op; may set condition codes 5863 and r1, r1, r3 @ result<- op, r0-r3 changed 5864 GET_INST_OPCODE(ip) @ extract opcode from rINST 5865 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5866 GOTO_OPCODE(ip) @ jump to next instruction 5867 /* 12-15 instructions */ 5868 5869 5870/* ------------------------------ */ 5871 .balign 64 5872.L_OP_OR_LONG_2ADDR: /* 0xc1 */ 5873/* File: armv6t2/OP_OR_LONG_2ADDR.S */ 5874/* File: armv6t2/binopWide2addr.S */ 5875 /* 5876 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5877 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5878 * This could be an ARM instruction or a function call. (If the result 5879 * comes back in a register other than r0, you can override "result".) 5880 * 5881 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5882 * vCC (r1). Useful for integer division and modulus. 5883 * 5884 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5885 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5886 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5887 * rem-double/2addr 5888 */ 5889 /* binop/2addr vA, vB */ 5890 mov r1, rINST, lsr #12 @ r1<- B 5891 ubfx r9, rINST, #8, #4 @ r9<- A 5892 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5893 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5894 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5895 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5896 .if 0 5897 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5898 beq common_errDivideByZero 5899 .endif 5900 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5901 5902 orr r0, r0, r2 @ optional op; may set condition codes 5903 orr r1, r1, r3 @ result<- op, r0-r3 changed 5904 GET_INST_OPCODE(ip) @ extract opcode from rINST 5905 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5906 GOTO_OPCODE(ip) @ jump to next instruction 5907 /* 12-15 instructions */ 5908 5909 5910/* ------------------------------ */ 5911 .balign 64 5912.L_OP_XOR_LONG_2ADDR: /* 0xc2 */ 5913/* File: armv6t2/OP_XOR_LONG_2ADDR.S */ 5914/* File: armv6t2/binopWide2addr.S */ 5915 /* 5916 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5917 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5918 * This could be an ARM instruction or a function call. (If the result 5919 * comes back in a register other than r0, you can override "result".) 5920 * 5921 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5922 * vCC (r1). Useful for integer division and modulus. 5923 * 5924 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5925 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5926 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5927 * rem-double/2addr 5928 */ 5929 /* binop/2addr vA, vB */ 5930 mov r1, rINST, lsr #12 @ r1<- B 5931 ubfx r9, rINST, #8, #4 @ r9<- A 5932 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5933 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5934 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5935 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5936 .if 0 5937 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5938 beq common_errDivideByZero 5939 .endif 5940 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5941 5942 eor r0, r0, r2 @ optional op; may set condition codes 5943 eor r1, r1, r3 @ result<- op, r0-r3 changed 5944 GET_INST_OPCODE(ip) @ extract opcode from rINST 5945 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5946 GOTO_OPCODE(ip) @ jump to next instruction 5947 /* 12-15 instructions */ 5948 5949 5950/* ------------------------------ */ 5951 .balign 64 5952.L_OP_SHL_LONG_2ADDR: /* 0xc3 */ 5953/* File: armv6t2/OP_SHL_LONG_2ADDR.S */ 5954 /* 5955 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5956 * 32-bit shift distance. 5957 */ 5958 /* shl-long/2addr vA, vB */ 5959 mov r3, rINST, lsr #12 @ r3<- B 5960 ubfx r9, rINST, #8, #4 @ r9<- A 5961 GET_VREG(r2, r3) @ r2<- vB 5962 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5963 and r2, r2, #63 @ r2<- r2 & 0x3f 5964 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5965 5966 mov r1, r1, asl r2 @ r1<- r1 << r2 5967 rsb r3, r2, #32 @ r3<- 32 - r2 5968 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 5969 subs ip, r2, #32 @ ip<- r2 - 32 5970 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5971 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 5972 mov r0, r0, asl r2 @ r0<- r0 << r2 5973 b .LOP_SHL_LONG_2ADDR_finish 5974 5975/* ------------------------------ */ 5976 .balign 64 5977.L_OP_SHR_LONG_2ADDR: /* 0xc4 */ 5978/* File: armv6t2/OP_SHR_LONG_2ADDR.S */ 5979 /* 5980 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5981 * 32-bit shift distance. 5982 */ 5983 /* shr-long/2addr vA, vB */ 5984 mov r3, rINST, lsr #12 @ r3<- B 5985 ubfx r9, rINST, #8, #4 @ r9<- A 5986 GET_VREG(r2, r3) @ r2<- vB 5987 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5988 and r2, r2, #63 @ r2<- r2 & 0x3f 5989 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5990 5991 mov r0, r0, lsr r2 @ r0<- r2 >> r2 5992 rsb r3, r2, #32 @ r3<- 32 - r2 5993 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 5994 subs ip, r2, #32 @ ip<- r2 - 32 5995 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5996 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 5997 mov r1, r1, asr r2 @ r1<- r1 >> r2 5998 b .LOP_SHR_LONG_2ADDR_finish 5999 6000/* ------------------------------ */ 6001 .balign 64 6002.L_OP_USHR_LONG_2ADDR: /* 0xc5 */ 6003/* File: armv6t2/OP_USHR_LONG_2ADDR.S */ 6004 /* 6005 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 6006 * 32-bit shift distance. 6007 */ 6008 /* ushr-long/2addr vA, vB */ 6009 mov r3, rINST, lsr #12 @ r3<- B 6010 ubfx r9, rINST, #8, #4 @ r9<- A 6011 GET_VREG(r2, r3) @ r2<- vB 6012 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6013 and r2, r2, #63 @ r2<- r2 & 0x3f 6014 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6015 6016 mov r0, r0, lsr r2 @ r0<- r2 >> r2 6017 rsb r3, r2, #32 @ r3<- 32 - r2 6018 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 6019 subs ip, r2, #32 @ ip<- r2 - 32 6020 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6021 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 6022 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 6023 b .LOP_USHR_LONG_2ADDR_finish 6024 6025/* ------------------------------ */ 6026 .balign 64 6027.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */ 6028/* File: arm-vfp/OP_ADD_FLOAT_2ADDR.S */ 6029/* File: arm-vfp/fbinop2addr.S */ 6030 /* 6031 * Generic 32-bit floating point "/2addr" binary operation. Provide 6032 * an "instr" line that specifies an instruction that performs 6033 * "s2 = s0 op s1". 6034 * 6035 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6036 */ 6037 /* binop/2addr vA, vB */ 6038 mov r3, rINST, lsr #12 @ r3<- B 6039 mov r9, rINST, lsr #8 @ r9<- A+ 6040 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6041 and r9, r9, #15 @ r9<- A 6042 flds s1, [r3] @ s1<- vB 6043 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6044 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6045 flds s0, [r9] @ s0<- vA 6046 6047 fadds s2, s0, s1 @ s2<- op 6048 GET_INST_OPCODE(ip) @ extract opcode from rINST 6049 fsts s2, [r9] @ vAA<- s2 6050 GOTO_OPCODE(ip) @ jump to next instruction 6051 6052 6053/* ------------------------------ */ 6054 .balign 64 6055.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */ 6056/* File: arm-vfp/OP_SUB_FLOAT_2ADDR.S */ 6057/* File: arm-vfp/fbinop2addr.S */ 6058 /* 6059 * Generic 32-bit floating point "/2addr" binary operation. Provide 6060 * an "instr" line that specifies an instruction that performs 6061 * "s2 = s0 op s1". 6062 * 6063 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6064 */ 6065 /* binop/2addr vA, vB */ 6066 mov r3, rINST, lsr #12 @ r3<- B 6067 mov r9, rINST, lsr #8 @ r9<- A+ 6068 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6069 and r9, r9, #15 @ r9<- A 6070 flds s1, [r3] @ s1<- vB 6071 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6072 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6073 flds s0, [r9] @ s0<- vA 6074 6075 fsubs s2, s0, s1 @ s2<- op 6076 GET_INST_OPCODE(ip) @ extract opcode from rINST 6077 fsts s2, [r9] @ vAA<- s2 6078 GOTO_OPCODE(ip) @ jump to next instruction 6079 6080 6081/* ------------------------------ */ 6082 .balign 64 6083.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */ 6084/* File: arm-vfp/OP_MUL_FLOAT_2ADDR.S */ 6085/* File: arm-vfp/fbinop2addr.S */ 6086 /* 6087 * Generic 32-bit floating point "/2addr" binary operation. Provide 6088 * an "instr" line that specifies an instruction that performs 6089 * "s2 = s0 op s1". 6090 * 6091 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6092 */ 6093 /* binop/2addr vA, vB */ 6094 mov r3, rINST, lsr #12 @ r3<- B 6095 mov r9, rINST, lsr #8 @ r9<- A+ 6096 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6097 and r9, r9, #15 @ r9<- A 6098 flds s1, [r3] @ s1<- vB 6099 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6100 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6101 flds s0, [r9] @ s0<- vA 6102 6103 fmuls s2, s0, s1 @ s2<- op 6104 GET_INST_OPCODE(ip) @ extract opcode from rINST 6105 fsts s2, [r9] @ vAA<- s2 6106 GOTO_OPCODE(ip) @ jump to next instruction 6107 6108 6109/* ------------------------------ */ 6110 .balign 64 6111.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */ 6112/* File: arm-vfp/OP_DIV_FLOAT_2ADDR.S */ 6113/* File: arm-vfp/fbinop2addr.S */ 6114 /* 6115 * Generic 32-bit floating point "/2addr" binary operation. Provide 6116 * an "instr" line that specifies an instruction that performs 6117 * "s2 = s0 op s1". 6118 * 6119 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6120 */ 6121 /* binop/2addr vA, vB */ 6122 mov r3, rINST, lsr #12 @ r3<- B 6123 mov r9, rINST, lsr #8 @ r9<- A+ 6124 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6125 and r9, r9, #15 @ r9<- A 6126 flds s1, [r3] @ s1<- vB 6127 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6128 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6129 flds s0, [r9] @ s0<- vA 6130 6131 fdivs s2, s0, s1 @ s2<- op 6132 GET_INST_OPCODE(ip) @ extract opcode from rINST 6133 fsts s2, [r9] @ vAA<- s2 6134 GOTO_OPCODE(ip) @ jump to next instruction 6135 6136 6137/* ------------------------------ */ 6138 .balign 64 6139.L_OP_REM_FLOAT_2ADDR: /* 0xca */ 6140/* File: armv6t2/OP_REM_FLOAT_2ADDR.S */ 6141/* EABI doesn't define a float remainder function, but libm does */ 6142/* File: armv6t2/binop2addr.S */ 6143 /* 6144 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6145 * that specifies an instruction that performs "result = r0 op r1". 6146 * This could be an ARM instruction or a function call. (If the result 6147 * comes back in a register other than r0, you can override "result".) 6148 * 6149 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6150 * vCC (r1). Useful for integer division and modulus. 6151 * 6152 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6153 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6154 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6155 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6156 */ 6157 /* binop/2addr vA, vB */ 6158 mov r3, rINST, lsr #12 @ r3<- B 6159 ubfx r9, rINST, #8, #4 @ r9<- A 6160 GET_VREG(r1, r3) @ r1<- vB 6161 GET_VREG(r0, r9) @ r0<- vA 6162 .if 0 6163 cmp r1, #0 @ is second operand zero? 6164 beq common_errDivideByZero 6165 .endif 6166 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6167 6168 @ optional op; may set condition codes 6169 bl fmodf @ r0<- op, r0-r3 changed 6170 GET_INST_OPCODE(ip) @ extract opcode from rINST 6171 SET_VREG(r0, r9) @ vAA<- r0 6172 GOTO_OPCODE(ip) @ jump to next instruction 6173 /* 10-13 instructions */ 6174 6175 6176/* ------------------------------ */ 6177 .balign 64 6178.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */ 6179/* File: arm-vfp/OP_ADD_DOUBLE_2ADDR.S */ 6180/* File: arm-vfp/fbinopWide2addr.S */ 6181 /* 6182 * Generic 64-bit floating point "/2addr" binary operation. Provide 6183 * an "instr" line that specifies an instruction that performs 6184 * "d2 = d0 op d1". 6185 * 6186 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6187 * div-double/2addr 6188 */ 6189 /* binop/2addr vA, vB */ 6190 mov r3, rINST, lsr #12 @ r3<- B 6191 mov r9, rINST, lsr #8 @ r9<- A+ 6192 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6193 and r9, r9, #15 @ r9<- A 6194 fldd d1, [r3] @ d1<- vB 6195 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6196 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6197 fldd d0, [r9] @ d0<- vA 6198 6199 faddd d2, d0, d1 @ d2<- op 6200 GET_INST_OPCODE(ip) @ extract opcode from rINST 6201 fstd d2, [r9] @ vAA<- d2 6202 GOTO_OPCODE(ip) @ jump to next instruction 6203 6204 6205/* ------------------------------ */ 6206 .balign 64 6207.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */ 6208/* File: arm-vfp/OP_SUB_DOUBLE_2ADDR.S */ 6209/* File: arm-vfp/fbinopWide2addr.S */ 6210 /* 6211 * Generic 64-bit floating point "/2addr" binary operation. Provide 6212 * an "instr" line that specifies an instruction that performs 6213 * "d2 = d0 op d1". 6214 * 6215 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6216 * div-double/2addr 6217 */ 6218 /* binop/2addr vA, vB */ 6219 mov r3, rINST, lsr #12 @ r3<- B 6220 mov r9, rINST, lsr #8 @ r9<- A+ 6221 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6222 and r9, r9, #15 @ r9<- A 6223 fldd d1, [r3] @ d1<- vB 6224 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6225 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6226 fldd d0, [r9] @ d0<- vA 6227 6228 fsubd d2, d0, d1 @ d2<- op 6229 GET_INST_OPCODE(ip) @ extract opcode from rINST 6230 fstd d2, [r9] @ vAA<- d2 6231 GOTO_OPCODE(ip) @ jump to next instruction 6232 6233 6234/* ------------------------------ */ 6235 .balign 64 6236.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */ 6237/* File: arm-vfp/OP_MUL_DOUBLE_2ADDR.S */ 6238/* File: arm-vfp/fbinopWide2addr.S */ 6239 /* 6240 * Generic 64-bit floating point "/2addr" binary operation. Provide 6241 * an "instr" line that specifies an instruction that performs 6242 * "d2 = d0 op d1". 6243 * 6244 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6245 * div-double/2addr 6246 */ 6247 /* binop/2addr vA, vB */ 6248 mov r3, rINST, lsr #12 @ r3<- B 6249 mov r9, rINST, lsr #8 @ r9<- A+ 6250 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6251 and r9, r9, #15 @ r9<- A 6252 fldd d1, [r3] @ d1<- vB 6253 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6254 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6255 fldd d0, [r9] @ d0<- vA 6256 6257 fmuld d2, d0, d1 @ d2<- op 6258 GET_INST_OPCODE(ip) @ extract opcode from rINST 6259 fstd d2, [r9] @ vAA<- d2 6260 GOTO_OPCODE(ip) @ jump to next instruction 6261 6262 6263/* ------------------------------ */ 6264 .balign 64 6265.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */ 6266/* File: arm-vfp/OP_DIV_DOUBLE_2ADDR.S */ 6267/* File: arm-vfp/fbinopWide2addr.S */ 6268 /* 6269 * Generic 64-bit floating point "/2addr" binary operation. Provide 6270 * an "instr" line that specifies an instruction that performs 6271 * "d2 = d0 op d1". 6272 * 6273 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6274 * div-double/2addr 6275 */ 6276 /* binop/2addr vA, vB */ 6277 mov r3, rINST, lsr #12 @ r3<- B 6278 mov r9, rINST, lsr #8 @ r9<- A+ 6279 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6280 and r9, r9, #15 @ r9<- A 6281 fldd d1, [r3] @ d1<- vB 6282 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6283 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6284 fldd d0, [r9] @ d0<- vA 6285 6286 fdivd d2, d0, d1 @ d2<- op 6287 GET_INST_OPCODE(ip) @ extract opcode from rINST 6288 fstd d2, [r9] @ vAA<- d2 6289 GOTO_OPCODE(ip) @ jump to next instruction 6290 6291 6292/* ------------------------------ */ 6293 .balign 64 6294.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */ 6295/* File: armv6t2/OP_REM_DOUBLE_2ADDR.S */ 6296/* EABI doesn't define a double remainder function, but libm does */ 6297/* File: armv6t2/binopWide2addr.S */ 6298 /* 6299 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6300 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6301 * This could be an ARM instruction or a function call. (If the result 6302 * comes back in a register other than r0, you can override "result".) 6303 * 6304 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6305 * vCC (r1). Useful for integer division and modulus. 6306 * 6307 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6308 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6309 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6310 * rem-double/2addr 6311 */ 6312 /* binop/2addr vA, vB */ 6313 mov r1, rINST, lsr #12 @ r1<- B 6314 ubfx r9, rINST, #8, #4 @ r9<- A 6315 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6316 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6317 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6318 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6319 .if 0 6320 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6321 beq common_errDivideByZero 6322 .endif 6323 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6324 6325 @ optional op; may set condition codes 6326 bl fmod @ result<- op, r0-r3 changed 6327 GET_INST_OPCODE(ip) @ extract opcode from rINST 6328 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6329 GOTO_OPCODE(ip) @ jump to next instruction 6330 /* 12-15 instructions */ 6331 6332 6333/* ------------------------------ */ 6334 .balign 64 6335.L_OP_ADD_INT_LIT16: /* 0xd0 */ 6336/* File: armv6t2/OP_ADD_INT_LIT16.S */ 6337/* File: armv6t2/binopLit16.S */ 6338 /* 6339 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6340 * that specifies an instruction that performs "result = r0 op r1". 6341 * This could be an ARM instruction or a function call. (If the result 6342 * comes back in a register other than r0, you can override "result".) 6343 * 6344 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6345 * vCC (r1). Useful for integer division and modulus. 6346 * 6347 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6348 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6349 */ 6350 /* binop/lit16 vA, vB, #+CCCC */ 6351 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6352 mov r2, rINST, lsr #12 @ r2<- B 6353 ubfx r9, rINST, #8, #4 @ r9<- A 6354 GET_VREG(r0, r2) @ r0<- vB 6355 .if 0 6356 cmp r1, #0 @ is second operand zero? 6357 beq common_errDivideByZero 6358 .endif 6359 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6360 6361 add r0, r0, r1 @ r0<- op, r0-r3 changed 6362 GET_INST_OPCODE(ip) @ extract opcode from rINST 6363 SET_VREG(r0, r9) @ vAA<- r0 6364 GOTO_OPCODE(ip) @ jump to next instruction 6365 /* 10-13 instructions */ 6366 6367 6368/* ------------------------------ */ 6369 .balign 64 6370.L_OP_RSUB_INT: /* 0xd1 */ 6371/* File: armv6t2/OP_RSUB_INT.S */ 6372/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */ 6373/* File: armv6t2/binopLit16.S */ 6374 /* 6375 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6376 * that specifies an instruction that performs "result = r0 op r1". 6377 * This could be an ARM instruction or a function call. (If the result 6378 * comes back in a register other than r0, you can override "result".) 6379 * 6380 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6381 * vCC (r1). Useful for integer division and modulus. 6382 * 6383 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6384 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6385 */ 6386 /* binop/lit16 vA, vB, #+CCCC */ 6387 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6388 mov r2, rINST, lsr #12 @ r2<- B 6389 ubfx r9, rINST, #8, #4 @ r9<- A 6390 GET_VREG(r0, r2) @ r0<- vB 6391 .if 0 6392 cmp r1, #0 @ is second operand zero? 6393 beq common_errDivideByZero 6394 .endif 6395 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6396 6397 rsb r0, r0, r1 @ r0<- op, r0-r3 changed 6398 GET_INST_OPCODE(ip) @ extract opcode from rINST 6399 SET_VREG(r0, r9) @ vAA<- r0 6400 GOTO_OPCODE(ip) @ jump to next instruction 6401 /* 10-13 instructions */ 6402 6403 6404/* ------------------------------ */ 6405 .balign 64 6406.L_OP_MUL_INT_LIT16: /* 0xd2 */ 6407/* File: armv6t2/OP_MUL_INT_LIT16.S */ 6408/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 6409/* File: armv6t2/binopLit16.S */ 6410 /* 6411 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6412 * that specifies an instruction that performs "result = r0 op r1". 6413 * This could be an ARM instruction or a function call. (If the result 6414 * comes back in a register other than r0, you can override "result".) 6415 * 6416 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6417 * vCC (r1). Useful for integer division and modulus. 6418 * 6419 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6420 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6421 */ 6422 /* binop/lit16 vA, vB, #+CCCC */ 6423 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6424 mov r2, rINST, lsr #12 @ r2<- B 6425 ubfx r9, rINST, #8, #4 @ r9<- A 6426 GET_VREG(r0, r2) @ r0<- vB 6427 .if 0 6428 cmp r1, #0 @ is second operand zero? 6429 beq common_errDivideByZero 6430 .endif 6431 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6432 6433 mul r0, r1, r0 @ r0<- op, r0-r3 changed 6434 GET_INST_OPCODE(ip) @ extract opcode from rINST 6435 SET_VREG(r0, r9) @ vAA<- r0 6436 GOTO_OPCODE(ip) @ jump to next instruction 6437 /* 10-13 instructions */ 6438 6439 6440/* ------------------------------ */ 6441 .balign 64 6442.L_OP_DIV_INT_LIT16: /* 0xd3 */ 6443/* File: armv6t2/OP_DIV_INT_LIT16.S */ 6444/* File: armv6t2/binopLit16.S */ 6445 /* 6446 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6447 * that specifies an instruction that performs "result = r0 op r1". 6448 * This could be an ARM instruction or a function call. (If the result 6449 * comes back in a register other than r0, you can override "result".) 6450 * 6451 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6452 * vCC (r1). Useful for integer division and modulus. 6453 * 6454 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6455 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6456 */ 6457 /* binop/lit16 vA, vB, #+CCCC */ 6458 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6459 mov r2, rINST, lsr #12 @ r2<- B 6460 ubfx r9, rINST, #8, #4 @ r9<- A 6461 GET_VREG(r0, r2) @ r0<- vB 6462 .if 1 6463 cmp r1, #0 @ is second operand zero? 6464 beq common_errDivideByZero 6465 .endif 6466 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6467 6468 bl __aeabi_idiv @ r0<- op, r0-r3 changed 6469 GET_INST_OPCODE(ip) @ extract opcode from rINST 6470 SET_VREG(r0, r9) @ vAA<- r0 6471 GOTO_OPCODE(ip) @ jump to next instruction 6472 /* 10-13 instructions */ 6473 6474 6475/* ------------------------------ */ 6476 .balign 64 6477.L_OP_REM_INT_LIT16: /* 0xd4 */ 6478/* File: armv6t2/OP_REM_INT_LIT16.S */ 6479/* idivmod returns quotient in r0 and remainder in r1 */ 6480/* File: armv6t2/binopLit16.S */ 6481 /* 6482 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6483 * that specifies an instruction that performs "result = r0 op r1". 6484 * This could be an ARM instruction or a function call. (If the result 6485 * comes back in a register other than r0, you can override "result".) 6486 * 6487 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6488 * vCC (r1). Useful for integer division and modulus. 6489 * 6490 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6491 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6492 */ 6493 /* binop/lit16 vA, vB, #+CCCC */ 6494 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6495 mov r2, rINST, lsr #12 @ r2<- B 6496 ubfx r9, rINST, #8, #4 @ r9<- A 6497 GET_VREG(r0, r2) @ r0<- vB 6498 .if 1 6499 cmp r1, #0 @ is second operand zero? 6500 beq common_errDivideByZero 6501 .endif 6502 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6503 6504 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 6505 GET_INST_OPCODE(ip) @ extract opcode from rINST 6506 SET_VREG(r1, r9) @ vAA<- r1 6507 GOTO_OPCODE(ip) @ jump to next instruction 6508 /* 10-13 instructions */ 6509 6510 6511/* ------------------------------ */ 6512 .balign 64 6513.L_OP_AND_INT_LIT16: /* 0xd5 */ 6514/* File: armv6t2/OP_AND_INT_LIT16.S */ 6515/* File: armv6t2/binopLit16.S */ 6516 /* 6517 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6518 * that specifies an instruction that performs "result = r0 op r1". 6519 * This could be an ARM instruction or a function call. (If the result 6520 * comes back in a register other than r0, you can override "result".) 6521 * 6522 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6523 * vCC (r1). Useful for integer division and modulus. 6524 * 6525 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6526 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6527 */ 6528 /* binop/lit16 vA, vB, #+CCCC */ 6529 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6530 mov r2, rINST, lsr #12 @ r2<- B 6531 ubfx r9, rINST, #8, #4 @ r9<- A 6532 GET_VREG(r0, r2) @ r0<- vB 6533 .if 0 6534 cmp r1, #0 @ is second operand zero? 6535 beq common_errDivideByZero 6536 .endif 6537 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6538 6539 and r0, r0, r1 @ r0<- op, r0-r3 changed 6540 GET_INST_OPCODE(ip) @ extract opcode from rINST 6541 SET_VREG(r0, r9) @ vAA<- r0 6542 GOTO_OPCODE(ip) @ jump to next instruction 6543 /* 10-13 instructions */ 6544 6545 6546/* ------------------------------ */ 6547 .balign 64 6548.L_OP_OR_INT_LIT16: /* 0xd6 */ 6549/* File: armv6t2/OP_OR_INT_LIT16.S */ 6550/* File: armv6t2/binopLit16.S */ 6551 /* 6552 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6553 * that specifies an instruction that performs "result = r0 op r1". 6554 * This could be an ARM instruction or a function call. (If the result 6555 * comes back in a register other than r0, you can override "result".) 6556 * 6557 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6558 * vCC (r1). Useful for integer division and modulus. 6559 * 6560 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6561 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6562 */ 6563 /* binop/lit16 vA, vB, #+CCCC */ 6564 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6565 mov r2, rINST, lsr #12 @ r2<- B 6566 ubfx r9, rINST, #8, #4 @ r9<- A 6567 GET_VREG(r0, r2) @ r0<- vB 6568 .if 0 6569 cmp r1, #0 @ is second operand zero? 6570 beq common_errDivideByZero 6571 .endif 6572 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6573 6574 orr r0, r0, r1 @ r0<- op, r0-r3 changed 6575 GET_INST_OPCODE(ip) @ extract opcode from rINST 6576 SET_VREG(r0, r9) @ vAA<- r0 6577 GOTO_OPCODE(ip) @ jump to next instruction 6578 /* 10-13 instructions */ 6579 6580 6581/* ------------------------------ */ 6582 .balign 64 6583.L_OP_XOR_INT_LIT16: /* 0xd7 */ 6584/* File: armv6t2/OP_XOR_INT_LIT16.S */ 6585/* File: armv6t2/binopLit16.S */ 6586 /* 6587 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6588 * that specifies an instruction that performs "result = r0 op r1". 6589 * This could be an ARM instruction or a function call. (If the result 6590 * comes back in a register other than r0, you can override "result".) 6591 * 6592 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6593 * vCC (r1). Useful for integer division and modulus. 6594 * 6595 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6596 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6597 */ 6598 /* binop/lit16 vA, vB, #+CCCC */ 6599 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6600 mov r2, rINST, lsr #12 @ r2<- B 6601 ubfx r9, rINST, #8, #4 @ r9<- A 6602 GET_VREG(r0, r2) @ r0<- vB 6603 .if 0 6604 cmp r1, #0 @ is second operand zero? 6605 beq common_errDivideByZero 6606 .endif 6607 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6608 6609 eor r0, r0, r1 @ r0<- op, r0-r3 changed 6610 GET_INST_OPCODE(ip) @ extract opcode from rINST 6611 SET_VREG(r0, r9) @ vAA<- r0 6612 GOTO_OPCODE(ip) @ jump to next instruction 6613 /* 10-13 instructions */ 6614 6615 6616/* ------------------------------ */ 6617 .balign 64 6618.L_OP_ADD_INT_LIT8: /* 0xd8 */ 6619/* File: armv5te/OP_ADD_INT_LIT8.S */ 6620/* File: armv5te/binopLit8.S */ 6621 /* 6622 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6623 * that specifies an instruction that performs "result = r0 op r1". 6624 * This could be an ARM instruction or a function call. (If the result 6625 * comes back in a register other than r0, you can override "result".) 6626 * 6627 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6628 * vCC (r1). Useful for integer division and modulus. 6629 * 6630 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6631 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6632 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6633 */ 6634 /* binop/lit8 vAA, vBB, #+CC */ 6635 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6636 mov r9, rINST, lsr #8 @ r9<- AA 6637 and r2, r3, #255 @ r2<- BB 6638 GET_VREG(r0, r2) @ r0<- vBB 6639 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6640 .if 0 6641 @cmp r1, #0 @ is second operand zero? 6642 beq common_errDivideByZero 6643 .endif 6644 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6645 6646 @ optional op; may set condition codes 6647 add r0, r0, r1 @ r0<- op, r0-r3 changed 6648 GET_INST_OPCODE(ip) @ extract opcode from rINST 6649 SET_VREG(r0, r9) @ vAA<- r0 6650 GOTO_OPCODE(ip) @ jump to next instruction 6651 /* 10-12 instructions */ 6652 6653 6654/* ------------------------------ */ 6655 .balign 64 6656.L_OP_RSUB_INT_LIT8: /* 0xd9 */ 6657/* File: armv5te/OP_RSUB_INT_LIT8.S */ 6658/* File: armv5te/binopLit8.S */ 6659 /* 6660 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6661 * that specifies an instruction that performs "result = r0 op r1". 6662 * This could be an ARM instruction or a function call. (If the result 6663 * comes back in a register other than r0, you can override "result".) 6664 * 6665 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6666 * vCC (r1). Useful for integer division and modulus. 6667 * 6668 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6669 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6670 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6671 */ 6672 /* binop/lit8 vAA, vBB, #+CC */ 6673 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6674 mov r9, rINST, lsr #8 @ r9<- AA 6675 and r2, r3, #255 @ r2<- BB 6676 GET_VREG(r0, r2) @ r0<- vBB 6677 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6678 .if 0 6679 @cmp r1, #0 @ is second operand zero? 6680 beq common_errDivideByZero 6681 .endif 6682 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6683 6684 @ optional op; may set condition codes 6685 rsb r0, r0, r1 @ r0<- op, r0-r3 changed 6686 GET_INST_OPCODE(ip) @ extract opcode from rINST 6687 SET_VREG(r0, r9) @ vAA<- r0 6688 GOTO_OPCODE(ip) @ jump to next instruction 6689 /* 10-12 instructions */ 6690 6691 6692/* ------------------------------ */ 6693 .balign 64 6694.L_OP_MUL_INT_LIT8: /* 0xda */ 6695/* File: armv5te/OP_MUL_INT_LIT8.S */ 6696/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 6697/* File: armv5te/binopLit8.S */ 6698 /* 6699 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6700 * that specifies an instruction that performs "result = r0 op r1". 6701 * This could be an ARM instruction or a function call. (If the result 6702 * comes back in a register other than r0, you can override "result".) 6703 * 6704 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6705 * vCC (r1). Useful for integer division and modulus. 6706 * 6707 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6708 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6709 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6710 */ 6711 /* binop/lit8 vAA, vBB, #+CC */ 6712 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6713 mov r9, rINST, lsr #8 @ r9<- AA 6714 and r2, r3, #255 @ r2<- BB 6715 GET_VREG(r0, r2) @ r0<- vBB 6716 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6717 .if 0 6718 @cmp r1, #0 @ is second operand zero? 6719 beq common_errDivideByZero 6720 .endif 6721 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6722 6723 @ optional op; may set condition codes 6724 mul r0, r1, r0 @ r0<- op, r0-r3 changed 6725 GET_INST_OPCODE(ip) @ extract opcode from rINST 6726 SET_VREG(r0, r9) @ vAA<- r0 6727 GOTO_OPCODE(ip) @ jump to next instruction 6728 /* 10-12 instructions */ 6729 6730 6731/* ------------------------------ */ 6732 .balign 64 6733.L_OP_DIV_INT_LIT8: /* 0xdb */ 6734/* File: armv5te/OP_DIV_INT_LIT8.S */ 6735/* File: armv5te/binopLit8.S */ 6736 /* 6737 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6738 * that specifies an instruction that performs "result = r0 op r1". 6739 * This could be an ARM instruction or a function call. (If the result 6740 * comes back in a register other than r0, you can override "result".) 6741 * 6742 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6743 * vCC (r1). Useful for integer division and modulus. 6744 * 6745 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6746 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6747 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6748 */ 6749 /* binop/lit8 vAA, vBB, #+CC */ 6750 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6751 mov r9, rINST, lsr #8 @ r9<- AA 6752 and r2, r3, #255 @ r2<- BB 6753 GET_VREG(r0, r2) @ r0<- vBB 6754 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6755 .if 1 6756 @cmp r1, #0 @ is second operand zero? 6757 beq common_errDivideByZero 6758 .endif 6759 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6760 6761 @ optional op; may set condition codes 6762 bl __aeabi_idiv @ r0<- op, r0-r3 changed 6763 GET_INST_OPCODE(ip) @ extract opcode from rINST 6764 SET_VREG(r0, r9) @ vAA<- r0 6765 GOTO_OPCODE(ip) @ jump to next instruction 6766 /* 10-12 instructions */ 6767 6768 6769/* ------------------------------ */ 6770 .balign 64 6771.L_OP_REM_INT_LIT8: /* 0xdc */ 6772/* File: armv5te/OP_REM_INT_LIT8.S */ 6773/* idivmod returns quotient in r0 and remainder in r1 */ 6774/* File: armv5te/binopLit8.S */ 6775 /* 6776 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6777 * that specifies an instruction that performs "result = r0 op r1". 6778 * This could be an ARM instruction or a function call. (If the result 6779 * comes back in a register other than r0, you can override "result".) 6780 * 6781 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6782 * vCC (r1). Useful for integer division and modulus. 6783 * 6784 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6785 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6786 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6787 */ 6788 /* binop/lit8 vAA, vBB, #+CC */ 6789 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6790 mov r9, rINST, lsr #8 @ r9<- AA 6791 and r2, r3, #255 @ r2<- BB 6792 GET_VREG(r0, r2) @ r0<- vBB 6793 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6794 .if 1 6795 @cmp r1, #0 @ is second operand zero? 6796 beq common_errDivideByZero 6797 .endif 6798 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6799 6800 @ optional op; may set condition codes 6801 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 6802 GET_INST_OPCODE(ip) @ extract opcode from rINST 6803 SET_VREG(r1, r9) @ vAA<- r1 6804 GOTO_OPCODE(ip) @ jump to next instruction 6805 /* 10-12 instructions */ 6806 6807 6808/* ------------------------------ */ 6809 .balign 64 6810.L_OP_AND_INT_LIT8: /* 0xdd */ 6811/* File: armv5te/OP_AND_INT_LIT8.S */ 6812/* File: armv5te/binopLit8.S */ 6813 /* 6814 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6815 * that specifies an instruction that performs "result = r0 op r1". 6816 * This could be an ARM instruction or a function call. (If the result 6817 * comes back in a register other than r0, you can override "result".) 6818 * 6819 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6820 * vCC (r1). Useful for integer division and modulus. 6821 * 6822 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6823 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6824 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6825 */ 6826 /* binop/lit8 vAA, vBB, #+CC */ 6827 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6828 mov r9, rINST, lsr #8 @ r9<- AA 6829 and r2, r3, #255 @ r2<- BB 6830 GET_VREG(r0, r2) @ r0<- vBB 6831 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6832 .if 0 6833 @cmp r1, #0 @ is second operand zero? 6834 beq common_errDivideByZero 6835 .endif 6836 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6837 6838 @ optional op; may set condition codes 6839 and r0, r0, r1 @ r0<- op, r0-r3 changed 6840 GET_INST_OPCODE(ip) @ extract opcode from rINST 6841 SET_VREG(r0, r9) @ vAA<- r0 6842 GOTO_OPCODE(ip) @ jump to next instruction 6843 /* 10-12 instructions */ 6844 6845 6846/* ------------------------------ */ 6847 .balign 64 6848.L_OP_OR_INT_LIT8: /* 0xde */ 6849/* File: armv5te/OP_OR_INT_LIT8.S */ 6850/* File: armv5te/binopLit8.S */ 6851 /* 6852 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6853 * that specifies an instruction that performs "result = r0 op r1". 6854 * This could be an ARM instruction or a function call. (If the result 6855 * comes back in a register other than r0, you can override "result".) 6856 * 6857 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6858 * vCC (r1). Useful for integer division and modulus. 6859 * 6860 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6861 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6862 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6863 */ 6864 /* binop/lit8 vAA, vBB, #+CC */ 6865 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6866 mov r9, rINST, lsr #8 @ r9<- AA 6867 and r2, r3, #255 @ r2<- BB 6868 GET_VREG(r0, r2) @ r0<- vBB 6869 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6870 .if 0 6871 @cmp r1, #0 @ is second operand zero? 6872 beq common_errDivideByZero 6873 .endif 6874 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6875 6876 @ optional op; may set condition codes 6877 orr r0, r0, r1 @ r0<- op, r0-r3 changed 6878 GET_INST_OPCODE(ip) @ extract opcode from rINST 6879 SET_VREG(r0, r9) @ vAA<- r0 6880 GOTO_OPCODE(ip) @ jump to next instruction 6881 /* 10-12 instructions */ 6882 6883 6884/* ------------------------------ */ 6885 .balign 64 6886.L_OP_XOR_INT_LIT8: /* 0xdf */ 6887/* File: armv5te/OP_XOR_INT_LIT8.S */ 6888/* File: armv5te/binopLit8.S */ 6889 /* 6890 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6891 * that specifies an instruction that performs "result = r0 op r1". 6892 * This could be an ARM instruction or a function call. (If the result 6893 * comes back in a register other than r0, you can override "result".) 6894 * 6895 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6896 * vCC (r1). Useful for integer division and modulus. 6897 * 6898 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6899 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6900 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6901 */ 6902 /* binop/lit8 vAA, vBB, #+CC */ 6903 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6904 mov r9, rINST, lsr #8 @ r9<- AA 6905 and r2, r3, #255 @ r2<- BB 6906 GET_VREG(r0, r2) @ r0<- vBB 6907 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6908 .if 0 6909 @cmp r1, #0 @ is second operand zero? 6910 beq common_errDivideByZero 6911 .endif 6912 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6913 6914 @ optional op; may set condition codes 6915 eor r0, r0, r1 @ r0<- op, r0-r3 changed 6916 GET_INST_OPCODE(ip) @ extract opcode from rINST 6917 SET_VREG(r0, r9) @ vAA<- r0 6918 GOTO_OPCODE(ip) @ jump to next instruction 6919 /* 10-12 instructions */ 6920 6921 6922/* ------------------------------ */ 6923 .balign 64 6924.L_OP_SHL_INT_LIT8: /* 0xe0 */ 6925/* File: armv5te/OP_SHL_INT_LIT8.S */ 6926/* File: armv5te/binopLit8.S */ 6927 /* 6928 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6929 * that specifies an instruction that performs "result = r0 op r1". 6930 * This could be an ARM instruction or a function call. (If the result 6931 * comes back in a register other than r0, you can override "result".) 6932 * 6933 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6934 * vCC (r1). Useful for integer division and modulus. 6935 * 6936 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6937 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6938 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6939 */ 6940 /* binop/lit8 vAA, vBB, #+CC */ 6941 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6942 mov r9, rINST, lsr #8 @ r9<- AA 6943 and r2, r3, #255 @ r2<- BB 6944 GET_VREG(r0, r2) @ r0<- vBB 6945 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6946 .if 0 6947 @cmp r1, #0 @ is second operand zero? 6948 beq common_errDivideByZero 6949 .endif 6950 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6951 6952 and r1, r1, #31 @ optional op; may set condition codes 6953 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 6954 GET_INST_OPCODE(ip) @ extract opcode from rINST 6955 SET_VREG(r0, r9) @ vAA<- r0 6956 GOTO_OPCODE(ip) @ jump to next instruction 6957 /* 10-12 instructions */ 6958 6959 6960/* ------------------------------ */ 6961 .balign 64 6962.L_OP_SHR_INT_LIT8: /* 0xe1 */ 6963/* File: armv5te/OP_SHR_INT_LIT8.S */ 6964/* File: armv5te/binopLit8.S */ 6965 /* 6966 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6967 * that specifies an instruction that performs "result = r0 op r1". 6968 * This could be an ARM instruction or a function call. (If the result 6969 * comes back in a register other than r0, you can override "result".) 6970 * 6971 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6972 * vCC (r1). Useful for integer division and modulus. 6973 * 6974 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6975 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6976 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6977 */ 6978 /* binop/lit8 vAA, vBB, #+CC */ 6979 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6980 mov r9, rINST, lsr #8 @ r9<- AA 6981 and r2, r3, #255 @ r2<- BB 6982 GET_VREG(r0, r2) @ r0<- vBB 6983 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6984 .if 0 6985 @cmp r1, #0 @ is second operand zero? 6986 beq common_errDivideByZero 6987 .endif 6988 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6989 6990 and r1, r1, #31 @ optional op; may set condition codes 6991 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 6992 GET_INST_OPCODE(ip) @ extract opcode from rINST 6993 SET_VREG(r0, r9) @ vAA<- r0 6994 GOTO_OPCODE(ip) @ jump to next instruction 6995 /* 10-12 instructions */ 6996 6997 6998/* ------------------------------ */ 6999 .balign 64 7000.L_OP_USHR_INT_LIT8: /* 0xe2 */ 7001/* File: armv5te/OP_USHR_INT_LIT8.S */ 7002/* File: armv5te/binopLit8.S */ 7003 /* 7004 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7005 * that specifies an instruction that performs "result = r0 op r1". 7006 * This could be an ARM instruction or a function call. (If the result 7007 * comes back in a register other than r0, you can override "result".) 7008 * 7009 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7010 * vCC (r1). Useful for integer division and modulus. 7011 * 7012 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7013 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7014 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7015 */ 7016 /* binop/lit8 vAA, vBB, #+CC */ 7017 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7018 mov r9, rINST, lsr #8 @ r9<- AA 7019 and r2, r3, #255 @ r2<- BB 7020 GET_VREG(r0, r2) @ r0<- vBB 7021 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7022 .if 0 7023 @cmp r1, #0 @ is second operand zero? 7024 beq common_errDivideByZero 7025 .endif 7026 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7027 7028 and r1, r1, #31 @ optional op; may set condition codes 7029 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 7030 GET_INST_OPCODE(ip) @ extract opcode from rINST 7031 SET_VREG(r0, r9) @ vAA<- r0 7032 GOTO_OPCODE(ip) @ jump to next instruction 7033 /* 10-12 instructions */ 7034 7035 7036/* ------------------------------ */ 7037 .balign 64 7038.L_OP_IGET_VOLATILE: /* 0xe3 */ 7039/* File: armv5te/OP_IGET_VOLATILE.S */ 7040/* File: armv5te/OP_IGET.S */ 7041 /* 7042 * General 32-bit instance field get. 7043 * 7044 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7045 */ 7046 /* op vA, vB, field@CCCC */ 7047 mov r0, rINST, lsr #12 @ r0<- B 7048 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7049 FETCH(r1, 1) @ r1<- field ref CCCC 7050 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7051 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7052 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7053 cmp r0, #0 @ is resolved entry null? 7054 bne .LOP_IGET_VOLATILE_finish @ no, already resolved 70558: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7056 EXPORT_PC() @ resolve() could throw 7057 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7058 bl dvmResolveInstField @ r0<- resolved InstField ptr 7059 cmp r0, #0 7060 bne .LOP_IGET_VOLATILE_finish 7061 b common_exceptionThrown 7062 7063 7064/* ------------------------------ */ 7065 .balign 64 7066.L_OP_IPUT_VOLATILE: /* 0xe4 */ 7067/* File: armv5te/OP_IPUT_VOLATILE.S */ 7068/* File: armv5te/OP_IPUT.S */ 7069 /* 7070 * General 32-bit instance field put. 7071 * 7072 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 7073 */ 7074 /* op vA, vB, field@CCCC */ 7075 mov r0, rINST, lsr #12 @ r0<- B 7076 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7077 FETCH(r1, 1) @ r1<- field ref CCCC 7078 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7079 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7080 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7081 cmp r0, #0 @ is resolved entry null? 7082 bne .LOP_IPUT_VOLATILE_finish @ no, already resolved 70838: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7084 EXPORT_PC() @ resolve() could throw 7085 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7086 bl dvmResolveInstField @ r0<- resolved InstField ptr 7087 cmp r0, #0 @ success? 7088 bne .LOP_IPUT_VOLATILE_finish @ yes, finish up 7089 b common_exceptionThrown 7090 7091 7092/* ------------------------------ */ 7093 .balign 64 7094.L_OP_SGET_VOLATILE: /* 0xe5 */ 7095/* File: armv5te/OP_SGET_VOLATILE.S */ 7096/* File: armv5te/OP_SGET.S */ 7097 /* 7098 * General 32-bit SGET handler. 7099 * 7100 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7101 */ 7102 /* op vAA, field@BBBB */ 7103 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 7104 FETCH(r1, 1) @ r1<- field ref BBBB 7105 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7106 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7107 cmp r0, #0 @ is resolved entry null? 7108 beq .LOP_SGET_VOLATILE_resolve @ yes, do resolve 7109.LOP_SGET_VOLATILE_finish: @ field ptr in r0 7110 ldr r1, [r0, #offStaticField_value] @ r1<- field value 7111 SMP_DMB @ acquiring load 7112 mov r2, rINST, lsr #8 @ r2<- AA 7113 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7114 SET_VREG(r1, r2) @ fp[AA]<- r1 7115 GET_INST_OPCODE(ip) @ extract opcode from rINST 7116 GOTO_OPCODE(ip) @ jump to next instruction 7117 7118 7119/* ------------------------------ */ 7120 .balign 64 7121.L_OP_SPUT_VOLATILE: /* 0xe6 */ 7122/* File: armv5te/OP_SPUT_VOLATILE.S */ 7123/* File: armv5te/OP_SPUT.S */ 7124 /* 7125 * General 32-bit SPUT handler. 7126 * 7127 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 7128 */ 7129 /* op vAA, field@BBBB */ 7130 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 7131 FETCH(r1, 1) @ r1<- field ref BBBB 7132 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7133 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7134 cmp r0, #0 @ is resolved entry null? 7135 beq .LOP_SPUT_VOLATILE_resolve @ yes, do resolve 7136.LOP_SPUT_VOLATILE_finish: @ field ptr in r0 7137 mov r2, rINST, lsr #8 @ r2<- AA 7138 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7139 GET_VREG(r1, r2) @ r1<- fp[AA] 7140 GET_INST_OPCODE(ip) @ extract opcode from rINST 7141 SMP_DMB @ releasing store 7142 str r1, [r0, #offStaticField_value] @ field<- vAA 7143 GOTO_OPCODE(ip) @ jump to next instruction 7144 7145 7146/* ------------------------------ */ 7147 .balign 64 7148.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */ 7149/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */ 7150/* File: armv5te/OP_IGET.S */ 7151 /* 7152 * General 32-bit instance field get. 7153 * 7154 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7155 */ 7156 /* op vA, vB, field@CCCC */ 7157 mov r0, rINST, lsr #12 @ r0<- B 7158 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7159 FETCH(r1, 1) @ r1<- field ref CCCC 7160 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7161 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7162 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7163 cmp r0, #0 @ is resolved entry null? 7164 bne .LOP_IGET_OBJECT_VOLATILE_finish @ no, already resolved 71658: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7166 EXPORT_PC() @ resolve() could throw 7167 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7168 bl dvmResolveInstField @ r0<- resolved InstField ptr 7169 cmp r0, #0 7170 bne .LOP_IGET_OBJECT_VOLATILE_finish 7171 b common_exceptionThrown 7172 7173 7174/* ------------------------------ */ 7175 .balign 64 7176.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */ 7177/* File: armv5te/OP_IGET_WIDE_VOLATILE.S */ 7178/* File: armv5te/OP_IGET_WIDE.S */ 7179 /* 7180 * Wide 32-bit instance field get. 7181 */ 7182 /* iget-wide vA, vB, field@CCCC */ 7183 mov r0, rINST, lsr #12 @ r0<- B 7184 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7185 FETCH(r1, 1) @ r1<- field ref CCCC 7186 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7187 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7188 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7189 cmp r0, #0 @ is resolved entry null? 7190 bne .LOP_IGET_WIDE_VOLATILE_finish @ no, already resolved 71918: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7192 EXPORT_PC() @ resolve() could throw 7193 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7194 bl dvmResolveInstField @ r0<- resolved InstField ptr 7195 cmp r0, #0 7196 bne .LOP_IGET_WIDE_VOLATILE_finish 7197 b common_exceptionThrown 7198 7199 7200/* ------------------------------ */ 7201 .balign 64 7202.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */ 7203/* File: armv5te/OP_IPUT_WIDE_VOLATILE.S */ 7204/* File: armv5te/OP_IPUT_WIDE.S */ 7205 /* iput-wide vA, vB, field@CCCC */ 7206 mov r0, rINST, lsr #12 @ r0<- B 7207 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7208 FETCH(r1, 1) @ r1<- field ref CCCC 7209 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7210 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7211 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7212 cmp r0, #0 @ is resolved entry null? 7213 bne .LOP_IPUT_WIDE_VOLATILE_finish @ no, already resolved 72148: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7215 EXPORT_PC() @ resolve() could throw 7216 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7217 bl dvmResolveInstField @ r0<- resolved InstField ptr 7218 cmp r0, #0 @ success? 7219 bne .LOP_IPUT_WIDE_VOLATILE_finish @ yes, finish up 7220 b common_exceptionThrown 7221 7222 7223/* ------------------------------ */ 7224 .balign 64 7225.L_OP_SGET_WIDE_VOLATILE: /* 0xea */ 7226/* File: armv5te/OP_SGET_WIDE_VOLATILE.S */ 7227/* File: armv5te/OP_SGET_WIDE.S */ 7228 /* 7229 * 64-bit SGET handler. 7230 */ 7231 /* sget-wide vAA, field@BBBB */ 7232 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 7233 FETCH(r1, 1) @ r1<- field ref BBBB 7234 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7235 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7236 cmp r0, #0 @ is resolved entry null? 7237 beq .LOP_SGET_WIDE_VOLATILE_resolve @ yes, do resolve 7238.LOP_SGET_WIDE_VOLATILE_finish: 7239 mov r9, rINST, lsr #8 @ r9<- AA 7240 .if 1 7241 add r0, r0, #offStaticField_value @ r0<- pointer to data 7242 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 7243 .else 7244 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 7245 .endif 7246 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7247 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7248 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 7249 GET_INST_OPCODE(ip) @ extract opcode from rINST 7250 GOTO_OPCODE(ip) @ jump to next instruction 7251 7252 7253/* ------------------------------ */ 7254 .balign 64 7255.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */ 7256/* File: armv5te/OP_SPUT_WIDE_VOLATILE.S */ 7257/* File: armv5te/OP_SPUT_WIDE.S */ 7258 /* 7259 * 64-bit SPUT handler. 7260 */ 7261 /* sput-wide vAA, field@BBBB */ 7262 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- DvmDex 7263 FETCH(r1, 1) @ r1<- field ref BBBB 7264 ldr r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields 7265 mov r9, rINST, lsr #8 @ r9<- AA 7266 ldr r2, [r0, r1, lsl #2] @ r2<- resolved StaticField ptr 7267 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7268 cmp r2, #0 @ is resolved entry null? 7269 beq .LOP_SPUT_WIDE_VOLATILE_resolve @ yes, do resolve 7270.LOP_SPUT_WIDE_VOLATILE_finish: @ field ptr in r2, AA in r9 7271 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7272 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 7273 GET_INST_OPCODE(r10) @ extract opcode from rINST 7274 .if 1 7275 add r2, r2, #offStaticField_value @ r2<- pointer to data 7276 bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2 7277 .else 7278 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 7279 .endif 7280 GOTO_OPCODE(r10) @ jump to next instruction 7281 7282 7283/* ------------------------------ */ 7284 .balign 64 7285.L_OP_BREAKPOINT: /* 0xec */ 7286/* File: armv5te/OP_BREAKPOINT.S */ 7287/* File: armv5te/unused.S */ 7288 bl common_abort 7289 7290 7291/* ------------------------------ */ 7292 .balign 64 7293.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */ 7294/* File: armv5te/OP_THROW_VERIFICATION_ERROR.S */ 7295 /* 7296 * Handle a throw-verification-error instruction. This throws an 7297 * exception for an error discovered during verification. The 7298 * exception is indicated by AA, with some detail provided by BBBB. 7299 */ 7300 /* op AA, ref@BBBB */ 7301 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 7302 FETCH(r2, 1) @ r2<- BBBB 7303 EXPORT_PC() @ export the PC 7304 mov r1, rINST, lsr #8 @ r1<- AA 7305 bl dvmThrowVerificationError @ always throws 7306 b common_exceptionThrown @ handle exception 7307 7308/* ------------------------------ */ 7309 .balign 64 7310.L_OP_EXECUTE_INLINE: /* 0xee */ 7311/* File: armv5te/OP_EXECUTE_INLINE.S */ 7312 /* 7313 * Execute a "native inline" instruction. 7314 * 7315 * We need to call an InlineOp4Func: 7316 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7317 * 7318 * The first four args are in r0-r3, pointer to return value storage 7319 * is on the stack. The function's return value is a flag that tells 7320 * us if an exception was thrown. 7321 */ 7322 /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */ 7323 FETCH(r10, 1) @ r10<- BBBB 7324 add r1, rGLUE, #offGlue_retval @ r1<- &glue->retval 7325 EXPORT_PC() @ can throw 7326 sub sp, sp, #8 @ make room for arg, +64 bit align 7327 mov r0, rINST, lsr #12 @ r0<- B 7328 str r1, [sp] @ push &glue->retval 7329 bl .LOP_EXECUTE_INLINE_continue @ make call; will return after 7330 add sp, sp, #8 @ pop stack 7331 cmp r0, #0 @ test boolean result of inline 7332 beq common_exceptionThrown @ returned false, handle exception 7333 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7334 GET_INST_OPCODE(ip) @ extract opcode from rINST 7335 GOTO_OPCODE(ip) @ jump to next instruction 7336 7337/* ------------------------------ */ 7338 .balign 64 7339.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */ 7340/* File: armv5te/OP_EXECUTE_INLINE_RANGE.S */ 7341 /* 7342 * Execute a "native inline" instruction, using "/range" semantics. 7343 * Same idea as execute-inline, but we get the args differently. 7344 * 7345 * We need to call an InlineOp4Func: 7346 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7347 * 7348 * The first four args are in r0-r3, pointer to return value storage 7349 * is on the stack. The function's return value is a flag that tells 7350 * us if an exception was thrown. 7351 */ 7352 /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */ 7353 FETCH(r10, 1) @ r10<- BBBB 7354 add r1, rGLUE, #offGlue_retval @ r1<- &glue->retval 7355 EXPORT_PC() @ can throw 7356 sub sp, sp, #8 @ make room for arg, +64 bit align 7357 mov r0, rINST, lsr #8 @ r0<- AA 7358 str r1, [sp] @ push &glue->retval 7359 bl .LOP_EXECUTE_INLINE_RANGE_continue @ make call; will return after 7360 add sp, sp, #8 @ pop stack 7361 cmp r0, #0 @ test boolean result of inline 7362 beq common_exceptionThrown @ returned false, handle exception 7363 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7364 GET_INST_OPCODE(ip) @ extract opcode from rINST 7365 GOTO_OPCODE(ip) @ jump to next instruction 7366 7367/* ------------------------------ */ 7368 .balign 64 7369.L_OP_INVOKE_OBJECT_INIT: /* 0xf0 */ 7370/* File: armv5te/OP_INVOKE_OBJECT_INIT.S */ 7371 /* 7372 * invoke-object-init is a no-op in a "standard" interpreter. 7373 */ 7374 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 7375 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 7376 GOTO_OPCODE(ip) @ execute it 7377 7378/* ------------------------------ */ 7379 .balign 64 7380.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */ 7381/* File: armv5te/OP_RETURN_VOID_BARRIER.S */ 7382 SMP_DMB_ST 7383 b common_returnFromMethod 7384 7385/* ------------------------------ */ 7386 .balign 64 7387.L_OP_IGET_QUICK: /* 0xf2 */ 7388/* File: armv6t2/OP_IGET_QUICK.S */ 7389 /* For: iget-quick, iget-object-quick */ 7390 /* op vA, vB, offset@CCCC */ 7391 mov r2, rINST, lsr #12 @ r2<- B 7392 FETCH(r1, 1) @ r1<- field byte offset 7393 GET_VREG(r3, r2) @ r3<- object we're operating on 7394 ubfx r2, rINST, #8, #4 @ r2<- A 7395 cmp r3, #0 @ check object for null 7396 beq common_errNullObject @ object was null 7397 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7398 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7399 GET_INST_OPCODE(ip) @ extract opcode from rINST 7400 SET_VREG(r0, r2) @ fp[A]<- r0 7401 GOTO_OPCODE(ip) @ jump to next instruction 7402 7403/* ------------------------------ */ 7404 .balign 64 7405.L_OP_IGET_WIDE_QUICK: /* 0xf3 */ 7406/* File: armv6t2/OP_IGET_WIDE_QUICK.S */ 7407 /* iget-wide-quick vA, vB, offset@CCCC */ 7408 mov r2, rINST, lsr #12 @ r2<- B 7409 FETCH(ip, 1) @ ip<- field byte offset 7410 GET_VREG(r3, r2) @ r3<- object we're operating on 7411 ubfx r2, rINST, #8, #4 @ r2<- A 7412 cmp r3, #0 @ check object for null 7413 beq common_errNullObject @ object was null 7414 ldrd r0, [r3, ip] @ r0<- obj.field (64 bits, aligned) 7415 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7416 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 7417 GET_INST_OPCODE(ip) @ extract opcode from rINST 7418 stmia r3, {r0-r1} @ fp[A]<- r0/r1 7419 GOTO_OPCODE(ip) @ jump to next instruction 7420 7421/* ------------------------------ */ 7422 .balign 64 7423.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */ 7424/* File: armv5te/OP_IGET_OBJECT_QUICK.S */ 7425/* File: armv5te/OP_IGET_QUICK.S */ 7426 /* For: iget-quick, iget-object-quick */ 7427 /* op vA, vB, offset@CCCC */ 7428 mov r2, rINST, lsr #12 @ r2<- B 7429 GET_VREG(r3, r2) @ r3<- object we're operating on 7430 FETCH(r1, 1) @ r1<- field byte offset 7431 cmp r3, #0 @ check object for null 7432 mov r2, rINST, lsr #8 @ r2<- A(+) 7433 beq common_errNullObject @ object was null 7434 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7435 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7436 and r2, r2, #15 7437 GET_INST_OPCODE(ip) @ extract opcode from rINST 7438 SET_VREG(r0, r2) @ fp[A]<- r0 7439 GOTO_OPCODE(ip) @ jump to next instruction 7440 7441 7442/* ------------------------------ */ 7443 .balign 64 7444.L_OP_IPUT_QUICK: /* 0xf5 */ 7445/* File: armv6t2/OP_IPUT_QUICK.S */ 7446 /* For: iput-quick, iput-object-quick */ 7447 /* op vA, vB, offset@CCCC */ 7448 mov r2, rINST, lsr #12 @ r2<- B 7449 FETCH(r1, 1) @ r1<- field byte offset 7450 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7451 ubfx r2, rINST, #8, #4 @ r2<- A 7452 cmp r3, #0 @ check object for null 7453 beq common_errNullObject @ object was null 7454 GET_VREG(r0, r2) @ r0<- fp[A] 7455 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7456 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7457 GET_INST_OPCODE(ip) @ extract opcode from rINST 7458 GOTO_OPCODE(ip) @ jump to next instruction 7459 7460/* ------------------------------ */ 7461 .balign 64 7462.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */ 7463/* File: armv6t2/OP_IPUT_WIDE_QUICK.S */ 7464 /* iput-wide-quick vA, vB, offset@CCCC */ 7465 mov r1, rINST, lsr #12 @ r1<- B 7466 ubfx r0, rINST, #8, #4 @ r0<- A 7467 GET_VREG(r2, r1) @ r2<- fp[B], the object pointer 7468 add r3, rFP, r0, lsl #2 @ r3<- &fp[A] 7469 cmp r2, #0 @ check object for null 7470 ldmia r3, {r0-r1} @ r0/r1<- fp[A] 7471 beq common_errNullObject @ object was null 7472 FETCH(r3, 1) @ r3<- field byte offset 7473 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7474 strd r0, [r2, r3] @ obj.field (64 bits, aligned)<- r0/r1 7475 GET_INST_OPCODE(ip) @ extract opcode from rINST 7476 GOTO_OPCODE(ip) @ jump to next instruction 7477 7478/* ------------------------------ */ 7479 .balign 64 7480.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */ 7481/* File: armv5te/OP_IPUT_OBJECT_QUICK.S */ 7482 /* For: iput-object-quick */ 7483 /* op vA, vB, offset@CCCC */ 7484 mov r2, rINST, lsr #12 @ r2<- B 7485 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7486 FETCH(r1, 1) @ r1<- field byte offset 7487 cmp r3, #0 @ check object for null 7488 mov r2, rINST, lsr #8 @ r2<- A(+) 7489 beq common_errNullObject @ object was null 7490 and r2, r2, #15 7491 GET_VREG(r0, r2) @ r0<- fp[A] 7492 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 7493 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7494 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7495 cmp r0, #0 7496 strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head 7497 GET_INST_OPCODE(ip) @ extract opcode from rINST 7498 GOTO_OPCODE(ip) @ jump to next instruction 7499 7500/* ------------------------------ */ 7501 .balign 64 7502.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */ 7503/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7504 /* 7505 * Handle an optimized virtual method call. 7506 * 7507 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 7508 */ 7509 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7510 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7511 FETCH(r3, 2) @ r3<- FEDC or CCCC 7512 FETCH(r1, 1) @ r1<- BBBB 7513 .if (!0) 7514 and r3, r3, #15 @ r3<- C (or stays CCCC) 7515 .endif 7516 GET_VREG(r2, r3) @ r2<- vC ("this" ptr) 7517 cmp r2, #0 @ is "this" null? 7518 beq common_errNullObject @ null "this", throw exception 7519 ldr r2, [r2, #offObject_clazz] @ r2<- thisPtr->clazz 7520 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7521 EXPORT_PC() @ invoke must export 7522 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7523 bl common_invokeMethodNoRange @ continue on 7524 7525/* ------------------------------ */ 7526 .balign 64 7527.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */ 7528/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */ 7529/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7530 /* 7531 * Handle an optimized virtual method call. 7532 * 7533 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 7534 */ 7535 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7536 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7537 FETCH(r3, 2) @ r3<- FEDC or CCCC 7538 FETCH(r1, 1) @ r1<- BBBB 7539 .if (!1) 7540 and r3, r3, #15 @ r3<- C (or stays CCCC) 7541 .endif 7542 GET_VREG(r2, r3) @ r2<- vC ("this" ptr) 7543 cmp r2, #0 @ is "this" null? 7544 beq common_errNullObject @ null "this", throw exception 7545 ldr r2, [r2, #offObject_clazz] @ r2<- thisPtr->clazz 7546 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7547 EXPORT_PC() @ invoke must export 7548 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7549 bl common_invokeMethodRange @ continue on 7550 7551 7552/* ------------------------------ */ 7553 .balign 64 7554.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */ 7555/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7556 /* 7557 * Handle an optimized "super" method call. 7558 * 7559 * for: [opt] invoke-super-quick, invoke-super-quick/range 7560 */ 7561 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7562 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7563 FETCH(r10, 2) @ r10<- GFED or CCCC 7564 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7565 .if (!0) 7566 and r10, r10, #15 @ r10<- D (or stays CCCC) 7567 .endif 7568 FETCH(r1, 1) @ r1<- BBBB 7569 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7570 EXPORT_PC() @ must export for invoke 7571 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7572 GET_VREG(r3, r10) @ r3<- "this" 7573 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7574 cmp r3, #0 @ null "this" ref? 7575 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7576 beq common_errNullObject @ "this" is null, throw exception 7577 bl common_invokeMethodNoRange @ continue on 7578 7579/* ------------------------------ */ 7580 .balign 64 7581.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */ 7582/* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */ 7583/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7584 /* 7585 * Handle an optimized "super" method call. 7586 * 7587 * for: [opt] invoke-super-quick, invoke-super-quick/range 7588 */ 7589 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7590 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7591 FETCH(r10, 2) @ r10<- GFED or CCCC 7592 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7593 .if (!1) 7594 and r10, r10, #15 @ r10<- D (or stays CCCC) 7595 .endif 7596 FETCH(r1, 1) @ r1<- BBBB 7597 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7598 EXPORT_PC() @ must export for invoke 7599 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7600 GET_VREG(r3, r10) @ r3<- "this" 7601 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7602 cmp r3, #0 @ null "this" ref? 7603 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7604 beq common_errNullObject @ "this" is null, throw exception 7605 bl common_invokeMethodRange @ continue on 7606 7607 7608/* ------------------------------ */ 7609 .balign 64 7610.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */ 7611/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */ 7612/* File: armv5te/OP_IPUT_OBJECT.S */ 7613 /* 7614 * 32-bit instance field put. 7615 * 7616 * for: iput-object, iput-object-volatile 7617 */ 7618 /* op vA, vB, field@CCCC */ 7619 mov r0, rINST, lsr #12 @ r0<- B 7620 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7621 FETCH(r1, 1) @ r1<- field ref CCCC 7622 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7623 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7624 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7625 cmp r0, #0 @ is resolved entry null? 7626 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ no, already resolved 76278: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7628 EXPORT_PC() @ resolve() could throw 7629 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7630 bl dvmResolveInstField @ r0<- resolved InstField ptr 7631 cmp r0, #0 @ success? 7632 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ yes, finish up 7633 b common_exceptionThrown 7634 7635 7636/* ------------------------------ */ 7637 .balign 64 7638.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */ 7639/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */ 7640/* File: armv5te/OP_SGET.S */ 7641 /* 7642 * General 32-bit SGET handler. 7643 * 7644 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7645 */ 7646 /* op vAA, field@BBBB */ 7647 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 7648 FETCH(r1, 1) @ r1<- field ref BBBB 7649 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7650 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7651 cmp r0, #0 @ is resolved entry null? 7652 beq .LOP_SGET_OBJECT_VOLATILE_resolve @ yes, do resolve 7653.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0 7654 ldr r1, [r0, #offStaticField_value] @ r1<- field value 7655 SMP_DMB @ acquiring load 7656 mov r2, rINST, lsr #8 @ r2<- AA 7657 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7658 SET_VREG(r1, r2) @ fp[AA]<- r1 7659 GET_INST_OPCODE(ip) @ extract opcode from rINST 7660 GOTO_OPCODE(ip) @ jump to next instruction 7661 7662 7663/* ------------------------------ */ 7664 .balign 64 7665.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */ 7666/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */ 7667/* File: armv5te/OP_SPUT_OBJECT.S */ 7668 /* 7669 * 32-bit SPUT handler for objects 7670 * 7671 * for: sput-object, sput-object-volatile 7672 */ 7673 /* op vAA, field@BBBB */ 7674 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 7675 FETCH(r1, 1) @ r1<- field ref BBBB 7676 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7677 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7678 cmp r0, #0 @ is resolved entry null? 7679 bne .LOP_SPUT_OBJECT_VOLATILE_finish @ no, continue 7680 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 7681 EXPORT_PC() @ resolve() could throw, so export now 7682 ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz 7683 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 7684 cmp r0, #0 @ success? 7685 bne .LOP_SPUT_OBJECT_VOLATILE_finish @ yes, finish 7686 b common_exceptionThrown @ no, handle exception 7687 7688 7689 7690/* ------------------------------ */ 7691 .balign 64 7692.L_OP_DISPATCH_FF: /* 0xff */ 7693/* File: armv5te/OP_DISPATCH_FF.S */ 7694 mov ip, rINST, lsr #8 @ r9<- extended opcode 7695 add ip, ip, #256 @ add offset for extended opcodes 7696 GOTO_OPCODE(ip) @ go to proper extended handler 7697 7698 7699/* ------------------------------ */ 7700 .balign 64 7701.L_OP_CONST_CLASS_JUMBO: /* 0x100 */ 7702/* File: armv5te/OP_CONST_CLASS_JUMBO.S */ 7703 /* const-class/jumbo vBBBB, Class@AAAAAAAA */ 7704 FETCH(r0, 1) @ r0<- aaaa (lo) 7705 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- glue->methodClassDex 7706 FETCH(r1, 2) @ r1<- AAAA (hi) 7707 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- dvmDex->pResClasses 7708 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 7709 FETCH(r9, 3) @ r9<- BBBB 7710 ldr r0, [r2, r1, lsl #2] @ r0<- pResClasses[AAAAaaaa] 7711 cmp r0, #0 @ not yet resolved? 7712 beq .LOP_CONST_CLASS_JUMBO_resolve 7713 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 7714 GET_INST_OPCODE(ip) @ extract opcode from rINST 7715 SET_VREG(r0, r9) @ vBBBB<- r0 7716 GOTO_OPCODE(ip) @ jump to next instruction 7717 7718/* ------------------------------ */ 7719 .balign 64 7720.L_OP_CHECK_CAST_JUMBO: /* 0x101 */ 7721/* File: armv5te/OP_CHECK_CAST_JUMBO.S */ 7722 /* 7723 * Check to see if a cast from one class to another is allowed. 7724 */ 7725 /* check-cast/jumbo vBBBB, class@AAAAAAAA */ 7726 FETCH(r0, 1) @ r0<- aaaa (lo) 7727 FETCH(r2, 2) @ r2<- AAAA (hi) 7728 FETCH(r3, 3) @ r3<- BBBB 7729 orr r2, r0, r2, lsl #16 @ r2<- AAAAaaaa 7730 GET_VREG(r9, r3) @ r9<- object 7731 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- pDvmDex 7732 cmp r9, #0 @ is object null? 7733 ldr r0, [r0, #offDvmDex_pResClasses] @ r0<- pDvmDex->pResClasses 7734 beq .LOP_CHECK_CAST_JUMBO_okay @ null obj, cast always succeeds 7735 ldr r1, [r0, r2, lsl #2] @ r1<- resolved class 7736 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 7737 cmp r1, #0 @ have we resolved this before? 7738 beq .LOP_CHECK_CAST_JUMBO_resolve @ not resolved, do it now 7739.LOP_CHECK_CAST_JUMBO_resolved: 7740 cmp r0, r1 @ same class (trivial success)? 7741 bne .LOP_CHECK_CAST_JUMBO_fullcheck @ no, do full check 7742 b .LOP_CHECK_CAST_JUMBO_okay @ yes, finish up 7743 7744/* ------------------------------ */ 7745 .balign 64 7746.L_OP_INSTANCE_OF_JUMBO: /* 0x102 */ 7747/* File: armv5te/OP_INSTANCE_OF_JUMBO.S */ 7748 /* 7749 * Check to see if an object reference is an instance of a class. 7750 * 7751 * Most common situation is a non-null object, being compared against 7752 * an already-resolved class. 7753 * 7754 * TODO: convert most of this into a common subroutine, shared with 7755 * OP_INSTANCE_OF.S. 7756 */ 7757 /* instance-of/jumbo vBBBB, vCCCC, class@AAAAAAAA */ 7758 FETCH(r3, 4) @ r3<- vCCCC 7759 FETCH(r9, 3) @ r9<- vBBBB 7760 GET_VREG(r0, r3) @ r0<- vCCCC (object) 7761 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- pDvmDex 7762 cmp r0, #0 @ is object null? 7763 beq .LOP_INSTANCE_OF_JUMBO_store @ null obj, not an instance, store r0 7764 FETCH(r1, 1) @ r1<- aaaa (lo) 7765 FETCH(r3, 2) @ r3<- AAAA (hi) 7766 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- pDvmDex->pResClasses 7767 orr r3, r1, r3, lsl #16 @ r3<- AAAAaaaa 7768 ldr r1, [r2, r3, lsl #2] @ r1<- resolved class 7769 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 7770 cmp r1, #0 @ have we resolved this before? 7771 beq .LOP_INSTANCE_OF_JUMBO_resolve @ not resolved, do it now 7772 b .LOP_INSTANCE_OF_JUMBO_resolved @ resolved, continue 7773 7774/* ------------------------------ */ 7775 .balign 64 7776.L_OP_NEW_INSTANCE_JUMBO: /* 0x103 */ 7777/* File: armv5te/OP_NEW_INSTANCE_JUMBO.S */ 7778 /* 7779 * Create a new instance of a class. 7780 */ 7781 /* new-instance/jumbo vBBBB, class@AAAAAAAA */ 7782 FETCH(r0, 1) @ r0<- aaaa (lo) 7783 FETCH(r1, 2) @ r1<- AAAA (hi) 7784 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 7785 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 7786 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 7787 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 7788 EXPORT_PC() @ req'd for init, resolve, alloc 7789 cmp r0, #0 @ already resolved? 7790 beq .LOP_NEW_INSTANCE_JUMBO_resolve @ no, resolve it now 7791.LOP_NEW_INSTANCE_JUMBO_resolved: @ r0=class 7792 ldrb r1, [r0, #offClassObject_status] @ r1<- ClassStatus enum 7793 cmp r1, #CLASS_INITIALIZED @ has class been initialized? 7794 bne .LOP_NEW_INSTANCE_JUMBO_needinit @ no, init class now 7795.LOP_NEW_INSTANCE_JUMBO_initialized: @ r0=class 7796 mov r1, #ALLOC_DONT_TRACK @ flags for alloc call 7797 bl dvmAllocObject @ r0<- new object 7798 b .LOP_NEW_INSTANCE_JUMBO_finish @ continue 7799 7800/* ------------------------------ */ 7801 .balign 64 7802.L_OP_NEW_ARRAY_JUMBO: /* 0x104 */ 7803/* File: armv5te/OP_NEW_ARRAY_JUMBO.S */ 7804 /* 7805 * Allocate an array of objects, specified with the array class 7806 * and a count. 7807 * 7808 * The verifier guarantees that this is an array class, so we don't 7809 * check for it here. 7810 */ 7811 /* new-array/jumbo vBBBB, vCCCC, class@AAAAAAAA */ 7812 FETCH(r2, 1) @ r2<- aaaa (lo) 7813 FETCH(r3, 2) @ r3<- AAAA (hi) 7814 FETCH(r0, 4) @ r0<- vCCCC 7815 orr r2, r2, r3, lsl #16 @ r2<- AAAAaaaa 7816 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 7817 GET_VREG(r1, r0) @ r1<- vCCCC (array length) 7818 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 7819 cmp r1, #0 @ check length 7820 ldr r0, [r3, r2, lsl #2] @ r0<- resolved class 7821 bmi common_errNegativeArraySize @ negative length, bail 7822 cmp r0, #0 @ already resolved? 7823 EXPORT_PC() @ req'd for resolve, alloc 7824 bne .LOP_NEW_ARRAY_JUMBO_finish @ resolved, continue 7825 b .LOP_NEW_ARRAY_JUMBO_resolve @ do resolve now 7826 7827/* ------------------------------ */ 7828 .balign 64 7829.L_OP_FILLED_NEW_ARRAY_JUMBO: /* 0x105 */ 7830/* File: armv5te/OP_FILLED_NEW_ARRAY_JUMBO.S */ 7831 /* 7832 * Create a new array with elements filled from registers. 7833 * 7834 * TODO: convert most of this into a common subroutine, shared with 7835 * OP_FILLED_NEW_ARRAY.S. 7836 */ 7837 /* filled-new-array/jumbo {vCCCC..v(CCCC+BBBB-1)}, type@AAAAAAAA */ 7838 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 7839 FETCH(r0, 1) @ r0<- aaaa (lo) 7840 FETCH(r1, 2) @ r1<- AAAA (hi) 7841 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 7842 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 7843 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 7844 EXPORT_PC() @ need for resolve and alloc 7845 cmp r0, #0 @ already resolved? 7846 bne .LOP_FILLED_NEW_ARRAY_JUMBO_continue @ yes, continue on 78478: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 7848 mov r2, #0 @ r2<- false 7849 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 7850 bl dvmResolveClass @ r0<- call(clazz, ref) 7851 cmp r0, #0 @ got null? 7852 beq common_exceptionThrown @ yes, handle exception 7853 b .LOP_FILLED_NEW_ARRAY_JUMBO_continue 7854 7855/* ------------------------------ */ 7856 .balign 64 7857.L_OP_IGET_JUMBO: /* 0x106 */ 7858/* File: armv5te/OP_IGET_JUMBO.S */ 7859 /* 7860 * Jumbo 32-bit instance field get. 7861 * 7862 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 7863 * iget-char/jumbo, iget-short/jumbo 7864 */ 7865 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 7866 FETCH(r1, 1) @ r1<- aaaa (lo) 7867 FETCH(r2, 2) @ r2<- AAAA (hi) 7868 FETCH(r0, 4) @ r0<- CCCC 7869 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7870 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 7871 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7872 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 7873 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7874 cmp r0, #0 @ is resolved entry null? 7875 bne .LOP_IGET_JUMBO_finish @ no, already resolved 78768: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7877 EXPORT_PC() @ resolve() could throw 7878 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7879 bl dvmResolveInstField @ r0<- resolved InstField ptr 7880 b .LOP_IGET_JUMBO_resolved @ resolved, continue 7881 7882/* ------------------------------ */ 7883 .balign 64 7884.L_OP_IGET_WIDE_JUMBO: /* 0x107 */ 7885/* File: armv5te/OP_IGET_WIDE_JUMBO.S */ 7886 /* 7887 * Jumbo 64-bit instance field get. 7888 */ 7889 /* iget-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */ 7890 FETCH(r1, 1) @ r1<- aaaa (lo) 7891 FETCH(r2, 2) @ r2<- AAAA (hi) 7892 FETCH(r0, 4) @ r0<- CCCC 7893 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7894 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 7895 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7896 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 7897 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7898 cmp r0, #0 @ is resolved entry null? 7899 bne .LOP_IGET_WIDE_JUMBO_finish @ no, already resolved 79008: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7901 EXPORT_PC() @ resolve() could throw 7902 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7903 bl dvmResolveInstField @ r0<- resolved InstField ptr 7904 b .LOP_IGET_WIDE_JUMBO_resolved @ resolved, continue 7905 7906/* ------------------------------ */ 7907 .balign 64 7908.L_OP_IGET_OBJECT_JUMBO: /* 0x108 */ 7909/* File: armv5te/OP_IGET_OBJECT_JUMBO.S */ 7910/* File: armv5te/OP_IGET_JUMBO.S */ 7911 /* 7912 * Jumbo 32-bit instance field get. 7913 * 7914 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 7915 * iget-char/jumbo, iget-short/jumbo 7916 */ 7917 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 7918 FETCH(r1, 1) @ r1<- aaaa (lo) 7919 FETCH(r2, 2) @ r2<- AAAA (hi) 7920 FETCH(r0, 4) @ r0<- CCCC 7921 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7922 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 7923 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7924 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 7925 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7926 cmp r0, #0 @ is resolved entry null? 7927 bne .LOP_IGET_OBJECT_JUMBO_finish @ no, already resolved 79288: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7929 EXPORT_PC() @ resolve() could throw 7930 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7931 bl dvmResolveInstField @ r0<- resolved InstField ptr 7932 b .LOP_IGET_OBJECT_JUMBO_resolved @ resolved, continue 7933 7934 7935/* ------------------------------ */ 7936 .balign 64 7937.L_OP_IGET_BOOLEAN_JUMBO: /* 0x109 */ 7938/* File: armv5te/OP_IGET_BOOLEAN_JUMBO.S */ 7939@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrb", "sqnum":"1" } 7940/* File: armv5te/OP_IGET_JUMBO.S */ 7941 /* 7942 * Jumbo 32-bit instance field get. 7943 * 7944 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 7945 * iget-char/jumbo, iget-short/jumbo 7946 */ 7947 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 7948 FETCH(r1, 1) @ r1<- aaaa (lo) 7949 FETCH(r2, 2) @ r2<- AAAA (hi) 7950 FETCH(r0, 4) @ r0<- CCCC 7951 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7952 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 7953 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7954 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 7955 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7956 cmp r0, #0 @ is resolved entry null? 7957 bne .LOP_IGET_BOOLEAN_JUMBO_finish @ no, already resolved 79588: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7959 EXPORT_PC() @ resolve() could throw 7960 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7961 bl dvmResolveInstField @ r0<- resolved InstField ptr 7962 b .LOP_IGET_BOOLEAN_JUMBO_resolved @ resolved, continue 7963 7964 7965/* ------------------------------ */ 7966 .balign 64 7967.L_OP_IGET_BYTE_JUMBO: /* 0x10a */ 7968/* File: armv5te/OP_IGET_BYTE_JUMBO.S */ 7969@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsb", "sqnum":"2" } 7970/* File: armv5te/OP_IGET_JUMBO.S */ 7971 /* 7972 * Jumbo 32-bit instance field get. 7973 * 7974 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 7975 * iget-char/jumbo, iget-short/jumbo 7976 */ 7977 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 7978 FETCH(r1, 1) @ r1<- aaaa (lo) 7979 FETCH(r2, 2) @ r2<- AAAA (hi) 7980 FETCH(r0, 4) @ r0<- CCCC 7981 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7982 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 7983 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7984 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 7985 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7986 cmp r0, #0 @ is resolved entry null? 7987 bne .LOP_IGET_BYTE_JUMBO_finish @ no, already resolved 79888: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7989 EXPORT_PC() @ resolve() could throw 7990 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7991 bl dvmResolveInstField @ r0<- resolved InstField ptr 7992 b .LOP_IGET_BYTE_JUMBO_resolved @ resolved, continue 7993 7994 7995/* ------------------------------ */ 7996 .balign 64 7997.L_OP_IGET_CHAR_JUMBO: /* 0x10b */ 7998/* File: armv5te/OP_IGET_CHAR_JUMBO.S */ 7999@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrh", "sqnum":"3" } 8000/* File: armv5te/OP_IGET_JUMBO.S */ 8001 /* 8002 * Jumbo 32-bit instance field get. 8003 * 8004 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 8005 * iget-char/jumbo, iget-short/jumbo 8006 */ 8007 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8008 FETCH(r1, 1) @ r1<- aaaa (lo) 8009 FETCH(r2, 2) @ r2<- AAAA (hi) 8010 FETCH(r0, 4) @ r0<- CCCC 8011 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8012 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8013 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8014 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8015 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8016 cmp r0, #0 @ is resolved entry null? 8017 bne .LOP_IGET_CHAR_JUMBO_finish @ no, already resolved 80188: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8019 EXPORT_PC() @ resolve() could throw 8020 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8021 bl dvmResolveInstField @ r0<- resolved InstField ptr 8022 b .LOP_IGET_CHAR_JUMBO_resolved @ resolved, continue 8023 8024 8025/* ------------------------------ */ 8026 .balign 64 8027.L_OP_IGET_SHORT_JUMBO: /* 0x10c */ 8028/* File: armv5te/OP_IGET_SHORT_JUMBO.S */ 8029@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsh", "sqnum":"4" } 8030/* File: armv5te/OP_IGET_JUMBO.S */ 8031 /* 8032 * Jumbo 32-bit instance field get. 8033 * 8034 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 8035 * iget-char/jumbo, iget-short/jumbo 8036 */ 8037 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8038 FETCH(r1, 1) @ r1<- aaaa (lo) 8039 FETCH(r2, 2) @ r2<- AAAA (hi) 8040 FETCH(r0, 4) @ r0<- CCCC 8041 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8042 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8043 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8044 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8045 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8046 cmp r0, #0 @ is resolved entry null? 8047 bne .LOP_IGET_SHORT_JUMBO_finish @ no, already resolved 80488: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8049 EXPORT_PC() @ resolve() could throw 8050 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8051 bl dvmResolveInstField @ r0<- resolved InstField ptr 8052 b .LOP_IGET_SHORT_JUMBO_resolved @ resolved, continue 8053 8054 8055/* ------------------------------ */ 8056 .balign 64 8057.L_OP_IPUT_JUMBO: /* 0x10d */ 8058/* File: armv5te/OP_IPUT_JUMBO.S */ 8059 /* 8060 * Jumbo 32-bit instance field put. 8061 * 8062 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8063 * iput-short/jumbo 8064 */ 8065 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8066 FETCH(r1, 1) @ r1<- aaaa (lo) 8067 FETCH(r2, 2) @ r2<- AAAA (hi) 8068 FETCH(r0, 4) @ r0<- CCCC 8069 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8070 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8071 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8072 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8073 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8074 cmp r0, #0 @ is resolved entry null? 8075 bne .LOP_IPUT_JUMBO_finish @ no, already resolved 80768: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8077 EXPORT_PC() @ resolve() could throw 8078 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8079 bl dvmResolveInstField @ r0<- resolved InstField ptr 8080 b .LOP_IPUT_JUMBO_resolved @ resolved, continue 8081 8082/* ------------------------------ */ 8083 .balign 64 8084.L_OP_IPUT_WIDE_JUMBO: /* 0x10e */ 8085/* File: armv5te/OP_IPUT_WIDE_JUMBO.S */ 8086 /* iput-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */ 8087 FETCH(r1, 1) @ r1<- aaaa (lo) 8088 FETCH(r2, 2) @ r2<- AAAA (hi) 8089 FETCH(r0, 4) @ r0<- CCCC 8090 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8091 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8092 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 8093 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 8094 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8095 cmp r0, #0 @ is resolved entry null? 8096 bne .LOP_IPUT_WIDE_JUMBO_finish @ no, already resolved 80978: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8098 EXPORT_PC() @ resolve() could throw 8099 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8100 bl dvmResolveInstField @ r0<- resolved InstField ptr 8101 b .LOP_IPUT_WIDE_JUMBO_resolved @ resolved, continue 8102 8103/* ------------------------------ */ 8104 .balign 64 8105.L_OP_IPUT_OBJECT_JUMBO: /* 0x10f */ 8106/* File: armv5te/OP_IPUT_OBJECT_JUMBO.S */ 8107 /* 8108 * Jumbo 32-bit instance field put. 8109 */ 8110 /* iput-object/jumbo vBBBB, vCCCC, field@AAAAAAAA */ 8111 FETCH(r1, 1) @ r1<- aaaa (lo) 8112 FETCH(r2, 2) @ r2<- AAAA (hi) 8113 FETCH(r0, 4) @ r0<- CCCC 8114 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8115 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8116 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8117 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8118 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8119 cmp r0, #0 @ is resolved entry null? 8120 bne .LOP_IPUT_OBJECT_JUMBO_finish @ no, already resolved 81218: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8122 EXPORT_PC() @ resolve() could throw 8123 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8124 bl dvmResolveInstField @ r0<- resolved InstField ptr 8125 b .LOP_IPUT_OBJECT_JUMBO_resolved @ resolved, continue 8126 8127/* ------------------------------ */ 8128 .balign 64 8129.L_OP_IPUT_BOOLEAN_JUMBO: /* 0x110 */ 8130/* File: armv5te/OP_IPUT_BOOLEAN_JUMBO.S */ 8131@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"1" } 8132/* File: armv5te/OP_IPUT_JUMBO.S */ 8133 /* 8134 * Jumbo 32-bit instance field put. 8135 * 8136 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8137 * iput-short/jumbo 8138 */ 8139 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8140 FETCH(r1, 1) @ r1<- aaaa (lo) 8141 FETCH(r2, 2) @ r2<- AAAA (hi) 8142 FETCH(r0, 4) @ r0<- CCCC 8143 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8144 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8145 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8146 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8147 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8148 cmp r0, #0 @ is resolved entry null? 8149 bne .LOP_IPUT_BOOLEAN_JUMBO_finish @ no, already resolved 81508: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8151 EXPORT_PC() @ resolve() could throw 8152 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8153 bl dvmResolveInstField @ r0<- resolved InstField ptr 8154 b .LOP_IPUT_BOOLEAN_JUMBO_resolved @ resolved, continue 8155 8156 8157/* ------------------------------ */ 8158 .balign 64 8159.L_OP_IPUT_BYTE_JUMBO: /* 0x111 */ 8160/* File: armv5te/OP_IPUT_BYTE_JUMBO.S */ 8161@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"2" } 8162/* File: armv5te/OP_IPUT_JUMBO.S */ 8163 /* 8164 * Jumbo 32-bit instance field put. 8165 * 8166 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8167 * iput-short/jumbo 8168 */ 8169 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8170 FETCH(r1, 1) @ r1<- aaaa (lo) 8171 FETCH(r2, 2) @ r2<- AAAA (hi) 8172 FETCH(r0, 4) @ r0<- CCCC 8173 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8174 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8175 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8176 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8177 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8178 cmp r0, #0 @ is resolved entry null? 8179 bne .LOP_IPUT_BYTE_JUMBO_finish @ no, already resolved 81808: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8181 EXPORT_PC() @ resolve() could throw 8182 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8183 bl dvmResolveInstField @ r0<- resolved InstField ptr 8184 b .LOP_IPUT_BYTE_JUMBO_resolved @ resolved, continue 8185 8186 8187/* ------------------------------ */ 8188 .balign 64 8189.L_OP_IPUT_CHAR_JUMBO: /* 0x112 */ 8190/* File: armv5te/OP_IPUT_CHAR_JUMBO.S */ 8191@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"3" } 8192/* File: armv5te/OP_IPUT_JUMBO.S */ 8193 /* 8194 * Jumbo 32-bit instance field put. 8195 * 8196 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8197 * iput-short/jumbo 8198 */ 8199 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8200 FETCH(r1, 1) @ r1<- aaaa (lo) 8201 FETCH(r2, 2) @ r2<- AAAA (hi) 8202 FETCH(r0, 4) @ r0<- CCCC 8203 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8204 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8205 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8206 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8207 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8208 cmp r0, #0 @ is resolved entry null? 8209 bne .LOP_IPUT_CHAR_JUMBO_finish @ no, already resolved 82108: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8211 EXPORT_PC() @ resolve() could throw 8212 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8213 bl dvmResolveInstField @ r0<- resolved InstField ptr 8214 b .LOP_IPUT_CHAR_JUMBO_resolved @ resolved, continue 8215 8216 8217/* ------------------------------ */ 8218 .balign 64 8219.L_OP_IPUT_SHORT_JUMBO: /* 0x113 */ 8220/* File: armv5te/OP_IPUT_SHORT_JUMBO.S */ 8221@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"4" } 8222/* File: armv5te/OP_IPUT_JUMBO.S */ 8223 /* 8224 * Jumbo 32-bit instance field put. 8225 * 8226 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8227 * iput-short/jumbo 8228 */ 8229 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8230 FETCH(r1, 1) @ r1<- aaaa (lo) 8231 FETCH(r2, 2) @ r2<- AAAA (hi) 8232 FETCH(r0, 4) @ r0<- CCCC 8233 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8234 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8235 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8236 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8237 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8238 cmp r0, #0 @ is resolved entry null? 8239 bne .LOP_IPUT_SHORT_JUMBO_finish @ no, already resolved 82408: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8241 EXPORT_PC() @ resolve() could throw 8242 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8243 bl dvmResolveInstField @ r0<- resolved InstField ptr 8244 b .LOP_IPUT_SHORT_JUMBO_resolved @ resolved, continue 8245 8246 8247/* ------------------------------ */ 8248 .balign 64 8249.L_OP_SGET_JUMBO: /* 0x114 */ 8250/* File: armv5te/OP_SGET_JUMBO.S */ 8251 /* 8252 * Jumbo 32-bit SGET handler. 8253 * 8254 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8255 * sget-char/jumbo, sget-short/jumbo 8256 */ 8257 /* exop vBBBB, field@AAAAAAAA */ 8258 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8259 FETCH(r0, 1) @ r0<- aaaa (lo) 8260 FETCH(r1, 2) @ r1<- AAAA (hi) 8261 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8262 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8263 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8264 cmp r0, #0 @ is resolved entry null? 8265 beq .LOP_SGET_JUMBO_resolve @ yes, do resolve 8266.LOP_SGET_JUMBO_finish: @ field ptr in r0 8267 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8268 @ no-op @ acquiring load 8269 FETCH(r2, 3) @ r2<- BBBB 8270 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8271 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8272 GET_INST_OPCODE(ip) @ extract opcode from rINST 8273 GOTO_OPCODE(ip) @ jump to next instruction 8274 8275/* ------------------------------ */ 8276 .balign 64 8277.L_OP_SGET_WIDE_JUMBO: /* 0x115 */ 8278/* File: armv5te/OP_SGET_WIDE_JUMBO.S */ 8279 /* 8280 * Jumbo 64-bit SGET handler. 8281 */ 8282 /* sget-wide/jumbo vBBBB, field@AAAAAAAA */ 8283 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8284 FETCH(r0, 1) @ r0<- aaaa (lo) 8285 FETCH(r1, 2) @ r1<- AAAA (hi) 8286 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8287 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8288 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8289 cmp r0, #0 @ is resolved entry null? 8290 beq .LOP_SGET_WIDE_JUMBO_resolve @ yes, do resolve 8291.LOP_SGET_WIDE_JUMBO_finish: 8292 FETCH(r9, 3) @ r9<- BBBB 8293 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 8294 add r9, rFP, r9, lsl #2 @ r9<- &fp[BBBB] 8295 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8296 stmia r9, {r0-r1} @ vBBBB/vBBBB+1<- r0/r1 8297 GET_INST_OPCODE(ip) @ extract opcode from rINST 8298 GOTO_OPCODE(ip) @ jump to next instruction 8299 8300/* ------------------------------ */ 8301 .balign 64 8302.L_OP_SGET_OBJECT_JUMBO: /* 0x116 */ 8303/* File: armv5te/OP_SGET_OBJECT_JUMBO.S */ 8304/* File: armv5te/OP_SGET_JUMBO.S */ 8305 /* 8306 * Jumbo 32-bit SGET handler. 8307 * 8308 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8309 * sget-char/jumbo, sget-short/jumbo 8310 */ 8311 /* exop vBBBB, field@AAAAAAAA */ 8312 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8313 FETCH(r0, 1) @ r0<- aaaa (lo) 8314 FETCH(r1, 2) @ r1<- AAAA (hi) 8315 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8316 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8317 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8318 cmp r0, #0 @ is resolved entry null? 8319 beq .LOP_SGET_OBJECT_JUMBO_resolve @ yes, do resolve 8320.LOP_SGET_OBJECT_JUMBO_finish: @ field ptr in r0 8321 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8322 @ no-op @ acquiring load 8323 FETCH(r2, 3) @ r2<- BBBB 8324 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8325 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8326 GET_INST_OPCODE(ip) @ extract opcode from rINST 8327 GOTO_OPCODE(ip) @ jump to next instruction 8328 8329 8330/* ------------------------------ */ 8331 .balign 64 8332.L_OP_SGET_BOOLEAN_JUMBO: /* 0x117 */ 8333/* File: armv5te/OP_SGET_BOOLEAN_JUMBO.S */ 8334/* File: armv5te/OP_SGET_JUMBO.S */ 8335 /* 8336 * Jumbo 32-bit SGET handler. 8337 * 8338 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8339 * sget-char/jumbo, sget-short/jumbo 8340 */ 8341 /* exop vBBBB, field@AAAAAAAA */ 8342 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8343 FETCH(r0, 1) @ r0<- aaaa (lo) 8344 FETCH(r1, 2) @ r1<- AAAA (hi) 8345 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8346 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8347 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8348 cmp r0, #0 @ is resolved entry null? 8349 beq .LOP_SGET_BOOLEAN_JUMBO_resolve @ yes, do resolve 8350.LOP_SGET_BOOLEAN_JUMBO_finish: @ field ptr in r0 8351 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8352 @ no-op @ acquiring load 8353 FETCH(r2, 3) @ r2<- BBBB 8354 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8355 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8356 GET_INST_OPCODE(ip) @ extract opcode from rINST 8357 GOTO_OPCODE(ip) @ jump to next instruction 8358 8359 8360/* ------------------------------ */ 8361 .balign 64 8362.L_OP_SGET_BYTE_JUMBO: /* 0x118 */ 8363/* File: armv5te/OP_SGET_BYTE_JUMBO.S */ 8364/* File: armv5te/OP_SGET_JUMBO.S */ 8365 /* 8366 * Jumbo 32-bit SGET handler. 8367 * 8368 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8369 * sget-char/jumbo, sget-short/jumbo 8370 */ 8371 /* exop vBBBB, field@AAAAAAAA */ 8372 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8373 FETCH(r0, 1) @ r0<- aaaa (lo) 8374 FETCH(r1, 2) @ r1<- AAAA (hi) 8375 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8376 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8377 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8378 cmp r0, #0 @ is resolved entry null? 8379 beq .LOP_SGET_BYTE_JUMBO_resolve @ yes, do resolve 8380.LOP_SGET_BYTE_JUMBO_finish: @ field ptr in r0 8381 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8382 @ no-op @ acquiring load 8383 FETCH(r2, 3) @ r2<- BBBB 8384 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8385 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8386 GET_INST_OPCODE(ip) @ extract opcode from rINST 8387 GOTO_OPCODE(ip) @ jump to next instruction 8388 8389 8390/* ------------------------------ */ 8391 .balign 64 8392.L_OP_SGET_CHAR_JUMBO: /* 0x119 */ 8393/* File: armv5te/OP_SGET_CHAR_JUMBO.S */ 8394/* File: armv5te/OP_SGET_JUMBO.S */ 8395 /* 8396 * Jumbo 32-bit SGET handler. 8397 * 8398 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8399 * sget-char/jumbo, sget-short/jumbo 8400 */ 8401 /* exop vBBBB, field@AAAAAAAA */ 8402 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8403 FETCH(r0, 1) @ r0<- aaaa (lo) 8404 FETCH(r1, 2) @ r1<- AAAA (hi) 8405 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8406 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8407 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8408 cmp r0, #0 @ is resolved entry null? 8409 beq .LOP_SGET_CHAR_JUMBO_resolve @ yes, do resolve 8410.LOP_SGET_CHAR_JUMBO_finish: @ field ptr in r0 8411 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8412 @ no-op @ acquiring load 8413 FETCH(r2, 3) @ r2<- BBBB 8414 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8415 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8416 GET_INST_OPCODE(ip) @ extract opcode from rINST 8417 GOTO_OPCODE(ip) @ jump to next instruction 8418 8419 8420/* ------------------------------ */ 8421 .balign 64 8422.L_OP_SGET_SHORT_JUMBO: /* 0x11a */ 8423/* File: armv5te/OP_SGET_SHORT_JUMBO.S */ 8424/* File: armv5te/OP_SGET_JUMBO.S */ 8425 /* 8426 * Jumbo 32-bit SGET handler. 8427 * 8428 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8429 * sget-char/jumbo, sget-short/jumbo 8430 */ 8431 /* exop vBBBB, field@AAAAAAAA */ 8432 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8433 FETCH(r0, 1) @ r0<- aaaa (lo) 8434 FETCH(r1, 2) @ r1<- AAAA (hi) 8435 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8436 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8437 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8438 cmp r0, #0 @ is resolved entry null? 8439 beq .LOP_SGET_SHORT_JUMBO_resolve @ yes, do resolve 8440.LOP_SGET_SHORT_JUMBO_finish: @ field ptr in r0 8441 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8442 @ no-op @ acquiring load 8443 FETCH(r2, 3) @ r2<- BBBB 8444 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8445 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8446 GET_INST_OPCODE(ip) @ extract opcode from rINST 8447 GOTO_OPCODE(ip) @ jump to next instruction 8448 8449 8450/* ------------------------------ */ 8451 .balign 64 8452.L_OP_SPUT_JUMBO: /* 0x11b */ 8453/* File: armv5te/OP_SPUT_JUMBO.S */ 8454 /* 8455 * Jumbo 32-bit SPUT handler. 8456 * 8457 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8458 * sput-short/jumbo 8459 */ 8460 /* exop vBBBB, field@AAAAAAAA */ 8461 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8462 FETCH(r0, 1) @ r0<- aaaa (lo) 8463 FETCH(r1, 2) @ r1<- AAAA (hi) 8464 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8465 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8466 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8467 cmp r0, #0 @ is resolved entry null? 8468 beq .LOP_SPUT_JUMBO_resolve @ yes, do resolve 8469.LOP_SPUT_JUMBO_finish: @ field ptr in r0 8470 FETCH(r2, 3) @ r2<- BBBB 8471 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8472 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8473 GET_INST_OPCODE(ip) @ extract opcode from rINST 8474 @ no-op @ releasing store 8475 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8476 GOTO_OPCODE(ip) @ jump to next instruction 8477 8478/* ------------------------------ */ 8479 .balign 64 8480.L_OP_SPUT_WIDE_JUMBO: /* 0x11c */ 8481/* File: armv5te/OP_SPUT_WIDE_JUMBO.S */ 8482 /* 8483 * Jumbo 64-bit SPUT handler. 8484 */ 8485 /* sput-wide/jumbo vBBBB, field@AAAAAAAA */ 8486 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- DvmDex 8487 FETCH(r1, 1) @ r1<- aaaa (lo) 8488 FETCH(r2, 2) @ r2<- AAAA (hi) 8489 ldr r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields 8490 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8491 FETCH(r9, 3) @ r9<- BBBB 8492 ldr r2, [r0, r1, lsl #2] @ r2<- resolved StaticField ptr 8493 add r9, rFP, r9, lsl #2 @ r9<- &fp[BBBB] 8494 cmp r2, #0 @ is resolved entry null? 8495 beq .LOP_SPUT_WIDE_JUMBO_resolve @ yes, do resolve 8496.LOP_SPUT_WIDE_JUMBO_finish: @ field ptr in r2, BBBB in r9 8497 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8498 ldmia r9, {r0-r1} @ r0/r1<- vBBBB/vBBBB+1 8499 GET_INST_OPCODE(r10) @ extract opcode from rINST 8500 strd r0, [r2, #offStaticField_value] @ field<- vBBBB/vBBBB+1 8501 GOTO_OPCODE(r10) @ jump to next instruction 8502 8503/* ------------------------------ */ 8504 .balign 64 8505.L_OP_SPUT_OBJECT_JUMBO: /* 0x11d */ 8506/* File: armv5te/OP_SPUT_OBJECT_JUMBO.S */ 8507 /* 8508 * Jumbo 32-bit SPUT handler for objects 8509 */ 8510 /* sput-object/jumbo vBBBB, field@AAAAAAAA */ 8511 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8512 FETCH(r0, 1) @ r0<- aaaa (lo) 8513 FETCH(r1, 2) @ r1<- AAAA (hi) 8514 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8515 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8516 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8517 cmp r0, #0 @ is resolved entry null? 8518 bne .LOP_SPUT_OBJECT_JUMBO_finish @ no, continue 8519 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 8520 EXPORT_PC() @ resolve() could throw, so export now 8521 ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz 8522 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8523 cmp r0, #0 @ success? 8524 bne .LOP_SPUT_OBJECT_JUMBO_finish @ yes, finish 8525 b common_exceptionThrown @ no, handle exception 8526 8527/* ------------------------------ */ 8528 .balign 64 8529.L_OP_SPUT_BOOLEAN_JUMBO: /* 0x11e */ 8530/* File: armv5te/OP_SPUT_BOOLEAN_JUMBO.S */ 8531/* File: armv5te/OP_SPUT_JUMBO.S */ 8532 /* 8533 * Jumbo 32-bit SPUT handler. 8534 * 8535 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8536 * sput-short/jumbo 8537 */ 8538 /* exop vBBBB, field@AAAAAAAA */ 8539 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8540 FETCH(r0, 1) @ r0<- aaaa (lo) 8541 FETCH(r1, 2) @ r1<- AAAA (hi) 8542 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8543 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8544 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8545 cmp r0, #0 @ is resolved entry null? 8546 beq .LOP_SPUT_BOOLEAN_JUMBO_resolve @ yes, do resolve 8547.LOP_SPUT_BOOLEAN_JUMBO_finish: @ field ptr in r0 8548 FETCH(r2, 3) @ r2<- BBBB 8549 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8550 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8551 GET_INST_OPCODE(ip) @ extract opcode from rINST 8552 @ no-op @ releasing store 8553 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8554 GOTO_OPCODE(ip) @ jump to next instruction 8555 8556 8557/* ------------------------------ */ 8558 .balign 64 8559.L_OP_SPUT_BYTE_JUMBO: /* 0x11f */ 8560/* File: armv5te/OP_SPUT_BYTE_JUMBO.S */ 8561/* File: armv5te/OP_SPUT_JUMBO.S */ 8562 /* 8563 * Jumbo 32-bit SPUT handler. 8564 * 8565 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8566 * sput-short/jumbo 8567 */ 8568 /* exop vBBBB, field@AAAAAAAA */ 8569 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8570 FETCH(r0, 1) @ r0<- aaaa (lo) 8571 FETCH(r1, 2) @ r1<- AAAA (hi) 8572 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8573 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8574 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8575 cmp r0, #0 @ is resolved entry null? 8576 beq .LOP_SPUT_BYTE_JUMBO_resolve @ yes, do resolve 8577.LOP_SPUT_BYTE_JUMBO_finish: @ field ptr in r0 8578 FETCH(r2, 3) @ r2<- BBBB 8579 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8580 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8581 GET_INST_OPCODE(ip) @ extract opcode from rINST 8582 @ no-op @ releasing store 8583 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8584 GOTO_OPCODE(ip) @ jump to next instruction 8585 8586 8587/* ------------------------------ */ 8588 .balign 64 8589.L_OP_SPUT_CHAR_JUMBO: /* 0x120 */ 8590/* File: armv5te/OP_SPUT_CHAR_JUMBO.S */ 8591/* File: armv5te/OP_SPUT_JUMBO.S */ 8592 /* 8593 * Jumbo 32-bit SPUT handler. 8594 * 8595 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8596 * sput-short/jumbo 8597 */ 8598 /* exop vBBBB, field@AAAAAAAA */ 8599 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8600 FETCH(r0, 1) @ r0<- aaaa (lo) 8601 FETCH(r1, 2) @ r1<- AAAA (hi) 8602 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8603 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8604 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8605 cmp r0, #0 @ is resolved entry null? 8606 beq .LOP_SPUT_CHAR_JUMBO_resolve @ yes, do resolve 8607.LOP_SPUT_CHAR_JUMBO_finish: @ field ptr in r0 8608 FETCH(r2, 3) @ r2<- BBBB 8609 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8610 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8611 GET_INST_OPCODE(ip) @ extract opcode from rINST 8612 @ no-op @ releasing store 8613 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8614 GOTO_OPCODE(ip) @ jump to next instruction 8615 8616 8617/* ------------------------------ */ 8618 .balign 64 8619.L_OP_SPUT_SHORT_JUMBO: /* 0x121 */ 8620/* File: armv5te/OP_SPUT_SHORT_JUMBO.S */ 8621/* File: armv5te/OP_SPUT_JUMBO.S */ 8622 /* 8623 * Jumbo 32-bit SPUT handler. 8624 * 8625 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8626 * sput-short/jumbo 8627 */ 8628 /* exop vBBBB, field@AAAAAAAA */ 8629 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8630 FETCH(r0, 1) @ r0<- aaaa (lo) 8631 FETCH(r1, 2) @ r1<- AAAA (hi) 8632 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8633 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8634 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8635 cmp r0, #0 @ is resolved entry null? 8636 beq .LOP_SPUT_SHORT_JUMBO_resolve @ yes, do resolve 8637.LOP_SPUT_SHORT_JUMBO_finish: @ field ptr in r0 8638 FETCH(r2, 3) @ r2<- BBBB 8639 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8640 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8641 GET_INST_OPCODE(ip) @ extract opcode from rINST 8642 @ no-op @ releasing store 8643 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8644 GOTO_OPCODE(ip) @ jump to next instruction 8645 8646 8647/* ------------------------------ */ 8648 .balign 64 8649.L_OP_INVOKE_VIRTUAL_JUMBO: /* 0x122 */ 8650/* File: armv5te/OP_INVOKE_VIRTUAL_JUMBO.S */ 8651 /* 8652 * Handle a virtual method call. 8653 */ 8654 /* invoke-virtual/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8655 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 8656 FETCH(r0, 1) @ r1<- aaaa (lo) 8657 FETCH(r1, 2) @ r1<- AAAA (hi) 8658 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 8659 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8660 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 8661 cmp r0, #0 @ already resolved? 8662 EXPORT_PC() @ must export for invoke 8663 bne .LOP_INVOKE_VIRTUAL_JUMBO_continue @ yes, continue on 8664 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 8665 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 8666 mov r2, #METHOD_VIRTUAL @ resolver method type 8667 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 8668 cmp r0, #0 @ got null? 8669 bne .LOP_INVOKE_VIRTUAL_JUMBO_continue @ no, continue 8670 b common_exceptionThrown @ yes, handle exception 8671 8672/* ------------------------------ */ 8673 .balign 64 8674.L_OP_INVOKE_SUPER_JUMBO: /* 0x123 */ 8675/* File: armv5te/OP_INVOKE_SUPER_JUMBO.S */ 8676 /* 8677 * Handle a "super" method call. 8678 */ 8679 /* invoke-super/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8680 FETCH(r10, 4) @ r10<- CCCC 8681 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 8682 FETCH(r0, 1) @ r1<- aaaa (lo) 8683 FETCH(r1, 2) @ r1<- AAAA (hi) 8684 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 8685 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8686 GET_VREG(r2, r10) @ r2<- "this" ptr 8687 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 8688 cmp r2, #0 @ null "this"? 8689 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 8690 beq common_errNullObject @ null "this", throw exception 8691 cmp r0, #0 @ already resolved? 8692 ldr r9, [r9, #offMethod_clazz] @ r9<- method->clazz 8693 EXPORT_PC() @ must export for invoke 8694 bne .LOP_INVOKE_SUPER_JUMBO_continue @ resolved, continue on 8695 b .LOP_INVOKE_SUPER_JUMBO_resolve @ do resolve now 8696 8697/* ------------------------------ */ 8698 .balign 64 8699.L_OP_INVOKE_DIRECT_JUMBO: /* 0x124 */ 8700/* File: armv5te/OP_INVOKE_DIRECT_JUMBO.S */ 8701 /* 8702 * Handle a direct method call. 8703 * 8704 * (We could defer the "is 'this' pointer null" test to the common 8705 * method invocation code, and use a flag to indicate that static 8706 * calls don't count. If we do this as part of copying the arguments 8707 * out we could avoiding loading the first arg twice.) 8708 * 8709 */ 8710 /* invoke-direct/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8711 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 8712 FETCH(r0, 1) @ r1<- aaaa (lo) 8713 FETCH(r1, 2) @ r1<- AAAA (hi) 8714 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 8715 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8716 FETCH(r10, 4) @ r10<- CCCC 8717 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 8718 cmp r0, #0 @ already resolved? 8719 EXPORT_PC() @ must export for invoke 8720 GET_VREG(r2, r10) @ r2<- "this" ptr 8721 beq .LOP_INVOKE_DIRECT_JUMBO_resolve @ not resolved, do it now 8722.LOP_INVOKE_DIRECT_JUMBO_finish: 8723 cmp r2, #0 @ null "this" ref? 8724 bne common_invokeMethodJumbo @ no, continue on 8725 b common_errNullObject @ yes, throw exception 8726 8727/* ------------------------------ */ 8728 .balign 64 8729.L_OP_INVOKE_STATIC_JUMBO: /* 0x125 */ 8730/* File: armv5te/OP_INVOKE_STATIC_JUMBO.S */ 8731 /* 8732 * Handle a static method call. 8733 */ 8734 /* invoke-static/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8735 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 8736 FETCH(r0, 1) @ r1<- aaaa (lo) 8737 FETCH(r1, 2) @ r1<- AAAA (hi) 8738 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 8739 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8740 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 8741 cmp r0, #0 @ already resolved? 8742 EXPORT_PC() @ must export for invoke 8743 bne common_invokeMethodJumbo @ yes, continue on 87440: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 8745 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 8746 mov r2, #METHOD_STATIC @ resolver method type 8747 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 8748 cmp r0, #0 @ got null? 8749 bne common_invokeMethodJumbo @ no, continue 8750 b common_exceptionThrown @ yes, handle exception 8751 8752/* ------------------------------ */ 8753 .balign 64 8754.L_OP_INVOKE_INTERFACE_JUMBO: /* 0x126 */ 8755/* File: armv5te/OP_INVOKE_INTERFACE_JUMBO.S */ 8756 /* 8757 * Handle an interface method call. 8758 */ 8759 /* invoke-interface/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8760 FETCH(r2, 4) @ r2<- CCCC 8761 FETCH(r0, 1) @ r0<- aaaa (lo) 8762 FETCH(r1, 2) @ r1<- AAAA (hi) 8763 EXPORT_PC() @ must export for invoke 8764 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8765 GET_VREG(r0, r2) @ r0<- first arg ("this") 8766 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- methodClassDex 8767 cmp r0, #0 @ null obj? 8768 ldr r2, [rGLUE, #offGlue_method] @ r2<- method 8769 beq common_errNullObject @ yes, fail 8770 ldr r0, [r0, #offObject_clazz] @ r0<- thisPtr->clazz 8771 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 8772 cmp r0, #0 @ failed? 8773 beq common_exceptionThrown @ yes, handle exception 8774 b common_invokeMethodJumbo @ jump to common handler 8775 8776/* ------------------------------ */ 8777 .balign 64 8778.L_OP_UNUSED_27FF: /* 0x127 */ 8779/* File: armv5te/OP_UNUSED_27FF.S */ 8780/* File: armv5te/unused.S */ 8781 bl common_abort 8782 8783 8784/* ------------------------------ */ 8785 .balign 64 8786.L_OP_UNUSED_28FF: /* 0x128 */ 8787/* File: armv5te/OP_UNUSED_28FF.S */ 8788/* File: armv5te/unused.S */ 8789 bl common_abort 8790 8791 8792/* ------------------------------ */ 8793 .balign 64 8794.L_OP_UNUSED_29FF: /* 0x129 */ 8795/* File: armv5te/OP_UNUSED_29FF.S */ 8796/* File: armv5te/unused.S */ 8797 bl common_abort 8798 8799 8800/* ------------------------------ */ 8801 .balign 64 8802.L_OP_UNUSED_2AFF: /* 0x12a */ 8803/* File: armv5te/OP_UNUSED_2AFF.S */ 8804/* File: armv5te/unused.S */ 8805 bl common_abort 8806 8807 8808/* ------------------------------ */ 8809 .balign 64 8810.L_OP_UNUSED_2BFF: /* 0x12b */ 8811/* File: armv5te/OP_UNUSED_2BFF.S */ 8812/* File: armv5te/unused.S */ 8813 bl common_abort 8814 8815 8816/* ------------------------------ */ 8817 .balign 64 8818.L_OP_UNUSED_2CFF: /* 0x12c */ 8819/* File: armv5te/OP_UNUSED_2CFF.S */ 8820/* File: armv5te/unused.S */ 8821 bl common_abort 8822 8823 8824/* ------------------------------ */ 8825 .balign 64 8826.L_OP_UNUSED_2DFF: /* 0x12d */ 8827/* File: armv5te/OP_UNUSED_2DFF.S */ 8828/* File: armv5te/unused.S */ 8829 bl common_abort 8830 8831 8832/* ------------------------------ */ 8833 .balign 64 8834.L_OP_UNUSED_2EFF: /* 0x12e */ 8835/* File: armv5te/OP_UNUSED_2EFF.S */ 8836/* File: armv5te/unused.S */ 8837 bl common_abort 8838 8839 8840/* ------------------------------ */ 8841 .balign 64 8842.L_OP_UNUSED_2FFF: /* 0x12f */ 8843/* File: armv5te/OP_UNUSED_2FFF.S */ 8844/* File: armv5te/unused.S */ 8845 bl common_abort 8846 8847 8848/* ------------------------------ */ 8849 .balign 64 8850.L_OP_UNUSED_30FF: /* 0x130 */ 8851/* File: armv5te/OP_UNUSED_30FF.S */ 8852/* File: armv5te/unused.S */ 8853 bl common_abort 8854 8855 8856/* ------------------------------ */ 8857 .balign 64 8858.L_OP_UNUSED_31FF: /* 0x131 */ 8859/* File: armv5te/OP_UNUSED_31FF.S */ 8860/* File: armv5te/unused.S */ 8861 bl common_abort 8862 8863 8864/* ------------------------------ */ 8865 .balign 64 8866.L_OP_UNUSED_32FF: /* 0x132 */ 8867/* File: armv5te/OP_UNUSED_32FF.S */ 8868/* File: armv5te/unused.S */ 8869 bl common_abort 8870 8871 8872/* ------------------------------ */ 8873 .balign 64 8874.L_OP_UNUSED_33FF: /* 0x133 */ 8875/* File: armv5te/OP_UNUSED_33FF.S */ 8876/* File: armv5te/unused.S */ 8877 bl common_abort 8878 8879 8880/* ------------------------------ */ 8881 .balign 64 8882.L_OP_UNUSED_34FF: /* 0x134 */ 8883/* File: armv5te/OP_UNUSED_34FF.S */ 8884/* File: armv5te/unused.S */ 8885 bl common_abort 8886 8887 8888/* ------------------------------ */ 8889 .balign 64 8890.L_OP_UNUSED_35FF: /* 0x135 */ 8891/* File: armv5te/OP_UNUSED_35FF.S */ 8892/* File: armv5te/unused.S */ 8893 bl common_abort 8894 8895 8896/* ------------------------------ */ 8897 .balign 64 8898.L_OP_UNUSED_36FF: /* 0x136 */ 8899/* File: armv5te/OP_UNUSED_36FF.S */ 8900/* File: armv5te/unused.S */ 8901 bl common_abort 8902 8903 8904/* ------------------------------ */ 8905 .balign 64 8906.L_OP_UNUSED_37FF: /* 0x137 */ 8907/* File: armv5te/OP_UNUSED_37FF.S */ 8908/* File: armv5te/unused.S */ 8909 bl common_abort 8910 8911 8912/* ------------------------------ */ 8913 .balign 64 8914.L_OP_UNUSED_38FF: /* 0x138 */ 8915/* File: armv5te/OP_UNUSED_38FF.S */ 8916/* File: armv5te/unused.S */ 8917 bl common_abort 8918 8919 8920/* ------------------------------ */ 8921 .balign 64 8922.L_OP_UNUSED_39FF: /* 0x139 */ 8923/* File: armv5te/OP_UNUSED_39FF.S */ 8924/* File: armv5te/unused.S */ 8925 bl common_abort 8926 8927 8928/* ------------------------------ */ 8929 .balign 64 8930.L_OP_UNUSED_3AFF: /* 0x13a */ 8931/* File: armv5te/OP_UNUSED_3AFF.S */ 8932/* File: armv5te/unused.S */ 8933 bl common_abort 8934 8935 8936/* ------------------------------ */ 8937 .balign 64 8938.L_OP_UNUSED_3BFF: /* 0x13b */ 8939/* File: armv5te/OP_UNUSED_3BFF.S */ 8940/* File: armv5te/unused.S */ 8941 bl common_abort 8942 8943 8944/* ------------------------------ */ 8945 .balign 64 8946.L_OP_UNUSED_3CFF: /* 0x13c */ 8947/* File: armv5te/OP_UNUSED_3CFF.S */ 8948/* File: armv5te/unused.S */ 8949 bl common_abort 8950 8951 8952/* ------------------------------ */ 8953 .balign 64 8954.L_OP_UNUSED_3DFF: /* 0x13d */ 8955/* File: armv5te/OP_UNUSED_3DFF.S */ 8956/* File: armv5te/unused.S */ 8957 bl common_abort 8958 8959 8960/* ------------------------------ */ 8961 .balign 64 8962.L_OP_UNUSED_3EFF: /* 0x13e */ 8963/* File: armv5te/OP_UNUSED_3EFF.S */ 8964/* File: armv5te/unused.S */ 8965 bl common_abort 8966 8967 8968/* ------------------------------ */ 8969 .balign 64 8970.L_OP_UNUSED_3FFF: /* 0x13f */ 8971/* File: armv5te/OP_UNUSED_3FFF.S */ 8972/* File: armv5te/unused.S */ 8973 bl common_abort 8974 8975 8976/* ------------------------------ */ 8977 .balign 64 8978.L_OP_UNUSED_40FF: /* 0x140 */ 8979/* File: armv5te/OP_UNUSED_40FF.S */ 8980/* File: armv5te/unused.S */ 8981 bl common_abort 8982 8983 8984/* ------------------------------ */ 8985 .balign 64 8986.L_OP_UNUSED_41FF: /* 0x141 */ 8987/* File: armv5te/OP_UNUSED_41FF.S */ 8988/* File: armv5te/unused.S */ 8989 bl common_abort 8990 8991 8992/* ------------------------------ */ 8993 .balign 64 8994.L_OP_UNUSED_42FF: /* 0x142 */ 8995/* File: armv5te/OP_UNUSED_42FF.S */ 8996/* File: armv5te/unused.S */ 8997 bl common_abort 8998 8999 9000/* ------------------------------ */ 9001 .balign 64 9002.L_OP_UNUSED_43FF: /* 0x143 */ 9003/* File: armv5te/OP_UNUSED_43FF.S */ 9004/* File: armv5te/unused.S */ 9005 bl common_abort 9006 9007 9008/* ------------------------------ */ 9009 .balign 64 9010.L_OP_UNUSED_44FF: /* 0x144 */ 9011/* File: armv5te/OP_UNUSED_44FF.S */ 9012/* File: armv5te/unused.S */ 9013 bl common_abort 9014 9015 9016/* ------------------------------ */ 9017 .balign 64 9018.L_OP_UNUSED_45FF: /* 0x145 */ 9019/* File: armv5te/OP_UNUSED_45FF.S */ 9020/* File: armv5te/unused.S */ 9021 bl common_abort 9022 9023 9024/* ------------------------------ */ 9025 .balign 64 9026.L_OP_UNUSED_46FF: /* 0x146 */ 9027/* File: armv5te/OP_UNUSED_46FF.S */ 9028/* File: armv5te/unused.S */ 9029 bl common_abort 9030 9031 9032/* ------------------------------ */ 9033 .balign 64 9034.L_OP_UNUSED_47FF: /* 0x147 */ 9035/* File: armv5te/OP_UNUSED_47FF.S */ 9036/* File: armv5te/unused.S */ 9037 bl common_abort 9038 9039 9040/* ------------------------------ */ 9041 .balign 64 9042.L_OP_UNUSED_48FF: /* 0x148 */ 9043/* File: armv5te/OP_UNUSED_48FF.S */ 9044/* File: armv5te/unused.S */ 9045 bl common_abort 9046 9047 9048/* ------------------------------ */ 9049 .balign 64 9050.L_OP_UNUSED_49FF: /* 0x149 */ 9051/* File: armv5te/OP_UNUSED_49FF.S */ 9052/* File: armv5te/unused.S */ 9053 bl common_abort 9054 9055 9056/* ------------------------------ */ 9057 .balign 64 9058.L_OP_UNUSED_4AFF: /* 0x14a */ 9059/* File: armv5te/OP_UNUSED_4AFF.S */ 9060/* File: armv5te/unused.S */ 9061 bl common_abort 9062 9063 9064/* ------------------------------ */ 9065 .balign 64 9066.L_OP_UNUSED_4BFF: /* 0x14b */ 9067/* File: armv5te/OP_UNUSED_4BFF.S */ 9068/* File: armv5te/unused.S */ 9069 bl common_abort 9070 9071 9072/* ------------------------------ */ 9073 .balign 64 9074.L_OP_UNUSED_4CFF: /* 0x14c */ 9075/* File: armv5te/OP_UNUSED_4CFF.S */ 9076/* File: armv5te/unused.S */ 9077 bl common_abort 9078 9079 9080/* ------------------------------ */ 9081 .balign 64 9082.L_OP_UNUSED_4DFF: /* 0x14d */ 9083/* File: armv5te/OP_UNUSED_4DFF.S */ 9084/* File: armv5te/unused.S */ 9085 bl common_abort 9086 9087 9088/* ------------------------------ */ 9089 .balign 64 9090.L_OP_UNUSED_4EFF: /* 0x14e */ 9091/* File: armv5te/OP_UNUSED_4EFF.S */ 9092/* File: armv5te/unused.S */ 9093 bl common_abort 9094 9095 9096/* ------------------------------ */ 9097 .balign 64 9098.L_OP_UNUSED_4FFF: /* 0x14f */ 9099/* File: armv5te/OP_UNUSED_4FFF.S */ 9100/* File: armv5te/unused.S */ 9101 bl common_abort 9102 9103 9104/* ------------------------------ */ 9105 .balign 64 9106.L_OP_UNUSED_50FF: /* 0x150 */ 9107/* File: armv5te/OP_UNUSED_50FF.S */ 9108/* File: armv5te/unused.S */ 9109 bl common_abort 9110 9111 9112/* ------------------------------ */ 9113 .balign 64 9114.L_OP_UNUSED_51FF: /* 0x151 */ 9115/* File: armv5te/OP_UNUSED_51FF.S */ 9116/* File: armv5te/unused.S */ 9117 bl common_abort 9118 9119 9120/* ------------------------------ */ 9121 .balign 64 9122.L_OP_UNUSED_52FF: /* 0x152 */ 9123/* File: armv5te/OP_UNUSED_52FF.S */ 9124/* File: armv5te/unused.S */ 9125 bl common_abort 9126 9127 9128/* ------------------------------ */ 9129 .balign 64 9130.L_OP_UNUSED_53FF: /* 0x153 */ 9131/* File: armv5te/OP_UNUSED_53FF.S */ 9132/* File: armv5te/unused.S */ 9133 bl common_abort 9134 9135 9136/* ------------------------------ */ 9137 .balign 64 9138.L_OP_UNUSED_54FF: /* 0x154 */ 9139/* File: armv5te/OP_UNUSED_54FF.S */ 9140/* File: armv5te/unused.S */ 9141 bl common_abort 9142 9143 9144/* ------------------------------ */ 9145 .balign 64 9146.L_OP_UNUSED_55FF: /* 0x155 */ 9147/* File: armv5te/OP_UNUSED_55FF.S */ 9148/* File: armv5te/unused.S */ 9149 bl common_abort 9150 9151 9152/* ------------------------------ */ 9153 .balign 64 9154.L_OP_UNUSED_56FF: /* 0x156 */ 9155/* File: armv5te/OP_UNUSED_56FF.S */ 9156/* File: armv5te/unused.S */ 9157 bl common_abort 9158 9159 9160/* ------------------------------ */ 9161 .balign 64 9162.L_OP_UNUSED_57FF: /* 0x157 */ 9163/* File: armv5te/OP_UNUSED_57FF.S */ 9164/* File: armv5te/unused.S */ 9165 bl common_abort 9166 9167 9168/* ------------------------------ */ 9169 .balign 64 9170.L_OP_UNUSED_58FF: /* 0x158 */ 9171/* File: armv5te/OP_UNUSED_58FF.S */ 9172/* File: armv5te/unused.S */ 9173 bl common_abort 9174 9175 9176/* ------------------------------ */ 9177 .balign 64 9178.L_OP_UNUSED_59FF: /* 0x159 */ 9179/* File: armv5te/OP_UNUSED_59FF.S */ 9180/* File: armv5te/unused.S */ 9181 bl common_abort 9182 9183 9184/* ------------------------------ */ 9185 .balign 64 9186.L_OP_UNUSED_5AFF: /* 0x15a */ 9187/* File: armv5te/OP_UNUSED_5AFF.S */ 9188/* File: armv5te/unused.S */ 9189 bl common_abort 9190 9191 9192/* ------------------------------ */ 9193 .balign 64 9194.L_OP_UNUSED_5BFF: /* 0x15b */ 9195/* File: armv5te/OP_UNUSED_5BFF.S */ 9196/* File: armv5te/unused.S */ 9197 bl common_abort 9198 9199 9200/* ------------------------------ */ 9201 .balign 64 9202.L_OP_UNUSED_5CFF: /* 0x15c */ 9203/* File: armv5te/OP_UNUSED_5CFF.S */ 9204/* File: armv5te/unused.S */ 9205 bl common_abort 9206 9207 9208/* ------------------------------ */ 9209 .balign 64 9210.L_OP_UNUSED_5DFF: /* 0x15d */ 9211/* File: armv5te/OP_UNUSED_5DFF.S */ 9212/* File: armv5te/unused.S */ 9213 bl common_abort 9214 9215 9216/* ------------------------------ */ 9217 .balign 64 9218.L_OP_UNUSED_5EFF: /* 0x15e */ 9219/* File: armv5te/OP_UNUSED_5EFF.S */ 9220/* File: armv5te/unused.S */ 9221 bl common_abort 9222 9223 9224/* ------------------------------ */ 9225 .balign 64 9226.L_OP_UNUSED_5FFF: /* 0x15f */ 9227/* File: armv5te/OP_UNUSED_5FFF.S */ 9228/* File: armv5te/unused.S */ 9229 bl common_abort 9230 9231 9232/* ------------------------------ */ 9233 .balign 64 9234.L_OP_UNUSED_60FF: /* 0x160 */ 9235/* File: armv5te/OP_UNUSED_60FF.S */ 9236/* File: armv5te/unused.S */ 9237 bl common_abort 9238 9239 9240/* ------------------------------ */ 9241 .balign 64 9242.L_OP_UNUSED_61FF: /* 0x161 */ 9243/* File: armv5te/OP_UNUSED_61FF.S */ 9244/* File: armv5te/unused.S */ 9245 bl common_abort 9246 9247 9248/* ------------------------------ */ 9249 .balign 64 9250.L_OP_UNUSED_62FF: /* 0x162 */ 9251/* File: armv5te/OP_UNUSED_62FF.S */ 9252/* File: armv5te/unused.S */ 9253 bl common_abort 9254 9255 9256/* ------------------------------ */ 9257 .balign 64 9258.L_OP_UNUSED_63FF: /* 0x163 */ 9259/* File: armv5te/OP_UNUSED_63FF.S */ 9260/* File: armv5te/unused.S */ 9261 bl common_abort 9262 9263 9264/* ------------------------------ */ 9265 .balign 64 9266.L_OP_UNUSED_64FF: /* 0x164 */ 9267/* File: armv5te/OP_UNUSED_64FF.S */ 9268/* File: armv5te/unused.S */ 9269 bl common_abort 9270 9271 9272/* ------------------------------ */ 9273 .balign 64 9274.L_OP_UNUSED_65FF: /* 0x165 */ 9275/* File: armv5te/OP_UNUSED_65FF.S */ 9276/* File: armv5te/unused.S */ 9277 bl common_abort 9278 9279 9280/* ------------------------------ */ 9281 .balign 64 9282.L_OP_UNUSED_66FF: /* 0x166 */ 9283/* File: armv5te/OP_UNUSED_66FF.S */ 9284/* File: armv5te/unused.S */ 9285 bl common_abort 9286 9287 9288/* ------------------------------ */ 9289 .balign 64 9290.L_OP_UNUSED_67FF: /* 0x167 */ 9291/* File: armv5te/OP_UNUSED_67FF.S */ 9292/* File: armv5te/unused.S */ 9293 bl common_abort 9294 9295 9296/* ------------------------------ */ 9297 .balign 64 9298.L_OP_UNUSED_68FF: /* 0x168 */ 9299/* File: armv5te/OP_UNUSED_68FF.S */ 9300/* File: armv5te/unused.S */ 9301 bl common_abort 9302 9303 9304/* ------------------------------ */ 9305 .balign 64 9306.L_OP_UNUSED_69FF: /* 0x169 */ 9307/* File: armv5te/OP_UNUSED_69FF.S */ 9308/* File: armv5te/unused.S */ 9309 bl common_abort 9310 9311 9312/* ------------------------------ */ 9313 .balign 64 9314.L_OP_UNUSED_6AFF: /* 0x16a */ 9315/* File: armv5te/OP_UNUSED_6AFF.S */ 9316/* File: armv5te/unused.S */ 9317 bl common_abort 9318 9319 9320/* ------------------------------ */ 9321 .balign 64 9322.L_OP_UNUSED_6BFF: /* 0x16b */ 9323/* File: armv5te/OP_UNUSED_6BFF.S */ 9324/* File: armv5te/unused.S */ 9325 bl common_abort 9326 9327 9328/* ------------------------------ */ 9329 .balign 64 9330.L_OP_UNUSED_6CFF: /* 0x16c */ 9331/* File: armv5te/OP_UNUSED_6CFF.S */ 9332/* File: armv5te/unused.S */ 9333 bl common_abort 9334 9335 9336/* ------------------------------ */ 9337 .balign 64 9338.L_OP_UNUSED_6DFF: /* 0x16d */ 9339/* File: armv5te/OP_UNUSED_6DFF.S */ 9340/* File: armv5te/unused.S */ 9341 bl common_abort 9342 9343 9344/* ------------------------------ */ 9345 .balign 64 9346.L_OP_UNUSED_6EFF: /* 0x16e */ 9347/* File: armv5te/OP_UNUSED_6EFF.S */ 9348/* File: armv5te/unused.S */ 9349 bl common_abort 9350 9351 9352/* ------------------------------ */ 9353 .balign 64 9354.L_OP_UNUSED_6FFF: /* 0x16f */ 9355/* File: armv5te/OP_UNUSED_6FFF.S */ 9356/* File: armv5te/unused.S */ 9357 bl common_abort 9358 9359 9360/* ------------------------------ */ 9361 .balign 64 9362.L_OP_UNUSED_70FF: /* 0x170 */ 9363/* File: armv5te/OP_UNUSED_70FF.S */ 9364/* File: armv5te/unused.S */ 9365 bl common_abort 9366 9367 9368/* ------------------------------ */ 9369 .balign 64 9370.L_OP_UNUSED_71FF: /* 0x171 */ 9371/* File: armv5te/OP_UNUSED_71FF.S */ 9372/* File: armv5te/unused.S */ 9373 bl common_abort 9374 9375 9376/* ------------------------------ */ 9377 .balign 64 9378.L_OP_UNUSED_72FF: /* 0x172 */ 9379/* File: armv5te/OP_UNUSED_72FF.S */ 9380/* File: armv5te/unused.S */ 9381 bl common_abort 9382 9383 9384/* ------------------------------ */ 9385 .balign 64 9386.L_OP_UNUSED_73FF: /* 0x173 */ 9387/* File: armv5te/OP_UNUSED_73FF.S */ 9388/* File: armv5te/unused.S */ 9389 bl common_abort 9390 9391 9392/* ------------------------------ */ 9393 .balign 64 9394.L_OP_UNUSED_74FF: /* 0x174 */ 9395/* File: armv5te/OP_UNUSED_74FF.S */ 9396/* File: armv5te/unused.S */ 9397 bl common_abort 9398 9399 9400/* ------------------------------ */ 9401 .balign 64 9402.L_OP_UNUSED_75FF: /* 0x175 */ 9403/* File: armv5te/OP_UNUSED_75FF.S */ 9404/* File: armv5te/unused.S */ 9405 bl common_abort 9406 9407 9408/* ------------------------------ */ 9409 .balign 64 9410.L_OP_UNUSED_76FF: /* 0x176 */ 9411/* File: armv5te/OP_UNUSED_76FF.S */ 9412/* File: armv5te/unused.S */ 9413 bl common_abort 9414 9415 9416/* ------------------------------ */ 9417 .balign 64 9418.L_OP_UNUSED_77FF: /* 0x177 */ 9419/* File: armv5te/OP_UNUSED_77FF.S */ 9420/* File: armv5te/unused.S */ 9421 bl common_abort 9422 9423 9424/* ------------------------------ */ 9425 .balign 64 9426.L_OP_UNUSED_78FF: /* 0x178 */ 9427/* File: armv5te/OP_UNUSED_78FF.S */ 9428/* File: armv5te/unused.S */ 9429 bl common_abort 9430 9431 9432/* ------------------------------ */ 9433 .balign 64 9434.L_OP_UNUSED_79FF: /* 0x179 */ 9435/* File: armv5te/OP_UNUSED_79FF.S */ 9436/* File: armv5te/unused.S */ 9437 bl common_abort 9438 9439 9440/* ------------------------------ */ 9441 .balign 64 9442.L_OP_UNUSED_7AFF: /* 0x17a */ 9443/* File: armv5te/OP_UNUSED_7AFF.S */ 9444/* File: armv5te/unused.S */ 9445 bl common_abort 9446 9447 9448/* ------------------------------ */ 9449 .balign 64 9450.L_OP_UNUSED_7BFF: /* 0x17b */ 9451/* File: armv5te/OP_UNUSED_7BFF.S */ 9452/* File: armv5te/unused.S */ 9453 bl common_abort 9454 9455 9456/* ------------------------------ */ 9457 .balign 64 9458.L_OP_UNUSED_7CFF: /* 0x17c */ 9459/* File: armv5te/OP_UNUSED_7CFF.S */ 9460/* File: armv5te/unused.S */ 9461 bl common_abort 9462 9463 9464/* ------------------------------ */ 9465 .balign 64 9466.L_OP_UNUSED_7DFF: /* 0x17d */ 9467/* File: armv5te/OP_UNUSED_7DFF.S */ 9468/* File: armv5te/unused.S */ 9469 bl common_abort 9470 9471 9472/* ------------------------------ */ 9473 .balign 64 9474.L_OP_UNUSED_7EFF: /* 0x17e */ 9475/* File: armv5te/OP_UNUSED_7EFF.S */ 9476/* File: armv5te/unused.S */ 9477 bl common_abort 9478 9479 9480/* ------------------------------ */ 9481 .balign 64 9482.L_OP_UNUSED_7FFF: /* 0x17f */ 9483/* File: armv5te/OP_UNUSED_7FFF.S */ 9484/* File: armv5te/unused.S */ 9485 bl common_abort 9486 9487 9488/* ------------------------------ */ 9489 .balign 64 9490.L_OP_UNUSED_80FF: /* 0x180 */ 9491/* File: armv5te/OP_UNUSED_80FF.S */ 9492/* File: armv5te/unused.S */ 9493 bl common_abort 9494 9495 9496/* ------------------------------ */ 9497 .balign 64 9498.L_OP_UNUSED_81FF: /* 0x181 */ 9499/* File: armv5te/OP_UNUSED_81FF.S */ 9500/* File: armv5te/unused.S */ 9501 bl common_abort 9502 9503 9504/* ------------------------------ */ 9505 .balign 64 9506.L_OP_UNUSED_82FF: /* 0x182 */ 9507/* File: armv5te/OP_UNUSED_82FF.S */ 9508/* File: armv5te/unused.S */ 9509 bl common_abort 9510 9511 9512/* ------------------------------ */ 9513 .balign 64 9514.L_OP_UNUSED_83FF: /* 0x183 */ 9515/* File: armv5te/OP_UNUSED_83FF.S */ 9516/* File: armv5te/unused.S */ 9517 bl common_abort 9518 9519 9520/* ------------------------------ */ 9521 .balign 64 9522.L_OP_UNUSED_84FF: /* 0x184 */ 9523/* File: armv5te/OP_UNUSED_84FF.S */ 9524/* File: armv5te/unused.S */ 9525 bl common_abort 9526 9527 9528/* ------------------------------ */ 9529 .balign 64 9530.L_OP_UNUSED_85FF: /* 0x185 */ 9531/* File: armv5te/OP_UNUSED_85FF.S */ 9532/* File: armv5te/unused.S */ 9533 bl common_abort 9534 9535 9536/* ------------------------------ */ 9537 .balign 64 9538.L_OP_UNUSED_86FF: /* 0x186 */ 9539/* File: armv5te/OP_UNUSED_86FF.S */ 9540/* File: armv5te/unused.S */ 9541 bl common_abort 9542 9543 9544/* ------------------------------ */ 9545 .balign 64 9546.L_OP_UNUSED_87FF: /* 0x187 */ 9547/* File: armv5te/OP_UNUSED_87FF.S */ 9548/* File: armv5te/unused.S */ 9549 bl common_abort 9550 9551 9552/* ------------------------------ */ 9553 .balign 64 9554.L_OP_UNUSED_88FF: /* 0x188 */ 9555/* File: armv5te/OP_UNUSED_88FF.S */ 9556/* File: armv5te/unused.S */ 9557 bl common_abort 9558 9559 9560/* ------------------------------ */ 9561 .balign 64 9562.L_OP_UNUSED_89FF: /* 0x189 */ 9563/* File: armv5te/OP_UNUSED_89FF.S */ 9564/* File: armv5te/unused.S */ 9565 bl common_abort 9566 9567 9568/* ------------------------------ */ 9569 .balign 64 9570.L_OP_UNUSED_8AFF: /* 0x18a */ 9571/* File: armv5te/OP_UNUSED_8AFF.S */ 9572/* File: armv5te/unused.S */ 9573 bl common_abort 9574 9575 9576/* ------------------------------ */ 9577 .balign 64 9578.L_OP_UNUSED_8BFF: /* 0x18b */ 9579/* File: armv5te/OP_UNUSED_8BFF.S */ 9580/* File: armv5te/unused.S */ 9581 bl common_abort 9582 9583 9584/* ------------------------------ */ 9585 .balign 64 9586.L_OP_UNUSED_8CFF: /* 0x18c */ 9587/* File: armv5te/OP_UNUSED_8CFF.S */ 9588/* File: armv5te/unused.S */ 9589 bl common_abort 9590 9591 9592/* ------------------------------ */ 9593 .balign 64 9594.L_OP_UNUSED_8DFF: /* 0x18d */ 9595/* File: armv5te/OP_UNUSED_8DFF.S */ 9596/* File: armv5te/unused.S */ 9597 bl common_abort 9598 9599 9600/* ------------------------------ */ 9601 .balign 64 9602.L_OP_UNUSED_8EFF: /* 0x18e */ 9603/* File: armv5te/OP_UNUSED_8EFF.S */ 9604/* File: armv5te/unused.S */ 9605 bl common_abort 9606 9607 9608/* ------------------------------ */ 9609 .balign 64 9610.L_OP_UNUSED_8FFF: /* 0x18f */ 9611/* File: armv5te/OP_UNUSED_8FFF.S */ 9612/* File: armv5te/unused.S */ 9613 bl common_abort 9614 9615 9616/* ------------------------------ */ 9617 .balign 64 9618.L_OP_UNUSED_90FF: /* 0x190 */ 9619/* File: armv5te/OP_UNUSED_90FF.S */ 9620/* File: armv5te/unused.S */ 9621 bl common_abort 9622 9623 9624/* ------------------------------ */ 9625 .balign 64 9626.L_OP_UNUSED_91FF: /* 0x191 */ 9627/* File: armv5te/OP_UNUSED_91FF.S */ 9628/* File: armv5te/unused.S */ 9629 bl common_abort 9630 9631 9632/* ------------------------------ */ 9633 .balign 64 9634.L_OP_UNUSED_92FF: /* 0x192 */ 9635/* File: armv5te/OP_UNUSED_92FF.S */ 9636/* File: armv5te/unused.S */ 9637 bl common_abort 9638 9639 9640/* ------------------------------ */ 9641 .balign 64 9642.L_OP_UNUSED_93FF: /* 0x193 */ 9643/* File: armv5te/OP_UNUSED_93FF.S */ 9644/* File: armv5te/unused.S */ 9645 bl common_abort 9646 9647 9648/* ------------------------------ */ 9649 .balign 64 9650.L_OP_UNUSED_94FF: /* 0x194 */ 9651/* File: armv5te/OP_UNUSED_94FF.S */ 9652/* File: armv5te/unused.S */ 9653 bl common_abort 9654 9655 9656/* ------------------------------ */ 9657 .balign 64 9658.L_OP_UNUSED_95FF: /* 0x195 */ 9659/* File: armv5te/OP_UNUSED_95FF.S */ 9660/* File: armv5te/unused.S */ 9661 bl common_abort 9662 9663 9664/* ------------------------------ */ 9665 .balign 64 9666.L_OP_UNUSED_96FF: /* 0x196 */ 9667/* File: armv5te/OP_UNUSED_96FF.S */ 9668/* File: armv5te/unused.S */ 9669 bl common_abort 9670 9671 9672/* ------------------------------ */ 9673 .balign 64 9674.L_OP_UNUSED_97FF: /* 0x197 */ 9675/* File: armv5te/OP_UNUSED_97FF.S */ 9676/* File: armv5te/unused.S */ 9677 bl common_abort 9678 9679 9680/* ------------------------------ */ 9681 .balign 64 9682.L_OP_UNUSED_98FF: /* 0x198 */ 9683/* File: armv5te/OP_UNUSED_98FF.S */ 9684/* File: armv5te/unused.S */ 9685 bl common_abort 9686 9687 9688/* ------------------------------ */ 9689 .balign 64 9690.L_OP_UNUSED_99FF: /* 0x199 */ 9691/* File: armv5te/OP_UNUSED_99FF.S */ 9692/* File: armv5te/unused.S */ 9693 bl common_abort 9694 9695 9696/* ------------------------------ */ 9697 .balign 64 9698.L_OP_UNUSED_9AFF: /* 0x19a */ 9699/* File: armv5te/OP_UNUSED_9AFF.S */ 9700/* File: armv5te/unused.S */ 9701 bl common_abort 9702 9703 9704/* ------------------------------ */ 9705 .balign 64 9706.L_OP_UNUSED_9BFF: /* 0x19b */ 9707/* File: armv5te/OP_UNUSED_9BFF.S */ 9708/* File: armv5te/unused.S */ 9709 bl common_abort 9710 9711 9712/* ------------------------------ */ 9713 .balign 64 9714.L_OP_UNUSED_9CFF: /* 0x19c */ 9715/* File: armv5te/OP_UNUSED_9CFF.S */ 9716/* File: armv5te/unused.S */ 9717 bl common_abort 9718 9719 9720/* ------------------------------ */ 9721 .balign 64 9722.L_OP_UNUSED_9DFF: /* 0x19d */ 9723/* File: armv5te/OP_UNUSED_9DFF.S */ 9724/* File: armv5te/unused.S */ 9725 bl common_abort 9726 9727 9728/* ------------------------------ */ 9729 .balign 64 9730.L_OP_UNUSED_9EFF: /* 0x19e */ 9731/* File: armv5te/OP_UNUSED_9EFF.S */ 9732/* File: armv5te/unused.S */ 9733 bl common_abort 9734 9735 9736/* ------------------------------ */ 9737 .balign 64 9738.L_OP_UNUSED_9FFF: /* 0x19f */ 9739/* File: armv5te/OP_UNUSED_9FFF.S */ 9740/* File: armv5te/unused.S */ 9741 bl common_abort 9742 9743 9744/* ------------------------------ */ 9745 .balign 64 9746.L_OP_UNUSED_A0FF: /* 0x1a0 */ 9747/* File: armv5te/OP_UNUSED_A0FF.S */ 9748/* File: armv5te/unused.S */ 9749 bl common_abort 9750 9751 9752/* ------------------------------ */ 9753 .balign 64 9754.L_OP_UNUSED_A1FF: /* 0x1a1 */ 9755/* File: armv5te/OP_UNUSED_A1FF.S */ 9756/* File: armv5te/unused.S */ 9757 bl common_abort 9758 9759 9760/* ------------------------------ */ 9761 .balign 64 9762.L_OP_UNUSED_A2FF: /* 0x1a2 */ 9763/* File: armv5te/OP_UNUSED_A2FF.S */ 9764/* File: armv5te/unused.S */ 9765 bl common_abort 9766 9767 9768/* ------------------------------ */ 9769 .balign 64 9770.L_OP_UNUSED_A3FF: /* 0x1a3 */ 9771/* File: armv5te/OP_UNUSED_A3FF.S */ 9772/* File: armv5te/unused.S */ 9773 bl common_abort 9774 9775 9776/* ------------------------------ */ 9777 .balign 64 9778.L_OP_UNUSED_A4FF: /* 0x1a4 */ 9779/* File: armv5te/OP_UNUSED_A4FF.S */ 9780/* File: armv5te/unused.S */ 9781 bl common_abort 9782 9783 9784/* ------------------------------ */ 9785 .balign 64 9786.L_OP_UNUSED_A5FF: /* 0x1a5 */ 9787/* File: armv5te/OP_UNUSED_A5FF.S */ 9788/* File: armv5te/unused.S */ 9789 bl common_abort 9790 9791 9792/* ------------------------------ */ 9793 .balign 64 9794.L_OP_UNUSED_A6FF: /* 0x1a6 */ 9795/* File: armv5te/OP_UNUSED_A6FF.S */ 9796/* File: armv5te/unused.S */ 9797 bl common_abort 9798 9799 9800/* ------------------------------ */ 9801 .balign 64 9802.L_OP_UNUSED_A7FF: /* 0x1a7 */ 9803/* File: armv5te/OP_UNUSED_A7FF.S */ 9804/* File: armv5te/unused.S */ 9805 bl common_abort 9806 9807 9808/* ------------------------------ */ 9809 .balign 64 9810.L_OP_UNUSED_A8FF: /* 0x1a8 */ 9811/* File: armv5te/OP_UNUSED_A8FF.S */ 9812/* File: armv5te/unused.S */ 9813 bl common_abort 9814 9815 9816/* ------------------------------ */ 9817 .balign 64 9818.L_OP_UNUSED_A9FF: /* 0x1a9 */ 9819/* File: armv5te/OP_UNUSED_A9FF.S */ 9820/* File: armv5te/unused.S */ 9821 bl common_abort 9822 9823 9824/* ------------------------------ */ 9825 .balign 64 9826.L_OP_UNUSED_AAFF: /* 0x1aa */ 9827/* File: armv5te/OP_UNUSED_AAFF.S */ 9828/* File: armv5te/unused.S */ 9829 bl common_abort 9830 9831 9832/* ------------------------------ */ 9833 .balign 64 9834.L_OP_UNUSED_ABFF: /* 0x1ab */ 9835/* File: armv5te/OP_UNUSED_ABFF.S */ 9836/* File: armv5te/unused.S */ 9837 bl common_abort 9838 9839 9840/* ------------------------------ */ 9841 .balign 64 9842.L_OP_UNUSED_ACFF: /* 0x1ac */ 9843/* File: armv5te/OP_UNUSED_ACFF.S */ 9844/* File: armv5te/unused.S */ 9845 bl common_abort 9846 9847 9848/* ------------------------------ */ 9849 .balign 64 9850.L_OP_UNUSED_ADFF: /* 0x1ad */ 9851/* File: armv5te/OP_UNUSED_ADFF.S */ 9852/* File: armv5te/unused.S */ 9853 bl common_abort 9854 9855 9856/* ------------------------------ */ 9857 .balign 64 9858.L_OP_UNUSED_AEFF: /* 0x1ae */ 9859/* File: armv5te/OP_UNUSED_AEFF.S */ 9860/* File: armv5te/unused.S */ 9861 bl common_abort 9862 9863 9864/* ------------------------------ */ 9865 .balign 64 9866.L_OP_UNUSED_AFFF: /* 0x1af */ 9867/* File: armv5te/OP_UNUSED_AFFF.S */ 9868/* File: armv5te/unused.S */ 9869 bl common_abort 9870 9871 9872/* ------------------------------ */ 9873 .balign 64 9874.L_OP_UNUSED_B0FF: /* 0x1b0 */ 9875/* File: armv5te/OP_UNUSED_B0FF.S */ 9876/* File: armv5te/unused.S */ 9877 bl common_abort 9878 9879 9880/* ------------------------------ */ 9881 .balign 64 9882.L_OP_UNUSED_B1FF: /* 0x1b1 */ 9883/* File: armv5te/OP_UNUSED_B1FF.S */ 9884/* File: armv5te/unused.S */ 9885 bl common_abort 9886 9887 9888/* ------------------------------ */ 9889 .balign 64 9890.L_OP_UNUSED_B2FF: /* 0x1b2 */ 9891/* File: armv5te/OP_UNUSED_B2FF.S */ 9892/* File: armv5te/unused.S */ 9893 bl common_abort 9894 9895 9896/* ------------------------------ */ 9897 .balign 64 9898.L_OP_UNUSED_B3FF: /* 0x1b3 */ 9899/* File: armv5te/OP_UNUSED_B3FF.S */ 9900/* File: armv5te/unused.S */ 9901 bl common_abort 9902 9903 9904/* ------------------------------ */ 9905 .balign 64 9906.L_OP_UNUSED_B4FF: /* 0x1b4 */ 9907/* File: armv5te/OP_UNUSED_B4FF.S */ 9908/* File: armv5te/unused.S */ 9909 bl common_abort 9910 9911 9912/* ------------------------------ */ 9913 .balign 64 9914.L_OP_UNUSED_B5FF: /* 0x1b5 */ 9915/* File: armv5te/OP_UNUSED_B5FF.S */ 9916/* File: armv5te/unused.S */ 9917 bl common_abort 9918 9919 9920/* ------------------------------ */ 9921 .balign 64 9922.L_OP_UNUSED_B6FF: /* 0x1b6 */ 9923/* File: armv5te/OP_UNUSED_B6FF.S */ 9924/* File: armv5te/unused.S */ 9925 bl common_abort 9926 9927 9928/* ------------------------------ */ 9929 .balign 64 9930.L_OP_UNUSED_B7FF: /* 0x1b7 */ 9931/* File: armv5te/OP_UNUSED_B7FF.S */ 9932/* File: armv5te/unused.S */ 9933 bl common_abort 9934 9935 9936/* ------------------------------ */ 9937 .balign 64 9938.L_OP_UNUSED_B8FF: /* 0x1b8 */ 9939/* File: armv5te/OP_UNUSED_B8FF.S */ 9940/* File: armv5te/unused.S */ 9941 bl common_abort 9942 9943 9944/* ------------------------------ */ 9945 .balign 64 9946.L_OP_UNUSED_B9FF: /* 0x1b9 */ 9947/* File: armv5te/OP_UNUSED_B9FF.S */ 9948/* File: armv5te/unused.S */ 9949 bl common_abort 9950 9951 9952/* ------------------------------ */ 9953 .balign 64 9954.L_OP_UNUSED_BAFF: /* 0x1ba */ 9955/* File: armv5te/OP_UNUSED_BAFF.S */ 9956/* File: armv5te/unused.S */ 9957 bl common_abort 9958 9959 9960/* ------------------------------ */ 9961 .balign 64 9962.L_OP_UNUSED_BBFF: /* 0x1bb */ 9963/* File: armv5te/OP_UNUSED_BBFF.S */ 9964/* File: armv5te/unused.S */ 9965 bl common_abort 9966 9967 9968/* ------------------------------ */ 9969 .balign 64 9970.L_OP_UNUSED_BCFF: /* 0x1bc */ 9971/* File: armv5te/OP_UNUSED_BCFF.S */ 9972/* File: armv5te/unused.S */ 9973 bl common_abort 9974 9975 9976/* ------------------------------ */ 9977 .balign 64 9978.L_OP_UNUSED_BDFF: /* 0x1bd */ 9979/* File: armv5te/OP_UNUSED_BDFF.S */ 9980/* File: armv5te/unused.S */ 9981 bl common_abort 9982 9983 9984/* ------------------------------ */ 9985 .balign 64 9986.L_OP_UNUSED_BEFF: /* 0x1be */ 9987/* File: armv5te/OP_UNUSED_BEFF.S */ 9988/* File: armv5te/unused.S */ 9989 bl common_abort 9990 9991 9992/* ------------------------------ */ 9993 .balign 64 9994.L_OP_UNUSED_BFFF: /* 0x1bf */ 9995/* File: armv5te/OP_UNUSED_BFFF.S */ 9996/* File: armv5te/unused.S */ 9997 bl common_abort 9998 9999 10000/* ------------------------------ */ 10001 .balign 64 10002.L_OP_UNUSED_C0FF: /* 0x1c0 */ 10003/* File: armv5te/OP_UNUSED_C0FF.S */ 10004/* File: armv5te/unused.S */ 10005 bl common_abort 10006 10007 10008/* ------------------------------ */ 10009 .balign 64 10010.L_OP_UNUSED_C1FF: /* 0x1c1 */ 10011/* File: armv5te/OP_UNUSED_C1FF.S */ 10012/* File: armv5te/unused.S */ 10013 bl common_abort 10014 10015 10016/* ------------------------------ */ 10017 .balign 64 10018.L_OP_UNUSED_C2FF: /* 0x1c2 */ 10019/* File: armv5te/OP_UNUSED_C2FF.S */ 10020/* File: armv5te/unused.S */ 10021 bl common_abort 10022 10023 10024/* ------------------------------ */ 10025 .balign 64 10026.L_OP_UNUSED_C3FF: /* 0x1c3 */ 10027/* File: armv5te/OP_UNUSED_C3FF.S */ 10028/* File: armv5te/unused.S */ 10029 bl common_abort 10030 10031 10032/* ------------------------------ */ 10033 .balign 64 10034.L_OP_UNUSED_C4FF: /* 0x1c4 */ 10035/* File: armv5te/OP_UNUSED_C4FF.S */ 10036/* File: armv5te/unused.S */ 10037 bl common_abort 10038 10039 10040/* ------------------------------ */ 10041 .balign 64 10042.L_OP_UNUSED_C5FF: /* 0x1c5 */ 10043/* File: armv5te/OP_UNUSED_C5FF.S */ 10044/* File: armv5te/unused.S */ 10045 bl common_abort 10046 10047 10048/* ------------------------------ */ 10049 .balign 64 10050.L_OP_UNUSED_C6FF: /* 0x1c6 */ 10051/* File: armv5te/OP_UNUSED_C6FF.S */ 10052/* File: armv5te/unused.S */ 10053 bl common_abort 10054 10055 10056/* ------------------------------ */ 10057 .balign 64 10058.L_OP_UNUSED_C7FF: /* 0x1c7 */ 10059/* File: armv5te/OP_UNUSED_C7FF.S */ 10060/* File: armv5te/unused.S */ 10061 bl common_abort 10062 10063 10064/* ------------------------------ */ 10065 .balign 64 10066.L_OP_UNUSED_C8FF: /* 0x1c8 */ 10067/* File: armv5te/OP_UNUSED_C8FF.S */ 10068/* File: armv5te/unused.S */ 10069 bl common_abort 10070 10071 10072/* ------------------------------ */ 10073 .balign 64 10074.L_OP_UNUSED_C9FF: /* 0x1c9 */ 10075/* File: armv5te/OP_UNUSED_C9FF.S */ 10076/* File: armv5te/unused.S */ 10077 bl common_abort 10078 10079 10080/* ------------------------------ */ 10081 .balign 64 10082.L_OP_UNUSED_CAFF: /* 0x1ca */ 10083/* File: armv5te/OP_UNUSED_CAFF.S */ 10084/* File: armv5te/unused.S */ 10085 bl common_abort 10086 10087 10088/* ------------------------------ */ 10089 .balign 64 10090.L_OP_UNUSED_CBFF: /* 0x1cb */ 10091/* File: armv5te/OP_UNUSED_CBFF.S */ 10092/* File: armv5te/unused.S */ 10093 bl common_abort 10094 10095 10096/* ------------------------------ */ 10097 .balign 64 10098.L_OP_UNUSED_CCFF: /* 0x1cc */ 10099/* File: armv5te/OP_UNUSED_CCFF.S */ 10100/* File: armv5te/unused.S */ 10101 bl common_abort 10102 10103 10104/* ------------------------------ */ 10105 .balign 64 10106.L_OP_UNUSED_CDFF: /* 0x1cd */ 10107/* File: armv5te/OP_UNUSED_CDFF.S */ 10108/* File: armv5te/unused.S */ 10109 bl common_abort 10110 10111 10112/* ------------------------------ */ 10113 .balign 64 10114.L_OP_UNUSED_CEFF: /* 0x1ce */ 10115/* File: armv5te/OP_UNUSED_CEFF.S */ 10116/* File: armv5te/unused.S */ 10117 bl common_abort 10118 10119 10120/* ------------------------------ */ 10121 .balign 64 10122.L_OP_UNUSED_CFFF: /* 0x1cf */ 10123/* File: armv5te/OP_UNUSED_CFFF.S */ 10124/* File: armv5te/unused.S */ 10125 bl common_abort 10126 10127 10128/* ------------------------------ */ 10129 .balign 64 10130.L_OP_UNUSED_D0FF: /* 0x1d0 */ 10131/* File: armv5te/OP_UNUSED_D0FF.S */ 10132/* File: armv5te/unused.S */ 10133 bl common_abort 10134 10135 10136/* ------------------------------ */ 10137 .balign 64 10138.L_OP_UNUSED_D1FF: /* 0x1d1 */ 10139/* File: armv5te/OP_UNUSED_D1FF.S */ 10140/* File: armv5te/unused.S */ 10141 bl common_abort 10142 10143 10144/* ------------------------------ */ 10145 .balign 64 10146.L_OP_UNUSED_D2FF: /* 0x1d2 */ 10147/* File: armv5te/OP_UNUSED_D2FF.S */ 10148/* File: armv5te/unused.S */ 10149 bl common_abort 10150 10151 10152/* ------------------------------ */ 10153 .balign 64 10154.L_OP_UNUSED_D3FF: /* 0x1d3 */ 10155/* File: armv5te/OP_UNUSED_D3FF.S */ 10156/* File: armv5te/unused.S */ 10157 bl common_abort 10158 10159 10160/* ------------------------------ */ 10161 .balign 64 10162.L_OP_UNUSED_D4FF: /* 0x1d4 */ 10163/* File: armv5te/OP_UNUSED_D4FF.S */ 10164/* File: armv5te/unused.S */ 10165 bl common_abort 10166 10167 10168/* ------------------------------ */ 10169 .balign 64 10170.L_OP_UNUSED_D5FF: /* 0x1d5 */ 10171/* File: armv5te/OP_UNUSED_D5FF.S */ 10172/* File: armv5te/unused.S */ 10173 bl common_abort 10174 10175 10176/* ------------------------------ */ 10177 .balign 64 10178.L_OP_UNUSED_D6FF: /* 0x1d6 */ 10179/* File: armv5te/OP_UNUSED_D6FF.S */ 10180/* File: armv5te/unused.S */ 10181 bl common_abort 10182 10183 10184/* ------------------------------ */ 10185 .balign 64 10186.L_OP_UNUSED_D7FF: /* 0x1d7 */ 10187/* File: armv5te/OP_UNUSED_D7FF.S */ 10188/* File: armv5te/unused.S */ 10189 bl common_abort 10190 10191 10192/* ------------------------------ */ 10193 .balign 64 10194.L_OP_UNUSED_D8FF: /* 0x1d8 */ 10195/* File: armv5te/OP_UNUSED_D8FF.S */ 10196/* File: armv5te/unused.S */ 10197 bl common_abort 10198 10199 10200/* ------------------------------ */ 10201 .balign 64 10202.L_OP_UNUSED_D9FF: /* 0x1d9 */ 10203/* File: armv5te/OP_UNUSED_D9FF.S */ 10204/* File: armv5te/unused.S */ 10205 bl common_abort 10206 10207 10208/* ------------------------------ */ 10209 .balign 64 10210.L_OP_UNUSED_DAFF: /* 0x1da */ 10211/* File: armv5te/OP_UNUSED_DAFF.S */ 10212/* File: armv5te/unused.S */ 10213 bl common_abort 10214 10215 10216/* ------------------------------ */ 10217 .balign 64 10218.L_OP_UNUSED_DBFF: /* 0x1db */ 10219/* File: armv5te/OP_UNUSED_DBFF.S */ 10220/* File: armv5te/unused.S */ 10221 bl common_abort 10222 10223 10224/* ------------------------------ */ 10225 .balign 64 10226.L_OP_UNUSED_DCFF: /* 0x1dc */ 10227/* File: armv5te/OP_UNUSED_DCFF.S */ 10228/* File: armv5te/unused.S */ 10229 bl common_abort 10230 10231 10232/* ------------------------------ */ 10233 .balign 64 10234.L_OP_UNUSED_DDFF: /* 0x1dd */ 10235/* File: armv5te/OP_UNUSED_DDFF.S */ 10236/* File: armv5te/unused.S */ 10237 bl common_abort 10238 10239 10240/* ------------------------------ */ 10241 .balign 64 10242.L_OP_UNUSED_DEFF: /* 0x1de */ 10243/* File: armv5te/OP_UNUSED_DEFF.S */ 10244/* File: armv5te/unused.S */ 10245 bl common_abort 10246 10247 10248/* ------------------------------ */ 10249 .balign 64 10250.L_OP_UNUSED_DFFF: /* 0x1df */ 10251/* File: armv5te/OP_UNUSED_DFFF.S */ 10252/* File: armv5te/unused.S */ 10253 bl common_abort 10254 10255 10256/* ------------------------------ */ 10257 .balign 64 10258.L_OP_UNUSED_E0FF: /* 0x1e0 */ 10259/* File: armv5te/OP_UNUSED_E0FF.S */ 10260/* File: armv5te/unused.S */ 10261 bl common_abort 10262 10263 10264/* ------------------------------ */ 10265 .balign 64 10266.L_OP_UNUSED_E1FF: /* 0x1e1 */ 10267/* File: armv5te/OP_UNUSED_E1FF.S */ 10268/* File: armv5te/unused.S */ 10269 bl common_abort 10270 10271 10272/* ------------------------------ */ 10273 .balign 64 10274.L_OP_UNUSED_E2FF: /* 0x1e2 */ 10275/* File: armv5te/OP_UNUSED_E2FF.S */ 10276/* File: armv5te/unused.S */ 10277 bl common_abort 10278 10279 10280/* ------------------------------ */ 10281 .balign 64 10282.L_OP_UNUSED_E3FF: /* 0x1e3 */ 10283/* File: armv5te/OP_UNUSED_E3FF.S */ 10284/* File: armv5te/unused.S */ 10285 bl common_abort 10286 10287 10288/* ------------------------------ */ 10289 .balign 64 10290.L_OP_UNUSED_E4FF: /* 0x1e4 */ 10291/* File: armv5te/OP_UNUSED_E4FF.S */ 10292/* File: armv5te/unused.S */ 10293 bl common_abort 10294 10295 10296/* ------------------------------ */ 10297 .balign 64 10298.L_OP_UNUSED_E5FF: /* 0x1e5 */ 10299/* File: armv5te/OP_UNUSED_E5FF.S */ 10300/* File: armv5te/unused.S */ 10301 bl common_abort 10302 10303 10304/* ------------------------------ */ 10305 .balign 64 10306.L_OP_UNUSED_E6FF: /* 0x1e6 */ 10307/* File: armv5te/OP_UNUSED_E6FF.S */ 10308/* File: armv5te/unused.S */ 10309 bl common_abort 10310 10311 10312/* ------------------------------ */ 10313 .balign 64 10314.L_OP_UNUSED_E7FF: /* 0x1e7 */ 10315/* File: armv5te/OP_UNUSED_E7FF.S */ 10316/* File: armv5te/unused.S */ 10317 bl common_abort 10318 10319 10320/* ------------------------------ */ 10321 .balign 64 10322.L_OP_UNUSED_E8FF: /* 0x1e8 */ 10323/* File: armv5te/OP_UNUSED_E8FF.S */ 10324/* File: armv5te/unused.S */ 10325 bl common_abort 10326 10327 10328/* ------------------------------ */ 10329 .balign 64 10330.L_OP_UNUSED_E9FF: /* 0x1e9 */ 10331/* File: armv5te/OP_UNUSED_E9FF.S */ 10332/* File: armv5te/unused.S */ 10333 bl common_abort 10334 10335 10336/* ------------------------------ */ 10337 .balign 64 10338.L_OP_UNUSED_EAFF: /* 0x1ea */ 10339/* File: armv5te/OP_UNUSED_EAFF.S */ 10340/* File: armv5te/unused.S */ 10341 bl common_abort 10342 10343 10344/* ------------------------------ */ 10345 .balign 64 10346.L_OP_UNUSED_EBFF: /* 0x1eb */ 10347/* File: armv5te/OP_UNUSED_EBFF.S */ 10348/* File: armv5te/unused.S */ 10349 bl common_abort 10350 10351 10352/* ------------------------------ */ 10353 .balign 64 10354.L_OP_UNUSED_ECFF: /* 0x1ec */ 10355/* File: armv5te/OP_UNUSED_ECFF.S */ 10356/* File: armv5te/unused.S */ 10357 bl common_abort 10358 10359 10360/* ------------------------------ */ 10361 .balign 64 10362.L_OP_UNUSED_EDFF: /* 0x1ed */ 10363/* File: armv5te/OP_UNUSED_EDFF.S */ 10364/* File: armv5te/unused.S */ 10365 bl common_abort 10366 10367 10368/* ------------------------------ */ 10369 .balign 64 10370.L_OP_UNUSED_EEFF: /* 0x1ee */ 10371/* File: armv5te/OP_UNUSED_EEFF.S */ 10372/* File: armv5te/unused.S */ 10373 bl common_abort 10374 10375 10376/* ------------------------------ */ 10377 .balign 64 10378.L_OP_UNUSED_EFFF: /* 0x1ef */ 10379/* File: armv5te/OP_UNUSED_EFFF.S */ 10380/* File: armv5te/unused.S */ 10381 bl common_abort 10382 10383 10384/* ------------------------------ */ 10385 .balign 64 10386.L_OP_UNUSED_F0FF: /* 0x1f0 */ 10387/* File: armv5te/OP_UNUSED_F0FF.S */ 10388/* File: armv5te/unused.S */ 10389 bl common_abort 10390 10391 10392/* ------------------------------ */ 10393 .balign 64 10394.L_OP_UNUSED_F1FF: /* 0x1f1 */ 10395/* File: armv5te/OP_UNUSED_F1FF.S */ 10396/* File: armv5te/unused.S */ 10397 bl common_abort 10398 10399 10400/* ------------------------------ */ 10401 .balign 64 10402.L_OP_UNUSED_F2FF: /* 0x1f2 */ 10403/* File: armv5te/OP_UNUSED_F2FF.S */ 10404/* File: armv5te/unused.S */ 10405 bl common_abort 10406 10407 10408/* ------------------------------ */ 10409 .balign 64 10410.L_OP_UNUSED_F3FF: /* 0x1f3 */ 10411/* File: armv5te/OP_UNUSED_F3FF.S */ 10412/* File: armv5te/unused.S */ 10413 bl common_abort 10414 10415 10416/* ------------------------------ */ 10417 .balign 64 10418.L_OP_UNUSED_F4FF: /* 0x1f4 */ 10419/* File: armv5te/OP_UNUSED_F4FF.S */ 10420/* File: armv5te/unused.S */ 10421 bl common_abort 10422 10423 10424/* ------------------------------ */ 10425 .balign 64 10426.L_OP_UNUSED_F5FF: /* 0x1f5 */ 10427/* File: armv5te/OP_UNUSED_F5FF.S */ 10428/* File: armv5te/unused.S */ 10429 bl common_abort 10430 10431 10432/* ------------------------------ */ 10433 .balign 64 10434.L_OP_UNUSED_F6FF: /* 0x1f6 */ 10435/* File: armv5te/OP_UNUSED_F6FF.S */ 10436/* File: armv5te/unused.S */ 10437 bl common_abort 10438 10439 10440/* ------------------------------ */ 10441 .balign 64 10442.L_OP_UNUSED_F7FF: /* 0x1f7 */ 10443/* File: armv5te/OP_UNUSED_F7FF.S */ 10444/* File: armv5te/unused.S */ 10445 bl common_abort 10446 10447 10448/* ------------------------------ */ 10449 .balign 64 10450.L_OP_UNUSED_F8FF: /* 0x1f8 */ 10451/* File: armv5te/OP_UNUSED_F8FF.S */ 10452/* File: armv5te/unused.S */ 10453 bl common_abort 10454 10455 10456/* ------------------------------ */ 10457 .balign 64 10458.L_OP_UNUSED_F9FF: /* 0x1f9 */ 10459/* File: armv5te/OP_UNUSED_F9FF.S */ 10460/* File: armv5te/unused.S */ 10461 bl common_abort 10462 10463 10464/* ------------------------------ */ 10465 .balign 64 10466.L_OP_UNUSED_FAFF: /* 0x1fa */ 10467/* File: armv5te/OP_UNUSED_FAFF.S */ 10468/* File: armv5te/unused.S */ 10469 bl common_abort 10470 10471 10472/* ------------------------------ */ 10473 .balign 64 10474.L_OP_UNUSED_FBFF: /* 0x1fb */ 10475/* File: armv5te/OP_UNUSED_FBFF.S */ 10476/* File: armv5te/unused.S */ 10477 bl common_abort 10478 10479 10480/* ------------------------------ */ 10481 .balign 64 10482.L_OP_UNUSED_FCFF: /* 0x1fc */ 10483/* File: armv5te/OP_UNUSED_FCFF.S */ 10484/* File: armv5te/unused.S */ 10485 bl common_abort 10486 10487 10488/* ------------------------------ */ 10489 .balign 64 10490.L_OP_UNUSED_FDFF: /* 0x1fd */ 10491/* File: armv5te/OP_UNUSED_FDFF.S */ 10492/* File: armv5te/unused.S */ 10493 bl common_abort 10494 10495 10496/* ------------------------------ */ 10497 .balign 64 10498.L_OP_UNUSED_FEFF: /* 0x1fe */ 10499/* File: armv5te/OP_UNUSED_FEFF.S */ 10500/* File: armv5te/unused.S */ 10501 bl common_abort 10502 10503 10504/* ------------------------------ */ 10505 .balign 64 10506.L_OP_THROW_VERIFICATION_ERROR_JUMBO: /* 0x1ff */ 10507/* File: armv5te/OP_THROW_VERIFICATION_ERROR_JUMBO.S */ 10508 /* 10509 * Handle a jumbo throw-verification-error instruction. This throws an 10510 * exception for an error discovered during verification. The 10511 * exception is indicated by BBBB, with some detail provided by AAAAAAAA. 10512 */ 10513 /* exop BBBB, Class@AAAAAAAA */ 10514 FETCH(r1, 1) @ r1<- aaaa (lo) 10515 FETCH(r2, 2) @ r2<- AAAA (hi) 10516 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 10517 orr r2, r1, r2, lsl #16 @ r2<- AAAAaaaa 10518 EXPORT_PC() @ export the PC 10519 FETCH(r1, 3) @ r1<- BBBB 10520 bl dvmThrowVerificationError @ always throws 10521 b common_exceptionThrown @ handle exception 10522 10523 10524 .balign 64 10525 .size dvmAsmInstructionStart, .-dvmAsmInstructionStart 10526 .global dvmAsmInstructionEnd 10527dvmAsmInstructionEnd: 10528 10529/* 10530 * =========================================================================== 10531 * Sister implementations 10532 * =========================================================================== 10533 */ 10534 .global dvmAsmSisterStart 10535 .type dvmAsmSisterStart, %function 10536 .text 10537 .balign 4 10538dvmAsmSisterStart: 10539 10540/* continuation for OP_CONST_STRING */ 10541 10542 /* 10543 * Continuation if the String has not yet been resolved. 10544 * r1: BBBB (String ref) 10545 * r9: target register 10546 */ 10547.LOP_CONST_STRING_resolve: 10548 EXPORT_PC() 10549 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 10550 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 10551 bl dvmResolveString @ r0<- String reference 10552 cmp r0, #0 @ failed? 10553 beq common_exceptionThrown @ yup, handle the exception 10554 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10555 GET_INST_OPCODE(ip) @ extract opcode from rINST 10556 SET_VREG(r0, r9) @ vAA<- r0 10557 GOTO_OPCODE(ip) @ jump to next instruction 10558 10559/* continuation for OP_CONST_STRING_JUMBO */ 10560 10561 /* 10562 * Continuation if the String has not yet been resolved. 10563 * r1: BBBBBBBB (String ref) 10564 * r9: target register 10565 */ 10566.LOP_CONST_STRING_JUMBO_resolve: 10567 EXPORT_PC() 10568 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 10569 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 10570 bl dvmResolveString @ r0<- String reference 10571 cmp r0, #0 @ failed? 10572 beq common_exceptionThrown @ yup, handle the exception 10573 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 10574 GET_INST_OPCODE(ip) @ extract opcode from rINST 10575 SET_VREG(r0, r9) @ vAA<- r0 10576 GOTO_OPCODE(ip) @ jump to next instruction 10577 10578/* continuation for OP_CONST_CLASS */ 10579 10580 /* 10581 * Continuation if the Class has not yet been resolved. 10582 * r1: BBBB (Class ref) 10583 * r9: target register 10584 */ 10585.LOP_CONST_CLASS_resolve: 10586 EXPORT_PC() 10587 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 10588 mov r2, #1 @ r2<- true 10589 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 10590 bl dvmResolveClass @ r0<- Class reference 10591 cmp r0, #0 @ failed? 10592 beq common_exceptionThrown @ yup, handle the exception 10593 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10594 GET_INST_OPCODE(ip) @ extract opcode from rINST 10595 SET_VREG(r0, r9) @ vAA<- r0 10596 GOTO_OPCODE(ip) @ jump to next instruction 10597 10598/* continuation for OP_CHECK_CAST */ 10599 10600 /* 10601 * Trivial test failed, need to perform full check. This is common. 10602 * r0 holds obj->clazz 10603 * r1 holds desired class resolved from BBBB 10604 * r9 holds object 10605 */ 10606.LOP_CHECK_CAST_fullcheck: 10607 mov r10, r1 @ avoid ClassObject getting clobbered 10608 bl dvmInstanceofNonTrivial @ r0<- boolean result 10609 cmp r0, #0 @ failed? 10610 bne .LOP_CHECK_CAST_okay @ no, success 10611 10612 @ A cast has failed. We need to throw a ClassCastException. 10613 EXPORT_PC() @ about to throw 10614 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class) 10615 mov r1, r10 @ r1<- desired class 10616 bl dvmThrowClassCastException 10617 b common_exceptionThrown 10618 10619 /* 10620 * Resolution required. This is the least-likely path. 10621 * 10622 * r2 holds BBBB 10623 * r9 holds object 10624 */ 10625.LOP_CHECK_CAST_resolve: 10626 EXPORT_PC() @ resolve() could throw 10627 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 10628 mov r1, r2 @ r1<- BBBB 10629 mov r2, #0 @ r2<- false 10630 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 10631 bl dvmResolveClass @ r0<- resolved ClassObject ptr 10632 cmp r0, #0 @ got null? 10633 beq common_exceptionThrown @ yes, handle exception 10634 mov r1, r0 @ r1<- class resolved from BBB 10635 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 10636 b .LOP_CHECK_CAST_resolved @ pick up where we left off 10637 10638/* continuation for OP_INSTANCE_OF */ 10639 10640 /* 10641 * Trivial test failed, need to perform full check. This is common. 10642 * r0 holds obj->clazz 10643 * r1 holds class resolved from BBBB 10644 * r9 holds A 10645 */ 10646.LOP_INSTANCE_OF_fullcheck: 10647 bl dvmInstanceofNonTrivial @ r0<- boolean result 10648 @ fall through to OP_INSTANCE_OF_store 10649 10650 /* 10651 * r0 holds boolean result 10652 * r9 holds A 10653 */ 10654.LOP_INSTANCE_OF_store: 10655 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10656 SET_VREG(r0, r9) @ vA<- r0 10657 GET_INST_OPCODE(ip) @ extract opcode from rINST 10658 GOTO_OPCODE(ip) @ jump to next instruction 10659 10660 /* 10661 * Trivial test succeeded, save and bail. 10662 * r9 holds A 10663 */ 10664.LOP_INSTANCE_OF_trivial: 10665 mov r0, #1 @ indicate success 10666 @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper 10667 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10668 SET_VREG(r0, r9) @ vA<- r0 10669 GET_INST_OPCODE(ip) @ extract opcode from rINST 10670 GOTO_OPCODE(ip) @ jump to next instruction 10671 10672 /* 10673 * Resolution required. This is the least-likely path. 10674 * 10675 * r3 holds BBBB 10676 * r9 holds A 10677 */ 10678.LOP_INSTANCE_OF_resolve: 10679 EXPORT_PC() @ resolve() could throw 10680 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 10681 mov r1, r3 @ r1<- BBBB 10682 mov r2, #1 @ r2<- true 10683 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 10684 bl dvmResolveClass @ r0<- resolved ClassObject ptr 10685 cmp r0, #0 @ got null? 10686 beq common_exceptionThrown @ yes, handle exception 10687 mov r1, r0 @ r1<- class resolved from BBB 10688 mov r3, rINST, lsr #12 @ r3<- B 10689 GET_VREG(r0, r3) @ r0<- vB (object) 10690 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 10691 b .LOP_INSTANCE_OF_resolved @ pick up where we left off 10692 10693/* continuation for OP_NEW_INSTANCE */ 10694 10695 .balign 32 @ minimize cache lines 10696.LOP_NEW_INSTANCE_finish: @ r0=new object 10697 mov r3, rINST, lsr #8 @ r3<- AA 10698 cmp r0, #0 @ failed? 10699 beq common_exceptionThrown @ yes, handle the exception 10700 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10701 GET_INST_OPCODE(ip) @ extract opcode from rINST 10702 SET_VREG(r0, r3) @ vAA<- r0 10703 GOTO_OPCODE(ip) @ jump to next instruction 10704 10705 /* 10706 * Class initialization required. 10707 * 10708 * r0 holds class object 10709 */ 10710.LOP_NEW_INSTANCE_needinit: 10711 mov r9, r0 @ save r0 10712 bl dvmInitClass @ initialize class 10713 cmp r0, #0 @ check boolean result 10714 mov r0, r9 @ restore r0 10715 bne .LOP_NEW_INSTANCE_initialized @ success, continue 10716 b common_exceptionThrown @ failed, deal with init exception 10717 10718 /* 10719 * Resolution required. This is the least-likely path. 10720 * 10721 * r1 holds BBBB 10722 */ 10723.LOP_NEW_INSTANCE_resolve: 10724 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 10725 mov r2, #0 @ r2<- false 10726 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 10727 bl dvmResolveClass @ r0<- resolved ClassObject ptr 10728 cmp r0, #0 @ got null? 10729 bne .LOP_NEW_INSTANCE_resolved @ no, continue 10730 b common_exceptionThrown @ yes, handle exception 10731 10732.LstrInstantiationErrorPtr: 10733 .word .LstrInstantiationError 10734 10735/* continuation for OP_NEW_ARRAY */ 10736 10737 10738 /* 10739 * Resolve class. (This is an uncommon case.) 10740 * 10741 * r1 holds array length 10742 * r2 holds class ref CCCC 10743 */ 10744.LOP_NEW_ARRAY_resolve: 10745 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 10746 mov r9, r1 @ r9<- length (save) 10747 mov r1, r2 @ r1<- CCCC 10748 mov r2, #0 @ r2<- false 10749 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 10750 bl dvmResolveClass @ r0<- call(clazz, ref) 10751 cmp r0, #0 @ got null? 10752 mov r1, r9 @ r1<- length (restore) 10753 beq common_exceptionThrown @ yes, handle exception 10754 @ fall through to OP_NEW_ARRAY_finish 10755 10756 /* 10757 * Finish allocation. 10758 * 10759 * r0 holds class 10760 * r1 holds array length 10761 */ 10762.LOP_NEW_ARRAY_finish: 10763 mov r2, #ALLOC_DONT_TRACK @ don't track in local refs table 10764 bl dvmAllocArrayByClass @ r0<- call(clazz, length, flags) 10765 cmp r0, #0 @ failed? 10766 mov r2, rINST, lsr #8 @ r2<- A+ 10767 beq common_exceptionThrown @ yes, handle the exception 10768 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10769 and r2, r2, #15 @ r2<- A 10770 GET_INST_OPCODE(ip) @ extract opcode from rINST 10771 SET_VREG(r0, r2) @ vA<- r0 10772 GOTO_OPCODE(ip) @ jump to next instruction 10773 10774/* continuation for OP_FILLED_NEW_ARRAY */ 10775 10776 /* 10777 * On entry: 10778 * r0 holds array class 10779 * r10 holds AA or BA 10780 */ 10781.LOP_FILLED_NEW_ARRAY_continue: 10782 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 10783 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 10784 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 10785 .if 0 10786 mov r1, r10 @ r1<- AA (length) 10787 .else 10788 mov r1, r10, lsr #4 @ r1<- B (length) 10789 .endif 10790 cmp rINST, #'I' @ array of ints? 10791 cmpne rINST, #'L' @ array of objects? 10792 cmpne rINST, #'[' @ array of arrays? 10793 mov r9, r1 @ save length in r9 10794 bne .LOP_FILLED_NEW_ARRAY_notimpl @ no, not handled yet 10795 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 10796 cmp r0, #0 @ null return? 10797 beq common_exceptionThrown @ alloc failed, handle exception 10798 10799 FETCH(r1, 2) @ r1<- FEDC or CCCC 10800 str r0, [rGLUE, #offGlue_retval] @ retval.l <- new array 10801 str rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type 10802 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 10803 subs r9, r9, #1 @ length--, check for neg 10804 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 10805 bmi 2f @ was zero, bail 10806 10807 @ copy values from registers into the array 10808 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 10809 .if 0 10810 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 108111: ldr r3, [r2], #4 @ r3<- *r2++ 10812 subs r9, r9, #1 @ count-- 10813 str r3, [r0], #4 @ *contents++ = vX 10814 bpl 1b 10815 @ continue at 2 10816 .else 10817 cmp r9, #4 @ length was initially 5? 10818 and r2, r10, #15 @ r2<- A 10819 bne 1f @ <= 4 args, branch 10820 GET_VREG(r3, r2) @ r3<- vA 10821 sub r9, r9, #1 @ count-- 10822 str r3, [r0, #16] @ contents[4] = vA 108231: and r2, r1, #15 @ r2<- F/E/D/C 10824 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 10825 mov r1, r1, lsr #4 @ r1<- next reg in low 4 10826 subs r9, r9, #1 @ count-- 10827 str r3, [r0], #4 @ *contents++ = vX 10828 bpl 1b 10829 @ continue at 2 10830 .endif 10831 108322: 10833 ldr r0, [rGLUE, #offGlue_retval] @ r0<- object 10834 ldr r1, [rGLUE, #offGlue_retval+4] @ r1<- type 10835 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 10836 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 10837 cmp r1, #'I' @ Is int array? 10838 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 10839 GOTO_OPCODE(ip) @ execute it 10840 10841 /* 10842 * Throw an exception indicating that we have not implemented this 10843 * mode of filled-new-array. 10844 */ 10845.LOP_FILLED_NEW_ARRAY_notimpl: 10846 ldr r0, .L_strInternalError 10847 ldr r1, .L_strFilledNewArrayNotImpl 10848 bl dvmThrowException 10849 b common_exceptionThrown 10850 10851 .if (!0) @ define in one or the other, not both 10852.L_strFilledNewArrayNotImpl: 10853 .word .LstrFilledNewArrayNotImpl 10854.L_strInternalError: 10855 .word .LstrInternalError 10856 .endif 10857 10858/* continuation for OP_FILLED_NEW_ARRAY_RANGE */ 10859 10860 /* 10861 * On entry: 10862 * r0 holds array class 10863 * r10 holds AA or BA 10864 */ 10865.LOP_FILLED_NEW_ARRAY_RANGE_continue: 10866 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 10867 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 10868 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 10869 .if 1 10870 mov r1, r10 @ r1<- AA (length) 10871 .else 10872 mov r1, r10, lsr #4 @ r1<- B (length) 10873 .endif 10874 cmp rINST, #'I' @ array of ints? 10875 cmpne rINST, #'L' @ array of objects? 10876 cmpne rINST, #'[' @ array of arrays? 10877 mov r9, r1 @ save length in r9 10878 bne .LOP_FILLED_NEW_ARRAY_RANGE_notimpl @ no, not handled yet 10879 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 10880 cmp r0, #0 @ null return? 10881 beq common_exceptionThrown @ alloc failed, handle exception 10882 10883 FETCH(r1, 2) @ r1<- FEDC or CCCC 10884 str r0, [rGLUE, #offGlue_retval] @ retval.l <- new array 10885 str rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type 10886 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 10887 subs r9, r9, #1 @ length--, check for neg 10888 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 10889 bmi 2f @ was zero, bail 10890 10891 @ copy values from registers into the array 10892 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 10893 .if 1 10894 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 108951: ldr r3, [r2], #4 @ r3<- *r2++ 10896 subs r9, r9, #1 @ count-- 10897 str r3, [r0], #4 @ *contents++ = vX 10898 bpl 1b 10899 @ continue at 2 10900 .else 10901 cmp r9, #4 @ length was initially 5? 10902 and r2, r10, #15 @ r2<- A 10903 bne 1f @ <= 4 args, branch 10904 GET_VREG(r3, r2) @ r3<- vA 10905 sub r9, r9, #1 @ count-- 10906 str r3, [r0, #16] @ contents[4] = vA 109071: and r2, r1, #15 @ r2<- F/E/D/C 10908 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 10909 mov r1, r1, lsr #4 @ r1<- next reg in low 4 10910 subs r9, r9, #1 @ count-- 10911 str r3, [r0], #4 @ *contents++ = vX 10912 bpl 1b 10913 @ continue at 2 10914 .endif 10915 109162: 10917 ldr r0, [rGLUE, #offGlue_retval] @ r0<- object 10918 ldr r1, [rGLUE, #offGlue_retval+4] @ r1<- type 10919 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 10920 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 10921 cmp r1, #'I' @ Is int array? 10922 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 10923 GOTO_OPCODE(ip) @ execute it 10924 10925 /* 10926 * Throw an exception indicating that we have not implemented this 10927 * mode of filled-new-array. 10928 */ 10929.LOP_FILLED_NEW_ARRAY_RANGE_notimpl: 10930 ldr r0, .L_strInternalError 10931 ldr r1, .L_strFilledNewArrayNotImpl 10932 bl dvmThrowException 10933 b common_exceptionThrown 10934 10935 .if (!1) @ define in one or the other, not both 10936.L_strFilledNewArrayNotImpl: 10937 .word .LstrFilledNewArrayNotImpl 10938.L_strInternalError: 10939 .word .LstrInternalError 10940 .endif 10941 10942/* continuation for OP_CMPL_FLOAT */ 10943.LOP_CMPL_FLOAT_finish: 10944 SET_VREG(r0, r9) @ vAA<- r0 10945 GOTO_OPCODE(ip) @ jump to next instruction 10946 10947/* continuation for OP_CMPG_FLOAT */ 10948.LOP_CMPG_FLOAT_finish: 10949 SET_VREG(r0, r9) @ vAA<- r0 10950 GOTO_OPCODE(ip) @ jump to next instruction 10951 10952/* continuation for OP_CMPL_DOUBLE */ 10953.LOP_CMPL_DOUBLE_finish: 10954 SET_VREG(r0, r9) @ vAA<- r0 10955 GOTO_OPCODE(ip) @ jump to next instruction 10956 10957/* continuation for OP_CMPG_DOUBLE */ 10958.LOP_CMPG_DOUBLE_finish: 10959 SET_VREG(r0, r9) @ vAA<- r0 10960 GOTO_OPCODE(ip) @ jump to next instruction 10961 10962/* continuation for OP_CMP_LONG */ 10963 10964.LOP_CMP_LONG_less: 10965 mvn r1, #0 @ r1<- -1 10966 @ Want to cond code the next mov so we can avoid branch, but don't see it; 10967 @ instead, we just replicate the tail end. 10968 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10969 SET_VREG(r1, r9) @ vAA<- r1 10970 GET_INST_OPCODE(ip) @ extract opcode from rINST 10971 GOTO_OPCODE(ip) @ jump to next instruction 10972 10973.LOP_CMP_LONG_greater: 10974 mov r1, #1 @ r1<- 1 10975 @ fall through to _finish 10976 10977.LOP_CMP_LONG_finish: 10978 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10979 SET_VREG(r1, r9) @ vAA<- r1 10980 GET_INST_OPCODE(ip) @ extract opcode from rINST 10981 GOTO_OPCODE(ip) @ jump to next instruction 10982 10983/* continuation for OP_AGET_WIDE */ 10984 10985.LOP_AGET_WIDE_finish: 10986 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10987 ldrd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 10988 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 10989 GET_INST_OPCODE(ip) @ extract opcode from rINST 10990 stmia r9, {r2-r3} @ vAA/vAA+1<- r2/r3 10991 GOTO_OPCODE(ip) @ jump to next instruction 10992 10993/* continuation for OP_APUT_WIDE */ 10994 10995.LOP_APUT_WIDE_finish: 10996 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10997 ldmia r9, {r2-r3} @ r2/r3<- vAA/vAA+1 10998 GET_INST_OPCODE(ip) @ extract opcode from rINST 10999 strd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 11000 GOTO_OPCODE(ip) @ jump to next instruction 11001 11002/* continuation for OP_APUT_OBJECT */ 11003 /* 11004 * On entry: 11005 * rINST = vBB (arrayObj) 11006 * r9 = vAA (obj) 11007 * r10 = offset into array (vBB + vCC * width) 11008 */ 11009.LOP_APUT_OBJECT_finish: 11010 cmp r9, #0 @ storing null reference? 11011 beq .LOP_APUT_OBJECT_skip_check @ yes, skip type checks 11012 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 11013 ldr r1, [rINST, #offObject_clazz] @ r1<- arrayObj->clazz 11014 bl dvmCanPutArrayElement @ test object type vs. array type 11015 cmp r0, #0 @ okay? 11016 beq .LOP_APUT_OBJECT_throw @ no 11017 mov r1, rINST @ r1<- arrayObj 11018 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11019 ldr r2, [rGLUE, #offGlue_cardTable] @ get biased CT base 11020 add r10, #offArrayObject_contents @ r0<- pointer to slot 11021 GET_INST_OPCODE(ip) @ extract opcode from rINST 11022 str r9, [r10] @ vBB[vCC]<- vAA 11023 strb r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head 11024 GOTO_OPCODE(ip) @ jump to next instruction 11025.LOP_APUT_OBJECT_skip_check: 11026 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11027 GET_INST_OPCODE(ip) @ extract opcode from rINST 11028 str r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA 11029 GOTO_OPCODE(ip) @ jump to next instruction 11030.LOP_APUT_OBJECT_throw: 11031 @ The types don't match. We need to throw an ArrayStoreException. 11032 ldr r0, [r9, #offObject_clazz] 11033 ldr r1, [rINST, #offObject_clazz] 11034 EXPORT_PC() 11035 bl dvmThrowArrayStoreException 11036 b common_exceptionThrown 11037 11038/* continuation for OP_IGET */ 11039 11040 /* 11041 * Currently: 11042 * r0 holds resolved field 11043 * r9 holds object 11044 */ 11045.LOP_IGET_finish: 11046 @bl common_squeak0 11047 cmp r9, #0 @ check object for null 11048 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11049 beq common_errNullObject @ object was null 11050 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11051 ubfx r2, rINST, #8, #4 @ r2<- A 11052 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11053 GET_INST_OPCODE(ip) @ extract opcode from rINST 11054 SET_VREG(r0, r2) @ fp[A]<- r0 11055 GOTO_OPCODE(ip) @ jump to next instruction 11056 11057/* continuation for OP_IGET_WIDE */ 11058 11059 /* 11060 * Currently: 11061 * r0 holds resolved field 11062 * r9 holds object 11063 */ 11064.LOP_IGET_WIDE_finish: 11065 cmp r9, #0 @ check object for null 11066 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11067 beq common_errNullObject @ object was null 11068 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 11069 ubfx r2, rINST, #8, #4 @ r2<- A 11070 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11071 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 11072 GET_INST_OPCODE(ip) @ extract opcode from rINST 11073 stmia r3, {r0-r1} @ fp[A]<- r0/r1 11074 GOTO_OPCODE(ip) @ jump to next instruction 11075 11076/* continuation for OP_IGET_OBJECT */ 11077 11078 /* 11079 * Currently: 11080 * r0 holds resolved field 11081 * r9 holds object 11082 */ 11083.LOP_IGET_OBJECT_finish: 11084 @bl common_squeak0 11085 cmp r9, #0 @ check object for null 11086 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11087 beq common_errNullObject @ object was null 11088 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11089 @ no-op @ acquiring load 11090 mov r2, rINST, lsr #8 @ r2<- A+ 11091 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11092 and r2, r2, #15 @ r2<- A 11093 GET_INST_OPCODE(ip) @ extract opcode from rINST 11094 SET_VREG(r0, r2) @ fp[A]<- r0 11095 GOTO_OPCODE(ip) @ jump to next instruction 11096 11097/* continuation for OP_IGET_BOOLEAN */ 11098 11099 /* 11100 * Currently: 11101 * r0 holds resolved field 11102 * r9 holds object 11103 */ 11104.LOP_IGET_BOOLEAN_finish: 11105 @bl common_squeak1 11106 cmp r9, #0 @ check object for null 11107 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11108 beq common_errNullObject @ object was null 11109 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11110 @ no-op @ acquiring load 11111 mov r2, rINST, lsr #8 @ r2<- A+ 11112 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11113 and r2, r2, #15 @ r2<- A 11114 GET_INST_OPCODE(ip) @ extract opcode from rINST 11115 SET_VREG(r0, r2) @ fp[A]<- r0 11116 GOTO_OPCODE(ip) @ jump to next instruction 11117 11118/* continuation for OP_IGET_BYTE */ 11119 11120 /* 11121 * Currently: 11122 * r0 holds resolved field 11123 * r9 holds object 11124 */ 11125.LOP_IGET_BYTE_finish: 11126 @bl common_squeak2 11127 cmp r9, #0 @ check object for null 11128 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11129 beq common_errNullObject @ object was null 11130 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11131 @ no-op @ acquiring load 11132 mov r2, rINST, lsr #8 @ r2<- A+ 11133 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11134 and r2, r2, #15 @ r2<- A 11135 GET_INST_OPCODE(ip) @ extract opcode from rINST 11136 SET_VREG(r0, r2) @ fp[A]<- r0 11137 GOTO_OPCODE(ip) @ jump to next instruction 11138 11139/* continuation for OP_IGET_CHAR */ 11140 11141 /* 11142 * Currently: 11143 * r0 holds resolved field 11144 * r9 holds object 11145 */ 11146.LOP_IGET_CHAR_finish: 11147 @bl common_squeak3 11148 cmp r9, #0 @ check object for null 11149 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11150 beq common_errNullObject @ object was null 11151 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11152 @ no-op @ acquiring load 11153 mov r2, rINST, lsr #8 @ r2<- A+ 11154 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11155 and r2, r2, #15 @ r2<- A 11156 GET_INST_OPCODE(ip) @ extract opcode from rINST 11157 SET_VREG(r0, r2) @ fp[A]<- r0 11158 GOTO_OPCODE(ip) @ jump to next instruction 11159 11160/* continuation for OP_IGET_SHORT */ 11161 11162 /* 11163 * Currently: 11164 * r0 holds resolved field 11165 * r9 holds object 11166 */ 11167.LOP_IGET_SHORT_finish: 11168 @bl common_squeak4 11169 cmp r9, #0 @ check object for null 11170 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11171 beq common_errNullObject @ object was null 11172 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11173 @ no-op @ acquiring load 11174 mov r2, rINST, lsr #8 @ r2<- A+ 11175 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11176 and r2, r2, #15 @ r2<- A 11177 GET_INST_OPCODE(ip) @ extract opcode from rINST 11178 SET_VREG(r0, r2) @ fp[A]<- r0 11179 GOTO_OPCODE(ip) @ jump to next instruction 11180 11181/* continuation for OP_IPUT */ 11182 11183 /* 11184 * Currently: 11185 * r0 holds resolved field 11186 * r9 holds object 11187 */ 11188.LOP_IPUT_finish: 11189 @bl common_squeak0 11190 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11191 ubfx r1, rINST, #8, #4 @ r1<- A 11192 cmp r9, #0 @ check object for null 11193 GET_VREG(r0, r1) @ r0<- fp[A] 11194 beq common_errNullObject @ object was null 11195 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11196 GET_INST_OPCODE(ip) @ extract opcode from rINST 11197 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11198 GOTO_OPCODE(ip) @ jump to next instruction 11199 11200/* continuation for OP_IPUT_WIDE */ 11201 11202 /* 11203 * Currently: 11204 * r0 holds resolved field 11205 * r9 holds object 11206 */ 11207.LOP_IPUT_WIDE_finish: 11208 ubfx r2, rINST, #8, #4 @ r2<- A 11209 cmp r9, #0 @ check object for null 11210 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11211 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 11212 beq common_errNullObject @ object was null 11213 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11214 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 11215 GET_INST_OPCODE(ip) @ extract opcode from rINST 11216 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0 11217 GOTO_OPCODE(ip) @ jump to next instruction 11218 11219/* continuation for OP_IPUT_OBJECT */ 11220 11221 /* 11222 * Currently: 11223 * r0 holds resolved field 11224 * r9 holds object 11225 */ 11226.LOP_IPUT_OBJECT_finish: 11227 @bl common_squeak0 11228 mov r1, rINST, lsr #8 @ r1<- A+ 11229 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11230 and r1, r1, #15 @ r1<- A 11231 cmp r9, #0 @ check object for null 11232 GET_VREG(r0, r1) @ r0<- fp[A] 11233 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 11234 beq common_errNullObject @ object was null 11235 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11236 GET_INST_OPCODE(ip) @ extract opcode from rINST 11237 @ no-op @ releasing store 11238 str r0, [r9, r3] @ obj.field (32 bits)<- r0 11239 cmp r0, #0 @ stored a null reference? 11240 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 11241 GOTO_OPCODE(ip) @ jump to next instruction 11242 11243/* continuation for OP_IPUT_BOOLEAN */ 11244 11245 /* 11246 * Currently: 11247 * r0 holds resolved field 11248 * r9 holds object 11249 */ 11250.LOP_IPUT_BOOLEAN_finish: 11251 @bl common_squeak1 11252 mov r1, rINST, lsr #8 @ r1<- A+ 11253 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11254 and r1, r1, #15 @ r1<- A 11255 cmp r9, #0 @ check object for null 11256 GET_VREG(r0, r1) @ r0<- fp[A] 11257 beq common_errNullObject @ object was null 11258 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11259 GET_INST_OPCODE(ip) @ extract opcode from rINST 11260 @ no-op @ releasing store 11261 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11262 GOTO_OPCODE(ip) @ jump to next instruction 11263 11264/* continuation for OP_IPUT_BYTE */ 11265 11266 /* 11267 * Currently: 11268 * r0 holds resolved field 11269 * r9 holds object 11270 */ 11271.LOP_IPUT_BYTE_finish: 11272 @bl common_squeak2 11273 mov r1, rINST, lsr #8 @ r1<- A+ 11274 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11275 and r1, r1, #15 @ r1<- A 11276 cmp r9, #0 @ check object for null 11277 GET_VREG(r0, r1) @ r0<- fp[A] 11278 beq common_errNullObject @ object was null 11279 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11280 GET_INST_OPCODE(ip) @ extract opcode from rINST 11281 @ no-op @ releasing store 11282 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11283 GOTO_OPCODE(ip) @ jump to next instruction 11284 11285/* continuation for OP_IPUT_CHAR */ 11286 11287 /* 11288 * Currently: 11289 * r0 holds resolved field 11290 * r9 holds object 11291 */ 11292.LOP_IPUT_CHAR_finish: 11293 @bl common_squeak3 11294 mov r1, rINST, lsr #8 @ r1<- A+ 11295 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11296 and r1, r1, #15 @ r1<- A 11297 cmp r9, #0 @ check object for null 11298 GET_VREG(r0, r1) @ r0<- fp[A] 11299 beq common_errNullObject @ object was null 11300 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11301 GET_INST_OPCODE(ip) @ extract opcode from rINST 11302 @ no-op @ releasing store 11303 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11304 GOTO_OPCODE(ip) @ jump to next instruction 11305 11306/* continuation for OP_IPUT_SHORT */ 11307 11308 /* 11309 * Currently: 11310 * r0 holds resolved field 11311 * r9 holds object 11312 */ 11313.LOP_IPUT_SHORT_finish: 11314 @bl common_squeak4 11315 mov r1, rINST, lsr #8 @ r1<- A+ 11316 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11317 and r1, r1, #15 @ r1<- A 11318 cmp r9, #0 @ check object for null 11319 GET_VREG(r0, r1) @ r0<- fp[A] 11320 beq common_errNullObject @ object was null 11321 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11322 GET_INST_OPCODE(ip) @ extract opcode from rINST 11323 @ no-op @ releasing store 11324 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11325 GOTO_OPCODE(ip) @ jump to next instruction 11326 11327/* continuation for OP_SGET */ 11328 11329 /* 11330 * Continuation if the field has not yet been resolved. 11331 * r1: BBBB field ref 11332 */ 11333.LOP_SGET_resolve: 11334 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11335 EXPORT_PC() @ resolve() could throw, so export now 11336 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11337 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11338 cmp r0, #0 @ success? 11339 bne .LOP_SGET_finish @ yes, finish 11340 b common_exceptionThrown @ no, handle exception 11341 11342/* continuation for OP_SGET_WIDE */ 11343 11344 /* 11345 * Continuation if the field has not yet been resolved. 11346 * r1: BBBB field ref 11347 * 11348 * Returns StaticField pointer in r0. 11349 */ 11350.LOP_SGET_WIDE_resolve: 11351 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11352 EXPORT_PC() @ resolve() could throw, so export now 11353 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11354 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11355 cmp r0, #0 @ success? 11356 bne .LOP_SGET_WIDE_finish @ yes, finish 11357 b common_exceptionThrown @ no, handle exception 11358 11359/* continuation for OP_SGET_OBJECT */ 11360 11361 /* 11362 * Continuation if the field has not yet been resolved. 11363 * r1: BBBB field ref 11364 */ 11365.LOP_SGET_OBJECT_resolve: 11366 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11367 EXPORT_PC() @ resolve() could throw, so export now 11368 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11369 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11370 cmp r0, #0 @ success? 11371 bne .LOP_SGET_OBJECT_finish @ yes, finish 11372 b common_exceptionThrown @ no, handle exception 11373 11374/* continuation for OP_SGET_BOOLEAN */ 11375 11376 /* 11377 * Continuation if the field has not yet been resolved. 11378 * r1: BBBB field ref 11379 */ 11380.LOP_SGET_BOOLEAN_resolve: 11381 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11382 EXPORT_PC() @ resolve() could throw, so export now 11383 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11384 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11385 cmp r0, #0 @ success? 11386 bne .LOP_SGET_BOOLEAN_finish @ yes, finish 11387 b common_exceptionThrown @ no, handle exception 11388 11389/* continuation for OP_SGET_BYTE */ 11390 11391 /* 11392 * Continuation if the field has not yet been resolved. 11393 * r1: BBBB field ref 11394 */ 11395.LOP_SGET_BYTE_resolve: 11396 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11397 EXPORT_PC() @ resolve() could throw, so export now 11398 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11399 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11400 cmp r0, #0 @ success? 11401 bne .LOP_SGET_BYTE_finish @ yes, finish 11402 b common_exceptionThrown @ no, handle exception 11403 11404/* continuation for OP_SGET_CHAR */ 11405 11406 /* 11407 * Continuation if the field has not yet been resolved. 11408 * r1: BBBB field ref 11409 */ 11410.LOP_SGET_CHAR_resolve: 11411 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11412 EXPORT_PC() @ resolve() could throw, so export now 11413 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11414 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11415 cmp r0, #0 @ success? 11416 bne .LOP_SGET_CHAR_finish @ yes, finish 11417 b common_exceptionThrown @ no, handle exception 11418 11419/* continuation for OP_SGET_SHORT */ 11420 11421 /* 11422 * Continuation if the field has not yet been resolved. 11423 * r1: BBBB field ref 11424 */ 11425.LOP_SGET_SHORT_resolve: 11426 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11427 EXPORT_PC() @ resolve() could throw, so export now 11428 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11429 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11430 cmp r0, #0 @ success? 11431 bne .LOP_SGET_SHORT_finish @ yes, finish 11432 b common_exceptionThrown @ no, handle exception 11433 11434/* continuation for OP_SPUT */ 11435 11436 /* 11437 * Continuation if the field has not yet been resolved. 11438 * r1: BBBB field ref 11439 */ 11440.LOP_SPUT_resolve: 11441 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11442 EXPORT_PC() @ resolve() could throw, so export now 11443 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11444 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11445 cmp r0, #0 @ success? 11446 bne .LOP_SPUT_finish @ yes, finish 11447 b common_exceptionThrown @ no, handle exception 11448 11449/* continuation for OP_SPUT_WIDE */ 11450 11451 /* 11452 * Continuation if the field has not yet been resolved. 11453 * r1: BBBB field ref 11454 * r9: &fp[AA] 11455 * 11456 * Returns StaticField pointer in r2. 11457 */ 11458.LOP_SPUT_WIDE_resolve: 11459 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11460 EXPORT_PC() @ resolve() could throw, so export now 11461 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11462 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11463 cmp r0, #0 @ success? 11464 mov r2, r0 @ copy to r2 11465 bne .LOP_SPUT_WIDE_finish @ yes, finish 11466 b common_exceptionThrown @ no, handle exception 11467 11468/* continuation for OP_SPUT_OBJECT */ 11469.LOP_SPUT_OBJECT_finish: @ field ptr in r0 11470 mov r2, rINST, lsr #8 @ r2<- AA 11471 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11472 GET_VREG(r1, r2) @ r1<- fp[AA] 11473 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 11474 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 11475 GET_INST_OPCODE(ip) @ extract opcode from rINST 11476 @ no-op @ releasing store 11477 str r1, [r0, #offStaticField_value] @ field<- vAA 11478 cmp r1, #0 @ stored a null object? 11479 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 11480 GOTO_OPCODE(ip) @ jump to next instruction 11481 11482/* continuation for OP_SPUT_BOOLEAN */ 11483 11484 /* 11485 * Continuation if the field has not yet been resolved. 11486 * r1: BBBB field ref 11487 */ 11488.LOP_SPUT_BOOLEAN_resolve: 11489 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11490 EXPORT_PC() @ resolve() could throw, so export now 11491 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11492 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11493 cmp r0, #0 @ success? 11494 bne .LOP_SPUT_BOOLEAN_finish @ yes, finish 11495 b common_exceptionThrown @ no, handle exception 11496 11497/* continuation for OP_SPUT_BYTE */ 11498 11499 /* 11500 * Continuation if the field has not yet been resolved. 11501 * r1: BBBB field ref 11502 */ 11503.LOP_SPUT_BYTE_resolve: 11504 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11505 EXPORT_PC() @ resolve() could throw, so export now 11506 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11507 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11508 cmp r0, #0 @ success? 11509 bne .LOP_SPUT_BYTE_finish @ yes, finish 11510 b common_exceptionThrown @ no, handle exception 11511 11512/* continuation for OP_SPUT_CHAR */ 11513 11514 /* 11515 * Continuation if the field has not yet been resolved. 11516 * r1: BBBB field ref 11517 */ 11518.LOP_SPUT_CHAR_resolve: 11519 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11520 EXPORT_PC() @ resolve() could throw, so export now 11521 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11522 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11523 cmp r0, #0 @ success? 11524 bne .LOP_SPUT_CHAR_finish @ yes, finish 11525 b common_exceptionThrown @ no, handle exception 11526 11527/* continuation for OP_SPUT_SHORT */ 11528 11529 /* 11530 * Continuation if the field has not yet been resolved. 11531 * r1: BBBB field ref 11532 */ 11533.LOP_SPUT_SHORT_resolve: 11534 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11535 EXPORT_PC() @ resolve() could throw, so export now 11536 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11537 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11538 cmp r0, #0 @ success? 11539 bne .LOP_SPUT_SHORT_finish @ yes, finish 11540 b common_exceptionThrown @ no, handle exception 11541 11542/* continuation for OP_INVOKE_VIRTUAL */ 11543 11544 /* 11545 * At this point: 11546 * r0 = resolved base method 11547 * r10 = C or CCCC (index of first arg, which is the "this" ptr) 11548 */ 11549.LOP_INVOKE_VIRTUAL_continue: 11550 GET_VREG(r1, r10) @ r1<- "this" ptr 11551 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 11552 cmp r1, #0 @ is "this" null? 11553 beq common_errNullObject @ null "this", throw exception 11554 ldr r3, [r1, #offObject_clazz] @ r1<- thisPtr->clazz 11555 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 11556 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 11557 bl common_invokeMethodNoRange @ continue on 11558 11559/* continuation for OP_INVOKE_SUPER */ 11560 11561 /* 11562 * At this point: 11563 * r0 = resolved base method 11564 * r9 = method->clazz 11565 */ 11566.LOP_INVOKE_SUPER_continue: 11567 ldr r1, [r9, #offClassObject_super] @ r1<- method->clazz->super 11568 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 11569 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 11570 EXPORT_PC() @ must export for invoke 11571 cmp r2, r3 @ compare (methodIndex, vtableCount) 11572 bcs .LOP_INVOKE_SUPER_nsm @ method not present in superclass 11573 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 11574 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 11575 bl common_invokeMethodNoRange @ continue on 11576 11577.LOP_INVOKE_SUPER_resolve: 11578 mov r0, r9 @ r0<- method->clazz 11579 mov r2, #METHOD_VIRTUAL @ resolver method type 11580 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 11581 cmp r0, #0 @ got null? 11582 bne .LOP_INVOKE_SUPER_continue @ no, continue 11583 b common_exceptionThrown @ yes, handle exception 11584 11585 /* 11586 * Throw a NoSuchMethodError with the method name as the message. 11587 * r0 = resolved base method 11588 */ 11589.LOP_INVOKE_SUPER_nsm: 11590 ldr r1, [r0, #offMethod_name] @ r1<- method name 11591 b common_errNoSuchMethod 11592 11593/* continuation for OP_INVOKE_DIRECT */ 11594 11595 /* 11596 * On entry: 11597 * r1 = reference (BBBB or CCCC) 11598 * r10 = "this" register 11599 */ 11600.LOP_INVOKE_DIRECT_resolve: 11601 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 11602 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 11603 mov r2, #METHOD_DIRECT @ resolver method type 11604 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 11605 cmp r0, #0 @ got null? 11606 GET_VREG(r2, r10) @ r2<- "this" ptr (reload) 11607 bne .LOP_INVOKE_DIRECT_finish @ no, continue 11608 b common_exceptionThrown @ yes, handle exception 11609 11610/* continuation for OP_INVOKE_VIRTUAL_RANGE */ 11611 11612 /* 11613 * At this point: 11614 * r0 = resolved base method 11615 * r10 = C or CCCC (index of first arg, which is the "this" ptr) 11616 */ 11617.LOP_INVOKE_VIRTUAL_RANGE_continue: 11618 GET_VREG(r1, r10) @ r1<- "this" ptr 11619 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 11620 cmp r1, #0 @ is "this" null? 11621 beq common_errNullObject @ null "this", throw exception 11622 ldr r3, [r1, #offObject_clazz] @ r1<- thisPtr->clazz 11623 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 11624 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 11625 bl common_invokeMethodRange @ continue on 11626 11627/* continuation for OP_INVOKE_SUPER_RANGE */ 11628 11629 /* 11630 * At this point: 11631 * r0 = resolved base method 11632 * r9 = method->clazz 11633 */ 11634.LOP_INVOKE_SUPER_RANGE_continue: 11635 ldr r1, [r9, #offClassObject_super] @ r1<- method->clazz->super 11636 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 11637 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 11638 EXPORT_PC() @ must export for invoke 11639 cmp r2, r3 @ compare (methodIndex, vtableCount) 11640 bcs .LOP_INVOKE_SUPER_RANGE_nsm @ method not present in superclass 11641 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 11642 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 11643 bl common_invokeMethodRange @ continue on 11644 11645.LOP_INVOKE_SUPER_RANGE_resolve: 11646 mov r0, r9 @ r0<- method->clazz 11647 mov r2, #METHOD_VIRTUAL @ resolver method type 11648 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 11649 cmp r0, #0 @ got null? 11650 bne .LOP_INVOKE_SUPER_RANGE_continue @ no, continue 11651 b common_exceptionThrown @ yes, handle exception 11652 11653 /* 11654 * Throw a NoSuchMethodError with the method name as the message. 11655 * r0 = resolved base method 11656 */ 11657.LOP_INVOKE_SUPER_RANGE_nsm: 11658 ldr r1, [r0, #offMethod_name] @ r1<- method name 11659 b common_errNoSuchMethod 11660 11661/* continuation for OP_INVOKE_DIRECT_RANGE */ 11662 11663 /* 11664 * On entry: 11665 * r1 = reference (BBBB or CCCC) 11666 * r10 = "this" register 11667 */ 11668.LOP_INVOKE_DIRECT_RANGE_resolve: 11669 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 11670 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 11671 mov r2, #METHOD_DIRECT @ resolver method type 11672 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 11673 cmp r0, #0 @ got null? 11674 GET_VREG(r2, r10) @ r2<- "this" ptr (reload) 11675 bne .LOP_INVOKE_DIRECT_RANGE_finish @ no, continue 11676 b common_exceptionThrown @ yes, handle exception 11677 11678/* continuation for OP_FLOAT_TO_LONG */ 11679/* 11680 * Convert the float in r0 to a long in r0/r1. 11681 * 11682 * We have to clip values to long min/max per the specification. The 11683 * expected common case is a "reasonable" value that converts directly 11684 * to modest integer. The EABI convert function isn't doing this for us. 11685 */ 11686f2l_doconv: 11687 stmfd sp!, {r4, lr} 11688 mov r1, #0x5f000000 @ (float)maxlong 11689 mov r4, r0 11690 bl __aeabi_fcmpge @ is arg >= maxlong? 11691 cmp r0, #0 @ nonzero == yes 11692 mvnne r0, #0 @ return maxlong (7fffffff) 11693 mvnne r1, #0x80000000 11694 ldmnefd sp!, {r4, pc} 11695 11696 mov r0, r4 @ recover arg 11697 mov r1, #0xdf000000 @ (float)minlong 11698 bl __aeabi_fcmple @ is arg <= minlong? 11699 cmp r0, #0 @ nonzero == yes 11700 movne r0, #0 @ return minlong (80000000) 11701 movne r1, #0x80000000 11702 ldmnefd sp!, {r4, pc} 11703 11704 mov r0, r4 @ recover arg 11705 mov r1, r4 11706 bl __aeabi_fcmpeq @ is arg == self? 11707 cmp r0, #0 @ zero == no 11708 moveq r1, #0 @ return zero for NaN 11709 ldmeqfd sp!, {r4, pc} 11710 11711 mov r0, r4 @ recover arg 11712 bl __aeabi_f2lz @ convert float to long 11713 ldmfd sp!, {r4, pc} 11714 11715/* continuation for OP_DOUBLE_TO_LONG */ 11716/* 11717 * Convert the double in r0/r1 to a long in r0/r1. 11718 * 11719 * We have to clip values to long min/max per the specification. The 11720 * expected common case is a "reasonable" value that converts directly 11721 * to modest integer. The EABI convert function isn't doing this for us. 11722 */ 11723d2l_doconv: 11724 stmfd sp!, {r4, r5, lr} @ save regs 11725 mov r3, #0x43000000 @ maxlong, as a double (high word) 11726 add r3, #0x00e00000 @ 0x43e00000 11727 mov r2, #0 @ maxlong, as a double (low word) 11728 sub sp, sp, #4 @ align for EABI 11729 mov r4, r0 @ save a copy of r0 11730 mov r5, r1 @ and r1 11731 bl __aeabi_dcmpge @ is arg >= maxlong? 11732 cmp r0, #0 @ nonzero == yes 11733 mvnne r0, #0 @ return maxlong (7fffffffffffffff) 11734 mvnne r1, #0x80000000 11735 bne 1f 11736 11737 mov r0, r4 @ recover arg 11738 mov r1, r5 11739 mov r3, #0xc3000000 @ minlong, as a double (high word) 11740 add r3, #0x00e00000 @ 0xc3e00000 11741 mov r2, #0 @ minlong, as a double (low word) 11742 bl __aeabi_dcmple @ is arg <= minlong? 11743 cmp r0, #0 @ nonzero == yes 11744 movne r0, #0 @ return minlong (8000000000000000) 11745 movne r1, #0x80000000 11746 bne 1f 11747 11748 mov r0, r4 @ recover arg 11749 mov r1, r5 11750 mov r2, r4 @ compare against self 11751 mov r3, r5 11752 bl __aeabi_dcmpeq @ is arg == self? 11753 cmp r0, #0 @ zero == no 11754 moveq r1, #0 @ return zero for NaN 11755 beq 1f 11756 11757 mov r0, r4 @ recover arg 11758 mov r1, r5 11759 bl __aeabi_d2lz @ convert double to long 11760 117611: 11762 add sp, sp, #4 11763 ldmfd sp!, {r4, r5, pc} 11764 11765/* continuation for OP_MUL_LONG */ 11766 11767.LOP_MUL_LONG_finish: 11768 GET_INST_OPCODE(ip) @ extract opcode from rINST 11769 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 11770 GOTO_OPCODE(ip) @ jump to next instruction 11771 11772/* continuation for OP_SHL_LONG */ 11773 11774.LOP_SHL_LONG_finish: 11775 mov r0, r0, asl r2 @ r0<- r0 << r2 11776 GET_INST_OPCODE(ip) @ extract opcode from rINST 11777 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11778 GOTO_OPCODE(ip) @ jump to next instruction 11779 11780/* continuation for OP_SHR_LONG */ 11781 11782.LOP_SHR_LONG_finish: 11783 mov r1, r1, asr r2 @ r1<- r1 >> r2 11784 GET_INST_OPCODE(ip) @ extract opcode from rINST 11785 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11786 GOTO_OPCODE(ip) @ jump to next instruction 11787 11788/* continuation for OP_USHR_LONG */ 11789 11790.LOP_USHR_LONG_finish: 11791 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 11792 GET_INST_OPCODE(ip) @ extract opcode from rINST 11793 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11794 GOTO_OPCODE(ip) @ jump to next instruction 11795 11796/* continuation for OP_SHL_LONG_2ADDR */ 11797 11798.LOP_SHL_LONG_2ADDR_finish: 11799 GET_INST_OPCODE(ip) @ extract opcode from rINST 11800 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11801 GOTO_OPCODE(ip) @ jump to next instruction 11802 11803/* continuation for OP_SHR_LONG_2ADDR */ 11804 11805.LOP_SHR_LONG_2ADDR_finish: 11806 GET_INST_OPCODE(ip) @ extract opcode from rINST 11807 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11808 GOTO_OPCODE(ip) @ jump to next instruction 11809 11810/* continuation for OP_USHR_LONG_2ADDR */ 11811 11812.LOP_USHR_LONG_2ADDR_finish: 11813 GET_INST_OPCODE(ip) @ extract opcode from rINST 11814 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11815 GOTO_OPCODE(ip) @ jump to next instruction 11816 11817/* continuation for OP_IGET_VOLATILE */ 11818 11819 /* 11820 * Currently: 11821 * r0 holds resolved field 11822 * r9 holds object 11823 */ 11824.LOP_IGET_VOLATILE_finish: 11825 @bl common_squeak0 11826 cmp r9, #0 @ check object for null 11827 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11828 beq common_errNullObject @ object was null 11829 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11830 SMP_DMB @ acquiring load 11831 mov r2, rINST, lsr #8 @ r2<- A+ 11832 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11833 and r2, r2, #15 @ r2<- A 11834 GET_INST_OPCODE(ip) @ extract opcode from rINST 11835 SET_VREG(r0, r2) @ fp[A]<- r0 11836 GOTO_OPCODE(ip) @ jump to next instruction 11837 11838/* continuation for OP_IPUT_VOLATILE */ 11839 11840 /* 11841 * Currently: 11842 * r0 holds resolved field 11843 * r9 holds object 11844 */ 11845.LOP_IPUT_VOLATILE_finish: 11846 @bl common_squeak0 11847 mov r1, rINST, lsr #8 @ r1<- A+ 11848 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11849 and r1, r1, #15 @ r1<- A 11850 cmp r9, #0 @ check object for null 11851 GET_VREG(r0, r1) @ r0<- fp[A] 11852 beq common_errNullObject @ object was null 11853 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11854 GET_INST_OPCODE(ip) @ extract opcode from rINST 11855 SMP_DMB @ releasing store 11856 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11857 GOTO_OPCODE(ip) @ jump to next instruction 11858 11859/* continuation for OP_SGET_VOLATILE */ 11860 11861 /* 11862 * Continuation if the field has not yet been resolved. 11863 * r1: BBBB field ref 11864 */ 11865.LOP_SGET_VOLATILE_resolve: 11866 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11867 EXPORT_PC() @ resolve() could throw, so export now 11868 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11869 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11870 cmp r0, #0 @ success? 11871 bne .LOP_SGET_VOLATILE_finish @ yes, finish 11872 b common_exceptionThrown @ no, handle exception 11873 11874/* continuation for OP_SPUT_VOLATILE */ 11875 11876 /* 11877 * Continuation if the field has not yet been resolved. 11878 * r1: BBBB field ref 11879 */ 11880.LOP_SPUT_VOLATILE_resolve: 11881 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11882 EXPORT_PC() @ resolve() could throw, so export now 11883 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11884 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11885 cmp r0, #0 @ success? 11886 bne .LOP_SPUT_VOLATILE_finish @ yes, finish 11887 b common_exceptionThrown @ no, handle exception 11888 11889/* continuation for OP_IGET_OBJECT_VOLATILE */ 11890 11891 /* 11892 * Currently: 11893 * r0 holds resolved field 11894 * r9 holds object 11895 */ 11896.LOP_IGET_OBJECT_VOLATILE_finish: 11897 @bl common_squeak0 11898 cmp r9, #0 @ check object for null 11899 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11900 beq common_errNullObject @ object was null 11901 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11902 SMP_DMB @ acquiring load 11903 mov r2, rINST, lsr #8 @ r2<- A+ 11904 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11905 and r2, r2, #15 @ r2<- A 11906 GET_INST_OPCODE(ip) @ extract opcode from rINST 11907 SET_VREG(r0, r2) @ fp[A]<- r0 11908 GOTO_OPCODE(ip) @ jump to next instruction 11909 11910/* continuation for OP_IGET_WIDE_VOLATILE */ 11911 11912 /* 11913 * Currently: 11914 * r0 holds resolved field 11915 * r9 holds object 11916 */ 11917.LOP_IGET_WIDE_VOLATILE_finish: 11918 cmp r9, #0 @ check object for null 11919 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11920 beq common_errNullObject @ object was null 11921 .if 1 11922 add r0, r9, r3 @ r0<- address of field 11923 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 11924 .else 11925 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 11926 .endif 11927 mov r2, rINST, lsr #8 @ r2<- A+ 11928 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11929 and r2, r2, #15 @ r2<- A 11930 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 11931 GET_INST_OPCODE(ip) @ extract opcode from rINST 11932 stmia r3, {r0-r1} @ fp[A]<- r0/r1 11933 GOTO_OPCODE(ip) @ jump to next instruction 11934 11935/* continuation for OP_IPUT_WIDE_VOLATILE */ 11936 11937 /* 11938 * Currently: 11939 * r0 holds resolved field 11940 * r9 holds object 11941 */ 11942.LOP_IPUT_WIDE_VOLATILE_finish: 11943 mov r2, rINST, lsr #8 @ r2<- A+ 11944 cmp r9, #0 @ check object for null 11945 and r2, r2, #15 @ r2<- A 11946 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11947 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 11948 beq common_errNullObject @ object was null 11949 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11950 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 11951 GET_INST_OPCODE(r10) @ extract opcode from rINST 11952 .if 1 11953 add r2, r9, r3 @ r2<- target address 11954 bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2 11955 .else 11956 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 11957 .endif 11958 GOTO_OPCODE(r10) @ jump to next instruction 11959 11960/* continuation for OP_SGET_WIDE_VOLATILE */ 11961 11962 /* 11963 * Continuation if the field has not yet been resolved. 11964 * r1: BBBB field ref 11965 * 11966 * Returns StaticField pointer in r0. 11967 */ 11968.LOP_SGET_WIDE_VOLATILE_resolve: 11969 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11970 EXPORT_PC() @ resolve() could throw, so export now 11971 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11972 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11973 cmp r0, #0 @ success? 11974 bne .LOP_SGET_WIDE_VOLATILE_finish @ yes, finish 11975 b common_exceptionThrown @ no, handle exception 11976 11977/* continuation for OP_SPUT_WIDE_VOLATILE */ 11978 11979 /* 11980 * Continuation if the field has not yet been resolved. 11981 * r1: BBBB field ref 11982 * r9: &fp[AA] 11983 * 11984 * Returns StaticField pointer in r2. 11985 */ 11986.LOP_SPUT_WIDE_VOLATILE_resolve: 11987 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11988 EXPORT_PC() @ resolve() could throw, so export now 11989 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11990 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11991 cmp r0, #0 @ success? 11992 mov r2, r0 @ copy to r2 11993 bne .LOP_SPUT_WIDE_VOLATILE_finish @ yes, finish 11994 b common_exceptionThrown @ no, handle exception 11995 11996/* continuation for OP_EXECUTE_INLINE */ 11997 11998 /* 11999 * Extract args, call function. 12000 * r0 = #of args (0-4) 12001 * r10 = call index 12002 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 12003 * 12004 * Other ideas: 12005 * - Use a jump table from the main piece to jump directly into the 12006 * AND/LDR pairs. Costs a data load, saves a branch. 12007 * - Have five separate pieces that do the loading, so we can work the 12008 * interleave a little better. Increases code size. 12009 */ 12010.LOP_EXECUTE_INLINE_continue: 12011 rsb r0, r0, #4 @ r0<- 4-r0 12012 FETCH(r9, 2) @ r9<- FEDC 12013 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 12014 bl common_abort @ (skipped due to ARM prefetch) 120154: and ip, r9, #0xf000 @ isolate F 12016 ldr r3, [rFP, ip, lsr #10] @ r3<- vF (shift right 12, left 2) 120173: and ip, r9, #0x0f00 @ isolate E 12018 ldr r2, [rFP, ip, lsr #6] @ r2<- vE 120192: and ip, r9, #0x00f0 @ isolate D 12020 ldr r1, [rFP, ip, lsr #2] @ r1<- vD 120211: and ip, r9, #0x000f @ isolate C 12022 ldr r0, [rFP, ip, lsl #2] @ r0<- vC 120230: 12024 ldr r9, .LOP_EXECUTE_INLINE_table @ table of InlineOperation 12025 ldr pc, [r9, r10, lsl #4] @ sizeof=16, "func" is first entry 12026 @ (not reached) 12027 12028.LOP_EXECUTE_INLINE_table: 12029 .word gDvmInlineOpsTable 12030 12031/* continuation for OP_EXECUTE_INLINE_RANGE */ 12032 12033 /* 12034 * Extract args, call function. 12035 * r0 = #of args (0-4) 12036 * r10 = call index 12037 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 12038 */ 12039.LOP_EXECUTE_INLINE_RANGE_continue: 12040 rsb r0, r0, #4 @ r0<- 4-r0 12041 FETCH(r9, 2) @ r9<- CCCC 12042 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 12043 bl common_abort @ (skipped due to ARM prefetch) 120444: add ip, r9, #3 @ base+3 12045 GET_VREG(r3, ip) @ r3<- vBase[3] 120463: add ip, r9, #2 @ base+2 12047 GET_VREG(r2, ip) @ r2<- vBase[2] 120482: add ip, r9, #1 @ base+1 12049 GET_VREG(r1, ip) @ r1<- vBase[1] 120501: add ip, r9, #0 @ (nop) 12051 GET_VREG(r0, ip) @ r0<- vBase[0] 120520: 12053 ldr r9, .LOP_EXECUTE_INLINE_RANGE_table @ table of InlineOperation 12054 ldr pc, [r9, r10, lsl #4] @ sizeof=16, "func" is first entry 12055 @ (not reached) 12056 12057.LOP_EXECUTE_INLINE_RANGE_table: 12058 .word gDvmInlineOpsTable 12059 12060/* continuation for OP_IPUT_OBJECT_VOLATILE */ 12061 12062 /* 12063 * Currently: 12064 * r0 holds resolved field 12065 * r9 holds object 12066 */ 12067.LOP_IPUT_OBJECT_VOLATILE_finish: 12068 @bl common_squeak0 12069 mov r1, rINST, lsr #8 @ r1<- A+ 12070 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12071 and r1, r1, #15 @ r1<- A 12072 cmp r9, #0 @ check object for null 12073 GET_VREG(r0, r1) @ r0<- fp[A] 12074 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 12075 beq common_errNullObject @ object was null 12076 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 12077 GET_INST_OPCODE(ip) @ extract opcode from rINST 12078 SMP_DMB @ releasing store 12079 str r0, [r9, r3] @ obj.field (32 bits)<- r0 12080 cmp r0, #0 @ stored a null reference? 12081 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 12082 GOTO_OPCODE(ip) @ jump to next instruction 12083 12084/* continuation for OP_SGET_OBJECT_VOLATILE */ 12085 12086 /* 12087 * Continuation if the field has not yet been resolved. 12088 * r1: BBBB field ref 12089 */ 12090.LOP_SGET_OBJECT_VOLATILE_resolve: 12091 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12092 EXPORT_PC() @ resolve() could throw, so export now 12093 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12094 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12095 cmp r0, #0 @ success? 12096 bne .LOP_SGET_OBJECT_VOLATILE_finish @ yes, finish 12097 b common_exceptionThrown @ no, handle exception 12098 12099/* continuation for OP_SPUT_OBJECT_VOLATILE */ 12100.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0 12101 mov r2, rINST, lsr #8 @ r2<- AA 12102 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 12103 GET_VREG(r1, r2) @ r1<- fp[AA] 12104 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 12105 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 12106 GET_INST_OPCODE(ip) @ extract opcode from rINST 12107 SMP_DMB @ releasing store 12108 str r1, [r0, #offStaticField_value] @ field<- vAA 12109 cmp r1, #0 @ stored a null object? 12110 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 12111 GOTO_OPCODE(ip) @ jump to next instruction 12112 12113/* continuation for OP_CONST_CLASS_JUMBO */ 12114 12115 /* 12116 * Continuation if the Class has not yet been resolved. 12117 * r1: AAAAAAAA (Class ref) 12118 * r9: target register 12119 */ 12120.LOP_CONST_CLASS_JUMBO_resolve: 12121 EXPORT_PC() 12122 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 12123 mov r2, #1 @ r2<- true 12124 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 12125 bl dvmResolveClass @ r0<- Class reference 12126 cmp r0, #0 @ failed? 12127 beq common_exceptionThrown @ yup, handle the exception 12128 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 12129 GET_INST_OPCODE(ip) @ extract opcode from rINST 12130 SET_VREG(r0, r9) @ vBBBB<- r0 12131 GOTO_OPCODE(ip) @ jump to next instruction 12132 12133/* continuation for OP_CHECK_CAST_JUMBO */ 12134 12135 /* 12136 * Trivial test failed, need to perform full check. This is common. 12137 * r0 holds obj->clazz 12138 * r1 holds desired class resolved from AAAAAAAA 12139 * r9 holds object 12140 */ 12141.LOP_CHECK_CAST_JUMBO_fullcheck: 12142 mov r10, r1 @ avoid ClassObject getting clobbered 12143 bl dvmInstanceofNonTrivial @ r0<- boolean result 12144 cmp r0, #0 @ failed? 12145 bne .LOP_CHECK_CAST_JUMBO_okay @ no, success 12146 12147 @ A cast has failed. We need to throw a ClassCastException. 12148 EXPORT_PC() @ about to throw 12149 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class) 12150 mov r1, r10 @ r1<- desired class 12151 bl dvmThrowClassCastException 12152 b common_exceptionThrown 12153 12154 /* 12155 * Advance PC and get the next opcode. 12156 */ 12157.LOP_CHECK_CAST_JUMBO_okay: 12158 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 12159 GET_INST_OPCODE(ip) @ extract opcode from rINST 12160 GOTO_OPCODE(ip) @ jump to next instruction 12161 12162 /* 12163 * Resolution required. This is the least-likely path. 12164 * 12165 * r2 holds AAAAAAAA 12166 * r9 holds object 12167 */ 12168.LOP_CHECK_CAST_JUMBO_resolve: 12169 EXPORT_PC() @ resolve() could throw 12170 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 12171 mov r1, r2 @ r1<- AAAAAAAA 12172 mov r2, #0 @ r2<- false 12173 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 12174 bl dvmResolveClass @ r0<- resolved ClassObject ptr 12175 cmp r0, #0 @ got null? 12176 beq common_exceptionThrown @ yes, handle exception 12177 mov r1, r0 @ r1<- class resolved from AAAAAAAA 12178 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 12179 b .LOP_CHECK_CAST_JUMBO_resolved @ pick up where we left off 12180 12181/* continuation for OP_INSTANCE_OF_JUMBO */ 12182 12183 /* 12184 * Class resolved, determine type of check necessary. This is common. 12185 * r0 holds obj->clazz 12186 * r1 holds class resolved from AAAAAAAA 12187 * r9 holds BBBB 12188 */ 12189.LOP_INSTANCE_OF_JUMBO_resolved: 12190 cmp r0, r1 @ same class (trivial success)? 12191 beq .LOP_INSTANCE_OF_JUMBO_trivial @ yes, trivial finish 12192 @ fall through to OP_INSTANCE_OF_JUMBO_fullcheck 12193 12194 /* 12195 * Trivial test failed, need to perform full check. This is common. 12196 * r0 holds obj->clazz 12197 * r1 holds class resolved from AAAAAAAA 12198 * r9 holds BBBB 12199 */ 12200.LOP_INSTANCE_OF_JUMBO_fullcheck: 12201 bl dvmInstanceofNonTrivial @ r0<- boolean result 12202 @ fall through to OP_INSTANCE_OF_JUMBO_store 12203 12204 /* 12205 * r0 holds boolean result 12206 * r9 holds BBBB 12207 */ 12208.LOP_INSTANCE_OF_JUMBO_store: 12209 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12210 SET_VREG(r0, r9) @ vBBBB<- r0 12211 GET_INST_OPCODE(ip) @ extract opcode from rINST 12212 GOTO_OPCODE(ip) @ jump to next instruction 12213 12214 /* 12215 * Trivial test succeeded, save and bail. 12216 * r9 holds BBBB 12217 */ 12218.LOP_INSTANCE_OF_JUMBO_trivial: 12219 mov r0, #1 @ indicate success 12220 @ could b OP_INSTANCE_OF_JUMBO_store, but copying is faster and cheaper 12221 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12222 SET_VREG(r0, r9) @ vBBBB<- r0 12223 GET_INST_OPCODE(ip) @ extract opcode from rINST 12224 GOTO_OPCODE(ip) @ jump to next instruction 12225 12226 /* 12227 * Resolution required. This is the least-likely path. 12228 * 12229 * r3 holds AAAAAAAA 12230 * r9 holds BBBB 12231 */ 12232 12233.LOP_INSTANCE_OF_JUMBO_resolve: 12234 EXPORT_PC() @ resolve() could throw 12235 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 12236 mov r1, r3 @ r1<- AAAAAAAA 12237 mov r2, #1 @ r2<- true 12238 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 12239 bl dvmResolveClass @ r0<- resolved ClassObject ptr 12240 cmp r0, #0 @ got null? 12241 beq common_exceptionThrown @ yes, handle exception 12242 FETCH(r3, 4) @ r3<- vCCCC 12243 mov r1, r0 @ r1<- class resolved from AAAAAAAA 12244 GET_VREG(r0, r3) @ r0<- vCCCC (object) 12245 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 12246 b .LOP_INSTANCE_OF_JUMBO_resolved @ pick up where we left off 12247 12248/* continuation for OP_NEW_INSTANCE_JUMBO */ 12249 12250 .balign 32 @ minimize cache lines 12251.LOP_NEW_INSTANCE_JUMBO_finish: @ r0=new object 12252 FETCH(r3, 3) @ r3<- BBBB 12253 cmp r0, #0 @ failed? 12254 beq common_exceptionThrown @ yes, handle the exception 12255 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 12256 GET_INST_OPCODE(ip) @ extract opcode from rINST 12257 SET_VREG(r0, r3) @ vBBBB<- r0 12258 GOTO_OPCODE(ip) @ jump to next instruction 12259 12260 /* 12261 * Class initialization required. 12262 * 12263 * r0 holds class object 12264 */ 12265.LOP_NEW_INSTANCE_JUMBO_needinit: 12266 mov r9, r0 @ save r0 12267 bl dvmInitClass @ initialize class 12268 cmp r0, #0 @ check boolean result 12269 mov r0, r9 @ restore r0 12270 bne .LOP_NEW_INSTANCE_JUMBO_initialized @ success, continue 12271 b common_exceptionThrown @ failed, deal with init exception 12272 12273 /* 12274 * Resolution required. This is the least-likely path. 12275 * 12276 * r1 holds AAAAAAAA 12277 */ 12278.LOP_NEW_INSTANCE_JUMBO_resolve: 12279 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 12280 mov r2, #0 @ r2<- false 12281 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 12282 bl dvmResolveClass @ r0<- resolved ClassObject ptr 12283 cmp r0, #0 @ got null? 12284 bne .LOP_NEW_INSTANCE_JUMBO_resolved @ no, continue 12285 b common_exceptionThrown @ yes, handle exception 12286 12287/* continuation for OP_NEW_ARRAY_JUMBO */ 12288 12289 12290 /* 12291 * Resolve class. (This is an uncommon case.) 12292 * 12293 * r1 holds array length 12294 * r2 holds class ref AAAAAAAA 12295 */ 12296.LOP_NEW_ARRAY_JUMBO_resolve: 12297 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 12298 mov r9, r1 @ r9<- length (save) 12299 mov r1, r2 @ r1<- AAAAAAAA 12300 mov r2, #0 @ r2<- false 12301 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 12302 bl dvmResolveClass @ r0<- call(clazz, ref) 12303 cmp r0, #0 @ got null? 12304 mov r1, r9 @ r1<- length (restore) 12305 beq common_exceptionThrown @ yes, handle exception 12306 @ fall through to OP_NEW_ARRAY_JUMBO_finish 12307 12308 /* 12309 * Finish allocation. 12310 * 12311 * r0 holds class 12312 * r1 holds array length 12313 */ 12314.LOP_NEW_ARRAY_JUMBO_finish: 12315 mov r2, #ALLOC_DONT_TRACK @ don't track in local refs table 12316 bl dvmAllocArrayByClass @ r0<- call(clazz, length, flags) 12317 cmp r0, #0 @ failed? 12318 FETCH(r2, 3) @ r2<- vBBBB 12319 beq common_exceptionThrown @ yes, handle the exception 12320 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12321 GET_INST_OPCODE(ip) @ extract opcode from rINST 12322 SET_VREG(r0, r2) @ vBBBB<- r0 12323 GOTO_OPCODE(ip) @ jump to next instruction 12324 12325/* continuation for OP_FILLED_NEW_ARRAY_JUMBO */ 12326 12327 /* 12328 * On entry: 12329 * r0 holds array class 12330 */ 12331.LOP_FILLED_NEW_ARRAY_JUMBO_continue: 12332 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 12333 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 12334 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 12335 FETCH(r1, 3) @ r1<- BBBB (length) 12336 cmp rINST, #'I' @ array of ints? 12337 cmpne rINST, #'L' @ array of objects? 12338 cmpne rINST, #'[' @ array of arrays? 12339 mov r9, r1 @ save length in r9 12340 bne .LOP_FILLED_NEW_ARRAY_JUMBO_notimpl @ no, not handled yet 12341 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 12342 cmp r0, #0 @ null return? 12343 beq common_exceptionThrown @ alloc failed, handle exception 12344 12345 FETCH(r1, 4) @ r1<- CCCC 12346 str r0, [rGLUE, #offGlue_retval] @ retval.l <- new array 12347 str rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type 12348 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 12349 subs r9, r9, #1 @ length--, check for neg 12350 FETCH_ADVANCE_INST(5) @ advance to next instr, load rINST 12351 bmi 2f @ was zero, bail 12352 12353 @ copy values from registers into the array 12354 @ r0=array, r1=CCCC, r9=BBBB (length) 12355 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 123561: ldr r3, [r2], #4 @ r3<- *r2++ 12357 subs r9, r9, #1 @ count-- 12358 str r3, [r0], #4 @ *contents++ = vX 12359 bpl 1b 12360 123612: ldr r0, [rGLUE, #offGlue_retval] @ r0<- object 12362 ldr r1, [rGLUE, #offGlue_retval+4] @ r1<- type 12363 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 12364 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 12365 cmp r1, #'I' @ Is int array? 12366 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 12367 GOTO_OPCODE(ip) @ execute it 12368 12369 /* 12370 * Throw an exception indicating that we have not implemented this 12371 * mode of filled-new-array. 12372 */ 12373.LOP_FILLED_NEW_ARRAY_JUMBO_notimpl: 12374 ldr r0, .L_strInternalError 12375 ldr r1, .L_strFilledNewArrayNotImpl 12376 bl dvmThrowException 12377 b common_exceptionThrown 12378 12379/* continuation for OP_IGET_JUMBO */ 12380 12381 /* 12382 * Currently: 12383 * r0 holds resolved field 12384 * r9 holds object 12385 */ 12386.LOP_IGET_JUMBO_resolved: 12387 cmp r0, #0 @ resolution unsuccessful? 12388 beq common_exceptionThrown @ yes, throw exception 12389 @ fall through to OP_IGET_JUMBO_finish 12390 12391 /* 12392 * Currently: 12393 * r0 holds resolved field 12394 * r9 holds object 12395 */ 12396.LOP_IGET_JUMBO_finish: 12397 @bl common_squeak0 12398 cmp r9, #0 @ check object for null 12399 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12400 beq common_errNullObject @ object was null 12401 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12402 @ no-op @ acquiring load 12403 FETCH(r2, 3) @ r2<- BBBB 12404 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12405 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12406 GET_INST_OPCODE(ip) @ extract opcode from rINST 12407 GOTO_OPCODE(ip) @ jump to next instruction 12408 12409/* continuation for OP_IGET_WIDE_JUMBO */ 12410 12411 /* 12412 * Currently: 12413 * r0 holds resolved field 12414 * r9 holds object 12415 */ 12416.LOP_IGET_WIDE_JUMBO_resolved: 12417 cmp r0, #0 @ resolution unsuccessful? 12418 beq common_exceptionThrown @ yes, throw exception 12419 @ fall through to OP_IGET_WIDE_JUMBO_finish 12420 12421 /* 12422 * Currently: 12423 * r0 holds resolved field 12424 * r9 holds object 12425 */ 12426.LOP_IGET_WIDE_JUMBO_finish: 12427 cmp r9, #0 @ check object for null 12428 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12429 beq common_errNullObject @ object was null 12430 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 12431 FETCH(r2, 3) @ r2<- BBBB 12432 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12433 add r3, rFP, r2, lsl #2 @ r3<- &fp[BBBB] 12434 GET_INST_OPCODE(ip) @ extract opcode from rINST 12435 stmia r3, {r0-r1} @ fp[BBBB]<- r0/r1 12436 GOTO_OPCODE(ip) @ jump to next instruction 12437 12438/* continuation for OP_IGET_OBJECT_JUMBO */ 12439 12440 /* 12441 * Currently: 12442 * r0 holds resolved field 12443 * r9 holds object 12444 */ 12445.LOP_IGET_OBJECT_JUMBO_resolved: 12446 cmp r0, #0 @ resolution unsuccessful? 12447 beq common_exceptionThrown @ yes, throw exception 12448 @ fall through to OP_IGET_OBJECT_JUMBO_finish 12449 12450 /* 12451 * Currently: 12452 * r0 holds resolved field 12453 * r9 holds object 12454 */ 12455.LOP_IGET_OBJECT_JUMBO_finish: 12456 @bl common_squeak0 12457 cmp r9, #0 @ check object for null 12458 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12459 beq common_errNullObject @ object was null 12460 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12461 @ no-op @ acquiring load 12462 FETCH(r2, 3) @ r2<- BBBB 12463 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12464 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12465 GET_INST_OPCODE(ip) @ extract opcode from rINST 12466 GOTO_OPCODE(ip) @ jump to next instruction 12467 12468/* continuation for OP_IGET_BOOLEAN_JUMBO */ 12469 12470 /* 12471 * Currently: 12472 * r0 holds resolved field 12473 * r9 holds object 12474 */ 12475.LOP_IGET_BOOLEAN_JUMBO_resolved: 12476 cmp r0, #0 @ resolution unsuccessful? 12477 beq common_exceptionThrown @ yes, throw exception 12478 @ fall through to OP_IGET_BOOLEAN_JUMBO_finish 12479 12480 /* 12481 * Currently: 12482 * r0 holds resolved field 12483 * r9 holds object 12484 */ 12485.LOP_IGET_BOOLEAN_JUMBO_finish: 12486 @bl common_squeak1 12487 cmp r9, #0 @ check object for null 12488 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12489 beq common_errNullObject @ object was null 12490 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12491 @ no-op @ acquiring load 12492 FETCH(r2, 3) @ r2<- BBBB 12493 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12494 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12495 GET_INST_OPCODE(ip) @ extract opcode from rINST 12496 GOTO_OPCODE(ip) @ jump to next instruction 12497 12498/* continuation for OP_IGET_BYTE_JUMBO */ 12499 12500 /* 12501 * Currently: 12502 * r0 holds resolved field 12503 * r9 holds object 12504 */ 12505.LOP_IGET_BYTE_JUMBO_resolved: 12506 cmp r0, #0 @ resolution unsuccessful? 12507 beq common_exceptionThrown @ yes, throw exception 12508 @ fall through to OP_IGET_BYTE_JUMBO_finish 12509 12510 /* 12511 * Currently: 12512 * r0 holds resolved field 12513 * r9 holds object 12514 */ 12515.LOP_IGET_BYTE_JUMBO_finish: 12516 @bl common_squeak2 12517 cmp r9, #0 @ check object for null 12518 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12519 beq common_errNullObject @ object was null 12520 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12521 @ no-op @ acquiring load 12522 FETCH(r2, 3) @ r2<- BBBB 12523 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12524 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12525 GET_INST_OPCODE(ip) @ extract opcode from rINST 12526 GOTO_OPCODE(ip) @ jump to next instruction 12527 12528/* continuation for OP_IGET_CHAR_JUMBO */ 12529 12530 /* 12531 * Currently: 12532 * r0 holds resolved field 12533 * r9 holds object 12534 */ 12535.LOP_IGET_CHAR_JUMBO_resolved: 12536 cmp r0, #0 @ resolution unsuccessful? 12537 beq common_exceptionThrown @ yes, throw exception 12538 @ fall through to OP_IGET_CHAR_JUMBO_finish 12539 12540 /* 12541 * Currently: 12542 * r0 holds resolved field 12543 * r9 holds object 12544 */ 12545.LOP_IGET_CHAR_JUMBO_finish: 12546 @bl common_squeak3 12547 cmp r9, #0 @ check object for null 12548 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12549 beq common_errNullObject @ object was null 12550 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12551 @ no-op @ acquiring load 12552 FETCH(r2, 3) @ r2<- BBBB 12553 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12554 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12555 GET_INST_OPCODE(ip) @ extract opcode from rINST 12556 GOTO_OPCODE(ip) @ jump to next instruction 12557 12558/* continuation for OP_IGET_SHORT_JUMBO */ 12559 12560 /* 12561 * Currently: 12562 * r0 holds resolved field 12563 * r9 holds object 12564 */ 12565.LOP_IGET_SHORT_JUMBO_resolved: 12566 cmp r0, #0 @ resolution unsuccessful? 12567 beq common_exceptionThrown @ yes, throw exception 12568 @ fall through to OP_IGET_SHORT_JUMBO_finish 12569 12570 /* 12571 * Currently: 12572 * r0 holds resolved field 12573 * r9 holds object 12574 */ 12575.LOP_IGET_SHORT_JUMBO_finish: 12576 @bl common_squeak4 12577 cmp r9, #0 @ check object for null 12578 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12579 beq common_errNullObject @ object was null 12580 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12581 @ no-op @ acquiring load 12582 FETCH(r2, 3) @ r2<- BBBB 12583 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12584 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12585 GET_INST_OPCODE(ip) @ extract opcode from rINST 12586 GOTO_OPCODE(ip) @ jump to next instruction 12587 12588/* continuation for OP_IPUT_JUMBO */ 12589 12590 /* 12591 * Currently: 12592 * r0 holds resolved field 12593 * r9 holds object 12594 */ 12595.LOP_IPUT_JUMBO_resolved: 12596 cmp r0, #0 @ resolution unsuccessful? 12597 beq common_exceptionThrown @ yes, throw exception 12598 @ fall through to OP_IPUT_JUMBO_finish 12599 12600 /* 12601 * Currently: 12602 * r0 holds resolved field 12603 * r9 holds object 12604 */ 12605.LOP_IPUT_JUMBO_finish: 12606 @bl common_squeak0 12607 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12608 FETCH(r1, 3) @ r1<- BBBB 12609 cmp r9, #0 @ check object for null 12610 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12611 beq common_errNullObject @ object was null 12612 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12613 GET_INST_OPCODE(ip) @ extract opcode from rINST 12614 @ no-op @ releasing store 12615 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12616 GOTO_OPCODE(ip) @ jump to next instruction 12617 12618/* continuation for OP_IPUT_WIDE_JUMBO */ 12619 12620 /* 12621 * Currently: 12622 * r0 holds resolved field 12623 * r9 holds object 12624 */ 12625.LOP_IPUT_WIDE_JUMBO_resolved: 12626 cmp r0, #0 @ resolution unsuccessful? 12627 beq common_exceptionThrown @ yes, throw exception 12628 @ fall through to OP_IPUT_WIDE_JUMBO_finish 12629 12630 /* 12631 * Currently: 12632 * r0 holds resolved field 12633 * r9 holds object 12634 */ 12635.LOP_IPUT_WIDE_JUMBO_finish: 12636 cmp r9, #0 @ check object for null 12637 FETCH(r2, 3) @ r1<- BBBB 12638 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12639 add r2, rFP, r2, lsl #2 @ r3<- &fp[BBBB] 12640 beq common_errNullObject @ object was null 12641 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12642 ldmia r2, {r0-r1} @ r0/r1<- fp[BBBB] 12643 GET_INST_OPCODE(r10) @ extract opcode from rINST 12644 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 12645 GOTO_OPCODE(r10) @ jump to next instruction 12646 12647/* continuation for OP_IPUT_OBJECT_JUMBO */ 12648 12649 /* 12650 * Currently: 12651 * r0 holds resolved field 12652 * r9 holds object 12653 */ 12654.LOP_IPUT_OBJECT_JUMBO_resolved: 12655 cmp r0, #0 @ resolution unsuccessful? 12656 beq common_exceptionThrown @ yes, throw exception 12657 @ fall through to OP_IPUT_OBJECT_JUMBO_finish 12658 12659 /* 12660 * Currently: 12661 * r0 holds resolved field 12662 * r9 holds object 12663 */ 12664.LOP_IPUT_OBJECT_JUMBO_finish: 12665 @bl common_squeak0 12666 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12667 FETCH(r1, 3) @ r1<- BBBB 12668 cmp r9, #0 @ check object for null 12669 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12670 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 12671 beq common_errNullObject @ object was null 12672 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12673 GET_INST_OPCODE(ip) @ extract opcode from rINST 12674 @ no-op @ releasing store 12675 str r0, [r9, r3] @ obj.field (32 bits)<- r0 12676 cmp r0, #0 @ stored a null reference? 12677 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 12678 GOTO_OPCODE(ip) @ jump to next instruction 12679 12680/* continuation for OP_IPUT_BOOLEAN_JUMBO */ 12681 12682 /* 12683 * Currently: 12684 * r0 holds resolved field 12685 * r9 holds object 12686 */ 12687.LOP_IPUT_BOOLEAN_JUMBO_resolved: 12688 cmp r0, #0 @ resolution unsuccessful? 12689 beq common_exceptionThrown @ yes, throw exception 12690 @ fall through to OP_IPUT_BOOLEAN_JUMBO_finish 12691 12692 /* 12693 * Currently: 12694 * r0 holds resolved field 12695 * r9 holds object 12696 */ 12697.LOP_IPUT_BOOLEAN_JUMBO_finish: 12698 @bl common_squeak1 12699 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12700 FETCH(r1, 3) @ r1<- BBBB 12701 cmp r9, #0 @ check object for null 12702 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12703 beq common_errNullObject @ object was null 12704 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12705 GET_INST_OPCODE(ip) @ extract opcode from rINST 12706 @ no-op @ releasing store 12707 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12708 GOTO_OPCODE(ip) @ jump to next instruction 12709 12710/* continuation for OP_IPUT_BYTE_JUMBO */ 12711 12712 /* 12713 * Currently: 12714 * r0 holds resolved field 12715 * r9 holds object 12716 */ 12717.LOP_IPUT_BYTE_JUMBO_resolved: 12718 cmp r0, #0 @ resolution unsuccessful? 12719 beq common_exceptionThrown @ yes, throw exception 12720 @ fall through to OP_IPUT_BYTE_JUMBO_finish 12721 12722 /* 12723 * Currently: 12724 * r0 holds resolved field 12725 * r9 holds object 12726 */ 12727.LOP_IPUT_BYTE_JUMBO_finish: 12728 @bl common_squeak2 12729 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12730 FETCH(r1, 3) @ r1<- BBBB 12731 cmp r9, #0 @ check object for null 12732 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12733 beq common_errNullObject @ object was null 12734 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12735 GET_INST_OPCODE(ip) @ extract opcode from rINST 12736 @ no-op @ releasing store 12737 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12738 GOTO_OPCODE(ip) @ jump to next instruction 12739 12740/* continuation for OP_IPUT_CHAR_JUMBO */ 12741 12742 /* 12743 * Currently: 12744 * r0 holds resolved field 12745 * r9 holds object 12746 */ 12747.LOP_IPUT_CHAR_JUMBO_resolved: 12748 cmp r0, #0 @ resolution unsuccessful? 12749 beq common_exceptionThrown @ yes, throw exception 12750 @ fall through to OP_IPUT_CHAR_JUMBO_finish 12751 12752 /* 12753 * Currently: 12754 * r0 holds resolved field 12755 * r9 holds object 12756 */ 12757.LOP_IPUT_CHAR_JUMBO_finish: 12758 @bl common_squeak3 12759 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12760 FETCH(r1, 3) @ r1<- BBBB 12761 cmp r9, #0 @ check object for null 12762 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12763 beq common_errNullObject @ object was null 12764 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12765 GET_INST_OPCODE(ip) @ extract opcode from rINST 12766 @ no-op @ releasing store 12767 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12768 GOTO_OPCODE(ip) @ jump to next instruction 12769 12770/* continuation for OP_IPUT_SHORT_JUMBO */ 12771 12772 /* 12773 * Currently: 12774 * r0 holds resolved field 12775 * r9 holds object 12776 */ 12777.LOP_IPUT_SHORT_JUMBO_resolved: 12778 cmp r0, #0 @ resolution unsuccessful? 12779 beq common_exceptionThrown @ yes, throw exception 12780 @ fall through to OP_IPUT_SHORT_JUMBO_finish 12781 12782 /* 12783 * Currently: 12784 * r0 holds resolved field 12785 * r9 holds object 12786 */ 12787.LOP_IPUT_SHORT_JUMBO_finish: 12788 @bl common_squeak4 12789 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12790 FETCH(r1, 3) @ r1<- BBBB 12791 cmp r9, #0 @ check object for null 12792 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12793 beq common_errNullObject @ object was null 12794 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12795 GET_INST_OPCODE(ip) @ extract opcode from rINST 12796 @ no-op @ releasing store 12797 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12798 GOTO_OPCODE(ip) @ jump to next instruction 12799 12800/* continuation for OP_SGET_JUMBO */ 12801 12802 /* 12803 * Continuation if the field has not yet been resolved. 12804 * r1: AAAAAAAA field ref 12805 */ 12806.LOP_SGET_JUMBO_resolve: 12807 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12808 EXPORT_PC() @ resolve() could throw, so export now 12809 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12810 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12811 cmp r0, #0 @ success? 12812 bne .LOP_SGET_JUMBO_finish @ yes, finish 12813 b common_exceptionThrown @ no, handle exception 12814 12815/* continuation for OP_SGET_WIDE_JUMBO */ 12816 12817 /* 12818 * Continuation if the field has not yet been resolved. 12819 * r1: BBBB field ref 12820 * 12821 * Returns StaticField pointer in r0. 12822 */ 12823.LOP_SGET_WIDE_JUMBO_resolve: 12824 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12825 EXPORT_PC() @ resolve() could throw, so export now 12826 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12827 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12828 cmp r0, #0 @ success? 12829 bne .LOP_SGET_WIDE_JUMBO_finish @ yes, finish 12830 b common_exceptionThrown @ no, handle exception 12831 12832/* continuation for OP_SGET_OBJECT_JUMBO */ 12833 12834 /* 12835 * Continuation if the field has not yet been resolved. 12836 * r1: AAAAAAAA field ref 12837 */ 12838.LOP_SGET_OBJECT_JUMBO_resolve: 12839 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12840 EXPORT_PC() @ resolve() could throw, so export now 12841 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12842 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12843 cmp r0, #0 @ success? 12844 bne .LOP_SGET_OBJECT_JUMBO_finish @ yes, finish 12845 b common_exceptionThrown @ no, handle exception 12846 12847/* continuation for OP_SGET_BOOLEAN_JUMBO */ 12848 12849 /* 12850 * Continuation if the field has not yet been resolved. 12851 * r1: AAAAAAAA field ref 12852 */ 12853.LOP_SGET_BOOLEAN_JUMBO_resolve: 12854 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12855 EXPORT_PC() @ resolve() could throw, so export now 12856 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12857 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12858 cmp r0, #0 @ success? 12859 bne .LOP_SGET_BOOLEAN_JUMBO_finish @ yes, finish 12860 b common_exceptionThrown @ no, handle exception 12861 12862/* continuation for OP_SGET_BYTE_JUMBO */ 12863 12864 /* 12865 * Continuation if the field has not yet been resolved. 12866 * r1: AAAAAAAA field ref 12867 */ 12868.LOP_SGET_BYTE_JUMBO_resolve: 12869 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12870 EXPORT_PC() @ resolve() could throw, so export now 12871 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12872 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12873 cmp r0, #0 @ success? 12874 bne .LOP_SGET_BYTE_JUMBO_finish @ yes, finish 12875 b common_exceptionThrown @ no, handle exception 12876 12877/* continuation for OP_SGET_CHAR_JUMBO */ 12878 12879 /* 12880 * Continuation if the field has not yet been resolved. 12881 * r1: AAAAAAAA field ref 12882 */ 12883.LOP_SGET_CHAR_JUMBO_resolve: 12884 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12885 EXPORT_PC() @ resolve() could throw, so export now 12886 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12887 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12888 cmp r0, #0 @ success? 12889 bne .LOP_SGET_CHAR_JUMBO_finish @ yes, finish 12890 b common_exceptionThrown @ no, handle exception 12891 12892/* continuation for OP_SGET_SHORT_JUMBO */ 12893 12894 /* 12895 * Continuation if the field has not yet been resolved. 12896 * r1: AAAAAAAA field ref 12897 */ 12898.LOP_SGET_SHORT_JUMBO_resolve: 12899 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12900 EXPORT_PC() @ resolve() could throw, so export now 12901 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12902 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12903 cmp r0, #0 @ success? 12904 bne .LOP_SGET_SHORT_JUMBO_finish @ yes, finish 12905 b common_exceptionThrown @ no, handle exception 12906 12907/* continuation for OP_SPUT_JUMBO */ 12908 12909 /* 12910 * Continuation if the field has not yet been resolved. 12911 * r1: AAAAAAAA field ref 12912 */ 12913.LOP_SPUT_JUMBO_resolve: 12914 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12915 EXPORT_PC() @ resolve() could throw, so export now 12916 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12917 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12918 cmp r0, #0 @ success? 12919 bne .LOP_SPUT_JUMBO_finish @ yes, finish 12920 b common_exceptionThrown @ no, handle exception 12921 12922/* continuation for OP_SPUT_WIDE_JUMBO */ 12923 12924 /* 12925 * Continuation if the field has not yet been resolved. 12926 * r1: BBBB field ref 12927 * r9: &fp[AA] 12928 * 12929 * Returns StaticField pointer in r2. 12930 */ 12931.LOP_SPUT_WIDE_JUMBO_resolve: 12932 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12933 EXPORT_PC() @ resolve() could throw, so export now 12934 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12935 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12936 cmp r0, #0 @ success? 12937 mov r2, r0 @ copy to r2 12938 bne .LOP_SPUT_WIDE_JUMBO_finish @ yes, finish 12939 b common_exceptionThrown @ no, handle exception 12940 12941/* continuation for OP_SPUT_OBJECT_JUMBO */ 12942 12943.LOP_SPUT_OBJECT_JUMBO_finish: @ field ptr in r0 12944 FETCH(r2, 3) @ r2<- BBBB 12945 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 12946 GET_VREG(r1, r2) @ r1<- fp[BBBB] 12947 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 12948 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 12949 GET_INST_OPCODE(ip) @ extract opcode from rINST 12950 @ no-op @ releasing store 12951 str r1, [r0, #offStaticField_value] @ field<- vBBBB 12952 cmp r1, #0 @ stored a null object? 12953 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 12954 GOTO_OPCODE(ip) @ jump to next instruction 12955 12956/* continuation for OP_SPUT_BOOLEAN_JUMBO */ 12957 12958 /* 12959 * Continuation if the field has not yet been resolved. 12960 * r1: AAAAAAAA field ref 12961 */ 12962.LOP_SPUT_BOOLEAN_JUMBO_resolve: 12963 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12964 EXPORT_PC() @ resolve() could throw, so export now 12965 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12966 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12967 cmp r0, #0 @ success? 12968 bne .LOP_SPUT_BOOLEAN_JUMBO_finish @ yes, finish 12969 b common_exceptionThrown @ no, handle exception 12970 12971/* continuation for OP_SPUT_BYTE_JUMBO */ 12972 12973 /* 12974 * Continuation if the field has not yet been resolved. 12975 * r1: AAAAAAAA field ref 12976 */ 12977.LOP_SPUT_BYTE_JUMBO_resolve: 12978 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12979 EXPORT_PC() @ resolve() could throw, so export now 12980 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12981 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12982 cmp r0, #0 @ success? 12983 bne .LOP_SPUT_BYTE_JUMBO_finish @ yes, finish 12984 b common_exceptionThrown @ no, handle exception 12985 12986/* continuation for OP_SPUT_CHAR_JUMBO */ 12987 12988 /* 12989 * Continuation if the field has not yet been resolved. 12990 * r1: AAAAAAAA field ref 12991 */ 12992.LOP_SPUT_CHAR_JUMBO_resolve: 12993 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12994 EXPORT_PC() @ resolve() could throw, so export now 12995 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12996 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12997 cmp r0, #0 @ success? 12998 bne .LOP_SPUT_CHAR_JUMBO_finish @ yes, finish 12999 b common_exceptionThrown @ no, handle exception 13000 13001/* continuation for OP_SPUT_SHORT_JUMBO */ 13002 13003 /* 13004 * Continuation if the field has not yet been resolved. 13005 * r1: AAAAAAAA field ref 13006 */ 13007.LOP_SPUT_SHORT_JUMBO_resolve: 13008 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13009 EXPORT_PC() @ resolve() could throw, so export now 13010 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13011 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13012 cmp r0, #0 @ success? 13013 bne .LOP_SPUT_SHORT_JUMBO_finish @ yes, finish 13014 b common_exceptionThrown @ no, handle exception 13015 13016/* continuation for OP_INVOKE_VIRTUAL_JUMBO */ 13017 13018 /* 13019 * At this point: 13020 * r0 = resolved base method 13021 */ 13022.LOP_INVOKE_VIRTUAL_JUMBO_continue: 13023 FETCH(r10, 4) @ r10<- CCCC 13024 GET_VREG(r1, r10) @ r1<- "this" ptr 13025 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 13026 cmp r1, #0 @ is "this" null? 13027 beq common_errNullObject @ null "this", throw exception 13028 ldr r3, [r1, #offObject_clazz] @ r1<- thisPtr->clazz 13029 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 13030 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 13031 bl common_invokeMethodJumbo @ continue on 13032 13033/* continuation for OP_INVOKE_SUPER_JUMBO */ 13034 13035 /* 13036 * At this point: 13037 * r0 = resolved base method 13038 * r9 = method->clazz 13039 */ 13040.LOP_INVOKE_SUPER_JUMBO_continue: 13041 ldr r1, [r9, #offClassObject_super] @ r1<- method->clazz->super 13042 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 13043 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 13044 EXPORT_PC() @ must export for invoke 13045 cmp r2, r3 @ compare (methodIndex, vtableCount) 13046 bcs .LOP_INVOKE_SUPER_JUMBO_nsm @ method not present in superclass 13047 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 13048 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 13049 bl common_invokeMethodJumbo @ continue on 13050 13051.LOP_INVOKE_SUPER_JUMBO_resolve: 13052 mov r0, r9 @ r0<- method->clazz 13053 mov r2, #METHOD_VIRTUAL @ resolver method type 13054 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 13055 cmp r0, #0 @ got null? 13056 bne .LOP_INVOKE_SUPER_JUMBO_continue @ no, continue 13057 b common_exceptionThrown @ yes, handle exception 13058 13059 /* 13060 * Throw a NoSuchMethodError with the method name as the message. 13061 * r0 = resolved base method 13062 */ 13063.LOP_INVOKE_SUPER_JUMBO_nsm: 13064 ldr r1, [r0, #offMethod_name] @ r1<- method name 13065 b common_errNoSuchMethod 13066 13067/* continuation for OP_INVOKE_DIRECT_JUMBO */ 13068 13069 /* 13070 * On entry: 13071 * r1 = reference (CCCC) 13072 * r10 = "this" register 13073 */ 13074.LOP_INVOKE_DIRECT_JUMBO_resolve: 13075 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 13076 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 13077 mov r2, #METHOD_DIRECT @ resolver method type 13078 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 13079 cmp r0, #0 @ got null? 13080 GET_VREG(r2, r10) @ r2<- "this" ptr (reload) 13081 bne .LOP_INVOKE_DIRECT_JUMBO_finish @ no, continue 13082 b common_exceptionThrown @ yes, handle exception 13083 13084 .size dvmAsmSisterStart, .-dvmAsmSisterStart 13085 .global dvmAsmSisterEnd 13086dvmAsmSisterEnd: 13087 13088/* File: armv5te/footer.S */ 13089 13090/* 13091 * =========================================================================== 13092 * Common subroutines and data 13093 * =========================================================================== 13094 */ 13095 13096 13097 13098 .text 13099 .align 2 13100 13101#if defined(WITH_JIT) 13102#if defined(WITH_SELF_VERIFICATION) 13103 .global dvmJitToInterpPunt 13104dvmJitToInterpPunt: 13105 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13106 mov r2,#kSVSPunt @ r2<- interpreter entry point 13107 mov r3, #0 13108 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13109 b jitSVShadowRunEnd @ doesn't return 13110 13111 .global dvmJitToInterpSingleStep 13112dvmJitToInterpSingleStep: 13113 str lr,[rGLUE,#offGlue_jitResumeNPC] 13114 str r1,[rGLUE,#offGlue_jitResumeDPC] 13115 mov r2,#kSVSSingleStep @ r2<- interpreter entry point 13116 b jitSVShadowRunEnd @ doesn't return 13117 13118 .global dvmJitToInterpNoChainNoProfile 13119dvmJitToInterpNoChainNoProfile: 13120 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13121 mov r0,rPC @ pass our target PC 13122 mov r2,#kSVSNoProfile @ r2<- interpreter entry point 13123 mov r3, #0 @ 0 means !inJitCodeCache 13124 str r3, [r10, #offThread_inJitCodeCache] @ back to the interp land 13125 b jitSVShadowRunEnd @ doesn't return 13126 13127 .global dvmJitToInterpTraceSelectNoChain 13128dvmJitToInterpTraceSelectNoChain: 13129 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13130 mov r0,rPC @ pass our target PC 13131 mov r2,#kSVSTraceSelect @ r2<- interpreter entry point 13132 mov r3, #0 @ 0 means !inJitCodeCache 13133 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13134 b jitSVShadowRunEnd @ doesn't return 13135 13136 .global dvmJitToInterpTraceSelect 13137dvmJitToInterpTraceSelect: 13138 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13139 ldr r0,[lr, #-1] @ pass our target PC 13140 mov r2,#kSVSTraceSelect @ r2<- interpreter entry point 13141 mov r3, #0 @ 0 means !inJitCodeCache 13142 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13143 b jitSVShadowRunEnd @ doesn't return 13144 13145 .global dvmJitToInterpBackwardBranch 13146dvmJitToInterpBackwardBranch: 13147 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13148 ldr r0,[lr, #-1] @ pass our target PC 13149 mov r2,#kSVSBackwardBranch @ r2<- interpreter entry point 13150 mov r3, #0 @ 0 means !inJitCodeCache 13151 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13152 b jitSVShadowRunEnd @ doesn't return 13153 13154 .global dvmJitToInterpNormal 13155dvmJitToInterpNormal: 13156 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13157 ldr r0,[lr, #-1] @ pass our target PC 13158 mov r2,#kSVSNormal @ r2<- interpreter entry point 13159 mov r3, #0 @ 0 means !inJitCodeCache 13160 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13161 b jitSVShadowRunEnd @ doesn't return 13162 13163 .global dvmJitToInterpNoChain 13164dvmJitToInterpNoChain: 13165 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13166 mov r0,rPC @ pass our target PC 13167 mov r2,#kSVSNoChain @ r2<- interpreter entry point 13168 mov r3, #0 @ 0 means !inJitCodeCache 13169 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13170 b jitSVShadowRunEnd @ doesn't return 13171#else 13172/* 13173 * Return from the translation cache to the interpreter when the compiler is 13174 * having issues translating/executing a Dalvik instruction. We have to skip 13175 * the code cache lookup otherwise it is possible to indefinitely bouce 13176 * between the interpreter and the code cache if the instruction that fails 13177 * to be compiled happens to be at a trace start. 13178 */ 13179 .global dvmJitToInterpPunt 13180dvmJitToInterpPunt: 13181 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13182 mov rPC, r0 13183#if defined(WITH_JIT_TUNING) 13184 mov r0,lr 13185 bl dvmBumpPunt; 13186#endif 13187 EXPORT_PC() 13188 mov r0, #0 13189 str r0, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13190 adrl rIBASE, dvmAsmInstructionStart 13191 FETCH_INST() 13192 GET_INST_OPCODE(ip) 13193 GOTO_OPCODE(ip) 13194 13195/* 13196 * Return to the interpreter to handle a single instruction. 13197 * On entry: 13198 * r0 <= PC 13199 * r1 <= PC of resume instruction 13200 * lr <= resume point in translation 13201 */ 13202 .global dvmJitToInterpSingleStep 13203dvmJitToInterpSingleStep: 13204 str lr,[rGLUE,#offGlue_jitResumeNPC] 13205 str r1,[rGLUE,#offGlue_jitResumeDPC] 13206 mov r1,#kInterpEntryInstr 13207 @ enum is 4 byte in aapcs-EABI 13208 str r1, [rGLUE, #offGlue_entryPoint] 13209 mov rPC,r0 13210 EXPORT_PC() 13211 13212 adrl rIBASE, dvmAsmInstructionStart 13213 mov r2,#kJitSingleStep @ Ask for single step and then revert 13214 str r2,[rGLUE,#offGlue_jitState] 13215 mov r1,#1 @ set changeInterp to bail to debug interp 13216 b common_gotoBail 13217 13218/* 13219 * Return from the translation cache and immediately request 13220 * a translation for the exit target. Commonly used for callees. 13221 */ 13222 .global dvmJitToInterpTraceSelectNoChain 13223dvmJitToInterpTraceSelectNoChain: 13224#if defined(WITH_JIT_TUNING) 13225 bl dvmBumpNoChain 13226#endif 13227 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13228 mov r0,rPC 13229 bl dvmJitGetTraceAddr @ Is there a translation? 13230 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13231 mov r1, rPC @ arg1 of translation may need this 13232 mov lr, #0 @ in case target is HANDLER_INTERPRET 13233 cmp r0,#0 @ !0 means translation exists 13234 bxne r0 @ continue native execution if so 13235 b 2f @ branch over to use the interpreter 13236 13237/* 13238 * Return from the translation cache and immediately request 13239 * a translation for the exit target. Commonly used following 13240 * invokes. 13241 */ 13242 .global dvmJitToInterpTraceSelect 13243dvmJitToInterpTraceSelect: 13244 ldr rPC,[lr, #-1] @ get our target PC 13245 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13246 add rINST,lr,#-5 @ save start of chain branch 13247 add rINST, #-4 @ .. which is 9 bytes back 13248 mov r0,rPC 13249 bl dvmJitGetTraceAddr @ Is there a translation? 13250 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13251 cmp r0,#0 13252 beq 2f 13253 mov r1,rINST 13254 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 13255 mov r1, rPC @ arg1 of translation may need this 13256 mov lr, #0 @ in case target is HANDLER_INTERPRET 13257 cmp r0,#0 @ successful chain? 13258 bxne r0 @ continue native execution 13259 b toInterpreter @ didn't chain - resume with interpreter 13260 13261/* No translation, so request one if profiling isn't disabled*/ 132622: 13263 adrl rIBASE, dvmAsmInstructionStart 13264 GET_JIT_PROF_TABLE(r0) 13265 FETCH_INST() 13266 cmp r0, #0 13267 movne r2,#kJitTSelectRequestHot @ ask for trace selection 13268 bne common_selectTrace 13269 GET_INST_OPCODE(ip) 13270 GOTO_OPCODE(ip) 13271 13272/* 13273 * Return from the translation cache to the interpreter. 13274 * The return was done with a BLX from thumb mode, and 13275 * the following 32-bit word contains the target rPC value. 13276 * Note that lr (r14) will have its low-order bit set to denote 13277 * its thumb-mode origin. 13278 * 13279 * We'll need to stash our lr origin away, recover the new 13280 * target and then check to see if there is a translation available 13281 * for our new target. If so, we do a translation chain and 13282 * go back to native execution. Otherwise, it's back to the 13283 * interpreter (after treating this entry as a potential 13284 * trace start). 13285 */ 13286 .global dvmJitToInterpNormal 13287dvmJitToInterpNormal: 13288 ldr rPC,[lr, #-1] @ get our target PC 13289 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13290 add rINST,lr,#-5 @ save start of chain branch 13291 add rINST,#-4 @ .. which is 9 bytes back 13292#if defined(WITH_JIT_TUNING) 13293 bl dvmBumpNormal 13294#endif 13295 mov r0,rPC 13296 bl dvmJitGetTraceAddr @ Is there a translation? 13297 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13298 cmp r0,#0 13299 beq toInterpreter @ go if not, otherwise do chain 13300 mov r1,rINST 13301 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 13302 mov r1, rPC @ arg1 of translation may need this 13303 mov lr, #0 @ in case target is HANDLER_INTERPRET 13304 cmp r0,#0 @ successful chain? 13305 bxne r0 @ continue native execution 13306 b toInterpreter @ didn't chain - resume with interpreter 13307 13308/* 13309 * Return from the translation cache to the interpreter to do method invocation. 13310 * Check if translation exists for the callee, but don't chain to it. 13311 */ 13312 .global dvmJitToInterpNoChainNoProfile 13313dvmJitToInterpNoChainNoProfile: 13314#if defined(WITH_JIT_TUNING) 13315 bl dvmBumpNoChain 13316#endif 13317 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13318 mov r0,rPC 13319 bl dvmJitGetTraceAddr @ Is there a translation? 13320 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13321 mov r1, rPC @ arg1 of translation may need this 13322 mov lr, #0 @ in case target is HANDLER_INTERPRET 13323 cmp r0,#0 13324 bxne r0 @ continue native execution if so 13325 EXPORT_PC() 13326 adrl rIBASE, dvmAsmInstructionStart 13327 FETCH_INST() 13328 GET_INST_OPCODE(ip) @ extract opcode from rINST 13329 GOTO_OPCODE(ip) @ jump to next instruction 13330 13331/* 13332 * Return from the translation cache to the interpreter to do method invocation. 13333 * Check if translation exists for the callee, but don't chain to it. 13334 */ 13335 .global dvmJitToInterpNoChain 13336dvmJitToInterpNoChain: 13337#if defined(WITH_JIT_TUNING) 13338 bl dvmBumpNoChain 13339#endif 13340 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13341 mov r0,rPC 13342 bl dvmJitGetTraceAddr @ Is there a translation? 13343 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13344 mov r1, rPC @ arg1 of translation may need this 13345 mov lr, #0 @ in case target is HANDLER_INTERPRET 13346 cmp r0,#0 13347 bxne r0 @ continue native execution if so 13348#endif 13349 13350/* 13351 * No translation, restore interpreter regs and start interpreting. 13352 * rGLUE & rFP were preserved in the translated code, and rPC has 13353 * already been restored by the time we get here. We'll need to set 13354 * up rIBASE & rINST, and load the address of the JitTable into r0. 13355 */ 13356toInterpreter: 13357 EXPORT_PC() 13358 adrl rIBASE, dvmAsmInstructionStart 13359 FETCH_INST() 13360 GET_JIT_PROF_TABLE(r0) 13361 @ NOTE: intended fallthrough 13362 13363/* 13364 * Common code to update potential trace start counter, and initiate 13365 * a trace-build if appropriate. On entry, rPC should point to the 13366 * next instruction to execute, and rINST should be already loaded with 13367 * the next opcode word, and r0 holds a pointer to the jit profile 13368 * table (pJitProfTable). 13369 */ 13370common_testUpdateProfile: 13371 cmp r0,#0 13372 GET_INST_OPCODE(ip) 13373 GOTO_OPCODE_IFEQ(ip) @ if not profiling, fallthrough otherwise */ 13374 13375common_updateProfile: 13376 eor r3,rPC,rPC,lsr #12 @ cheap, but fast hash function 13377 lsl r3,r3,#(32 - JIT_PROF_SIZE_LOG_2) @ shift out excess bits 13378 ldrb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter 13379 GET_INST_OPCODE(ip) 13380 subs r1,r1,#1 @ decrement counter 13381 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it 13382 GOTO_OPCODE_IFNE(ip) @ if not threshold, fallthrough otherwise */ 13383 13384/* 13385 * Here, we switch to the debug interpreter to request 13386 * trace selection. First, though, check to see if there 13387 * is already a native translation in place (and, if so, 13388 * jump to it now). 13389 */ 13390 GET_JIT_THRESHOLD(r1) 13391 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13392 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter 13393 EXPORT_PC() 13394 mov r0,rPC 13395 bl dvmJitGetTraceAddr @ r0<- dvmJitGetTraceAddr(rPC) 13396 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13397 mov r1, rPC @ arg1 of translation may need this 13398 mov lr, #0 @ in case target is HANDLER_INTERPRET 13399 cmp r0,#0 13400#if !defined(WITH_SELF_VERIFICATION) 13401 bxne r0 @ jump to the translation 13402 mov r2,#kJitTSelectRequest @ ask for trace selection 13403 @ fall-through to common_selectTrace 13404#else 13405 moveq r2,#kJitTSelectRequest @ ask for trace selection 13406 beq common_selectTrace 13407 /* 13408 * At this point, we have a target translation. However, if 13409 * that translation is actually the interpret-only pseudo-translation 13410 * we want to treat it the same as no translation. 13411 */ 13412 mov r10, r0 @ save target 13413 bl dvmCompilerGetInterpretTemplate 13414 cmp r0, r10 @ special case? 13415 bne jitSVShadowRunStart @ set up self verification shadow space 13416 @ Need to clear the inJitCodeCache flag 13417 ldr r10, [rGLUE, #offGlue_self] @ r10 <- glue->self 13418 mov r3, #0 @ 0 means not in the JIT code cache 13419 str r3, [r10, #offThread_inJitCodeCache] @ back to the interp land 13420 GET_INST_OPCODE(ip) 13421 GOTO_OPCODE(ip) 13422 /* no return */ 13423#endif 13424 13425/* 13426 * On entry: 13427 * r2 is jit state, e.g. kJitTSelectRequest or kJitTSelectRequestHot 13428 */ 13429common_selectTrace: 13430 str r2,[rGLUE,#offGlue_jitState] 13431 mov r2,#kInterpEntryInstr @ normal entry reason 13432 str r2,[rGLUE,#offGlue_entryPoint] 13433 mov r1,#1 @ set changeInterp 13434 b common_gotoBail 13435 13436#if defined(WITH_SELF_VERIFICATION) 13437/* 13438 * Save PC and registers to shadow memory for self verification mode 13439 * before jumping to native translation. 13440 * On entry: 13441 * rPC, rFP, rGLUE: the values that they should contain 13442 * r10: the address of the target translation. 13443 */ 13444jitSVShadowRunStart: 13445 mov r0,rPC @ r0<- program counter 13446 mov r1,rFP @ r1<- frame pointer 13447 mov r2,rGLUE @ r2<- InterpState pointer 13448 mov r3,r10 @ r3<- target translation 13449 bl dvmSelfVerificationSaveState @ save registers to shadow space 13450 ldr rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space 13451 add rGLUE,r0,#offShadowSpace_interpState @ rGLUE<- rGLUE in shadow space 13452 bx r10 @ jump to the translation 13453 13454/* 13455 * Restore PC, registers, and interpState to original values 13456 * before jumping back to the interpreter. 13457 */ 13458jitSVShadowRunEnd: 13459 mov r1,rFP @ pass ending fp 13460 bl dvmSelfVerificationRestoreState @ restore pc and fp values 13461 ldr rPC,[r0,#offShadowSpace_startPC] @ restore PC 13462 ldr rFP,[r0,#offShadowSpace_fp] @ restore FP 13463 ldr rGLUE,[r0,#offShadowSpace_glue] @ restore InterpState 13464 ldr r1,[r0,#offShadowSpace_svState] @ get self verification state 13465 cmp r1,#0 @ check for punt condition 13466 beq 1f 13467 mov r2,#kJitSelfVerification @ ask for self verification 13468 str r2,[rGLUE,#offGlue_jitState] 13469 mov r2,#kInterpEntryInstr @ normal entry reason 13470 str r2,[rGLUE,#offGlue_entryPoint] 13471 mov r1,#1 @ set changeInterp 13472 b common_gotoBail 13473 134741: @ exit to interpreter without check 13475 EXPORT_PC() 13476 adrl rIBASE, dvmAsmInstructionStart 13477 FETCH_INST() 13478 GET_INST_OPCODE(ip) 13479 GOTO_OPCODE(ip) 13480#endif 13481 13482#endif 13483 13484/* 13485 * Common code when a backward branch is taken. 13486 * 13487 * TODO: we could avoid a branch by just setting r0 and falling through 13488 * into the common_periodicChecks code, and having a test on r0 at the 13489 * end determine if we should return to the caller or update & branch to 13490 * the next instr. 13491 * 13492 * On entry: 13493 * r9 is PC adjustment *in bytes* 13494 */ 13495common_backwardBranch: 13496 mov r0, #kInterpEntryInstr 13497 bl common_periodicChecks 13498#if defined(WITH_JIT) 13499 GET_JIT_PROF_TABLE(r0) 13500 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 13501 cmp r0,#0 13502 bne common_updateProfile 13503 GET_INST_OPCODE(ip) 13504 GOTO_OPCODE(ip) 13505#else 13506 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 13507 GET_INST_OPCODE(ip) @ extract opcode from rINST 13508 GOTO_OPCODE(ip) @ jump to next instruction 13509#endif 13510 13511 13512/* 13513 * Need to see if the thread needs to be suspended or debugger/profiler 13514 * activity has begun. If so, we suspend the thread or side-exit to 13515 * the debug interpreter as appropriate. 13516 * 13517 * The common case is no activity on any of these, so we want to figure 13518 * that out quickly. If something is up, we can then sort out what. 13519 * 13520 * We want to be fast if the VM was built without debugger or profiler 13521 * support, but we also need to recognize that the system is usually 13522 * shipped with both of these enabled. 13523 * 13524 * TODO: reduce this so we're just checking a single location. 13525 * 13526 * On entry: 13527 * r0 is reentry type, e.g. kInterpEntryInstr (for debugger/profiling) 13528 * r9 is trampoline PC adjustment *in bytes* 13529 */ 13530common_periodicChecks: 13531 ldr r1, [rGLUE, #offGlue_pInterpBreak] @ r3<- &interpBreak 13532 /* speculatively load address of thread-specific suspend count */ 13533 ldr r3, [rGLUE, #offGlue_pSelfSuspendCount] @ r3<- &suspendCount 13534 ldr r1, [r1] @ r1<- interpBreak 13535 /* speculatively load thread-specific suspend count */ 13536 ldr ip, [r3] @ ip<- suspendCount (int) 13537 cmp r1, #0 @ anything unusual? 13538 bxeq lr @ return if not 13539 /* 13540 * One or more interesting events have happened. Figure out what. 13541 * 13542 * r0 still holds the reentry type. 13543 */ 13544 cmp ip, #0 @ want suspend? 13545 beq 3f @ no, must be something else 13546 13547 stmfd sp!, {r0, lr} @ preserve r0 and lr 13548#if defined(WITH_JIT) 13549 /* 13550 * Refresh the Jit's cached copy of profile table pointer. This pointer 13551 * doubles as the Jit's on/off switch. 13552 */ 13553 ldr r3, [rGLUE, #offGlue_ppJitProfTable] @ r3<-&gDvmJit.pJitProfTable 13554 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 13555 ldr r3, [r3] @ r3 <- pJitProfTable 13556 EXPORT_PC() @ need for precise GC 13557 str r3, [rGLUE, #offGlue_pJitProfTable] @ refresh Jit's on/off switch 13558#else 13559 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 13560 EXPORT_PC() @ need for precise GC 13561#endif 13562 bl dvmCheckSuspendPending @ do full check, suspend if necessary 13563 ldmfd sp!, {r0, lr} @ restore r0 and lr 13564 13565 /* 13566 * Reload the interpBreak flags - they may have changed while we 13567 * were suspended. 13568 */ 13569 ldr r1, [rGLUE, #offGlue_pInterpBreak] @ r1<- &interpBreak 13570 ldr r1, [r1] @ r1<- interpBreak 135713: 13572 /* 13573 * TODO: this code is too fragile. Need a general mechanism 13574 * to identify what actions to take by submode. Some profiling modes 13575 * (instruction count) need to single-step, while method tracing 13576 * may not. Debugging with breakpoints can run unfettered, but 13577 * source-level single-stepping requires Dalvik singlestepping. 13578 * GC may require a one-shot action and then full-speed resumption. 13579 */ 13580 ands r1, #(kSubModeDebuggerActive | kSubModeEmulatorTrace | kSubModeInstCounting) 13581 bxeq lr @ nothing to do, return 13582 13583 @ debugger/profiler enabled, bail out; glue->entryPoint was set above 13584 str r0, [rGLUE, #offGlue_entryPoint] @ store r0, need for debug/prof 13585 add rPC, rPC, r9 @ update rPC 13586 mov r1, #1 @ "want switch" = true 13587 b common_gotoBail @ side exit 13588 13589 13590/* 13591 * The equivalent of "goto bail", this calls through the "bail handler". 13592 * 13593 * State registers will be saved to the "glue" area before bailing. 13594 * 13595 * On entry: 13596 * r1 is "bool changeInterp", indicating if we want to switch to the 13597 * other interpreter or just bail all the way out 13598 */ 13599common_gotoBail: 13600 SAVE_PC_FP_TO_GLUE() @ export state to "glue" 13601 mov r0, rGLUE @ r0<- glue ptr 13602 b dvmMterpStdBail @ call(glue, changeInterp) 13603 13604 @add r1, r1, #1 @ using (boolean+1) 13605 @add r0, rGLUE, #offGlue_jmpBuf @ r0<- &glue->jmpBuf 13606 @bl _longjmp @ does not return 13607 @bl common_abort 13608 13609 13610/* 13611 * Common code for jumbo method invocation. 13612 * NOTE: this adjusts rPC to account for the difference in instruction width. 13613 * As a result, the savedPc in the stack frame will not be wholly accurate. So 13614 * long as that is only used for source file line number calculations, we're 13615 * okay. 13616 * 13617 * On entry: 13618 * r0 is "Method* methodToCall", the method we're trying to call 13619 */ 13620common_invokeMethodJumbo: 13621.LinvokeNewJumbo: 13622 @ prepare to copy args to "outs" area of current frame 13623 add rPC, rPC, #4 @ adjust pc to make return consistent 13624 FETCH(r2, 1) @ r2<- BBBB (arg count) 13625 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 13626 cmp r2, #0 @ no args? 13627 beq .LinvokeArgsDone @ if no args, skip the rest 13628 FETCH(r1, 2) @ r1<- CCCC 13629 b .LinvokeRangeArgs @ handle args like invoke range 13630 13631/* 13632 * Common code for method invocation with range. 13633 * 13634 * On entry: 13635 * r0 is "Method* methodToCall", the method we're trying to call 13636 */ 13637common_invokeMethodRange: 13638.LinvokeNewRange: 13639 @ prepare to copy args to "outs" area of current frame 13640 movs r2, rINST, lsr #8 @ r2<- AA (arg count) -- test for zero 13641 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 13642 beq .LinvokeArgsDone @ if no args, skip the rest 13643 FETCH(r1, 2) @ r1<- CCCC 13644 13645.LinvokeRangeArgs: 13646 @ r0=methodToCall, r1=CCCC, r2=count, r10=outs 13647 @ (very few methods have > 10 args; could unroll for common cases) 13648 add r3, rFP, r1, lsl #2 @ r3<- &fp[CCCC] 13649 sub r10, r10, r2, lsl #2 @ r10<- "outs" area, for call args 136501: ldr r1, [r3], #4 @ val = *fp++ 13651 subs r2, r2, #1 @ count-- 13652 str r1, [r10], #4 @ *outs++ = val 13653 bne 1b @ ...while count != 0 13654 b .LinvokeArgsDone 13655 13656/* 13657 * Common code for method invocation without range. 13658 * 13659 * On entry: 13660 * r0 is "Method* methodToCall", the method we're trying to call 13661 */ 13662common_invokeMethodNoRange: 13663.LinvokeNewNoRange: 13664 @ prepare to copy args to "outs" area of current frame 13665 movs r2, rINST, lsr #12 @ r2<- B (arg count) -- test for zero 13666 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 13667 FETCH(r1, 2) @ r1<- GFED (load here to hide latency) 13668 beq .LinvokeArgsDone 13669 13670 @ r0=methodToCall, r1=GFED, r2=count, r10=outs 13671.LinvokeNonRange: 13672 rsb r2, r2, #5 @ r2<- 5-r2 13673 add pc, pc, r2, lsl #4 @ computed goto, 4 instrs each 13674 bl common_abort @ (skipped due to ARM prefetch) 136755: and ip, rINST, #0x0f00 @ isolate A 13676 ldr r2, [rFP, ip, lsr #6] @ r2<- vA (shift right 8, left 2) 13677 mov r0, r0 @ nop 13678 str r2, [r10, #-4]! @ *--outs = vA 136794: and ip, r1, #0xf000 @ isolate G 13680 ldr r2, [rFP, ip, lsr #10] @ r2<- vG (shift right 12, left 2) 13681 mov r0, r0 @ nop 13682 str r2, [r10, #-4]! @ *--outs = vG 136833: and ip, r1, #0x0f00 @ isolate F 13684 ldr r2, [rFP, ip, lsr #6] @ r2<- vF 13685 mov r0, r0 @ nop 13686 str r2, [r10, #-4]! @ *--outs = vF 136872: and ip, r1, #0x00f0 @ isolate E 13688 ldr r2, [rFP, ip, lsr #2] @ r2<- vE 13689 mov r0, r0 @ nop 13690 str r2, [r10, #-4]! @ *--outs = vE 136911: and ip, r1, #0x000f @ isolate D 13692 ldr r2, [rFP, ip, lsl #2] @ r2<- vD 13693 mov r0, r0 @ nop 13694 str r2, [r10, #-4]! @ *--outs = vD 136950: @ fall through to .LinvokeArgsDone 13696 13697.LinvokeArgsDone: @ r0=methodToCall 13698 ldrh r9, [r0, #offMethod_registersSize] @ r9<- methodToCall->regsSize 13699 ldrh r3, [r0, #offMethod_outsSize] @ r3<- methodToCall->outsSize 13700 ldr r2, [r0, #offMethod_insns] @ r2<- method->insns 13701 ldr rINST, [r0, #offMethod_clazz] @ rINST<- method->clazz 13702 @ find space for the new stack frame, check for overflow 13703 SAVEAREA_FROM_FP(r1, rFP) @ r1<- stack save area 13704 sub r1, r1, r9, lsl #2 @ r1<- newFp (old savearea - regsSize) 13705 SAVEAREA_FROM_FP(r10, r1) @ r10<- newSaveArea 13706@ bl common_dumpRegs 13707 ldr r9, [rGLUE, #offGlue_interpStackEnd] @ r9<- interpStackEnd 13708 sub r3, r10, r3, lsl #2 @ r3<- bottom (newsave - outsSize) 13709 cmp r3, r9 @ bottom < interpStackEnd? 13710 ldr lr, [rGLUE, #offGlue_pInterpBreak] 13711 ldr r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags 13712 blo .LstackOverflow @ yes, this frame will overflow stack 13713 13714 @ set up newSaveArea 13715 ldr lr, [lr] @ lr<- active submodes 13716#ifdef EASY_GDB 13717 SAVEAREA_FROM_FP(ip, rFP) @ ip<- stack save area 13718 str ip, [r10, #offStackSaveArea_prevSave] 13719#endif 13720 str rFP, [r10, #offStackSaveArea_prevFrame] 13721 str rPC, [r10, #offStackSaveArea_savedPc] 13722#if defined(WITH_JIT) 13723 mov r9, #0 13724 str r9, [r10, #offStackSaveArea_returnAddr] 13725#endif 13726 ands lr, #kSubModeMethodTrace @ method tracing? 13727 beq 1f @ skip if not 13728 stmfd sp!, {r0-r3} @ preserve r0-r3 13729 mov r1, r6 13730 @ r0=methodToCall, r1=rGlue 13731 bl dvmFastMethodTraceEnter 13732 ldmfd sp!, {r0-r3} @ restore r0-r3 137331: 13734 str r0, [r10, #offStackSaveArea_method] 13735 tst r3, #ACC_NATIVE 13736 bne .LinvokeNative 13737 13738 /* 13739 stmfd sp!, {r0-r3} 13740 bl common_printNewline 13741 mov r0, rFP 13742 mov r1, #0 13743 bl dvmDumpFp 13744 ldmfd sp!, {r0-r3} 13745 stmfd sp!, {r0-r3} 13746 mov r0, r1 13747 mov r1, r10 13748 bl dvmDumpFp 13749 bl common_printNewline 13750 ldmfd sp!, {r0-r3} 13751 */ 13752 13753 ldrh r9, [r2] @ r9 <- load INST from new PC 13754 ldr r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex 13755 mov rPC, r2 @ publish new rPC 13756 ldr r2, [rGLUE, #offGlue_self] @ r2<- glue->self 13757 13758 @ Update "glue" values for the new method 13759 @ r0=methodToCall, r1=newFp, r2=self, r3=newMethodClass, r9=newINST 13760 str r0, [rGLUE, #offGlue_method] @ glue->method = methodToCall 13761 str r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ... 13762#if defined(WITH_JIT) 13763 GET_JIT_PROF_TABLE(r0) 13764 mov rFP, r1 @ fp = newFp 13765 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 13766 mov rINST, r9 @ publish new rINST 13767 str r1, [r2, #offThread_curFrame] @ self->curFrame = newFp 13768 cmp r0,#0 13769 bne common_updateProfile 13770 GOTO_OPCODE(ip) @ jump to next instruction 13771#else 13772 mov rFP, r1 @ fp = newFp 13773 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 13774 mov rINST, r9 @ publish new rINST 13775 str r1, [r2, #offThread_curFrame] @ self->curFrame = newFp 13776 GOTO_OPCODE(ip) @ jump to next instruction 13777#endif 13778 13779.LinvokeNative: 13780 @ Prep for the native call 13781 @ r0=methodToCall, r1=newFp, r10=newSaveArea 13782 ldr r3, [rGLUE, #offGlue_self] @ r3<- glue->self 13783 ldr lr, [rGLUE, #offGlue_pInterpBreak] 13784 ldr r9, [r3, #offThread_jniLocal_topCookie] @ r9<- thread->localRef->... 13785 str r1, [r3, #offThread_curFrame] @ self->curFrame = newFp 13786 str r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top 13787 ldr lr, [lr] @ lr<- active submodes 13788 mov r9, r3 @ r9<- glue->self (preserve) 13789 13790 mov r2, r0 @ r2<- methodToCall 13791 mov r0, r1 @ r0<- newFp (points to args) 13792 add r1, rGLUE, #offGlue_retval @ r1<- &retval 13793 13794#ifdef ASSIST_DEBUGGER 13795 /* insert fake function header to help gdb find the stack frame */ 13796 b .Lskip 13797 .type dalvik_mterp, %function 13798dalvik_mterp: 13799 .fnstart 13800 MTERP_ENTRY1 13801 MTERP_ENTRY2 13802.Lskip: 13803#endif 13804 13805 ands lr, #kSubModeMethodTrace @ method tracing? 13806 beq 110f @ hop if not 13807 @ r2=JNIMethod, r6=rGLUE 13808 stmfd sp!, {r2,r6} 13809 13810 mov lr, pc @ set return addr 13811 ldr pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 13812 13813 @ r0=JNIMethod, r1=rGLUE 13814 ldmfd sp!, {r0-r1} 13815 bl dvmFastNativeMethodTraceExit 13816 @ r2=JNIMethod, r6=rGLUE 13817 stmfd sp!, {r2,r6} 13818 b 220f 13819110: 13820 mov lr, pc @ set return addr 13821 ldr pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 13822220: 13823#if defined(WITH_JIT) 13824 ldr r3, [rGLUE, #offGlue_ppJitProfTable] @ Refresh Jit's on/off status 13825#endif 13826 13827 @ native return; r9=self, r10=newSaveArea 13828 @ equivalent to dvmPopJniLocals 13829 ldr r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top 13830 ldr r1, [r9, #offThread_exception] @ check for exception 13831#if defined(WITH_JIT) 13832 ldr r3, [r3] @ r3 <- gDvmJit.pProfTable 13833#endif 13834 str rFP, [r9, #offThread_curFrame] @ self->curFrame = fp 13835 cmp r1, #0 @ null? 13836 str r0, [r9, #offThread_jniLocal_topCookie] @ new top <- old top 13837#if defined(WITH_JIT) 13838 str r3, [rGLUE, #offGlue_pJitProfTable] @ refresh cached on/off switch 13839#endif 13840 bne common_exceptionThrown @ no, handle exception 13841 13842 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 13843 GET_INST_OPCODE(ip) @ extract opcode from rINST 13844 GOTO_OPCODE(ip) @ jump to next instruction 13845 13846.LstackOverflow: @ r0=methodToCall 13847 mov r1, r0 @ r1<- methodToCall 13848 ldr r0, [rGLUE, #offGlue_self] @ r0<- self 13849 bl dvmHandleStackOverflow 13850 b common_exceptionThrown 13851#ifdef ASSIST_DEBUGGER 13852 .fnend 13853#endif 13854 13855 13856 /* 13857 * Common code for method invocation, calling through "glue code". 13858 * 13859 * TODO: now that we have range and non-range invoke handlers, this 13860 * needs to be split into two. Maybe just create entry points 13861 * that set r9 and jump here? 13862 * 13863 * On entry: 13864 * r0 is "Method* methodToCall", the method we're trying to call 13865 * r9 is "bool methodCallRange", indicating if this is a /range variant 13866 */ 13867 .if 0 13868.LinvokeOld: 13869 sub sp, sp, #8 @ space for args + pad 13870 FETCH(ip, 2) @ ip<- FEDC or CCCC 13871 mov r2, r0 @ A2<- methodToCall 13872 mov r0, rGLUE @ A0<- glue 13873 SAVE_PC_FP_TO_GLUE() @ export state to "glue" 13874 mov r1, r9 @ A1<- methodCallRange 13875 mov r3, rINST, lsr #8 @ A3<- AA 13876 str ip, [sp, #0] @ A4<- ip 13877 bl dvmMterp_invokeMethod @ call the C invokeMethod 13878 add sp, sp, #8 @ remove arg area 13879 b common_resumeAfterGlueCall @ continue to next instruction 13880 .endif 13881 13882 13883 13884/* 13885 * Common code for handling a return instruction. 13886 * 13887 * This does not return. 13888 */ 13889common_returnFromMethod: 13890.LreturnNew: 13891 mov r0, #kInterpEntryReturn 13892 mov r9, #0 13893 bl common_periodicChecks 13894 13895 ldr lr, [rGLUE, #offGlue_pInterpBreak] 13896 SAVEAREA_FROM_FP(r0, rFP) 13897 ldr lr, [lr] @ lr<- active submodes 13898 ldr r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc 13899 ands lr, #kSubModeMethodTrace @ method tracing? 13900 beq 333f 13901 stmfd sp!, {r0-r3} @ preserve r0-r3 13902 mov r0, r6 13903 @ r0=rGlue 13904 bl dvmFastJavaMethodTraceExit 13905 ldmfd sp!, {r0-r3} @ restore r0-r3 13906333: 13907 ldr rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame 13908 ldr r3, [rGLUE, #offGlue_self] @ r3<- glue->self 13909 ldr r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)] 13910 @ r2<- method we're returning to 13911 cmp r2, #0 @ is this a break frame? 13912#if defined(WORKAROUND_CORTEX_A9_745320) 13913 /* Don't use conditional loads if the HW defect exists */ 13914 beq 101f 13915 ldr r10, [r2, #offMethod_clazz] @ r10<- method->clazz 13916101: 13917#else 13918 ldrne r10, [r2, #offMethod_clazz] @ r10<- method->clazz 13919#endif 13920 mov r1, #0 @ "want switch" = false 13921 beq common_gotoBail @ break frame, bail out completely 13922 13923 PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST 13924 str r2, [rGLUE, #offGlue_method]@ glue->method = newSave->method 13925 ldr r1, [r10, #offClassObject_pDvmDex] @ r1<- method->clazz->pDvmDex 13926 str rFP, [r3, #offThread_curFrame] @ self->curFrame = fp 13927#if defined(WITH_JIT) 13928 ldr r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr 13929 mov rPC, r9 @ publish new rPC 13930 str r1, [rGLUE, #offGlue_methodClassDex] 13931 str r10, [r3, #offThread_inJitCodeCache] @ may return to JIT'ed land 13932 cmp r10, #0 @ caller is compiled code 13933 blxne r10 13934 GET_INST_OPCODE(ip) @ extract opcode from rINST 13935 GOTO_OPCODE(ip) @ jump to next instruction 13936#else 13937 GET_INST_OPCODE(ip) @ extract opcode from rINST 13938 mov rPC, r9 @ publish new rPC 13939 str r1, [rGLUE, #offGlue_methodClassDex] 13940 GOTO_OPCODE(ip) @ jump to next instruction 13941#endif 13942 13943 /* 13944 * Return handling, calls through "glue code". 13945 */ 13946 .if 0 13947.LreturnOld: 13948 SAVE_PC_FP_TO_GLUE() @ export state 13949 mov r0, rGLUE @ arg to function 13950 bl dvmMterp_returnFromMethod 13951 b common_resumeAfterGlueCall 13952 .endif 13953 13954 13955/* 13956 * Somebody has thrown an exception. Handle it. 13957 * 13958 * If the exception processing code returns to us (instead of falling 13959 * out of the interpreter), continue with whatever the next instruction 13960 * now happens to be. 13961 * 13962 * This does not return. 13963 */ 13964 .global dvmMterpCommonExceptionThrown 13965dvmMterpCommonExceptionThrown: 13966common_exceptionThrown: 13967.LexceptionNew: 13968 mov r0, #kInterpEntryThrow 13969 mov r9, #0 13970 bl common_periodicChecks 13971 13972 ldr r10, [rGLUE, #offGlue_self] @ r10<- glue->self 13973 ldr r9, [r10, #offThread_exception] @ r9<- self->exception 13974 mov r1, r10 @ r1<- self 13975 mov r0, r9 @ r0<- exception 13976 bl dvmAddTrackedAlloc @ don't let the exception be GCed 13977 mov r3, #0 @ r3<- NULL 13978 str r3, [r10, #offThread_exception] @ self->exception = NULL 13979 13980 /* set up args and a local for "&fp" */ 13981 /* (str sp, [sp, #-4]! would be perfect here, but is discouraged) */ 13982 str rFP, [sp, #-4]! @ *--sp = fp 13983 mov ip, sp @ ip<- &fp 13984 mov r3, #0 @ r3<- false 13985 str ip, [sp, #-4]! @ *--sp = &fp 13986 ldr r1, [rGLUE, #offGlue_method] @ r1<- glue->method 13987 mov r0, r10 @ r0<- self 13988 ldr r1, [r1, #offMethod_insns] @ r1<- method->insns 13989 mov r2, r9 @ r2<- exception 13990 sub r1, rPC, r1 @ r1<- pc - method->insns 13991 mov r1, r1, asr #1 @ r1<- offset in code units 13992 13993 /* call, r0 gets catchRelPc (a code-unit offset) */ 13994 bl dvmFindCatchBlock @ call(self, relPc, exc, scan?, &fp) 13995 13996 /* fix earlier stack overflow if necessary; may trash rFP */ 13997 ldrb r1, [r10, #offThread_stackOverflowed] 13998 cmp r1, #0 @ did we overflow earlier? 13999 beq 1f @ no, skip ahead 14000 mov rFP, r0 @ save relPc result in rFP 14001 mov r0, r10 @ r0<- self 14002 mov r1, r9 @ r1<- exception 14003 bl dvmCleanupStackOverflow @ call(self) 14004 mov r0, rFP @ restore result 140051: 14006 14007 /* update frame pointer and check result from dvmFindCatchBlock */ 14008 ldr rFP, [sp, #4] @ retrieve the updated rFP 14009 cmp r0, #0 @ is catchRelPc < 0? 14010 add sp, sp, #8 @ restore stack 14011 bmi .LnotCaughtLocally 14012 14013 /* adjust locals to match self->curFrame and updated PC */ 14014 SAVEAREA_FROM_FP(r1, rFP) @ r1<- new save area 14015 ldr r1, [r1, #offStackSaveArea_method] @ r1<- new method 14016 str r1, [rGLUE, #offGlue_method] @ glue->method = new method 14017 ldr r2, [r1, #offMethod_clazz] @ r2<- method->clazz 14018 ldr r3, [r1, #offMethod_insns] @ r3<- method->insns 14019 ldr r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex 14020 add rPC, r3, r0, asl #1 @ rPC<- method->insns + catchRelPc 14021 str r2, [rGLUE, #offGlue_methodClassDex] @ glue->pDvmDex = meth... 14022 14023 /* release the tracked alloc on the exception */ 14024 mov r0, r9 @ r0<- exception 14025 mov r1, r10 @ r1<- self 14026 bl dvmReleaseTrackedAlloc @ release the exception 14027 14028 /* restore the exception if the handler wants it */ 14029 FETCH_INST() @ load rINST from rPC 14030 GET_INST_OPCODE(ip) @ extract opcode from rINST 14031 cmp ip, #OP_MOVE_EXCEPTION @ is it "move-exception"? 14032 streq r9, [r10, #offThread_exception] @ yes, restore the exception 14033 GOTO_OPCODE(ip) @ jump to next instruction 14034 14035.LnotCaughtLocally: @ r9=exception, r10=self 14036 /* fix stack overflow if necessary */ 14037 ldrb r1, [r10, #offThread_stackOverflowed] 14038 cmp r1, #0 @ did we overflow earlier? 14039 movne r0, r10 @ if yes: r0<- self 14040 movne r1, r9 @ if yes: r1<- exception 14041 blne dvmCleanupStackOverflow @ if yes: call(self) 14042 14043 @ may want to show "not caught locally" debug messages here 14044#if DVM_SHOW_EXCEPTION >= 2 14045 /* call __android_log_print(prio, tag, format, ...) */ 14046 /* "Exception %s from %s:%d not caught locally" */ 14047 @ dvmLineNumFromPC(method, pc - method->insns) 14048 ldr r0, [rGLUE, #offGlue_method] 14049 ldr r1, [r0, #offMethod_insns] 14050 sub r1, rPC, r1 14051 asr r1, r1, #1 14052 bl dvmLineNumFromPC 14053 str r0, [sp, #-4]! 14054 @ dvmGetMethodSourceFile(method) 14055 ldr r0, [rGLUE, #offGlue_method] 14056 bl dvmGetMethodSourceFile 14057 str r0, [sp, #-4]! 14058 @ exception->clazz->descriptor 14059 ldr r3, [r9, #offObject_clazz] 14060 ldr r3, [r3, #offClassObject_descriptor] 14061 @ 14062 ldr r2, strExceptionNotCaughtLocally 14063 ldr r1, strLogTag 14064 mov r0, #3 @ LOG_DEBUG 14065 bl __android_log_print 14066#endif 14067 str r9, [r10, #offThread_exception] @ restore exception 14068 mov r0, r9 @ r0<- exception 14069 mov r1, r10 @ r1<- self 14070 bl dvmReleaseTrackedAlloc @ release the exception 14071 mov r1, #0 @ "want switch" = false 14072 b common_gotoBail @ bail out 14073 14074 14075 /* 14076 * Exception handling, calls through "glue code". 14077 */ 14078 .if 0 14079.LexceptionOld: 14080 SAVE_PC_FP_TO_GLUE() @ export state 14081 mov r0, rGLUE @ arg to function 14082 bl dvmMterp_exceptionThrown 14083 b common_resumeAfterGlueCall 14084 .endif 14085 14086 14087/* 14088 * After returning from a "glued" function, pull out the updated 14089 * values and start executing at the next instruction. 14090 */ 14091common_resumeAfterGlueCall: 14092 LOAD_PC_FP_FROM_GLUE() @ pull rPC and rFP out of glue 14093 FETCH_INST() @ load rINST from rPC 14094 GET_INST_OPCODE(ip) @ extract opcode from rINST 14095 GOTO_OPCODE(ip) @ jump to next instruction 14096 14097/* 14098 * Invalid array index. Note that our calling convention is strange; we use r1 14099 * and r3 because those just happen to be the registers all our callers are 14100 * using. We shuffle them here before calling the C function. 14101 * r1: index 14102 * r3: size 14103 */ 14104common_errArrayIndex: 14105 EXPORT_PC() 14106 mov r0, r1 14107 mov r1, r3 14108 bl dvmThrowAIOOBE 14109 b common_exceptionThrown 14110 14111/* 14112 * Integer divide or mod by zero. 14113 */ 14114common_errDivideByZero: 14115 EXPORT_PC() 14116 ldr r0, strArithmeticException 14117 ldr r1, strDivideByZero 14118 bl dvmThrowException 14119 b common_exceptionThrown 14120 14121/* 14122 * Attempt to allocate an array with a negative size. 14123 */ 14124common_errNegativeArraySize: 14125 EXPORT_PC() 14126 ldr r0, strNegativeArraySizeException 14127 mov r1, #0 14128 bl dvmThrowException 14129 b common_exceptionThrown 14130 14131/* 14132 * Invocation of a non-existent method. 14133 */ 14134common_errNoSuchMethod: 14135 EXPORT_PC() 14136 ldr r0, strNoSuchMethodError 14137 mov r1, #0 14138 bl dvmThrowException 14139 b common_exceptionThrown 14140 14141/* 14142 * We encountered a null object when we weren't expecting one. We 14143 * export the PC, throw a NullPointerException, and goto the exception 14144 * processing code. 14145 */ 14146common_errNullObject: 14147 EXPORT_PC() 14148 ldr r0, strNullPointerException 14149 mov r1, #0 14150 bl dvmThrowException 14151 b common_exceptionThrown 14152 14153/* 14154 * For debugging, cause an immediate fault. The source address will 14155 * be in lr (use a bl instruction to jump here). 14156 */ 14157common_abort: 14158 ldr pc, .LdeadFood 14159.LdeadFood: 14160 .word 0xdeadf00d 14161 14162/* 14163 * Spit out a "we were here", preserving all registers. (The attempt 14164 * to save ip won't work, but we need to save an even number of 14165 * registers for EABI 64-bit stack alignment.) 14166 */ 14167 .macro SQUEAK num 14168common_squeak\num: 14169 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14170 ldr r0, strSqueak 14171 mov r1, #\num 14172 bl printf 14173 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14174 bx lr 14175 .endm 14176 14177 SQUEAK 0 14178 SQUEAK 1 14179 SQUEAK 2 14180 SQUEAK 3 14181 SQUEAK 4 14182 SQUEAK 5 14183 14184/* 14185 * Spit out the number in r0, preserving registers. 14186 */ 14187common_printNum: 14188 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14189 mov r1, r0 14190 ldr r0, strSqueak 14191 bl printf 14192 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14193 bx lr 14194 14195/* 14196 * Print a newline, preserving registers. 14197 */ 14198common_printNewline: 14199 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14200 ldr r0, strNewline 14201 bl printf 14202 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14203 bx lr 14204 14205 /* 14206 * Print the 32-bit quantity in r0 as a hex value, preserving registers. 14207 */ 14208common_printHex: 14209 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14210 mov r1, r0 14211 ldr r0, strPrintHex 14212 bl printf 14213 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14214 bx lr 14215 14216/* 14217 * Print the 64-bit quantity in r0-r1, preserving registers. 14218 */ 14219common_printLong: 14220 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14221 mov r3, r1 14222 mov r2, r0 14223 ldr r0, strPrintLong 14224 bl printf 14225 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14226 bx lr 14227 14228/* 14229 * Print full method info. Pass the Method* in r0. Preserves regs. 14230 */ 14231common_printMethod: 14232 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14233 bl dvmMterpPrintMethod 14234 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14235 bx lr 14236 14237/* 14238 * Call a C helper function that dumps regs and possibly some 14239 * additional info. Requires the C function to be compiled in. 14240 */ 14241 .if 0 14242common_dumpRegs: 14243 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14244 bl dvmMterpDumpArmRegs 14245 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14246 bx lr 14247 .endif 14248 14249#if 0 14250/* 14251 * Experiment on VFP mode. 14252 * 14253 * uint32_t setFPSCR(uint32_t val, uint32_t mask) 14254 * 14255 * Updates the bits specified by "mask", setting them to the values in "val". 14256 */ 14257setFPSCR: 14258 and r0, r0, r1 @ make sure no stray bits are set 14259 fmrx r2, fpscr @ get VFP reg 14260 mvn r1, r1 @ bit-invert mask 14261 and r2, r2, r1 @ clear masked bits 14262 orr r2, r2, r0 @ set specified bits 14263 fmxr fpscr, r2 @ set VFP reg 14264 mov r0, r2 @ return new value 14265 bx lr 14266 14267 .align 2 14268 .global dvmConfigureFP 14269 .type dvmConfigureFP, %function 14270dvmConfigureFP: 14271 stmfd sp!, {ip, lr} 14272 /* 0x03000000 sets DN/FZ */ 14273 /* 0x00009f00 clears the six exception enable flags */ 14274 bl common_squeak0 14275 mov r0, #0x03000000 @ r0<- 0x03000000 14276 add r1, r0, #0x9f00 @ r1<- 0x03009f00 14277 bl setFPSCR 14278 ldmfd sp!, {ip, pc} 14279#endif 14280 14281 14282/* 14283 * String references, must be close to the code that uses them. 14284 */ 14285 .align 2 14286strArithmeticException: 14287 .word .LstrArithmeticException 14288strDivideByZero: 14289 .word .LstrDivideByZero 14290strNegativeArraySizeException: 14291 .word .LstrNegativeArraySizeException 14292strNoSuchMethodError: 14293 .word .LstrNoSuchMethodError 14294strNullPointerException: 14295 .word .LstrNullPointerException 14296 14297strLogTag: 14298 .word .LstrLogTag 14299strExceptionNotCaughtLocally: 14300 .word .LstrExceptionNotCaughtLocally 14301 14302strNewline: 14303 .word .LstrNewline 14304strSqueak: 14305 .word .LstrSqueak 14306strPrintHex: 14307 .word .LstrPrintHex 14308strPrintLong: 14309 .word .LstrPrintLong 14310 14311/* 14312 * Zero-terminated ASCII string data. 14313 * 14314 * On ARM we have two choices: do like gcc does, and LDR from a .word 14315 * with the address, or use an ADR pseudo-op to get the address 14316 * directly. ADR saves 4 bytes and an indirection, but it's using a 14317 * PC-relative addressing mode and hence has a limited range, which 14318 * makes it not work well with mergeable string sections. 14319 */ 14320 .section .rodata.str1.4,"aMS",%progbits,1 14321 14322.LstrBadEntryPoint: 14323 .asciz "Bad entry point %d\n" 14324.LstrArithmeticException: 14325 .asciz "Ljava/lang/ArithmeticException;" 14326.LstrDivideByZero: 14327 .asciz "divide by zero" 14328.LstrFilledNewArrayNotImpl: 14329 .asciz "filled-new-array only implemented for objects and 'int'" 14330.LstrInternalError: 14331 .asciz "Ljava/lang/InternalError;" 14332.LstrInstantiationError: 14333 .asciz "Ljava/lang/InstantiationError;" 14334.LstrNegativeArraySizeException: 14335 .asciz "Ljava/lang/NegativeArraySizeException;" 14336.LstrNoSuchMethodError: 14337 .asciz "Ljava/lang/NoSuchMethodError;" 14338.LstrNullPointerException: 14339 .asciz "Ljava/lang/NullPointerException;" 14340 14341.LstrLogTag: 14342 .asciz "mterp" 14343.LstrExceptionNotCaughtLocally: 14344 .asciz "Exception %s from %s:%d not caught locally\n" 14345 14346.LstrNewline: 14347 .asciz "\n" 14348.LstrSqueak: 14349 .asciz "<%d>" 14350.LstrPrintHex: 14351 .asciz "<0x%x>" 14352.LstrPrintLong: 14353 .asciz "<%lld>" 14354 14355