InterpAsm-armv5te-vfp.S revision cfdeca37fcaa27c37bad5077223e4d1e87f1182e
1/* 2 * This file was generated automatically by gen-mterp.py for 'armv5te-vfp'. 3 * 4 * --> DO NOT EDIT <-- 5 */ 6 7/* File: armv5te/header.S */ 8/* 9 * Copyright (C) 2008 The Android Open Source Project 10 * 11 * Licensed under the Apache License, Version 2.0 (the "License"); 12 * you may not use this file except in compliance with the License. 13 * You may obtain a copy of the License at 14 * 15 * http://www.apache.org/licenses/LICENSE-2.0 16 * 17 * Unless required by applicable law or agreed to in writing, software 18 * distributed under the License is distributed on an "AS IS" BASIS, 19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 * See the License for the specific language governing permissions and 21 * limitations under the License. 22 */ 23 24/* 25 * ARMv5 definitions and declarations. 26 */ 27 28/* 29ARM EABI general notes: 30 31r0-r3 hold first 4 args to a method; they are not preserved across method calls 32r4-r8 are available for general use 33r9 is given special treatment in some situations, but not for us 34r10 (sl) seems to be generally available 35r11 (fp) is used by gcc (unless -fomit-frame-pointer is set) 36r12 (ip) is scratch -- not preserved across method calls 37r13 (sp) should be managed carefully in case a signal arrives 38r14 (lr) must be preserved 39r15 (pc) can be tinkered with directly 40 41r0 holds returns of <= 4 bytes 42r0-r1 hold returns of 8 bytes, low word in r0 43 44Callee must save/restore r4+ (except r12) if it modifies them. If VFP 45is present, registers s16-s31 (a/k/a d8-d15, a/k/a q4-q7) must be preserved, 46s0-s15 (d0-d7, q0-a3) do not need to be. 47 48Stack is "full descending". Only the arguments that don't fit in the first 4 49registers are placed on the stack. "sp" points at the first stacked argument 50(i.e. the 5th arg). 51 52VFP: single-precision results in s0, double-precision results in d0. 53 54In the EABI, "sp" must be 64-bit aligned on entry to a function, and any 5564-bit quantities (long long, double) must be 64-bit aligned. 56*/ 57 58/* 59Mterp and ARM notes: 60 61The following registers have fixed assignments: 62 63 reg nick purpose 64 r4 rPC interpreted program counter, used for fetching instructions 65 r5 rFP interpreted frame pointer, used for accessing locals and args 66 r6 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: armv5te/platform.S */ 210/* 211 * =========================================================================== 212 * CPU-version-specific defines 213 * =========================================================================== 214 */ 215 216/* 217 * Macro for data memory barrier; not meaningful pre-ARMv6K. 218 */ 219.macro SMP_DMB 220.endm 221 222/* 223 * Macro for data memory barrier; not meaningful pre-ARMv6K. 224 */ 225.macro SMP_DMB_ST 226.endm 227 228/* File: armv5te/entry.S */ 229/* 230 * Copyright (C) 2008 The Android Open Source Project 231 * 232 * Licensed under the Apache License, Version 2.0 (the "License"); 233 * you may not use this file except in compliance with the License. 234 * You may obtain a copy of the License at 235 * 236 * http://www.apache.org/licenses/LICENSE-2.0 237 * 238 * Unless required by applicable law or agreed to in writing, software 239 * distributed under the License is distributed on an "AS IS" BASIS, 240 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 241 * See the License for the specific language governing permissions and 242 * limitations under the License. 243 */ 244/* 245 * Interpreter entry point. 246 */ 247 248/* 249 * We don't have formal stack frames, so gdb scans upward in the code 250 * to find the start of the function (a label with the %function type), 251 * and then looks at the next few instructions to figure out what 252 * got pushed onto the stack. From this it figures out how to restore 253 * the registers, including PC, for the previous stack frame. If gdb 254 * sees a non-function label, it stops scanning, so either we need to 255 * have nothing but assembler-local labels between the entry point and 256 * the break, or we need to fake it out. 257 * 258 * When this is defined, we add some stuff to make gdb less confused. 259 */ 260#define ASSIST_DEBUGGER 1 261 262 .text 263 .align 2 264 .global dvmMterpStdRun 265 .type dvmMterpStdRun, %function 266 267/* 268 * On entry: 269 * r0 MterpGlue* glue 270 * 271 * This function returns a boolean "changeInterp" value. The return comes 272 * via a call to dvmMterpStdBail(). 273 */ 274dvmMterpStdRun: 275#define MTERP_ENTRY1 \ 276 .save {r4-r10,fp,lr}; \ 277 stmfd sp!, {r4-r10,fp,lr} @ save 9 regs 278#define MTERP_ENTRY2 \ 279 .pad #4; \ 280 sub sp, sp, #4 @ align 64 281 282 .fnstart 283 MTERP_ENTRY1 284 MTERP_ENTRY2 285 286 /* save stack pointer, add magic word for debuggerd */ 287 str sp, [r0, #offGlue_bailPtr] @ save SP for eventual return 288 289 /* set up "named" registers, figure out entry point */ 290 mov rGLUE, r0 @ set rGLUE 291 ldr r1, [r0, #offGlue_entryPoint] @ enum is 4 bytes in aapcs-EABI 292 LOAD_PC_FP_FROM_GLUE() @ load rPC and rFP from "glue" 293 adr rIBASE, dvmAsmInstructionStart @ set rIBASE 294 cmp r1, #kInterpEntryInstr @ usual case? 295 bne .Lnot_instr @ no, handle it 296 297#if defined(WITH_JIT) 298.LentryInstr: 299 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 300 /* Entry is always a possible trace start */ 301 GET_JIT_PROF_TABLE(r0) 302 FETCH_INST() 303 mov r1, #0 @ prepare the value for the new state 304 str r1, [r10, #offThread_inJitCodeCache] @ back to the interp land 305 cmp r0,#0 @ is profiling disabled? 306#if !defined(WITH_SELF_VERIFICATION) 307 bne common_updateProfile @ profiling is enabled 308#else 309 ldr r2, [r10, #offThread_shadowSpace] @ to find out the jit exit state 310 beq 1f @ profiling is disabled 311 ldr r3, [r2, #offShadowSpace_jitExitState] @ jit exit state 312 cmp r3, #kSVSTraceSelect @ hot trace following? 313 moveq r2,#kJitTSelectRequestHot @ ask for trace selection 314 beq common_selectTrace @ go build the trace 315 cmp r3, #kSVSNoProfile @ don't profile the next instruction? 316 beq 1f @ intrepret the next instruction 317 b common_updateProfile @ collect profiles 318#endif 3191: 320 GET_INST_OPCODE(ip) 321 GOTO_OPCODE(ip) 322#else 323 /* start executing the instruction at rPC */ 324 FETCH_INST() @ load rINST from rPC 325 GET_INST_OPCODE(ip) @ extract opcode from rINST 326 GOTO_OPCODE(ip) @ jump to next instruction 327#endif 328 329.Lnot_instr: 330 cmp r1, #kInterpEntryReturn @ were we returning from a method? 331 beq common_returnFromMethod 332 333.Lnot_return: 334 cmp r1, #kInterpEntryThrow @ were we throwing an exception? 335 beq common_exceptionThrown 336 337#if defined(WITH_JIT) 338.Lnot_throw: 339 ldr r10,[rGLUE, #offGlue_jitResumeNPC] 340 ldr r2,[rGLUE, #offGlue_jitResumeDPC] 341 cmp r1, #kInterpEntryResume @ resuming after Jit single-step? 342 bne .Lbad_arg 343 cmp rPC,r2 344 bne .LentryInstr @ must have branched, don't resume 345#if defined(WITH_SELF_VERIFICATION) 346 @ glue->entryPoint will be set in dvmSelfVerificationSaveState 347 b jitSVShadowRunStart @ re-enter the translation after the 348 @ single-stepped instruction 349 @noreturn 350#endif 351 mov r1, #kInterpEntryInstr 352 str r1, [rGLUE, #offGlue_entryPoint] 353 bx r10 @ re-enter the translation 354#endif 355 356.Lbad_arg: 357 ldr r0, strBadEntryPoint 358 @ r1 holds value of entryPoint 359 bl printf 360 bl dvmAbort 361 .fnend 362 363 364 .global dvmMterpStdBail 365 .type dvmMterpStdBail, %function 366 367/* 368 * Restore the stack pointer and PC from the save point established on entry. 369 * This is essentially the same as a longjmp, but should be cheaper. The 370 * last instruction causes us to return to whoever called dvmMterpStdRun. 371 * 372 * We pushed some registers on the stack in dvmMterpStdRun, then saved 373 * SP and LR. Here we restore SP, restore the registers, and then restore 374 * LR to PC. 375 * 376 * On entry: 377 * r0 MterpGlue* glue 378 * r1 bool changeInterp 379 */ 380dvmMterpStdBail: 381 ldr sp, [r0, #offGlue_bailPtr] @ sp<- saved SP 382 mov r0, r1 @ return the changeInterp value 383 add sp, sp, #4 @ un-align 64 384 ldmfd sp!, {r4-r10,fp,pc} @ restore 9 regs and return 385 386 387/* 388 * String references. 389 */ 390strBadEntryPoint: 391 .word .LstrBadEntryPoint 392 393 394 .global dvmAsmInstructionStart 395 .type dvmAsmInstructionStart, %function 396dvmAsmInstructionStart = .L_OP_NOP 397 .text 398 399/* ------------------------------ */ 400 .balign 64 401.L_OP_NOP: /* 0x00 */ 402/* File: armv5te/OP_NOP.S */ 403 FETCH_ADVANCE_INST(1) @ advance to next instr, load rINST 404 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 405 GOTO_OPCODE(ip) @ execute it 406 407#ifdef ASSIST_DEBUGGER 408 /* insert fake function header to help gdb find the stack frame */ 409 .type dalvik_inst, %function 410dalvik_inst: 411 .fnstart 412 MTERP_ENTRY1 413 MTERP_ENTRY2 414 .fnend 415#endif 416 417/* ------------------------------ */ 418 .balign 64 419.L_OP_MOVE: /* 0x01 */ 420/* File: armv5te/OP_MOVE.S */ 421 /* for move, move-object, long-to-int */ 422 /* op vA, vB */ 423 mov r1, rINST, lsr #12 @ r1<- B from 15:12 424 mov r0, rINST, lsr #8 @ r0<- A from 11:8 425 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 426 GET_VREG(r2, r1) @ r2<- fp[B] 427 and r0, r0, #15 428 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 429 SET_VREG(r2, r0) @ fp[A]<- r2 430 GOTO_OPCODE(ip) @ execute next instruction 431 432/* ------------------------------ */ 433 .balign 64 434.L_OP_MOVE_FROM16: /* 0x02 */ 435/* File: armv5te/OP_MOVE_FROM16.S */ 436 /* for: move/from16, move-object/from16 */ 437 /* op vAA, vBBBB */ 438 FETCH(r1, 1) @ r1<- BBBB 439 mov r0, rINST, lsr #8 @ r0<- AA 440 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 441 GET_VREG(r2, r1) @ r2<- fp[BBBB] 442 GET_INST_OPCODE(ip) @ extract opcode from rINST 443 SET_VREG(r2, r0) @ fp[AA]<- r2 444 GOTO_OPCODE(ip) @ jump to next instruction 445 446/* ------------------------------ */ 447 .balign 64 448.L_OP_MOVE_16: /* 0x03 */ 449/* File: armv5te/OP_MOVE_16.S */ 450 /* for: move/16, move-object/16 */ 451 /* op vAAAA, vBBBB */ 452 FETCH(r1, 2) @ r1<- BBBB 453 FETCH(r0, 1) @ r0<- AAAA 454 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 455 GET_VREG(r2, r1) @ r2<- fp[BBBB] 456 GET_INST_OPCODE(ip) @ extract opcode from rINST 457 SET_VREG(r2, r0) @ fp[AAAA]<- r2 458 GOTO_OPCODE(ip) @ jump to next instruction 459 460/* ------------------------------ */ 461 .balign 64 462.L_OP_MOVE_WIDE: /* 0x04 */ 463/* File: armv5te/OP_MOVE_WIDE.S */ 464 /* move-wide vA, vB */ 465 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 466 mov r2, rINST, lsr #8 @ r2<- A(+) 467 mov r3, rINST, lsr #12 @ r3<- B 468 and r2, r2, #15 469 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 470 add r2, rFP, r2, lsl #2 @ r2<- &fp[A] 471 ldmia r3, {r0-r1} @ r0/r1<- fp[B] 472 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 473 GET_INST_OPCODE(ip) @ extract opcode from rINST 474 stmia r2, {r0-r1} @ fp[A]<- r0/r1 475 GOTO_OPCODE(ip) @ jump to next instruction 476 477/* ------------------------------ */ 478 .balign 64 479.L_OP_MOVE_WIDE_FROM16: /* 0x05 */ 480/* File: armv5te/OP_MOVE_WIDE_FROM16.S */ 481 /* move-wide/from16 vAA, vBBBB */ 482 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 483 FETCH(r3, 1) @ r3<- BBBB 484 mov r2, rINST, lsr #8 @ r2<- AA 485 add r3, rFP, r3, lsl #2 @ r3<- &fp[BBBB] 486 add r2, rFP, r2, lsl #2 @ r2<- &fp[AA] 487 ldmia r3, {r0-r1} @ r0/r1<- fp[BBBB] 488 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 489 GET_INST_OPCODE(ip) @ extract opcode from rINST 490 stmia r2, {r0-r1} @ fp[AA]<- r0/r1 491 GOTO_OPCODE(ip) @ jump to next instruction 492 493/* ------------------------------ */ 494 .balign 64 495.L_OP_MOVE_WIDE_16: /* 0x06 */ 496/* File: armv5te/OP_MOVE_WIDE_16.S */ 497 /* move-wide/16 vAAAA, vBBBB */ 498 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 499 FETCH(r3, 2) @ r3<- BBBB 500 FETCH(r2, 1) @ r2<- AAAA 501 add r3, rFP, r3, lsl #2 @ r3<- &fp[BBBB] 502 add r2, rFP, r2, lsl #2 @ r2<- &fp[AAAA] 503 ldmia r3, {r0-r1} @ r0/r1<- fp[BBBB] 504 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 505 GET_INST_OPCODE(ip) @ extract opcode from rINST 506 stmia r2, {r0-r1} @ fp[AAAA]<- r0/r1 507 GOTO_OPCODE(ip) @ jump to next instruction 508 509/* ------------------------------ */ 510 .balign 64 511.L_OP_MOVE_OBJECT: /* 0x07 */ 512/* File: armv5te/OP_MOVE_OBJECT.S */ 513/* File: armv5te/OP_MOVE.S */ 514 /* for move, move-object, long-to-int */ 515 /* op vA, vB */ 516 mov r1, rINST, lsr #12 @ r1<- B from 15:12 517 mov r0, rINST, lsr #8 @ r0<- A from 11:8 518 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 519 GET_VREG(r2, r1) @ r2<- fp[B] 520 and r0, r0, #15 521 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 522 SET_VREG(r2, r0) @ fp[A]<- r2 523 GOTO_OPCODE(ip) @ execute next instruction 524 525 526/* ------------------------------ */ 527 .balign 64 528.L_OP_MOVE_OBJECT_FROM16: /* 0x08 */ 529/* File: armv5te/OP_MOVE_OBJECT_FROM16.S */ 530/* File: armv5te/OP_MOVE_FROM16.S */ 531 /* for: move/from16, move-object/from16 */ 532 /* op vAA, vBBBB */ 533 FETCH(r1, 1) @ r1<- BBBB 534 mov r0, rINST, lsr #8 @ r0<- AA 535 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 536 GET_VREG(r2, r1) @ r2<- fp[BBBB] 537 GET_INST_OPCODE(ip) @ extract opcode from rINST 538 SET_VREG(r2, r0) @ fp[AA]<- r2 539 GOTO_OPCODE(ip) @ jump to next instruction 540 541 542/* ------------------------------ */ 543 .balign 64 544.L_OP_MOVE_OBJECT_16: /* 0x09 */ 545/* File: armv5te/OP_MOVE_OBJECT_16.S */ 546/* File: armv5te/OP_MOVE_16.S */ 547 /* for: move/16, move-object/16 */ 548 /* op vAAAA, vBBBB */ 549 FETCH(r1, 2) @ r1<- BBBB 550 FETCH(r0, 1) @ r0<- AAAA 551 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 552 GET_VREG(r2, r1) @ r2<- fp[BBBB] 553 GET_INST_OPCODE(ip) @ extract opcode from rINST 554 SET_VREG(r2, r0) @ fp[AAAA]<- r2 555 GOTO_OPCODE(ip) @ jump to next instruction 556 557 558/* ------------------------------ */ 559 .balign 64 560.L_OP_MOVE_RESULT: /* 0x0a */ 561/* File: armv5te/OP_MOVE_RESULT.S */ 562 /* for: move-result, move-result-object */ 563 /* op vAA */ 564 mov r2, rINST, lsr #8 @ r2<- AA 565 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 566 ldr r0, [rGLUE, #offGlue_retval] @ r0<- glue->retval.i 567 GET_INST_OPCODE(ip) @ extract opcode from rINST 568 SET_VREG(r0, r2) @ fp[AA]<- r0 569 GOTO_OPCODE(ip) @ jump to next instruction 570 571/* ------------------------------ */ 572 .balign 64 573.L_OP_MOVE_RESULT_WIDE: /* 0x0b */ 574/* File: armv5te/OP_MOVE_RESULT_WIDE.S */ 575 /* move-result-wide vAA */ 576 mov r2, rINST, lsr #8 @ r2<- AA 577 add r3, rGLUE, #offGlue_retval @ r3<- &glue->retval 578 add r2, rFP, r2, lsl #2 @ r2<- &fp[AA] 579 ldmia r3, {r0-r1} @ r0/r1<- retval.j 580 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 581 GET_INST_OPCODE(ip) @ extract opcode from rINST 582 stmia r2, {r0-r1} @ fp[AA]<- r0/r1 583 GOTO_OPCODE(ip) @ jump to next instruction 584 585/* ------------------------------ */ 586 .balign 64 587.L_OP_MOVE_RESULT_OBJECT: /* 0x0c */ 588/* File: armv5te/OP_MOVE_RESULT_OBJECT.S */ 589/* File: armv5te/OP_MOVE_RESULT.S */ 590 /* for: move-result, move-result-object */ 591 /* op vAA */ 592 mov r2, rINST, lsr #8 @ r2<- AA 593 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 594 ldr r0, [rGLUE, #offGlue_retval] @ r0<- glue->retval.i 595 GET_INST_OPCODE(ip) @ extract opcode from rINST 596 SET_VREG(r0, r2) @ fp[AA]<- r0 597 GOTO_OPCODE(ip) @ jump to next instruction 598 599 600/* ------------------------------ */ 601 .balign 64 602.L_OP_MOVE_EXCEPTION: /* 0x0d */ 603/* File: armv5te/OP_MOVE_EXCEPTION.S */ 604 /* move-exception vAA */ 605 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 606 mov r2, rINST, lsr #8 @ r2<- AA 607 ldr r3, [r0, #offThread_exception] @ r3<- dvmGetException bypass 608 mov r1, #0 @ r1<- 0 609 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 610 SET_VREG(r3, r2) @ fp[AA]<- exception obj 611 GET_INST_OPCODE(ip) @ extract opcode from rINST 612 str r1, [r0, #offThread_exception] @ dvmClearException bypass 613 GOTO_OPCODE(ip) @ jump to next instruction 614 615/* ------------------------------ */ 616 .balign 64 617.L_OP_RETURN_VOID: /* 0x0e */ 618/* File: armv5te/OP_RETURN_VOID.S */ 619 b common_returnFromMethod 620 621/* ------------------------------ */ 622 .balign 64 623.L_OP_RETURN: /* 0x0f */ 624/* File: armv5te/OP_RETURN.S */ 625 /* 626 * Return a 32-bit value. Copies the return value into the "glue" 627 * structure, then jumps to the return handler. 628 * 629 * for: return, return-object 630 */ 631 /* op vAA */ 632 mov r2, rINST, lsr #8 @ r2<- AA 633 GET_VREG(r0, r2) @ r0<- vAA 634 str r0, [rGLUE, #offGlue_retval] @ retval.i <- vAA 635 b common_returnFromMethod 636 637/* ------------------------------ */ 638 .balign 64 639.L_OP_RETURN_WIDE: /* 0x10 */ 640/* File: armv5te/OP_RETURN_WIDE.S */ 641 /* 642 * Return a 64-bit value. Copies the return value into the "glue" 643 * structure, then jumps to the return handler. 644 */ 645 /* return-wide vAA */ 646 mov r2, rINST, lsr #8 @ r2<- AA 647 add r2, rFP, r2, lsl #2 @ r2<- &fp[AA] 648 add r3, rGLUE, #offGlue_retval @ r3<- &glue->retval 649 ldmia r2, {r0-r1} @ r0/r1 <- vAA/vAA+1 650 stmia r3, {r0-r1} @ retval<- r0/r1 651 b common_returnFromMethod 652 653/* ------------------------------ */ 654 .balign 64 655.L_OP_RETURN_OBJECT: /* 0x11 */ 656/* File: armv5te/OP_RETURN_OBJECT.S */ 657/* File: armv5te/OP_RETURN.S */ 658 /* 659 * Return a 32-bit value. Copies the return value into the "glue" 660 * structure, then jumps to the return handler. 661 * 662 * for: return, return-object 663 */ 664 /* op vAA */ 665 mov r2, rINST, lsr #8 @ r2<- AA 666 GET_VREG(r0, r2) @ r0<- vAA 667 str r0, [rGLUE, #offGlue_retval] @ retval.i <- vAA 668 b common_returnFromMethod 669 670 671/* ------------------------------ */ 672 .balign 64 673.L_OP_CONST_4: /* 0x12 */ 674/* File: armv5te/OP_CONST_4.S */ 675 /* const/4 vA, #+B */ 676 mov r1, rINST, lsl #16 @ r1<- Bxxx0000 677 mov r0, rINST, lsr #8 @ r0<- A+ 678 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 679 mov r1, r1, asr #28 @ r1<- sssssssB (sign-extended) 680 and r0, r0, #15 681 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 682 SET_VREG(r1, r0) @ fp[A]<- r1 683 GOTO_OPCODE(ip) @ execute next instruction 684 685/* ------------------------------ */ 686 .balign 64 687.L_OP_CONST_16: /* 0x13 */ 688/* File: armv5te/OP_CONST_16.S */ 689 /* const/16 vAA, #+BBBB */ 690 FETCH_S(r0, 1) @ r0<- ssssBBBB (sign-extended) 691 mov r3, rINST, lsr #8 @ r3<- AA 692 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 693 SET_VREG(r0, r3) @ vAA<- r0 694 GET_INST_OPCODE(ip) @ extract opcode from rINST 695 GOTO_OPCODE(ip) @ jump to next instruction 696 697/* ------------------------------ */ 698 .balign 64 699.L_OP_CONST: /* 0x14 */ 700/* File: armv5te/OP_CONST.S */ 701 /* const vAA, #+BBBBbbbb */ 702 mov r3, rINST, lsr #8 @ r3<- AA 703 FETCH(r0, 1) @ r0<- bbbb (low) 704 FETCH(r1, 2) @ r1<- BBBB (high) 705 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 706 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 707 GET_INST_OPCODE(ip) @ extract opcode from rINST 708 SET_VREG(r0, r3) @ vAA<- r0 709 GOTO_OPCODE(ip) @ jump to next instruction 710 711/* ------------------------------ */ 712 .balign 64 713.L_OP_CONST_HIGH16: /* 0x15 */ 714/* File: armv5te/OP_CONST_HIGH16.S */ 715 /* const/high16 vAA, #+BBBB0000 */ 716 FETCH(r0, 1) @ r0<- 0000BBBB (zero-extended) 717 mov r3, rINST, lsr #8 @ r3<- AA 718 mov r0, r0, lsl #16 @ r0<- BBBB0000 719 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 720 SET_VREG(r0, r3) @ vAA<- r0 721 GET_INST_OPCODE(ip) @ extract opcode from rINST 722 GOTO_OPCODE(ip) @ jump to next instruction 723 724/* ------------------------------ */ 725 .balign 64 726.L_OP_CONST_WIDE_16: /* 0x16 */ 727/* File: armv5te/OP_CONST_WIDE_16.S */ 728 /* const-wide/16 vAA, #+BBBB */ 729 FETCH_S(r0, 1) @ r0<- ssssBBBB (sign-extended) 730 mov r3, rINST, lsr #8 @ r3<- AA 731 mov r1, r0, asr #31 @ r1<- ssssssss 732 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 733 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 734 GET_INST_OPCODE(ip) @ extract opcode from rINST 735 stmia r3, {r0-r1} @ vAA<- r0/r1 736 GOTO_OPCODE(ip) @ jump to next instruction 737 738/* ------------------------------ */ 739 .balign 64 740.L_OP_CONST_WIDE_32: /* 0x17 */ 741/* File: armv5te/OP_CONST_WIDE_32.S */ 742 /* const-wide/32 vAA, #+BBBBbbbb */ 743 FETCH(r0, 1) @ r0<- 0000bbbb (low) 744 mov r3, rINST, lsr #8 @ r3<- AA 745 FETCH_S(r2, 2) @ r2<- ssssBBBB (high) 746 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 747 orr r0, r0, r2, lsl #16 @ r0<- BBBBbbbb 748 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 749 mov r1, r0, asr #31 @ r1<- ssssssss 750 GET_INST_OPCODE(ip) @ extract opcode from rINST 751 stmia r3, {r0-r1} @ vAA<- r0/r1 752 GOTO_OPCODE(ip) @ jump to next instruction 753 754/* ------------------------------ */ 755 .balign 64 756.L_OP_CONST_WIDE: /* 0x18 */ 757/* File: armv5te/OP_CONST_WIDE.S */ 758 /* const-wide vAA, #+HHHHhhhhBBBBbbbb */ 759 FETCH(r0, 1) @ r0<- bbbb (low) 760 FETCH(r1, 2) @ r1<- BBBB (low middle) 761 FETCH(r2, 3) @ r2<- hhhh (high middle) 762 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb (low word) 763 FETCH(r3, 4) @ r3<- HHHH (high) 764 mov r9, rINST, lsr #8 @ r9<- AA 765 orr r1, r2, r3, lsl #16 @ r1<- HHHHhhhh (high word) 766 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 767 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 768 GET_INST_OPCODE(ip) @ extract opcode from rINST 769 stmia r9, {r0-r1} @ vAA<- r0/r1 770 GOTO_OPCODE(ip) @ jump to next instruction 771 772/* ------------------------------ */ 773 .balign 64 774.L_OP_CONST_WIDE_HIGH16: /* 0x19 */ 775/* File: armv5te/OP_CONST_WIDE_HIGH16.S */ 776 /* const-wide/high16 vAA, #+BBBB000000000000 */ 777 FETCH(r1, 1) @ r1<- 0000BBBB (zero-extended) 778 mov r3, rINST, lsr #8 @ r3<- AA 779 mov r0, #0 @ r0<- 00000000 780 mov r1, r1, lsl #16 @ r1<- BBBB0000 781 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 782 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 783 GET_INST_OPCODE(ip) @ extract opcode from rINST 784 stmia r3, {r0-r1} @ vAA<- r0/r1 785 GOTO_OPCODE(ip) @ jump to next instruction 786 787/* ------------------------------ */ 788 .balign 64 789.L_OP_CONST_STRING: /* 0x1a */ 790/* File: armv5te/OP_CONST_STRING.S */ 791 /* const/string vAA, String@BBBB */ 792 FETCH(r1, 1) @ r1<- BBBB 793 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- glue->methodClassDex 794 mov r9, rINST, lsr #8 @ r9<- AA 795 ldr r2, [r2, #offDvmDex_pResStrings] @ r2<- dvmDex->pResStrings 796 ldr r0, [r2, r1, lsl #2] @ r0<- pResStrings[BBBB] 797 cmp r0, #0 @ not yet resolved? 798 beq .LOP_CONST_STRING_resolve 799 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 800 GET_INST_OPCODE(ip) @ extract opcode from rINST 801 SET_VREG(r0, r9) @ vAA<- r0 802 GOTO_OPCODE(ip) @ jump to next instruction 803 804/* ------------------------------ */ 805 .balign 64 806.L_OP_CONST_STRING_JUMBO: /* 0x1b */ 807/* File: armv5te/OP_CONST_STRING_JUMBO.S */ 808 /* const/string vAA, String@BBBBBBBB */ 809 FETCH(r0, 1) @ r0<- bbbb (low) 810 FETCH(r1, 2) @ r1<- BBBB (high) 811 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- glue->methodClassDex 812 mov r9, rINST, lsr #8 @ r9<- AA 813 ldr r2, [r2, #offDvmDex_pResStrings] @ r2<- dvmDex->pResStrings 814 orr r1, r0, r1, lsl #16 @ r1<- BBBBbbbb 815 ldr r0, [r2, r1, lsl #2] @ r0<- pResStrings[BBBB] 816 cmp r0, #0 817 beq .LOP_CONST_STRING_JUMBO_resolve 818 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 819 GET_INST_OPCODE(ip) @ extract opcode from rINST 820 SET_VREG(r0, r9) @ vAA<- r0 821 GOTO_OPCODE(ip) @ jump to next instruction 822 823/* ------------------------------ */ 824 .balign 64 825.L_OP_CONST_CLASS: /* 0x1c */ 826/* File: armv5te/OP_CONST_CLASS.S */ 827 /* const/class vAA, Class@BBBB */ 828 FETCH(r1, 1) @ r1<- BBBB 829 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- glue->methodClassDex 830 mov r9, rINST, lsr #8 @ r9<- AA 831 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- dvmDex->pResClasses 832 ldr r0, [r2, r1, lsl #2] @ r0<- pResClasses[BBBB] 833 cmp r0, #0 @ not yet resolved? 834 beq .LOP_CONST_CLASS_resolve 835 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 836 GET_INST_OPCODE(ip) @ extract opcode from rINST 837 SET_VREG(r0, r9) @ vAA<- r0 838 GOTO_OPCODE(ip) @ jump to next instruction 839 840/* ------------------------------ */ 841 .balign 64 842.L_OP_MONITOR_ENTER: /* 0x1d */ 843/* File: armv5te/OP_MONITOR_ENTER.S */ 844 /* 845 * Synchronize on an object. 846 */ 847 /* monitor-enter vAA */ 848 mov r2, rINST, lsr #8 @ r2<- AA 849 GET_VREG(r1, r2) @ r1<- vAA (object) 850 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 851 cmp r1, #0 @ null object? 852 EXPORT_PC() @ need for precise GC, MONITOR_TRACKING 853 beq common_errNullObject @ null object, throw an exception 854 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 855 bl dvmLockObject @ call(self, obj) 856#ifdef WITH_DEADLOCK_PREDICTION /* implies WITH_MONITOR_TRACKING */ 857 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 858 ldr r1, [r0, #offThread_exception] @ check for exception 859 cmp r1, #0 860 bne common_exceptionThrown @ exception raised, bail out 861#endif 862 GET_INST_OPCODE(ip) @ extract opcode from rINST 863 GOTO_OPCODE(ip) @ jump to next instruction 864 865/* ------------------------------ */ 866 .balign 64 867.L_OP_MONITOR_EXIT: /* 0x1e */ 868/* File: armv5te/OP_MONITOR_EXIT.S */ 869 /* 870 * Unlock an object. 871 * 872 * Exceptions that occur when unlocking a monitor need to appear as 873 * if they happened at the following instruction. See the Dalvik 874 * instruction spec. 875 */ 876 /* monitor-exit vAA */ 877 mov r2, rINST, lsr #8 @ r2<- AA 878 EXPORT_PC() @ before fetch: export the PC 879 GET_VREG(r1, r2) @ r1<- vAA (object) 880 cmp r1, #0 @ null object? 881 beq 1f @ yes 882 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 883 bl dvmUnlockObject @ r0<- success for unlock(self, obj) 884 cmp r0, #0 @ failed? 885 FETCH_ADVANCE_INST(1) @ before throw: advance rPC, load rINST 886 beq common_exceptionThrown @ yes, exception is pending 887 GET_INST_OPCODE(ip) @ extract opcode from rINST 888 GOTO_OPCODE(ip) @ jump to next instruction 8891: 890 FETCH_ADVANCE_INST(1) @ advance before throw 891 b common_errNullObject 892 893/* ------------------------------ */ 894 .balign 64 895.L_OP_CHECK_CAST: /* 0x1f */ 896/* File: armv5te/OP_CHECK_CAST.S */ 897 /* 898 * Check to see if a cast from one class to another is allowed. 899 */ 900 /* check-cast vAA, class@BBBB */ 901 mov r3, rINST, lsr #8 @ r3<- AA 902 FETCH(r2, 1) @ r2<- BBBB 903 GET_VREG(r9, r3) @ r9<- object 904 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- pDvmDex 905 cmp r9, #0 @ is object null? 906 ldr r0, [r0, #offDvmDex_pResClasses] @ r0<- pDvmDex->pResClasses 907 beq .LOP_CHECK_CAST_okay @ null obj, cast always succeeds 908 ldr r1, [r0, r2, lsl #2] @ r1<- resolved class 909 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 910 cmp r1, #0 @ have we resolved this before? 911 beq .LOP_CHECK_CAST_resolve @ not resolved, do it now 912.LOP_CHECK_CAST_resolved: 913 cmp r0, r1 @ same class (trivial success)? 914 bne .LOP_CHECK_CAST_fullcheck @ no, do full check 915.LOP_CHECK_CAST_okay: 916 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 917 GET_INST_OPCODE(ip) @ extract opcode from rINST 918 GOTO_OPCODE(ip) @ jump to next instruction 919 920/* ------------------------------ */ 921 .balign 64 922.L_OP_INSTANCE_OF: /* 0x20 */ 923/* File: armv5te/OP_INSTANCE_OF.S */ 924 /* 925 * Check to see if an object reference is an instance of a class. 926 * 927 * Most common situation is a non-null object, being compared against 928 * an already-resolved class. 929 */ 930 /* instance-of vA, vB, class@CCCC */ 931 mov r3, rINST, lsr #12 @ r3<- B 932 mov r9, rINST, lsr #8 @ r9<- A+ 933 GET_VREG(r0, r3) @ r0<- vB (object) 934 and r9, r9, #15 @ r9<- A 935 cmp r0, #0 @ is object null? 936 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- pDvmDex 937 beq .LOP_INSTANCE_OF_store @ null obj, not an instance, store r0 938 FETCH(r3, 1) @ r3<- CCCC 939 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- pDvmDex->pResClasses 940 ldr r1, [r2, r3, lsl #2] @ r1<- resolved class 941 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 942 cmp r1, #0 @ have we resolved this before? 943 beq .LOP_INSTANCE_OF_resolve @ not resolved, do it now 944.LOP_INSTANCE_OF_resolved: @ r0=obj->clazz, r1=resolved class 945 cmp r0, r1 @ same class (trivial success)? 946 beq .LOP_INSTANCE_OF_trivial @ yes, trivial finish 947 b .LOP_INSTANCE_OF_fullcheck @ no, do full check 948 949/* ------------------------------ */ 950 .balign 64 951.L_OP_ARRAY_LENGTH: /* 0x21 */ 952/* File: armv5te/OP_ARRAY_LENGTH.S */ 953 /* 954 * Return the length of an array. 955 */ 956 mov r1, rINST, lsr #12 @ r1<- B 957 mov r2, rINST, lsr #8 @ r2<- A+ 958 GET_VREG(r0, r1) @ r0<- vB (object ref) 959 and r2, r2, #15 @ r2<- A 960 cmp r0, #0 @ is object null? 961 beq common_errNullObject @ yup, fail 962 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 963 ldr r3, [r0, #offArrayObject_length] @ r3<- array length 964 GET_INST_OPCODE(ip) @ extract opcode from rINST 965 SET_VREG(r3, r2) @ vB<- length 966 GOTO_OPCODE(ip) @ jump to next instruction 967 968/* ------------------------------ */ 969 .balign 64 970.L_OP_NEW_INSTANCE: /* 0x22 */ 971/* File: armv5te/OP_NEW_INSTANCE.S */ 972 /* 973 * Create a new instance of a class. 974 */ 975 /* new-instance vAA, class@BBBB */ 976 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 977 FETCH(r1, 1) @ r1<- BBBB 978 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 979 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 980 EXPORT_PC() @ req'd for init, resolve, alloc 981 cmp r0, #0 @ already resolved? 982 beq .LOP_NEW_INSTANCE_resolve @ no, resolve it now 983.LOP_NEW_INSTANCE_resolved: @ r0=class 984 ldrb r1, [r0, #offClassObject_status] @ r1<- ClassStatus enum 985 cmp r1, #CLASS_INITIALIZED @ has class been initialized? 986 bne .LOP_NEW_INSTANCE_needinit @ no, init class now 987.LOP_NEW_INSTANCE_initialized: @ r0=class 988 mov r1, #ALLOC_DONT_TRACK @ flags for alloc call 989 bl dvmAllocObject @ r0<- new object 990 b .LOP_NEW_INSTANCE_finish @ continue 991 992/* ------------------------------ */ 993 .balign 64 994.L_OP_NEW_ARRAY: /* 0x23 */ 995/* File: armv5te/OP_NEW_ARRAY.S */ 996 /* 997 * Allocate an array of objects, specified with the array class 998 * and a count. 999 * 1000 * The verifier guarantees that this is an array class, so we don't 1001 * check for it here. 1002 */ 1003 /* new-array vA, vB, class@CCCC */ 1004 mov r0, rINST, lsr #12 @ r0<- B 1005 FETCH(r2, 1) @ r2<- CCCC 1006 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 1007 GET_VREG(r1, r0) @ r1<- vB (array length) 1008 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1009 cmp r1, #0 @ check length 1010 ldr r0, [r3, r2, lsl #2] @ r0<- resolved class 1011 bmi common_errNegativeArraySize @ negative length, bail 1012 cmp r0, #0 @ already resolved? 1013 EXPORT_PC() @ req'd for resolve, alloc 1014 bne .LOP_NEW_ARRAY_finish @ resolved, continue 1015 b .LOP_NEW_ARRAY_resolve @ do resolve now 1016 1017/* ------------------------------ */ 1018 .balign 64 1019.L_OP_FILLED_NEW_ARRAY: /* 0x24 */ 1020/* File: armv5te/OP_FILLED_NEW_ARRAY.S */ 1021 /* 1022 * Create a new array with elements filled from registers. 1023 * 1024 * for: filled-new-array, filled-new-array/range 1025 */ 1026 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1027 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1028 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 1029 FETCH(r1, 1) @ r1<- BBBB 1030 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1031 EXPORT_PC() @ need for resolve and alloc 1032 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 1033 mov r10, rINST, lsr #8 @ r10<- AA or BA 1034 cmp r0, #0 @ already resolved? 1035 bne .LOP_FILLED_NEW_ARRAY_continue @ yes, continue on 10368: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 1037 mov r2, #0 @ r2<- false 1038 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 1039 bl dvmResolveClass @ r0<- call(clazz, ref) 1040 cmp r0, #0 @ got null? 1041 beq common_exceptionThrown @ yes, handle exception 1042 b .LOP_FILLED_NEW_ARRAY_continue 1043 1044/* ------------------------------ */ 1045 .balign 64 1046.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */ 1047/* File: armv5te/OP_FILLED_NEW_ARRAY_RANGE.S */ 1048/* File: armv5te/OP_FILLED_NEW_ARRAY.S */ 1049 /* 1050 * Create a new array with elements filled from registers. 1051 * 1052 * for: filled-new-array, filled-new-array/range 1053 */ 1054 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1055 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1056 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 1057 FETCH(r1, 1) @ r1<- BBBB 1058 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1059 EXPORT_PC() @ need for resolve and alloc 1060 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 1061 mov r10, rINST, lsr #8 @ r10<- AA or BA 1062 cmp r0, #0 @ already resolved? 1063 bne .LOP_FILLED_NEW_ARRAY_RANGE_continue @ yes, continue on 10648: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 1065 mov r2, #0 @ r2<- false 1066 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 1067 bl dvmResolveClass @ r0<- call(clazz, ref) 1068 cmp r0, #0 @ got null? 1069 beq common_exceptionThrown @ yes, handle exception 1070 b .LOP_FILLED_NEW_ARRAY_RANGE_continue 1071 1072 1073/* ------------------------------ */ 1074 .balign 64 1075.L_OP_FILL_ARRAY_DATA: /* 0x26 */ 1076/* File: armv5te/OP_FILL_ARRAY_DATA.S */ 1077 /* fill-array-data vAA, +BBBBBBBB */ 1078 FETCH(r0, 1) @ r0<- bbbb (lo) 1079 FETCH(r1, 2) @ r1<- BBBB (hi) 1080 mov r3, rINST, lsr #8 @ r3<- AA 1081 orr r1, r0, r1, lsl #16 @ r1<- BBBBbbbb 1082 GET_VREG(r0, r3) @ r0<- vAA (array object) 1083 add r1, rPC, r1, lsl #1 @ r1<- PC + BBBBbbbb*2 (array data off.) 1084 EXPORT_PC(); 1085 bl dvmInterpHandleFillArrayData@ fill the array with predefined data 1086 cmp r0, #0 @ 0 means an exception is thrown 1087 beq common_exceptionThrown @ has exception 1088 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 1089 GET_INST_OPCODE(ip) @ extract opcode from rINST 1090 GOTO_OPCODE(ip) @ jump to next instruction 1091 1092/* ------------------------------ */ 1093 .balign 64 1094.L_OP_THROW: /* 0x27 */ 1095/* File: armv5te/OP_THROW.S */ 1096 /* 1097 * Throw an exception object in the current thread. 1098 */ 1099 /* throw vAA */ 1100 mov r2, rINST, lsr #8 @ r2<- AA 1101 GET_VREG(r1, r2) @ r1<- vAA (exception object) 1102 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 1103 EXPORT_PC() @ exception handler can throw 1104 cmp r1, #0 @ null object? 1105 beq common_errNullObject @ yes, throw an NPE instead 1106 @ bypass dvmSetException, just store it 1107 str r1, [r0, #offThread_exception] @ thread->exception<- obj 1108 b common_exceptionThrown 1109 1110/* ------------------------------ */ 1111 .balign 64 1112.L_OP_GOTO: /* 0x28 */ 1113/* File: armv5te/OP_GOTO.S */ 1114 /* 1115 * Unconditional branch, 8-bit offset. 1116 * 1117 * The branch distance is a signed code-unit offset, which we need to 1118 * double to get a byte offset. 1119 */ 1120 /* goto +AA */ 1121 mov r0, rINST, lsl #16 @ r0<- AAxx0000 1122 movs r9, r0, asr #24 @ r9<- ssssssAA (sign-extended) 1123 mov r9, r9, lsl #1 @ r9<- byte offset 1124 bmi common_backwardBranch @ backward branch, do periodic checks 1125#if defined(WITH_JIT) 1126 GET_JIT_PROF_TABLE(r0) 1127 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1128 cmp r0,#0 1129 bne common_updateProfile 1130 GET_INST_OPCODE(ip) @ extract opcode from rINST 1131 GOTO_OPCODE(ip) @ jump to next instruction 1132#else 1133 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1134 GET_INST_OPCODE(ip) @ extract opcode from rINST 1135 GOTO_OPCODE(ip) @ jump to next instruction 1136#endif 1137 1138/* ------------------------------ */ 1139 .balign 64 1140.L_OP_GOTO_16: /* 0x29 */ 1141/* File: armv5te/OP_GOTO_16.S */ 1142 /* 1143 * Unconditional branch, 16-bit offset. 1144 * 1145 * The branch distance is a signed code-unit offset, which we need to 1146 * double to get a byte offset. 1147 */ 1148 /* goto/16 +AAAA */ 1149 FETCH_S(r0, 1) @ r0<- ssssAAAA (sign-extended) 1150 movs r9, r0, asl #1 @ r9<- byte offset, check sign 1151 bmi common_backwardBranch @ backward branch, do periodic checks 1152#if defined(WITH_JIT) 1153 GET_JIT_PROF_TABLE(r0) 1154 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1155 cmp r0,#0 1156 bne common_updateProfile 1157 GET_INST_OPCODE(ip) @ extract opcode from rINST 1158 GOTO_OPCODE(ip) @ jump to next instruction 1159#else 1160 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1161 GET_INST_OPCODE(ip) @ extract opcode from rINST 1162 GOTO_OPCODE(ip) @ jump to next instruction 1163#endif 1164 1165/* ------------------------------ */ 1166 .balign 64 1167.L_OP_GOTO_32: /* 0x2a */ 1168/* File: armv5te/OP_GOTO_32.S */ 1169 /* 1170 * Unconditional branch, 32-bit offset. 1171 * 1172 * The branch distance is a signed code-unit offset, which we need to 1173 * double to get a byte offset. 1174 * 1175 * Unlike most opcodes, this one is allowed to branch to itself, so 1176 * our "backward branch" test must be "<=0" instead of "<0". The ORRS 1177 * instruction doesn't affect the V flag, so we need to clear it 1178 * explicitly. 1179 */ 1180 /* goto/32 +AAAAAAAA */ 1181 FETCH(r0, 1) @ r0<- aaaa (lo) 1182 FETCH(r1, 2) @ r1<- AAAA (hi) 1183 cmp ip, ip @ (clear V flag during stall) 1184 orrs r0, r0, r1, lsl #16 @ r0<- AAAAaaaa, check sign 1185 mov r9, r0, asl #1 @ r9<- byte offset 1186 ble common_backwardBranch @ backward branch, do periodic checks 1187#if defined(WITH_JIT) 1188 GET_JIT_PROF_TABLE(r0) 1189 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1190 cmp r0,#0 1191 bne common_updateProfile 1192 GET_INST_OPCODE(ip) @ extract opcode from rINST 1193 GOTO_OPCODE(ip) @ jump to next instruction 1194#else 1195 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1196 GET_INST_OPCODE(ip) @ extract opcode from rINST 1197 GOTO_OPCODE(ip) @ jump to next instruction 1198#endif 1199 1200/* ------------------------------ */ 1201 .balign 64 1202.L_OP_PACKED_SWITCH: /* 0x2b */ 1203/* File: armv5te/OP_PACKED_SWITCH.S */ 1204 /* 1205 * Handle a packed-switch or sparse-switch instruction. In both cases 1206 * we decode it and hand it off to a helper function. 1207 * 1208 * We don't really expect backward branches in a switch statement, but 1209 * they're perfectly legal, so we check for them here. 1210 * 1211 * for: packed-switch, sparse-switch 1212 */ 1213 /* op vAA, +BBBB */ 1214 FETCH(r0, 1) @ r0<- bbbb (lo) 1215 FETCH(r1, 2) @ r1<- BBBB (hi) 1216 mov r3, rINST, lsr #8 @ r3<- AA 1217 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 1218 GET_VREG(r1, r3) @ r1<- vAA 1219 add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 1220 bl dvmInterpHandlePackedSwitch @ r0<- code-unit branch offset 1221 movs r9, r0, asl #1 @ r9<- branch byte offset, check sign 1222 bmi common_backwardBranch @ backward branch, do periodic checks 1223 beq common_backwardBranch @ (want to use BLE but V is unknown) 1224#if defined(WITH_JIT) 1225 GET_JIT_PROF_TABLE(r0) 1226 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1227 cmp r0,#0 1228 bne common_updateProfile 1229 GET_INST_OPCODE(ip) @ extract opcode from rINST 1230 GOTO_OPCODE(ip) @ jump to next instruction 1231#else 1232 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1233 GET_INST_OPCODE(ip) @ extract opcode from rINST 1234 GOTO_OPCODE(ip) @ jump to next instruction 1235#endif 1236 1237/* ------------------------------ */ 1238 .balign 64 1239.L_OP_SPARSE_SWITCH: /* 0x2c */ 1240/* File: armv5te/OP_SPARSE_SWITCH.S */ 1241/* File: armv5te/OP_PACKED_SWITCH.S */ 1242 /* 1243 * Handle a packed-switch or sparse-switch instruction. In both cases 1244 * we decode it and hand it off to a helper function. 1245 * 1246 * We don't really expect backward branches in a switch statement, but 1247 * they're perfectly legal, so we check for them here. 1248 * 1249 * for: packed-switch, sparse-switch 1250 */ 1251 /* op vAA, +BBBB */ 1252 FETCH(r0, 1) @ r0<- bbbb (lo) 1253 FETCH(r1, 2) @ r1<- BBBB (hi) 1254 mov r3, rINST, lsr #8 @ r3<- AA 1255 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 1256 GET_VREG(r1, r3) @ r1<- vAA 1257 add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 1258 bl dvmInterpHandleSparseSwitch @ r0<- code-unit branch offset 1259 movs r9, r0, asl #1 @ r9<- branch byte offset, check sign 1260 bmi common_backwardBranch @ backward branch, do periodic checks 1261 beq common_backwardBranch @ (want to use BLE but V is unknown) 1262#if defined(WITH_JIT) 1263 GET_JIT_PROF_TABLE(r0) 1264 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1265 cmp r0,#0 1266 bne common_updateProfile 1267 GET_INST_OPCODE(ip) @ extract opcode from rINST 1268 GOTO_OPCODE(ip) @ jump to next instruction 1269#else 1270 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1271 GET_INST_OPCODE(ip) @ extract opcode from rINST 1272 GOTO_OPCODE(ip) @ jump to next instruction 1273#endif 1274 1275 1276/* ------------------------------ */ 1277 .balign 64 1278.L_OP_CMPL_FLOAT: /* 0x2d */ 1279/* File: arm-vfp/OP_CMPL_FLOAT.S */ 1280 /* 1281 * Compare two floating-point values. Puts 0, 1, or -1 into the 1282 * destination register based on the results of the comparison. 1283 * 1284 * int compare(x, y) { 1285 * if (x == y) { 1286 * return 0; 1287 * } else if (x > y) { 1288 * return 1; 1289 * } else if (x < y) { 1290 * return -1; 1291 * } else { 1292 * return -1; 1293 * } 1294 * } 1295 */ 1296 /* op vAA, vBB, vCC */ 1297 FETCH(r0, 1) @ r0<- CCBB 1298 mov r9, rINST, lsr #8 @ r9<- AA 1299 and r2, r0, #255 @ r2<- BB 1300 mov r3, r0, lsr #8 @ r3<- CC 1301 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1302 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1303 flds s0, [r2] @ s0<- vBB 1304 flds s1, [r3] @ s1<- vCC 1305 fcmpes s0, s1 @ compare (vBB, vCC) 1306 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1307 mvn r0, #0 @ r0<- -1 (default) 1308 GET_INST_OPCODE(ip) @ extract opcode from rINST 1309 fmstat @ export status flags 1310 movgt r0, #1 @ (greater than) r1<- 1 1311 moveq r0, #0 @ (equal) r1<- 0 1312 b .LOP_CMPL_FLOAT_finish @ argh 1313 1314 1315/* ------------------------------ */ 1316 .balign 64 1317.L_OP_CMPG_FLOAT: /* 0x2e */ 1318/* File: arm-vfp/OP_CMPG_FLOAT.S */ 1319 /* 1320 * Compare two floating-point values. Puts 0, 1, or -1 into the 1321 * destination register based on the results of the comparison. 1322 * 1323 * int compare(x, y) { 1324 * if (x == y) { 1325 * return 0; 1326 * } else if (x < y) { 1327 * return -1; 1328 * } else if (x > y) { 1329 * return 1; 1330 * } else { 1331 * return 1; 1332 * } 1333 * } 1334 */ 1335 /* op vAA, vBB, vCC */ 1336 FETCH(r0, 1) @ r0<- CCBB 1337 mov r9, rINST, lsr #8 @ r9<- AA 1338 and r2, r0, #255 @ r2<- BB 1339 mov r3, r0, lsr #8 @ r3<- CC 1340 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1341 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1342 flds s0, [r2] @ s0<- vBB 1343 flds s1, [r3] @ s1<- vCC 1344 fcmpes s0, s1 @ compare (vBB, vCC) 1345 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1346 mov r0, #1 @ r0<- 1 (default) 1347 GET_INST_OPCODE(ip) @ extract opcode from rINST 1348 fmstat @ export status flags 1349 mvnmi r0, #0 @ (less than) r1<- -1 1350 moveq r0, #0 @ (equal) r1<- 0 1351 b .LOP_CMPG_FLOAT_finish @ argh 1352 1353 1354/* ------------------------------ */ 1355 .balign 64 1356.L_OP_CMPL_DOUBLE: /* 0x2f */ 1357/* File: arm-vfp/OP_CMPL_DOUBLE.S */ 1358 /* 1359 * Compare two floating-point values. Puts 0, 1, or -1 into the 1360 * destination register based on the results of the comparison. 1361 * 1362 * int compare(x, y) { 1363 * if (x == y) { 1364 * return 0; 1365 * } else if (x > y) { 1366 * return 1; 1367 * } else if (x < y) { 1368 * return -1; 1369 * } else { 1370 * return -1; 1371 * } 1372 * } 1373 */ 1374 /* op vAA, vBB, vCC */ 1375 FETCH(r0, 1) @ r0<- CCBB 1376 mov r9, rINST, lsr #8 @ r9<- AA 1377 and r2, r0, #255 @ r2<- BB 1378 mov r3, r0, lsr #8 @ r3<- CC 1379 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1380 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1381 fldd d0, [r2] @ d0<- vBB 1382 fldd d1, [r3] @ d1<- vCC 1383 fcmped d0, d1 @ compare (vBB, vCC) 1384 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1385 mvn r0, #0 @ r0<- -1 (default) 1386 GET_INST_OPCODE(ip) @ extract opcode from rINST 1387 fmstat @ export status flags 1388 movgt r0, #1 @ (greater than) r1<- 1 1389 moveq r0, #0 @ (equal) r1<- 0 1390 b .LOP_CMPL_DOUBLE_finish @ argh 1391 1392 1393/* ------------------------------ */ 1394 .balign 64 1395.L_OP_CMPG_DOUBLE: /* 0x30 */ 1396/* File: arm-vfp/OP_CMPG_DOUBLE.S */ 1397 /* 1398 * Compare two floating-point values. Puts 0, 1, or -1 into the 1399 * destination register based on the results of the comparison. 1400 * 1401 * int compare(x, y) { 1402 * if (x == y) { 1403 * return 0; 1404 * } else if (x < y) { 1405 * return -1; 1406 * } else if (x > y) { 1407 * return 1; 1408 * } else { 1409 * return 1; 1410 * } 1411 * } 1412 */ 1413 /* op vAA, vBB, vCC */ 1414 FETCH(r0, 1) @ r0<- CCBB 1415 mov r9, rINST, lsr #8 @ r9<- AA 1416 and r2, r0, #255 @ r2<- BB 1417 mov r3, r0, lsr #8 @ r3<- CC 1418 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1419 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1420 fldd d0, [r2] @ d0<- vBB 1421 fldd d1, [r3] @ d1<- vCC 1422 fcmped d0, d1 @ compare (vBB, vCC) 1423 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1424 mov r0, #1 @ r0<- 1 (default) 1425 GET_INST_OPCODE(ip) @ extract opcode from rINST 1426 fmstat @ export status flags 1427 mvnmi r0, #0 @ (less than) r1<- -1 1428 moveq r0, #0 @ (equal) r1<- 0 1429 b .LOP_CMPG_DOUBLE_finish @ argh 1430 1431 1432/* ------------------------------ */ 1433 .balign 64 1434.L_OP_CMP_LONG: /* 0x31 */ 1435/* File: armv5te/OP_CMP_LONG.S */ 1436 /* 1437 * Compare two 64-bit values. Puts 0, 1, or -1 into the destination 1438 * register based on the results of the comparison. 1439 * 1440 * We load the full values with LDM, but in practice many values could 1441 * be resolved by only looking at the high word. This could be made 1442 * faster or slower by splitting the LDM into a pair of LDRs. 1443 * 1444 * If we just wanted to set condition flags, we could do this: 1445 * subs ip, r0, r2 1446 * sbcs ip, r1, r3 1447 * subeqs ip, r0, r2 1448 * Leaving { <0, 0, >0 } in ip. However, we have to set it to a specific 1449 * integer value, which we can do with 2 conditional mov/mvn instructions 1450 * (set 1, set -1; if they're equal we already have 0 in ip), giving 1451 * us a constant 5-cycle path plus a branch at the end to the 1452 * instruction epilogue code. The multi-compare approach below needs 1453 * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch 1454 * in the worst case (the 64-bit values are equal). 1455 */ 1456 /* cmp-long vAA, vBB, vCC */ 1457 FETCH(r0, 1) @ r0<- CCBB 1458 mov r9, rINST, lsr #8 @ r9<- AA 1459 and r2, r0, #255 @ r2<- BB 1460 mov r3, r0, lsr #8 @ r3<- CC 1461 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 1462 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 1463 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 1464 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 1465 cmp r1, r3 @ compare (vBB+1, vCC+1) 1466 blt .LOP_CMP_LONG_less @ signed compare on high part 1467 bgt .LOP_CMP_LONG_greater 1468 subs r1, r0, r2 @ r1<- r0 - r2 1469 bhi .LOP_CMP_LONG_greater @ unsigned compare on low part 1470 bne .LOP_CMP_LONG_less 1471 b .LOP_CMP_LONG_finish @ equal; r1 already holds 0 1472 1473/* ------------------------------ */ 1474 .balign 64 1475.L_OP_IF_EQ: /* 0x32 */ 1476/* File: armv5te/OP_IF_EQ.S */ 1477/* File: armv5te/bincmp.S */ 1478 /* 1479 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1480 * fragment that specifies the *reverse* comparison to perform, e.g. 1481 * for "if-le" you would use "gt". 1482 * 1483 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1484 */ 1485 /* if-cmp vA, vB, +CCCC */ 1486 mov r0, rINST, lsr #8 @ r0<- A+ 1487 mov r1, rINST, lsr #12 @ r1<- B 1488 and r0, r0, #15 1489 GET_VREG(r3, r1) @ r3<- vB 1490 GET_VREG(r2, r0) @ r2<- vA 1491 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1492 cmp r2, r3 @ compare (vA, vB) 1493 bne 1f @ branch to 1 if comparison failed 1494 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1495 movs r9, r9, asl #1 @ convert to bytes, check sign 1496 bmi common_backwardBranch @ yes, do periodic checks 14971: 1498#if defined(WITH_JIT) 1499 GET_JIT_PROF_TABLE(r0) 1500 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1501 b common_testUpdateProfile 1502#else 1503 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1504 GET_INST_OPCODE(ip) @ extract opcode from rINST 1505 GOTO_OPCODE(ip) @ jump to next instruction 1506#endif 1507 1508 1509/* ------------------------------ */ 1510 .balign 64 1511.L_OP_IF_NE: /* 0x33 */ 1512/* File: armv5te/OP_IF_NE.S */ 1513/* File: armv5te/bincmp.S */ 1514 /* 1515 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1516 * fragment that specifies the *reverse* comparison to perform, e.g. 1517 * for "if-le" you would use "gt". 1518 * 1519 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1520 */ 1521 /* if-cmp vA, vB, +CCCC */ 1522 mov r0, rINST, lsr #8 @ r0<- A+ 1523 mov r1, rINST, lsr #12 @ r1<- B 1524 and r0, r0, #15 1525 GET_VREG(r3, r1) @ r3<- vB 1526 GET_VREG(r2, r0) @ r2<- vA 1527 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1528 cmp r2, r3 @ compare (vA, vB) 1529 beq 1f @ branch to 1 if comparison failed 1530 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1531 movs r9, r9, asl #1 @ convert to bytes, check sign 1532 bmi common_backwardBranch @ yes, do periodic checks 15331: 1534#if defined(WITH_JIT) 1535 GET_JIT_PROF_TABLE(r0) 1536 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1537 b common_testUpdateProfile 1538#else 1539 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1540 GET_INST_OPCODE(ip) @ extract opcode from rINST 1541 GOTO_OPCODE(ip) @ jump to next instruction 1542#endif 1543 1544 1545/* ------------------------------ */ 1546 .balign 64 1547.L_OP_IF_LT: /* 0x34 */ 1548/* File: armv5te/OP_IF_LT.S */ 1549/* File: armv5te/bincmp.S */ 1550 /* 1551 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1552 * fragment that specifies the *reverse* comparison to perform, e.g. 1553 * for "if-le" you would use "gt". 1554 * 1555 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1556 */ 1557 /* if-cmp vA, vB, +CCCC */ 1558 mov r0, rINST, lsr #8 @ r0<- A+ 1559 mov r1, rINST, lsr #12 @ r1<- B 1560 and r0, r0, #15 1561 GET_VREG(r3, r1) @ r3<- vB 1562 GET_VREG(r2, r0) @ r2<- vA 1563 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1564 cmp r2, r3 @ compare (vA, vB) 1565 bge 1f @ branch to 1 if comparison failed 1566 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1567 movs r9, r9, asl #1 @ convert to bytes, check sign 1568 bmi common_backwardBranch @ yes, do periodic checks 15691: 1570#if defined(WITH_JIT) 1571 GET_JIT_PROF_TABLE(r0) 1572 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1573 b common_testUpdateProfile 1574#else 1575 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1576 GET_INST_OPCODE(ip) @ extract opcode from rINST 1577 GOTO_OPCODE(ip) @ jump to next instruction 1578#endif 1579 1580 1581/* ------------------------------ */ 1582 .balign 64 1583.L_OP_IF_GE: /* 0x35 */ 1584/* File: armv5te/OP_IF_GE.S */ 1585/* File: armv5te/bincmp.S */ 1586 /* 1587 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1588 * fragment that specifies the *reverse* comparison to perform, e.g. 1589 * for "if-le" you would use "gt". 1590 * 1591 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1592 */ 1593 /* if-cmp vA, vB, +CCCC */ 1594 mov r0, rINST, lsr #8 @ r0<- A+ 1595 mov r1, rINST, lsr #12 @ r1<- B 1596 and r0, r0, #15 1597 GET_VREG(r3, r1) @ r3<- vB 1598 GET_VREG(r2, r0) @ r2<- vA 1599 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: armv5te/OP_IF_GT.S */ 1621/* File: armv5te/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 r0, rINST, lsr #8 @ r0<- A+ 1631 mov r1, rINST, lsr #12 @ r1<- B 1632 and r0, r0, #15 1633 GET_VREG(r3, r1) @ r3<- vB 1634 GET_VREG(r2, r0) @ r2<- vA 1635 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1636 cmp r2, r3 @ compare (vA, vB) 1637 ble 1f @ branch to 1 if comparison failed 1638 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1639 movs r9, r9, asl #1 @ convert to bytes, check sign 1640 bmi common_backwardBranch @ yes, do periodic checks 16411: 1642#if defined(WITH_JIT) 1643 GET_JIT_PROF_TABLE(r0) 1644 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1645 b common_testUpdateProfile 1646#else 1647 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1648 GET_INST_OPCODE(ip) @ extract opcode from rINST 1649 GOTO_OPCODE(ip) @ jump to next instruction 1650#endif 1651 1652 1653/* ------------------------------ */ 1654 .balign 64 1655.L_OP_IF_LE: /* 0x37 */ 1656/* File: armv5te/OP_IF_LE.S */ 1657/* File: armv5te/bincmp.S */ 1658 /* 1659 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1660 * fragment that specifies the *reverse* comparison to perform, e.g. 1661 * for "if-le" you would use "gt". 1662 * 1663 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1664 */ 1665 /* if-cmp vA, vB, +CCCC */ 1666 mov r0, rINST, lsr #8 @ r0<- A+ 1667 mov r1, rINST, lsr #12 @ r1<- B 1668 and r0, r0, #15 1669 GET_VREG(r3, r1) @ r3<- vB 1670 GET_VREG(r2, r0) @ r2<- vA 1671 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1672 cmp r2, r3 @ compare (vA, vB) 1673 bgt 1f @ branch to 1 if comparison failed 1674 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1675 movs r9, r9, asl #1 @ convert to bytes, check sign 1676 bmi common_backwardBranch @ yes, do periodic checks 16771: 1678#if defined(WITH_JIT) 1679 GET_JIT_PROF_TABLE(r0) 1680 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1681 b common_testUpdateProfile 1682#else 1683 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1684 GET_INST_OPCODE(ip) @ extract opcode from rINST 1685 GOTO_OPCODE(ip) @ jump to next instruction 1686#endif 1687 1688 1689/* ------------------------------ */ 1690 .balign 64 1691.L_OP_IF_EQZ: /* 0x38 */ 1692/* File: armv5te/OP_IF_EQZ.S */ 1693/* File: armv5te/zcmp.S */ 1694 /* 1695 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1696 * fragment that specifies the *reverse* comparison to perform, e.g. 1697 * for "if-le" you would use "gt". 1698 * 1699 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1700 */ 1701 /* if-cmp vAA, +BBBB */ 1702 mov r0, rINST, lsr #8 @ r0<- AA 1703 GET_VREG(r2, r0) @ r2<- vAA 1704 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1705 cmp r2, #0 @ compare (vA, 0) 1706 bne 1f @ branch to 1 if comparison failed 1707 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1708 movs r9, r9, asl #1 @ convert to bytes, check sign 1709 bmi common_backwardBranch @ backward branch, do periodic checks 17101: 1711#if defined(WITH_JIT) 1712 GET_JIT_PROF_TABLE(r0) 1713 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1714 cmp r0,#0 1715 bne common_updateProfile 1716 GET_INST_OPCODE(ip) @ extract opcode from rINST 1717 GOTO_OPCODE(ip) @ jump to next instruction 1718#else 1719 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1720 GET_INST_OPCODE(ip) @ extract opcode from rINST 1721 GOTO_OPCODE(ip) @ jump to next instruction 1722#endif 1723 1724 1725/* ------------------------------ */ 1726 .balign 64 1727.L_OP_IF_NEZ: /* 0x39 */ 1728/* File: armv5te/OP_IF_NEZ.S */ 1729/* File: armv5te/zcmp.S */ 1730 /* 1731 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1732 * fragment that specifies the *reverse* comparison to perform, e.g. 1733 * for "if-le" you would use "gt". 1734 * 1735 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1736 */ 1737 /* if-cmp vAA, +BBBB */ 1738 mov r0, rINST, lsr #8 @ r0<- AA 1739 GET_VREG(r2, r0) @ r2<- vAA 1740 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1741 cmp r2, #0 @ compare (vA, 0) 1742 beq 1f @ branch to 1 if comparison failed 1743 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1744 movs r9, r9, asl #1 @ convert to bytes, check sign 1745 bmi common_backwardBranch @ backward branch, do periodic checks 17461: 1747#if defined(WITH_JIT) 1748 GET_JIT_PROF_TABLE(r0) 1749 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1750 cmp r0,#0 1751 bne common_updateProfile 1752 GET_INST_OPCODE(ip) @ extract opcode from rINST 1753 GOTO_OPCODE(ip) @ jump to next instruction 1754#else 1755 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1756 GET_INST_OPCODE(ip) @ extract opcode from rINST 1757 GOTO_OPCODE(ip) @ jump to next instruction 1758#endif 1759 1760 1761/* ------------------------------ */ 1762 .balign 64 1763.L_OP_IF_LTZ: /* 0x3a */ 1764/* File: armv5te/OP_IF_LTZ.S */ 1765/* File: armv5te/zcmp.S */ 1766 /* 1767 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1768 * fragment that specifies the *reverse* comparison to perform, e.g. 1769 * for "if-le" you would use "gt". 1770 * 1771 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1772 */ 1773 /* if-cmp vAA, +BBBB */ 1774 mov r0, rINST, lsr #8 @ r0<- AA 1775 GET_VREG(r2, r0) @ r2<- vAA 1776 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1777 cmp r2, #0 @ compare (vA, 0) 1778 bge 1f @ branch to 1 if comparison failed 1779 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1780 movs r9, r9, asl #1 @ convert to bytes, check sign 1781 bmi common_backwardBranch @ backward branch, do periodic checks 17821: 1783#if defined(WITH_JIT) 1784 GET_JIT_PROF_TABLE(r0) 1785 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1786 cmp r0,#0 1787 bne common_updateProfile 1788 GET_INST_OPCODE(ip) @ extract opcode from rINST 1789 GOTO_OPCODE(ip) @ jump to next instruction 1790#else 1791 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1792 GET_INST_OPCODE(ip) @ extract opcode from rINST 1793 GOTO_OPCODE(ip) @ jump to next instruction 1794#endif 1795 1796 1797/* ------------------------------ */ 1798 .balign 64 1799.L_OP_IF_GEZ: /* 0x3b */ 1800/* File: armv5te/OP_IF_GEZ.S */ 1801/* File: armv5te/zcmp.S */ 1802 /* 1803 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1804 * fragment that specifies the *reverse* comparison to perform, e.g. 1805 * for "if-le" you would use "gt". 1806 * 1807 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1808 */ 1809 /* if-cmp vAA, +BBBB */ 1810 mov r0, rINST, lsr #8 @ r0<- AA 1811 GET_VREG(r2, r0) @ r2<- vAA 1812 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1813 cmp r2, #0 @ compare (vA, 0) 1814 blt 1f @ branch to 1 if comparison failed 1815 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1816 movs r9, r9, asl #1 @ convert to bytes, check sign 1817 bmi common_backwardBranch @ backward branch, do periodic checks 18181: 1819#if defined(WITH_JIT) 1820 GET_JIT_PROF_TABLE(r0) 1821 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1822 cmp r0,#0 1823 bne common_updateProfile 1824 GET_INST_OPCODE(ip) @ extract opcode from rINST 1825 GOTO_OPCODE(ip) @ jump to next instruction 1826#else 1827 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1828 GET_INST_OPCODE(ip) @ extract opcode from rINST 1829 GOTO_OPCODE(ip) @ jump to next instruction 1830#endif 1831 1832 1833/* ------------------------------ */ 1834 .balign 64 1835.L_OP_IF_GTZ: /* 0x3c */ 1836/* File: armv5te/OP_IF_GTZ.S */ 1837/* File: armv5te/zcmp.S */ 1838 /* 1839 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1840 * fragment that specifies the *reverse* comparison to perform, e.g. 1841 * for "if-le" you would use "gt". 1842 * 1843 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1844 */ 1845 /* if-cmp vAA, +BBBB */ 1846 mov r0, rINST, lsr #8 @ r0<- AA 1847 GET_VREG(r2, r0) @ r2<- vAA 1848 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1849 cmp r2, #0 @ compare (vA, 0) 1850 ble 1f @ branch to 1 if comparison failed 1851 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1852 movs r9, r9, asl #1 @ convert to bytes, check sign 1853 bmi common_backwardBranch @ backward branch, do periodic checks 18541: 1855#if defined(WITH_JIT) 1856 GET_JIT_PROF_TABLE(r0) 1857 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1858 cmp r0,#0 1859 bne common_updateProfile 1860 GET_INST_OPCODE(ip) @ extract opcode from rINST 1861 GOTO_OPCODE(ip) @ jump to next instruction 1862#else 1863 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1864 GET_INST_OPCODE(ip) @ extract opcode from rINST 1865 GOTO_OPCODE(ip) @ jump to next instruction 1866#endif 1867 1868 1869/* ------------------------------ */ 1870 .balign 64 1871.L_OP_IF_LEZ: /* 0x3d */ 1872/* File: armv5te/OP_IF_LEZ.S */ 1873/* File: armv5te/zcmp.S */ 1874 /* 1875 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1876 * fragment that specifies the *reverse* comparison to perform, e.g. 1877 * for "if-le" you would use "gt". 1878 * 1879 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1880 */ 1881 /* if-cmp vAA, +BBBB */ 1882 mov r0, rINST, lsr #8 @ r0<- AA 1883 GET_VREG(r2, r0) @ r2<- vAA 1884 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1885 cmp r2, #0 @ compare (vA, 0) 1886 bgt 1f @ branch to 1 if comparison failed 1887 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1888 movs r9, r9, asl #1 @ convert to bytes, check sign 1889 bmi common_backwardBranch @ backward branch, do periodic checks 18901: 1891#if defined(WITH_JIT) 1892 GET_JIT_PROF_TABLE(r0) 1893 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1894 cmp r0,#0 1895 bne common_updateProfile 1896 GET_INST_OPCODE(ip) @ extract opcode from rINST 1897 GOTO_OPCODE(ip) @ jump to next instruction 1898#else 1899 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1900 GET_INST_OPCODE(ip) @ extract opcode from rINST 1901 GOTO_OPCODE(ip) @ jump to next instruction 1902#endif 1903 1904 1905/* ------------------------------ */ 1906 .balign 64 1907.L_OP_UNUSED_3E: /* 0x3e */ 1908/* File: armv5te/OP_UNUSED_3E.S */ 1909/* File: armv5te/unused.S */ 1910 bl common_abort 1911 1912 1913/* ------------------------------ */ 1914 .balign 64 1915.L_OP_UNUSED_3F: /* 0x3f */ 1916/* File: armv5te/OP_UNUSED_3F.S */ 1917/* File: armv5te/unused.S */ 1918 bl common_abort 1919 1920 1921/* ------------------------------ */ 1922 .balign 64 1923.L_OP_UNUSED_40: /* 0x40 */ 1924/* File: armv5te/OP_UNUSED_40.S */ 1925/* File: armv5te/unused.S */ 1926 bl common_abort 1927 1928 1929/* ------------------------------ */ 1930 .balign 64 1931.L_OP_UNUSED_41: /* 0x41 */ 1932/* File: armv5te/OP_UNUSED_41.S */ 1933/* File: armv5te/unused.S */ 1934 bl common_abort 1935 1936 1937/* ------------------------------ */ 1938 .balign 64 1939.L_OP_UNUSED_42: /* 0x42 */ 1940/* File: armv5te/OP_UNUSED_42.S */ 1941/* File: armv5te/unused.S */ 1942 bl common_abort 1943 1944 1945/* ------------------------------ */ 1946 .balign 64 1947.L_OP_UNUSED_43: /* 0x43 */ 1948/* File: armv5te/OP_UNUSED_43.S */ 1949/* File: armv5te/unused.S */ 1950 bl common_abort 1951 1952 1953/* ------------------------------ */ 1954 .balign 64 1955.L_OP_AGET: /* 0x44 */ 1956/* File: armv5te/OP_AGET.S */ 1957 /* 1958 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1959 * 1960 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1961 * instructions. We use a pair of FETCH_Bs instead. 1962 * 1963 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1964 */ 1965 /* op vAA, vBB, vCC */ 1966 FETCH_B(r2, 1, 0) @ r2<- BB 1967 mov r9, rINST, lsr #8 @ r9<- AA 1968 FETCH_B(r3, 1, 1) @ r3<- CC 1969 GET_VREG(r0, r2) @ r0<- vBB (array object) 1970 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1971 cmp r0, #0 @ null array object? 1972 beq common_errNullObject @ yes, bail 1973 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1974 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 1975 cmp r1, r3 @ compare unsigned index, length 1976 bcs common_errArrayIndex @ index >= length, bail 1977 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1978 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 1979 GET_INST_OPCODE(ip) @ extract opcode from rINST 1980 SET_VREG(r2, r9) @ vAA<- r2 1981 GOTO_OPCODE(ip) @ jump to next instruction 1982 1983/* ------------------------------ */ 1984 .balign 64 1985.L_OP_AGET_WIDE: /* 0x45 */ 1986/* File: armv5te/OP_AGET_WIDE.S */ 1987 /* 1988 * Array get, 64 bits. vAA <- vBB[vCC]. 1989 * 1990 * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD. 1991 */ 1992 /* aget-wide vAA, vBB, vCC */ 1993 FETCH(r0, 1) @ r0<- CCBB 1994 mov r9, rINST, lsr #8 @ r9<- AA 1995 and r2, r0, #255 @ r2<- BB 1996 mov r3, r0, lsr #8 @ r3<- CC 1997 GET_VREG(r0, r2) @ r0<- vBB (array object) 1998 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1999 cmp r0, #0 @ null array object? 2000 beq common_errNullObject @ yes, bail 2001 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2002 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 2003 cmp r1, r3 @ compare unsigned index, length 2004 bcc .LOP_AGET_WIDE_finish @ okay, continue below 2005 b common_errArrayIndex @ index >= length, bail 2006 @ May want to swap the order of these two branches depending on how the 2007 @ branch prediction (if any) handles conditional forward branches vs. 2008 @ unconditional forward branches. 2009 2010/* ------------------------------ */ 2011 .balign 64 2012.L_OP_AGET_OBJECT: /* 0x46 */ 2013/* File: armv5te/OP_AGET_OBJECT.S */ 2014/* File: armv5te/OP_AGET.S */ 2015 /* 2016 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2017 * 2018 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2019 * instructions. We use a pair of FETCH_Bs instead. 2020 * 2021 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2022 */ 2023 /* op vAA, vBB, vCC */ 2024 FETCH_B(r2, 1, 0) @ r2<- BB 2025 mov r9, rINST, lsr #8 @ r9<- AA 2026 FETCH_B(r3, 1, 1) @ r3<- CC 2027 GET_VREG(r0, r2) @ r0<- vBB (array object) 2028 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2029 cmp r0, #0 @ null array object? 2030 beq common_errNullObject @ yes, bail 2031 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2032 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 2033 cmp r1, r3 @ compare unsigned index, length 2034 bcs common_errArrayIndex @ index >= length, bail 2035 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2036 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2037 GET_INST_OPCODE(ip) @ extract opcode from rINST 2038 SET_VREG(r2, r9) @ vAA<- r2 2039 GOTO_OPCODE(ip) @ jump to next instruction 2040 2041 2042/* ------------------------------ */ 2043 .balign 64 2044.L_OP_AGET_BOOLEAN: /* 0x47 */ 2045/* File: armv5te/OP_AGET_BOOLEAN.S */ 2046/* File: armv5te/OP_AGET.S */ 2047 /* 2048 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2049 * 2050 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2051 * instructions. We use a pair of FETCH_Bs instead. 2052 * 2053 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2054 */ 2055 /* op vAA, vBB, vCC */ 2056 FETCH_B(r2, 1, 0) @ r2<- BB 2057 mov r9, rINST, lsr #8 @ r9<- AA 2058 FETCH_B(r3, 1, 1) @ r3<- CC 2059 GET_VREG(r0, r2) @ r0<- vBB (array object) 2060 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2061 cmp r0, #0 @ null array object? 2062 beq common_errNullObject @ yes, bail 2063 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2064 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2065 cmp r1, r3 @ compare unsigned index, length 2066 bcs common_errArrayIndex @ index >= length, bail 2067 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2068 ldrb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2069 GET_INST_OPCODE(ip) @ extract opcode from rINST 2070 SET_VREG(r2, r9) @ vAA<- r2 2071 GOTO_OPCODE(ip) @ jump to next instruction 2072 2073 2074/* ------------------------------ */ 2075 .balign 64 2076.L_OP_AGET_BYTE: /* 0x48 */ 2077/* File: armv5te/OP_AGET_BYTE.S */ 2078/* File: armv5te/OP_AGET.S */ 2079 /* 2080 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2081 * 2082 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2083 * instructions. We use a pair of FETCH_Bs instead. 2084 * 2085 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2086 */ 2087 /* op vAA, vBB, vCC */ 2088 FETCH_B(r2, 1, 0) @ r2<- BB 2089 mov r9, rINST, lsr #8 @ r9<- AA 2090 FETCH_B(r3, 1, 1) @ r3<- CC 2091 GET_VREG(r0, r2) @ r0<- vBB (array object) 2092 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2093 cmp r0, #0 @ null array object? 2094 beq common_errNullObject @ yes, bail 2095 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2096 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2097 cmp r1, r3 @ compare unsigned index, length 2098 bcs common_errArrayIndex @ index >= length, bail 2099 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2100 ldrsb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2101 GET_INST_OPCODE(ip) @ extract opcode from rINST 2102 SET_VREG(r2, r9) @ vAA<- r2 2103 GOTO_OPCODE(ip) @ jump to next instruction 2104 2105 2106/* ------------------------------ */ 2107 .balign 64 2108.L_OP_AGET_CHAR: /* 0x49 */ 2109/* File: armv5te/OP_AGET_CHAR.S */ 2110/* File: armv5te/OP_AGET.S */ 2111 /* 2112 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2113 * 2114 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2115 * instructions. We use a pair of FETCH_Bs instead. 2116 * 2117 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2118 */ 2119 /* op vAA, vBB, vCC */ 2120 FETCH_B(r2, 1, 0) @ r2<- BB 2121 mov r9, rINST, lsr #8 @ r9<- AA 2122 FETCH_B(r3, 1, 1) @ r3<- CC 2123 GET_VREG(r0, r2) @ r0<- vBB (array object) 2124 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2125 cmp r0, #0 @ null array object? 2126 beq common_errNullObject @ yes, bail 2127 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2128 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2129 cmp r1, r3 @ compare unsigned index, length 2130 bcs common_errArrayIndex @ index >= length, bail 2131 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2132 ldrh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2133 GET_INST_OPCODE(ip) @ extract opcode from rINST 2134 SET_VREG(r2, r9) @ vAA<- r2 2135 GOTO_OPCODE(ip) @ jump to next instruction 2136 2137 2138/* ------------------------------ */ 2139 .balign 64 2140.L_OP_AGET_SHORT: /* 0x4a */ 2141/* File: armv5te/OP_AGET_SHORT.S */ 2142/* File: armv5te/OP_AGET.S */ 2143 /* 2144 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2145 * 2146 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2147 * instructions. We use a pair of FETCH_Bs instead. 2148 * 2149 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2150 */ 2151 /* op vAA, vBB, vCC */ 2152 FETCH_B(r2, 1, 0) @ r2<- BB 2153 mov r9, rINST, lsr #8 @ r9<- AA 2154 FETCH_B(r3, 1, 1) @ r3<- CC 2155 GET_VREG(r0, r2) @ r0<- vBB (array object) 2156 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2157 cmp r0, #0 @ null array object? 2158 beq common_errNullObject @ yes, bail 2159 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2160 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2161 cmp r1, r3 @ compare unsigned index, length 2162 bcs common_errArrayIndex @ index >= length, bail 2163 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2164 ldrsh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2165 GET_INST_OPCODE(ip) @ extract opcode from rINST 2166 SET_VREG(r2, r9) @ vAA<- r2 2167 GOTO_OPCODE(ip) @ jump to next instruction 2168 2169 2170/* ------------------------------ */ 2171 .balign 64 2172.L_OP_APUT: /* 0x4b */ 2173/* File: armv5te/OP_APUT.S */ 2174 /* 2175 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2176 * 2177 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2178 * instructions. We use a pair of FETCH_Bs instead. 2179 * 2180 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2181 */ 2182 /* op vAA, vBB, vCC */ 2183 FETCH_B(r2, 1, 0) @ r2<- BB 2184 mov r9, rINST, lsr #8 @ r9<- AA 2185 FETCH_B(r3, 1, 1) @ r3<- CC 2186 GET_VREG(r0, r2) @ r0<- vBB (array object) 2187 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2188 cmp r0, #0 @ null array object? 2189 beq common_errNullObject @ yes, bail 2190 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2191 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 2192 cmp r1, r3 @ compare unsigned index, length 2193 bcs common_errArrayIndex @ index >= length, bail 2194 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2195 GET_VREG(r2, r9) @ r2<- vAA 2196 GET_INST_OPCODE(ip) @ extract opcode from rINST 2197 str r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2198 GOTO_OPCODE(ip) @ jump to next instruction 2199 2200/* ------------------------------ */ 2201 .balign 64 2202.L_OP_APUT_WIDE: /* 0x4c */ 2203/* File: armv5te/OP_APUT_WIDE.S */ 2204 /* 2205 * Array put, 64 bits. vBB[vCC] <- vAA. 2206 * 2207 * Arrays of long/double are 64-bit aligned, so it's okay to use STRD. 2208 */ 2209 /* aput-wide vAA, vBB, vCC */ 2210 FETCH(r0, 1) @ r0<- CCBB 2211 mov r9, rINST, lsr #8 @ r9<- AA 2212 and r2, r0, #255 @ r2<- BB 2213 mov r3, r0, lsr #8 @ r3<- CC 2214 GET_VREG(r0, r2) @ r0<- vBB (array object) 2215 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2216 cmp r0, #0 @ null array object? 2217 beq common_errNullObject @ yes, bail 2218 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2219 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 2220 cmp r1, r3 @ compare unsigned index, length 2221 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2222 bcc .LOP_APUT_WIDE_finish @ okay, continue below 2223 b common_errArrayIndex @ index >= length, bail 2224 @ May want to swap the order of these two branches depending on how the 2225 @ branch prediction (if any) handles conditional forward branches vs. 2226 @ unconditional forward branches. 2227 2228/* ------------------------------ */ 2229 .balign 64 2230.L_OP_APUT_OBJECT: /* 0x4d */ 2231/* File: armv5te/OP_APUT_OBJECT.S */ 2232 /* 2233 * Store an object into an array. vBB[vCC] <- vAA. 2234 */ 2235 /* op vAA, vBB, vCC */ 2236 FETCH(r0, 1) @ r0<- CCBB 2237 mov r9, rINST, lsr #8 @ r9<- AA 2238 and r2, r0, #255 @ r2<- BB 2239 mov r3, r0, lsr #8 @ r3<- CC 2240 GET_VREG(rINST, r2) @ rINST<- vBB (array object) 2241 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2242 cmp rINST, #0 @ null array object? 2243 GET_VREG(r9, r9) @ r9<- vAA 2244 beq common_errNullObject @ yes, bail 2245 ldr r3, [rINST, #offArrayObject_length] @ r3<- arrayObj->length 2246 add r10, rINST, r1, lsl #2 @ r10<- arrayObj + index*width 2247 cmp r1, r3 @ compare unsigned index, length 2248 bcc .LOP_APUT_OBJECT_finish @ we're okay, continue on 2249 b common_errArrayIndex @ index >= length, bail 2250 2251 2252/* ------------------------------ */ 2253 .balign 64 2254.L_OP_APUT_BOOLEAN: /* 0x4e */ 2255/* File: armv5te/OP_APUT_BOOLEAN.S */ 2256/* File: armv5te/OP_APUT.S */ 2257 /* 2258 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2259 * 2260 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2261 * instructions. We use a pair of FETCH_Bs instead. 2262 * 2263 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2264 */ 2265 /* op vAA, vBB, vCC */ 2266 FETCH_B(r2, 1, 0) @ r2<- BB 2267 mov r9, rINST, lsr #8 @ r9<- AA 2268 FETCH_B(r3, 1, 1) @ r3<- CC 2269 GET_VREG(r0, r2) @ r0<- vBB (array object) 2270 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2271 cmp r0, #0 @ null array object? 2272 beq common_errNullObject @ yes, bail 2273 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2274 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2275 cmp r1, r3 @ compare unsigned index, length 2276 bcs common_errArrayIndex @ index >= length, bail 2277 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2278 GET_VREG(r2, r9) @ r2<- vAA 2279 GET_INST_OPCODE(ip) @ extract opcode from rINST 2280 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2281 GOTO_OPCODE(ip) @ jump to next instruction 2282 2283 2284/* ------------------------------ */ 2285 .balign 64 2286.L_OP_APUT_BYTE: /* 0x4f */ 2287/* File: armv5te/OP_APUT_BYTE.S */ 2288/* File: armv5te/OP_APUT.S */ 2289 /* 2290 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2291 * 2292 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2293 * instructions. We use a pair of FETCH_Bs instead. 2294 * 2295 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2296 */ 2297 /* op vAA, vBB, vCC */ 2298 FETCH_B(r2, 1, 0) @ r2<- BB 2299 mov r9, rINST, lsr #8 @ r9<- AA 2300 FETCH_B(r3, 1, 1) @ r3<- CC 2301 GET_VREG(r0, r2) @ r0<- vBB (array object) 2302 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2303 cmp r0, #0 @ null array object? 2304 beq common_errNullObject @ yes, bail 2305 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2306 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2307 cmp r1, r3 @ compare unsigned index, length 2308 bcs common_errArrayIndex @ index >= length, bail 2309 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2310 GET_VREG(r2, r9) @ r2<- vAA 2311 GET_INST_OPCODE(ip) @ extract opcode from rINST 2312 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2313 GOTO_OPCODE(ip) @ jump to next instruction 2314 2315 2316/* ------------------------------ */ 2317 .balign 64 2318.L_OP_APUT_CHAR: /* 0x50 */ 2319/* File: armv5te/OP_APUT_CHAR.S */ 2320/* File: armv5te/OP_APUT.S */ 2321 /* 2322 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2323 * 2324 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2325 * instructions. We use a pair of FETCH_Bs instead. 2326 * 2327 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2328 */ 2329 /* op vAA, vBB, vCC */ 2330 FETCH_B(r2, 1, 0) @ r2<- BB 2331 mov r9, rINST, lsr #8 @ r9<- AA 2332 FETCH_B(r3, 1, 1) @ r3<- CC 2333 GET_VREG(r0, r2) @ r0<- vBB (array object) 2334 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2335 cmp r0, #0 @ null array object? 2336 beq common_errNullObject @ yes, bail 2337 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2338 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2339 cmp r1, r3 @ compare unsigned index, length 2340 bcs common_errArrayIndex @ index >= length, bail 2341 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2342 GET_VREG(r2, r9) @ r2<- vAA 2343 GET_INST_OPCODE(ip) @ extract opcode from rINST 2344 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2345 GOTO_OPCODE(ip) @ jump to next instruction 2346 2347 2348/* ------------------------------ */ 2349 .balign 64 2350.L_OP_APUT_SHORT: /* 0x51 */ 2351/* File: armv5te/OP_APUT_SHORT.S */ 2352/* File: armv5te/OP_APUT.S */ 2353 /* 2354 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2355 * 2356 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2357 * instructions. We use a pair of FETCH_Bs instead. 2358 * 2359 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2360 */ 2361 /* op vAA, vBB, vCC */ 2362 FETCH_B(r2, 1, 0) @ r2<- BB 2363 mov r9, rINST, lsr #8 @ r9<- AA 2364 FETCH_B(r3, 1, 1) @ r3<- CC 2365 GET_VREG(r0, r2) @ r0<- vBB (array object) 2366 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2367 cmp r0, #0 @ null array object? 2368 beq common_errNullObject @ yes, bail 2369 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2370 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2371 cmp r1, r3 @ compare unsigned index, length 2372 bcs common_errArrayIndex @ index >= length, bail 2373 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2374 GET_VREG(r2, r9) @ r2<- vAA 2375 GET_INST_OPCODE(ip) @ extract opcode from rINST 2376 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2377 GOTO_OPCODE(ip) @ jump to next instruction 2378 2379 2380/* ------------------------------ */ 2381 .balign 64 2382.L_OP_IGET: /* 0x52 */ 2383/* File: armv5te/OP_IGET.S */ 2384 /* 2385 * General 32-bit instance field get. 2386 * 2387 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2388 */ 2389 /* op vA, vB, field@CCCC */ 2390 mov r0, rINST, lsr #12 @ r0<- B 2391 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2392 FETCH(r1, 1) @ r1<- field ref CCCC 2393 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2394 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2395 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2396 cmp r0, #0 @ is resolved entry null? 2397 bne .LOP_IGET_finish @ no, already resolved 23988: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2399 EXPORT_PC() @ resolve() could throw 2400 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2401 bl dvmResolveInstField @ r0<- resolved InstField ptr 2402 cmp r0, #0 2403 bne .LOP_IGET_finish 2404 b common_exceptionThrown 2405 2406/* ------------------------------ */ 2407 .balign 64 2408.L_OP_IGET_WIDE: /* 0x53 */ 2409/* File: armv5te/OP_IGET_WIDE.S */ 2410 /* 2411 * Wide 32-bit instance field get. 2412 */ 2413 /* iget-wide vA, vB, field@CCCC */ 2414 mov r0, rINST, lsr #12 @ r0<- B 2415 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2416 FETCH(r1, 1) @ r1<- field ref CCCC 2417 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2418 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2419 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2420 cmp r0, #0 @ is resolved entry null? 2421 bne .LOP_IGET_WIDE_finish @ no, already resolved 24228: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2423 EXPORT_PC() @ resolve() could throw 2424 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2425 bl dvmResolveInstField @ r0<- resolved InstField ptr 2426 cmp r0, #0 2427 bne .LOP_IGET_WIDE_finish 2428 b common_exceptionThrown 2429 2430/* ------------------------------ */ 2431 .balign 64 2432.L_OP_IGET_OBJECT: /* 0x54 */ 2433/* File: armv5te/OP_IGET_OBJECT.S */ 2434/* File: armv5te/OP_IGET.S */ 2435 /* 2436 * General 32-bit instance field get. 2437 * 2438 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2439 */ 2440 /* op vA, vB, field@CCCC */ 2441 mov r0, rINST, lsr #12 @ r0<- B 2442 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2443 FETCH(r1, 1) @ r1<- field ref CCCC 2444 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2445 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2446 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2447 cmp r0, #0 @ is resolved entry null? 2448 bne .LOP_IGET_OBJECT_finish @ no, already resolved 24498: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2450 EXPORT_PC() @ resolve() could throw 2451 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2452 bl dvmResolveInstField @ r0<- resolved InstField ptr 2453 cmp r0, #0 2454 bne .LOP_IGET_OBJECT_finish 2455 b common_exceptionThrown 2456 2457 2458/* ------------------------------ */ 2459 .balign 64 2460.L_OP_IGET_BOOLEAN: /* 0x55 */ 2461/* File: armv5te/OP_IGET_BOOLEAN.S */ 2462@include "armv5te/OP_IGET.S" { "load":"ldrb", "sqnum":"1" } 2463/* File: armv5te/OP_IGET.S */ 2464 /* 2465 * General 32-bit instance field get. 2466 * 2467 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2468 */ 2469 /* op vA, vB, field@CCCC */ 2470 mov r0, rINST, lsr #12 @ r0<- B 2471 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2472 FETCH(r1, 1) @ r1<- field ref CCCC 2473 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2474 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2475 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2476 cmp r0, #0 @ is resolved entry null? 2477 bne .LOP_IGET_BOOLEAN_finish @ no, already resolved 24788: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2479 EXPORT_PC() @ resolve() could throw 2480 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2481 bl dvmResolveInstField @ r0<- resolved InstField ptr 2482 cmp r0, #0 2483 bne .LOP_IGET_BOOLEAN_finish 2484 b common_exceptionThrown 2485 2486 2487/* ------------------------------ */ 2488 .balign 64 2489.L_OP_IGET_BYTE: /* 0x56 */ 2490/* File: armv5te/OP_IGET_BYTE.S */ 2491@include "armv5te/OP_IGET.S" { "load":"ldrsb", "sqnum":"2" } 2492/* File: armv5te/OP_IGET.S */ 2493 /* 2494 * General 32-bit instance field get. 2495 * 2496 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2497 */ 2498 /* op vA, vB, field@CCCC */ 2499 mov r0, rINST, lsr #12 @ r0<- B 2500 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2501 FETCH(r1, 1) @ r1<- field ref CCCC 2502 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2503 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2504 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2505 cmp r0, #0 @ is resolved entry null? 2506 bne .LOP_IGET_BYTE_finish @ no, already resolved 25078: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2508 EXPORT_PC() @ resolve() could throw 2509 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2510 bl dvmResolveInstField @ r0<- resolved InstField ptr 2511 cmp r0, #0 2512 bne .LOP_IGET_BYTE_finish 2513 b common_exceptionThrown 2514 2515 2516/* ------------------------------ */ 2517 .balign 64 2518.L_OP_IGET_CHAR: /* 0x57 */ 2519/* File: armv5te/OP_IGET_CHAR.S */ 2520@include "armv5te/OP_IGET.S" { "load":"ldrh", "sqnum":"3" } 2521/* File: armv5te/OP_IGET.S */ 2522 /* 2523 * General 32-bit instance field get. 2524 * 2525 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2526 */ 2527 /* op vA, vB, field@CCCC */ 2528 mov r0, rINST, lsr #12 @ r0<- B 2529 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2530 FETCH(r1, 1) @ r1<- field ref CCCC 2531 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2532 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2533 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2534 cmp r0, #0 @ is resolved entry null? 2535 bne .LOP_IGET_CHAR_finish @ no, already resolved 25368: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2537 EXPORT_PC() @ resolve() could throw 2538 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2539 bl dvmResolveInstField @ r0<- resolved InstField ptr 2540 cmp r0, #0 2541 bne .LOP_IGET_CHAR_finish 2542 b common_exceptionThrown 2543 2544 2545/* ------------------------------ */ 2546 .balign 64 2547.L_OP_IGET_SHORT: /* 0x58 */ 2548/* File: armv5te/OP_IGET_SHORT.S */ 2549@include "armv5te/OP_IGET.S" { "load":"ldrsh", "sqnum":"4" } 2550/* File: armv5te/OP_IGET.S */ 2551 /* 2552 * General 32-bit instance field get. 2553 * 2554 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2555 */ 2556 /* op vA, vB, field@CCCC */ 2557 mov r0, rINST, lsr #12 @ r0<- B 2558 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2559 FETCH(r1, 1) @ r1<- field ref CCCC 2560 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2561 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2562 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2563 cmp r0, #0 @ is resolved entry null? 2564 bne .LOP_IGET_SHORT_finish @ no, already resolved 25658: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2566 EXPORT_PC() @ resolve() could throw 2567 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2568 bl dvmResolveInstField @ r0<- resolved InstField ptr 2569 cmp r0, #0 2570 bne .LOP_IGET_SHORT_finish 2571 b common_exceptionThrown 2572 2573 2574/* ------------------------------ */ 2575 .balign 64 2576.L_OP_IPUT: /* 0x59 */ 2577/* File: armv5te/OP_IPUT.S */ 2578 /* 2579 * General 32-bit instance field put. 2580 * 2581 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2582 */ 2583 /* op vA, vB, field@CCCC */ 2584 mov r0, rINST, lsr #12 @ r0<- B 2585 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2586 FETCH(r1, 1) @ r1<- field ref CCCC 2587 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2588 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2589 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2590 cmp r0, #0 @ is resolved entry null? 2591 bne .LOP_IPUT_finish @ no, already resolved 25928: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2593 EXPORT_PC() @ resolve() could throw 2594 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2595 bl dvmResolveInstField @ r0<- resolved InstField ptr 2596 cmp r0, #0 @ success? 2597 bne .LOP_IPUT_finish @ yes, finish up 2598 b common_exceptionThrown 2599 2600/* ------------------------------ */ 2601 .balign 64 2602.L_OP_IPUT_WIDE: /* 0x5a */ 2603/* File: armv5te/OP_IPUT_WIDE.S */ 2604 /* iput-wide vA, vB, field@CCCC */ 2605 mov r0, rINST, lsr #12 @ r0<- B 2606 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2607 FETCH(r1, 1) @ r1<- field ref CCCC 2608 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2609 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2610 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2611 cmp r0, #0 @ is resolved entry null? 2612 bne .LOP_IPUT_WIDE_finish @ no, already resolved 26138: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2614 EXPORT_PC() @ resolve() could throw 2615 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2616 bl dvmResolveInstField @ r0<- resolved InstField ptr 2617 cmp r0, #0 @ success? 2618 bne .LOP_IPUT_WIDE_finish @ yes, finish up 2619 b common_exceptionThrown 2620 2621/* ------------------------------ */ 2622 .balign 64 2623.L_OP_IPUT_OBJECT: /* 0x5b */ 2624/* File: armv5te/OP_IPUT_OBJECT.S */ 2625 /* 2626 * 32-bit instance field put. 2627 * 2628 * for: iput-object, iput-object-volatile 2629 */ 2630 /* op vA, vB, field@CCCC */ 2631 mov r0, rINST, lsr #12 @ r0<- B 2632 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2633 FETCH(r1, 1) @ r1<- field ref CCCC 2634 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2635 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2636 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2637 cmp r0, #0 @ is resolved entry null? 2638 bne .LOP_IPUT_OBJECT_finish @ no, already resolved 26398: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2640 EXPORT_PC() @ resolve() could throw 2641 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2642 bl dvmResolveInstField @ r0<- resolved InstField ptr 2643 cmp r0, #0 @ success? 2644 bne .LOP_IPUT_OBJECT_finish @ yes, finish up 2645 b common_exceptionThrown 2646 2647/* ------------------------------ */ 2648 .balign 64 2649.L_OP_IPUT_BOOLEAN: /* 0x5c */ 2650/* File: armv5te/OP_IPUT_BOOLEAN.S */ 2651@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"1" } 2652/* File: armv5te/OP_IPUT.S */ 2653 /* 2654 * General 32-bit instance field put. 2655 * 2656 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2657 */ 2658 /* op vA, vB, field@CCCC */ 2659 mov r0, rINST, lsr #12 @ r0<- B 2660 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2661 FETCH(r1, 1) @ r1<- field ref CCCC 2662 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2663 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2664 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2665 cmp r0, #0 @ is resolved entry null? 2666 bne .LOP_IPUT_BOOLEAN_finish @ no, already resolved 26678: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2668 EXPORT_PC() @ resolve() could throw 2669 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2670 bl dvmResolveInstField @ r0<- resolved InstField ptr 2671 cmp r0, #0 @ success? 2672 bne .LOP_IPUT_BOOLEAN_finish @ yes, finish up 2673 b common_exceptionThrown 2674 2675 2676/* ------------------------------ */ 2677 .balign 64 2678.L_OP_IPUT_BYTE: /* 0x5d */ 2679/* File: armv5te/OP_IPUT_BYTE.S */ 2680@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"2" } 2681/* File: armv5te/OP_IPUT.S */ 2682 /* 2683 * General 32-bit instance field put. 2684 * 2685 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2686 */ 2687 /* op vA, vB, field@CCCC */ 2688 mov r0, rINST, lsr #12 @ r0<- B 2689 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2690 FETCH(r1, 1) @ r1<- field ref CCCC 2691 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2692 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2693 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2694 cmp r0, #0 @ is resolved entry null? 2695 bne .LOP_IPUT_BYTE_finish @ no, already resolved 26968: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2697 EXPORT_PC() @ resolve() could throw 2698 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2699 bl dvmResolveInstField @ r0<- resolved InstField ptr 2700 cmp r0, #0 @ success? 2701 bne .LOP_IPUT_BYTE_finish @ yes, finish up 2702 b common_exceptionThrown 2703 2704 2705/* ------------------------------ */ 2706 .balign 64 2707.L_OP_IPUT_CHAR: /* 0x5e */ 2708/* File: armv5te/OP_IPUT_CHAR.S */ 2709@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"3" } 2710/* File: armv5te/OP_IPUT.S */ 2711 /* 2712 * General 32-bit instance field put. 2713 * 2714 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2715 */ 2716 /* op vA, vB, field@CCCC */ 2717 mov r0, rINST, lsr #12 @ r0<- B 2718 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2719 FETCH(r1, 1) @ r1<- field ref CCCC 2720 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2721 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2722 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2723 cmp r0, #0 @ is resolved entry null? 2724 bne .LOP_IPUT_CHAR_finish @ no, already resolved 27258: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2726 EXPORT_PC() @ resolve() could throw 2727 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2728 bl dvmResolveInstField @ r0<- resolved InstField ptr 2729 cmp r0, #0 @ success? 2730 bne .LOP_IPUT_CHAR_finish @ yes, finish up 2731 b common_exceptionThrown 2732 2733 2734/* ------------------------------ */ 2735 .balign 64 2736.L_OP_IPUT_SHORT: /* 0x5f */ 2737/* File: armv5te/OP_IPUT_SHORT.S */ 2738@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"4" } 2739/* File: armv5te/OP_IPUT.S */ 2740 /* 2741 * General 32-bit instance field put. 2742 * 2743 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2744 */ 2745 /* op vA, vB, field@CCCC */ 2746 mov r0, rINST, lsr #12 @ r0<- B 2747 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2748 FETCH(r1, 1) @ r1<- field ref CCCC 2749 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2750 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2751 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2752 cmp r0, #0 @ is resolved entry null? 2753 bne .LOP_IPUT_SHORT_finish @ no, already resolved 27548: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2755 EXPORT_PC() @ resolve() could throw 2756 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2757 bl dvmResolveInstField @ r0<- resolved InstField ptr 2758 cmp r0, #0 @ success? 2759 bne .LOP_IPUT_SHORT_finish @ yes, finish up 2760 b common_exceptionThrown 2761 2762 2763/* ------------------------------ */ 2764 .balign 64 2765.L_OP_SGET: /* 0x60 */ 2766/* File: armv5te/OP_SGET.S */ 2767 /* 2768 * General 32-bit SGET handler. 2769 * 2770 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2771 */ 2772 /* op vAA, field@BBBB */ 2773 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2774 FETCH(r1, 1) @ r1<- field ref BBBB 2775 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2776 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2777 cmp r0, #0 @ is resolved entry null? 2778 beq .LOP_SGET_resolve @ yes, do resolve 2779.LOP_SGET_finish: @ field ptr in r0 2780 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2781 @ no-op @ acquiring load 2782 mov r2, rINST, lsr #8 @ r2<- AA 2783 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2784 SET_VREG(r1, r2) @ fp[AA]<- r1 2785 GET_INST_OPCODE(ip) @ extract opcode from rINST 2786 GOTO_OPCODE(ip) @ jump to next instruction 2787 2788/* ------------------------------ */ 2789 .balign 64 2790.L_OP_SGET_WIDE: /* 0x61 */ 2791/* File: armv5te/OP_SGET_WIDE.S */ 2792 /* 2793 * 64-bit SGET handler. 2794 */ 2795 /* sget-wide vAA, field@BBBB */ 2796 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2797 FETCH(r1, 1) @ r1<- field ref BBBB 2798 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2799 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2800 cmp r0, #0 @ is resolved entry null? 2801 beq .LOP_SGET_WIDE_resolve @ yes, do resolve 2802.LOP_SGET_WIDE_finish: 2803 mov r9, rINST, lsr #8 @ r9<- AA 2804 .if 0 2805 add r0, r0, #offStaticField_value @ r0<- pointer to data 2806 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 2807 .else 2808 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 2809 .endif 2810 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2811 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2812 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 2813 GET_INST_OPCODE(ip) @ extract opcode from rINST 2814 GOTO_OPCODE(ip) @ jump to next instruction 2815 2816/* ------------------------------ */ 2817 .balign 64 2818.L_OP_SGET_OBJECT: /* 0x62 */ 2819/* File: armv5te/OP_SGET_OBJECT.S */ 2820/* File: armv5te/OP_SGET.S */ 2821 /* 2822 * General 32-bit SGET handler. 2823 * 2824 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2825 */ 2826 /* op vAA, field@BBBB */ 2827 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2828 FETCH(r1, 1) @ r1<- field ref BBBB 2829 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2830 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2831 cmp r0, #0 @ is resolved entry null? 2832 beq .LOP_SGET_OBJECT_resolve @ yes, do resolve 2833.LOP_SGET_OBJECT_finish: @ field ptr in r0 2834 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2835 @ no-op @ acquiring load 2836 mov r2, rINST, lsr #8 @ r2<- AA 2837 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2838 SET_VREG(r1, r2) @ fp[AA]<- r1 2839 GET_INST_OPCODE(ip) @ extract opcode from rINST 2840 GOTO_OPCODE(ip) @ jump to next instruction 2841 2842 2843/* ------------------------------ */ 2844 .balign 64 2845.L_OP_SGET_BOOLEAN: /* 0x63 */ 2846/* File: armv5te/OP_SGET_BOOLEAN.S */ 2847/* File: armv5te/OP_SGET.S */ 2848 /* 2849 * General 32-bit SGET handler. 2850 * 2851 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2852 */ 2853 /* op vAA, field@BBBB */ 2854 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2855 FETCH(r1, 1) @ r1<- field ref BBBB 2856 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2857 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2858 cmp r0, #0 @ is resolved entry null? 2859 beq .LOP_SGET_BOOLEAN_resolve @ yes, do resolve 2860.LOP_SGET_BOOLEAN_finish: @ field ptr in r0 2861 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2862 @ no-op @ acquiring load 2863 mov r2, rINST, lsr #8 @ r2<- AA 2864 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2865 SET_VREG(r1, r2) @ fp[AA]<- r1 2866 GET_INST_OPCODE(ip) @ extract opcode from rINST 2867 GOTO_OPCODE(ip) @ jump to next instruction 2868 2869 2870/* ------------------------------ */ 2871 .balign 64 2872.L_OP_SGET_BYTE: /* 0x64 */ 2873/* File: armv5te/OP_SGET_BYTE.S */ 2874/* File: armv5te/OP_SGET.S */ 2875 /* 2876 * General 32-bit SGET handler. 2877 * 2878 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2879 */ 2880 /* op vAA, field@BBBB */ 2881 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2882 FETCH(r1, 1) @ r1<- field ref BBBB 2883 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2884 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2885 cmp r0, #0 @ is resolved entry null? 2886 beq .LOP_SGET_BYTE_resolve @ yes, do resolve 2887.LOP_SGET_BYTE_finish: @ field ptr in r0 2888 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2889 @ no-op @ acquiring load 2890 mov r2, rINST, lsr #8 @ r2<- AA 2891 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2892 SET_VREG(r1, r2) @ fp[AA]<- r1 2893 GET_INST_OPCODE(ip) @ extract opcode from rINST 2894 GOTO_OPCODE(ip) @ jump to next instruction 2895 2896 2897/* ------------------------------ */ 2898 .balign 64 2899.L_OP_SGET_CHAR: /* 0x65 */ 2900/* File: armv5te/OP_SGET_CHAR.S */ 2901/* File: armv5te/OP_SGET.S */ 2902 /* 2903 * General 32-bit SGET handler. 2904 * 2905 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2906 */ 2907 /* op vAA, field@BBBB */ 2908 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2909 FETCH(r1, 1) @ r1<- field ref BBBB 2910 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2911 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2912 cmp r0, #0 @ is resolved entry null? 2913 beq .LOP_SGET_CHAR_resolve @ yes, do resolve 2914.LOP_SGET_CHAR_finish: @ field ptr in r0 2915 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2916 @ no-op @ acquiring load 2917 mov r2, rINST, lsr #8 @ r2<- AA 2918 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2919 SET_VREG(r1, r2) @ fp[AA]<- r1 2920 GET_INST_OPCODE(ip) @ extract opcode from rINST 2921 GOTO_OPCODE(ip) @ jump to next instruction 2922 2923 2924/* ------------------------------ */ 2925 .balign 64 2926.L_OP_SGET_SHORT: /* 0x66 */ 2927/* File: armv5te/OP_SGET_SHORT.S */ 2928/* File: armv5te/OP_SGET.S */ 2929 /* 2930 * General 32-bit SGET handler. 2931 * 2932 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2933 */ 2934 /* op vAA, field@BBBB */ 2935 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2936 FETCH(r1, 1) @ r1<- field ref BBBB 2937 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2938 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2939 cmp r0, #0 @ is resolved entry null? 2940 beq .LOP_SGET_SHORT_resolve @ yes, do resolve 2941.LOP_SGET_SHORT_finish: @ field ptr in r0 2942 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2943 @ no-op @ acquiring load 2944 mov r2, rINST, lsr #8 @ r2<- AA 2945 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2946 SET_VREG(r1, r2) @ fp[AA]<- r1 2947 GET_INST_OPCODE(ip) @ extract opcode from rINST 2948 GOTO_OPCODE(ip) @ jump to next instruction 2949 2950 2951/* ------------------------------ */ 2952 .balign 64 2953.L_OP_SPUT: /* 0x67 */ 2954/* File: armv5te/OP_SPUT.S */ 2955 /* 2956 * General 32-bit SPUT handler. 2957 * 2958 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2959 */ 2960 /* op vAA, field@BBBB */ 2961 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2962 FETCH(r1, 1) @ r1<- field ref BBBB 2963 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2964 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2965 cmp r0, #0 @ is resolved entry null? 2966 beq .LOP_SPUT_resolve @ yes, do resolve 2967.LOP_SPUT_finish: @ field ptr in r0 2968 mov r2, rINST, lsr #8 @ r2<- AA 2969 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2970 GET_VREG(r1, r2) @ r1<- fp[AA] 2971 GET_INST_OPCODE(ip) @ extract opcode from rINST 2972 @ no-op @ releasing store 2973 str r1, [r0, #offStaticField_value] @ field<- vAA 2974 GOTO_OPCODE(ip) @ jump to next instruction 2975 2976/* ------------------------------ */ 2977 .balign 64 2978.L_OP_SPUT_WIDE: /* 0x68 */ 2979/* File: armv5te/OP_SPUT_WIDE.S */ 2980 /* 2981 * 64-bit SPUT handler. 2982 */ 2983 /* sput-wide vAA, field@BBBB */ 2984 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- DvmDex 2985 FETCH(r1, 1) @ r1<- field ref BBBB 2986 ldr r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields 2987 mov r9, rINST, lsr #8 @ r9<- AA 2988 ldr r2, [r0, r1, lsl #2] @ r2<- resolved StaticField ptr 2989 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2990 cmp r2, #0 @ is resolved entry null? 2991 beq .LOP_SPUT_WIDE_resolve @ yes, do resolve 2992.LOP_SPUT_WIDE_finish: @ field ptr in r2, AA in r9 2993 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2994 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 2995 GET_INST_OPCODE(r10) @ extract opcode from rINST 2996 .if 0 2997 add r2, r2, #offStaticField_value @ r2<- pointer to data 2998 bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2 2999 .else 3000 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 3001 .endif 3002 GOTO_OPCODE(r10) @ jump to next instruction 3003 3004/* ------------------------------ */ 3005 .balign 64 3006.L_OP_SPUT_OBJECT: /* 0x69 */ 3007/* File: armv5te/OP_SPUT_OBJECT.S */ 3008 /* 3009 * 32-bit SPUT handler for objects 3010 * 3011 * for: sput-object, sput-object-volatile 3012 */ 3013 /* op vAA, field@BBBB */ 3014 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3015 FETCH(r1, 1) @ r1<- field ref BBBB 3016 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3017 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3018 cmp r0, #0 @ is resolved entry null? 3019 bne .LOP_SPUT_OBJECT_finish @ no, continue 3020 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 3021 EXPORT_PC() @ resolve() could throw, so export now 3022 ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz 3023 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 3024 cmp r0, #0 @ success? 3025 bne .LOP_SPUT_OBJECT_finish @ yes, finish 3026 b common_exceptionThrown @ no, handle exception 3027 3028 3029/* ------------------------------ */ 3030 .balign 64 3031.L_OP_SPUT_BOOLEAN: /* 0x6a */ 3032/* File: armv5te/OP_SPUT_BOOLEAN.S */ 3033/* File: armv5te/OP_SPUT.S */ 3034 /* 3035 * General 32-bit SPUT handler. 3036 * 3037 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3038 */ 3039 /* op vAA, field@BBBB */ 3040 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3041 FETCH(r1, 1) @ r1<- field ref BBBB 3042 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3043 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3044 cmp r0, #0 @ is resolved entry null? 3045 beq .LOP_SPUT_BOOLEAN_resolve @ yes, do resolve 3046.LOP_SPUT_BOOLEAN_finish: @ field ptr in r0 3047 mov r2, rINST, lsr #8 @ r2<- AA 3048 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3049 GET_VREG(r1, r2) @ r1<- fp[AA] 3050 GET_INST_OPCODE(ip) @ extract opcode from rINST 3051 @ no-op @ releasing store 3052 str r1, [r0, #offStaticField_value] @ field<- vAA 3053 GOTO_OPCODE(ip) @ jump to next instruction 3054 3055 3056/* ------------------------------ */ 3057 .balign 64 3058.L_OP_SPUT_BYTE: /* 0x6b */ 3059/* File: armv5te/OP_SPUT_BYTE.S */ 3060/* File: armv5te/OP_SPUT.S */ 3061 /* 3062 * General 32-bit SPUT handler. 3063 * 3064 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3065 */ 3066 /* op vAA, field@BBBB */ 3067 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3068 FETCH(r1, 1) @ r1<- field ref BBBB 3069 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3070 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3071 cmp r0, #0 @ is resolved entry null? 3072 beq .LOP_SPUT_BYTE_resolve @ yes, do resolve 3073.LOP_SPUT_BYTE_finish: @ field ptr in r0 3074 mov r2, rINST, lsr #8 @ r2<- AA 3075 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3076 GET_VREG(r1, r2) @ r1<- fp[AA] 3077 GET_INST_OPCODE(ip) @ extract opcode from rINST 3078 @ no-op @ releasing store 3079 str r1, [r0, #offStaticField_value] @ field<- vAA 3080 GOTO_OPCODE(ip) @ jump to next instruction 3081 3082 3083/* ------------------------------ */ 3084 .balign 64 3085.L_OP_SPUT_CHAR: /* 0x6c */ 3086/* File: armv5te/OP_SPUT_CHAR.S */ 3087/* File: armv5te/OP_SPUT.S */ 3088 /* 3089 * General 32-bit SPUT handler. 3090 * 3091 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3092 */ 3093 /* op vAA, field@BBBB */ 3094 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3095 FETCH(r1, 1) @ r1<- field ref BBBB 3096 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3097 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3098 cmp r0, #0 @ is resolved entry null? 3099 beq .LOP_SPUT_CHAR_resolve @ yes, do resolve 3100.LOP_SPUT_CHAR_finish: @ field ptr in r0 3101 mov r2, rINST, lsr #8 @ r2<- AA 3102 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3103 GET_VREG(r1, r2) @ r1<- fp[AA] 3104 GET_INST_OPCODE(ip) @ extract opcode from rINST 3105 @ no-op @ releasing store 3106 str r1, [r0, #offStaticField_value] @ field<- vAA 3107 GOTO_OPCODE(ip) @ jump to next instruction 3108 3109 3110/* ------------------------------ */ 3111 .balign 64 3112.L_OP_SPUT_SHORT: /* 0x6d */ 3113/* File: armv5te/OP_SPUT_SHORT.S */ 3114/* File: armv5te/OP_SPUT.S */ 3115 /* 3116 * General 32-bit SPUT handler. 3117 * 3118 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3119 */ 3120 /* op vAA, field@BBBB */ 3121 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3122 FETCH(r1, 1) @ r1<- field ref BBBB 3123 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3124 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3125 cmp r0, #0 @ is resolved entry null? 3126 beq .LOP_SPUT_SHORT_resolve @ yes, do resolve 3127.LOP_SPUT_SHORT_finish: @ field ptr in r0 3128 mov r2, rINST, lsr #8 @ r2<- AA 3129 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3130 GET_VREG(r1, r2) @ r1<- fp[AA] 3131 GET_INST_OPCODE(ip) @ extract opcode from rINST 3132 @ no-op @ releasing store 3133 str r1, [r0, #offStaticField_value] @ field<- vAA 3134 GOTO_OPCODE(ip) @ jump to next instruction 3135 3136 3137/* ------------------------------ */ 3138 .balign 64 3139.L_OP_INVOKE_VIRTUAL: /* 0x6e */ 3140/* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3141 /* 3142 * Handle a virtual method call. 3143 * 3144 * for: invoke-virtual, invoke-virtual/range 3145 */ 3146 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3147 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3148 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3149 FETCH(r1, 1) @ r1<- BBBB 3150 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3151 FETCH(r10, 2) @ r10<- GFED or CCCC 3152 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3153 .if (!0) 3154 and r10, r10, #15 @ r10<- D (or stays CCCC) 3155 .endif 3156 cmp r0, #0 @ already resolved? 3157 EXPORT_PC() @ must export for invoke 3158 bne .LOP_INVOKE_VIRTUAL_continue @ yes, continue on 3159 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 3160 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3161 mov r2, #METHOD_VIRTUAL @ resolver method type 3162 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3163 cmp r0, #0 @ got null? 3164 bne .LOP_INVOKE_VIRTUAL_continue @ no, continue 3165 b common_exceptionThrown @ yes, handle exception 3166 3167/* ------------------------------ */ 3168 .balign 64 3169.L_OP_INVOKE_SUPER: /* 0x6f */ 3170/* File: armv5te/OP_INVOKE_SUPER.S */ 3171 /* 3172 * Handle a "super" method call. 3173 * 3174 * for: invoke-super, invoke-super/range 3175 */ 3176 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3177 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3178 FETCH(r10, 2) @ r10<- GFED or CCCC 3179 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3180 .if (!0) 3181 and r10, r10, #15 @ r10<- D (or stays CCCC) 3182 .endif 3183 FETCH(r1, 1) @ r1<- BBBB 3184 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3185 GET_VREG(r2, r10) @ r2<- "this" ptr 3186 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3187 cmp r2, #0 @ null "this"? 3188 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 3189 beq common_errNullObject @ null "this", throw exception 3190 cmp r0, #0 @ already resolved? 3191 ldr r9, [r9, #offMethod_clazz] @ r9<- method->clazz 3192 EXPORT_PC() @ must export for invoke 3193 bne .LOP_INVOKE_SUPER_continue @ resolved, continue on 3194 b .LOP_INVOKE_SUPER_resolve @ do resolve now 3195 3196/* ------------------------------ */ 3197 .balign 64 3198.L_OP_INVOKE_DIRECT: /* 0x70 */ 3199/* File: armv5te/OP_INVOKE_DIRECT.S */ 3200 /* 3201 * Handle a direct method call. 3202 * 3203 * (We could defer the "is 'this' pointer null" test to the common 3204 * method invocation code, and use a flag to indicate that static 3205 * calls don't count. If we do this as part of copying the arguments 3206 * out we could avoiding loading the first arg twice.) 3207 * 3208 * for: invoke-direct, invoke-direct/range 3209 */ 3210 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3211 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3212 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3213 FETCH(r1, 1) @ r1<- BBBB 3214 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3215 FETCH(r10, 2) @ r10<- GFED or CCCC 3216 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3217 .if (!0) 3218 and r10, r10, #15 @ r10<- D (or stays CCCC) 3219 .endif 3220 cmp r0, #0 @ already resolved? 3221 EXPORT_PC() @ must export for invoke 3222 GET_VREG(r2, r10) @ r2<- "this" ptr 3223 beq .LOP_INVOKE_DIRECT_resolve @ not resolved, do it now 3224.LOP_INVOKE_DIRECT_finish: 3225 cmp r2, #0 @ null "this" ref? 3226 bne common_invokeMethodNoRange @ no, continue on 3227 b common_errNullObject @ yes, throw exception 3228 3229/* ------------------------------ */ 3230 .balign 64 3231.L_OP_INVOKE_STATIC: /* 0x71 */ 3232/* File: armv5te/OP_INVOKE_STATIC.S */ 3233 /* 3234 * Handle a static method call. 3235 * 3236 * for: invoke-static, invoke-static/range 3237 */ 3238 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3239 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3240 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3241 FETCH(r1, 1) @ r1<- BBBB 3242 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3243 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3244 cmp r0, #0 @ already resolved? 3245 EXPORT_PC() @ must export for invoke 3246 bne common_invokeMethodNoRange @ yes, continue on 32470: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 3248 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3249 mov r2, #METHOD_STATIC @ resolver method type 3250 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3251 cmp r0, #0 @ got null? 3252 bne common_invokeMethodNoRange @ no, continue 3253 b common_exceptionThrown @ yes, handle exception 3254 3255/* ------------------------------ */ 3256 .balign 64 3257.L_OP_INVOKE_INTERFACE: /* 0x72 */ 3258/* File: armv5te/OP_INVOKE_INTERFACE.S */ 3259 /* 3260 * Handle an interface method call. 3261 * 3262 * for: invoke-interface, invoke-interface/range 3263 */ 3264 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3265 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3266 FETCH(r2, 2) @ r2<- FEDC or CCCC 3267 FETCH(r1, 1) @ r1<- BBBB 3268 .if (!0) 3269 and r2, r2, #15 @ r2<- C (or stays CCCC) 3270 .endif 3271 EXPORT_PC() @ must export for invoke 3272 GET_VREG(r0, r2) @ r0<- first arg ("this") 3273 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- methodClassDex 3274 cmp r0, #0 @ null obj? 3275 ldr r2, [rGLUE, #offGlue_method] @ r2<- method 3276 beq common_errNullObject @ yes, fail 3277 ldr r0, [r0, #offObject_clazz] @ r0<- thisPtr->clazz 3278 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3279 cmp r0, #0 @ failed? 3280 beq common_exceptionThrown @ yes, handle exception 3281 b common_invokeMethodNoRange @ jump to common handler 3282 3283/* ------------------------------ */ 3284 .balign 64 3285.L_OP_UNUSED_73: /* 0x73 */ 3286/* File: armv5te/OP_UNUSED_73.S */ 3287/* File: armv5te/unused.S */ 3288 bl common_abort 3289 3290 3291/* ------------------------------ */ 3292 .balign 64 3293.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */ 3294/* File: armv5te/OP_INVOKE_VIRTUAL_RANGE.S */ 3295/* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3296 /* 3297 * Handle a virtual method call. 3298 * 3299 * for: invoke-virtual, invoke-virtual/range 3300 */ 3301 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3302 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3303 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3304 FETCH(r1, 1) @ r1<- BBBB 3305 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3306 FETCH(r10, 2) @ r10<- GFED or CCCC 3307 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3308 .if (!1) 3309 and r10, r10, #15 @ r10<- D (or stays CCCC) 3310 .endif 3311 cmp r0, #0 @ already resolved? 3312 EXPORT_PC() @ must export for invoke 3313 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ yes, continue on 3314 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 3315 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3316 mov r2, #METHOD_VIRTUAL @ resolver method type 3317 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3318 cmp r0, #0 @ got null? 3319 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ no, continue 3320 b common_exceptionThrown @ yes, handle exception 3321 3322 3323/* ------------------------------ */ 3324 .balign 64 3325.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */ 3326/* File: armv5te/OP_INVOKE_SUPER_RANGE.S */ 3327/* File: armv5te/OP_INVOKE_SUPER.S */ 3328 /* 3329 * Handle a "super" method call. 3330 * 3331 * for: invoke-super, invoke-super/range 3332 */ 3333 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3334 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3335 FETCH(r10, 2) @ r10<- GFED or CCCC 3336 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3337 .if (!1) 3338 and r10, r10, #15 @ r10<- D (or stays CCCC) 3339 .endif 3340 FETCH(r1, 1) @ r1<- BBBB 3341 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3342 GET_VREG(r2, r10) @ r2<- "this" ptr 3343 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3344 cmp r2, #0 @ null "this"? 3345 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 3346 beq common_errNullObject @ null "this", throw exception 3347 cmp r0, #0 @ already resolved? 3348 ldr r9, [r9, #offMethod_clazz] @ r9<- method->clazz 3349 EXPORT_PC() @ must export for invoke 3350 bne .LOP_INVOKE_SUPER_RANGE_continue @ resolved, continue on 3351 b .LOP_INVOKE_SUPER_RANGE_resolve @ do resolve now 3352 3353 3354/* ------------------------------ */ 3355 .balign 64 3356.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */ 3357/* File: armv5te/OP_INVOKE_DIRECT_RANGE.S */ 3358/* File: armv5te/OP_INVOKE_DIRECT.S */ 3359 /* 3360 * Handle a direct method call. 3361 * 3362 * (We could defer the "is 'this' pointer null" test to the common 3363 * method invocation code, and use a flag to indicate that static 3364 * calls don't count. If we do this as part of copying the arguments 3365 * out we could avoiding loading the first arg twice.) 3366 * 3367 * for: invoke-direct, invoke-direct/range 3368 */ 3369 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3370 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3371 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3372 FETCH(r1, 1) @ r1<- BBBB 3373 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3374 FETCH(r10, 2) @ r10<- GFED or CCCC 3375 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3376 .if (!1) 3377 and r10, r10, #15 @ r10<- D (or stays CCCC) 3378 .endif 3379 cmp r0, #0 @ already resolved? 3380 EXPORT_PC() @ must export for invoke 3381 GET_VREG(r2, r10) @ r2<- "this" ptr 3382 beq .LOP_INVOKE_DIRECT_RANGE_resolve @ not resolved, do it now 3383.LOP_INVOKE_DIRECT_RANGE_finish: 3384 cmp r2, #0 @ null "this" ref? 3385 bne common_invokeMethodRange @ no, continue on 3386 b common_errNullObject @ yes, throw exception 3387 3388 3389/* ------------------------------ */ 3390 .balign 64 3391.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */ 3392/* File: armv5te/OP_INVOKE_STATIC_RANGE.S */ 3393/* File: armv5te/OP_INVOKE_STATIC.S */ 3394 /* 3395 * Handle a static method call. 3396 * 3397 * for: invoke-static, invoke-static/range 3398 */ 3399 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3400 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3401 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3402 FETCH(r1, 1) @ r1<- BBBB 3403 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3404 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3405 cmp r0, #0 @ already resolved? 3406 EXPORT_PC() @ must export for invoke 3407 bne common_invokeMethodRange @ yes, continue on 34080: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 3409 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3410 mov r2, #METHOD_STATIC @ resolver method type 3411 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3412 cmp r0, #0 @ got null? 3413 bne common_invokeMethodRange @ no, continue 3414 b common_exceptionThrown @ yes, handle exception 3415 3416 3417/* ------------------------------ */ 3418 .balign 64 3419.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */ 3420/* File: armv5te/OP_INVOKE_INTERFACE_RANGE.S */ 3421/* File: armv5te/OP_INVOKE_INTERFACE.S */ 3422 /* 3423 * Handle an interface method call. 3424 * 3425 * for: invoke-interface, invoke-interface/range 3426 */ 3427 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3428 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3429 FETCH(r2, 2) @ r2<- FEDC or CCCC 3430 FETCH(r1, 1) @ r1<- BBBB 3431 .if (!1) 3432 and r2, r2, #15 @ r2<- C (or stays CCCC) 3433 .endif 3434 EXPORT_PC() @ must export for invoke 3435 GET_VREG(r0, r2) @ r0<- first arg ("this") 3436 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- methodClassDex 3437 cmp r0, #0 @ null obj? 3438 ldr r2, [rGLUE, #offGlue_method] @ r2<- method 3439 beq common_errNullObject @ yes, fail 3440 ldr r0, [r0, #offObject_clazz] @ r0<- thisPtr->clazz 3441 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3442 cmp r0, #0 @ failed? 3443 beq common_exceptionThrown @ yes, handle exception 3444 b common_invokeMethodRange @ jump to common handler 3445 3446 3447/* ------------------------------ */ 3448 .balign 64 3449.L_OP_UNUSED_79: /* 0x79 */ 3450/* File: armv5te/OP_UNUSED_79.S */ 3451/* File: armv5te/unused.S */ 3452 bl common_abort 3453 3454 3455/* ------------------------------ */ 3456 .balign 64 3457.L_OP_UNUSED_7A: /* 0x7a */ 3458/* File: armv5te/OP_UNUSED_7A.S */ 3459/* File: armv5te/unused.S */ 3460 bl common_abort 3461 3462 3463/* ------------------------------ */ 3464 .balign 64 3465.L_OP_NEG_INT: /* 0x7b */ 3466/* File: armv5te/OP_NEG_INT.S */ 3467/* File: armv5te/unop.S */ 3468 /* 3469 * Generic 32-bit unary operation. Provide an "instr" line that 3470 * specifies an instruction that performs "result = op r0". 3471 * This could be an ARM instruction or a function call. 3472 * 3473 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3474 * int-to-byte, int-to-char, int-to-short 3475 */ 3476 /* unop vA, vB */ 3477 mov r3, rINST, lsr #12 @ r3<- B 3478 mov r9, rINST, lsr #8 @ r9<- A+ 3479 GET_VREG(r0, r3) @ r0<- vB 3480 and r9, r9, #15 3481 @ optional op; may set condition codes 3482 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3483 rsb r0, r0, #0 @ r0<- op, r0-r3 changed 3484 GET_INST_OPCODE(ip) @ extract opcode from rINST 3485 SET_VREG(r0, r9) @ vAA<- r0 3486 GOTO_OPCODE(ip) @ jump to next instruction 3487 /* 9-10 instructions */ 3488 3489 3490/* ------------------------------ */ 3491 .balign 64 3492.L_OP_NOT_INT: /* 0x7c */ 3493/* File: armv5te/OP_NOT_INT.S */ 3494/* File: armv5te/unop.S */ 3495 /* 3496 * Generic 32-bit unary operation. Provide an "instr" line that 3497 * specifies an instruction that performs "result = op r0". 3498 * This could be an ARM instruction or a function call. 3499 * 3500 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3501 * int-to-byte, int-to-char, int-to-short 3502 */ 3503 /* unop vA, vB */ 3504 mov r3, rINST, lsr #12 @ r3<- B 3505 mov r9, rINST, lsr #8 @ r9<- A+ 3506 GET_VREG(r0, r3) @ r0<- vB 3507 and r9, r9, #15 3508 @ optional op; may set condition codes 3509 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3510 mvn r0, r0 @ r0<- op, r0-r3 changed 3511 GET_INST_OPCODE(ip) @ extract opcode from rINST 3512 SET_VREG(r0, r9) @ vAA<- r0 3513 GOTO_OPCODE(ip) @ jump to next instruction 3514 /* 9-10 instructions */ 3515 3516 3517/* ------------------------------ */ 3518 .balign 64 3519.L_OP_NEG_LONG: /* 0x7d */ 3520/* File: armv5te/OP_NEG_LONG.S */ 3521/* File: armv5te/unopWide.S */ 3522 /* 3523 * Generic 64-bit unary operation. Provide an "instr" line that 3524 * specifies an instruction that performs "result = op r0/r1". 3525 * This could be an ARM instruction or a function call. 3526 * 3527 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3528 */ 3529 /* unop vA, vB */ 3530 mov r9, rINST, lsr #8 @ r9<- A+ 3531 mov r3, rINST, lsr #12 @ r3<- B 3532 and r9, r9, #15 3533 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3534 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3535 ldmia r3, {r0-r1} @ r0/r1<- vAA 3536 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3537 rsbs r0, r0, #0 @ optional op; may set condition codes 3538 rsc r1, r1, #0 @ r0/r1<- op, r2-r3 changed 3539 GET_INST_OPCODE(ip) @ extract opcode from rINST 3540 stmia r9, {r0-r1} @ vAA<- r0/r1 3541 GOTO_OPCODE(ip) @ jump to next instruction 3542 /* 12-13 instructions */ 3543 3544 3545/* ------------------------------ */ 3546 .balign 64 3547.L_OP_NOT_LONG: /* 0x7e */ 3548/* File: armv5te/OP_NOT_LONG.S */ 3549/* File: armv5te/unopWide.S */ 3550 /* 3551 * Generic 64-bit unary operation. Provide an "instr" line that 3552 * specifies an instruction that performs "result = op r0/r1". 3553 * This could be an ARM instruction or a function call. 3554 * 3555 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3556 */ 3557 /* unop vA, vB */ 3558 mov r9, rINST, lsr #8 @ r9<- A+ 3559 mov r3, rINST, lsr #12 @ r3<- B 3560 and r9, r9, #15 3561 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3562 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3563 ldmia r3, {r0-r1} @ r0/r1<- vAA 3564 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3565 mvn r0, r0 @ optional op; may set condition codes 3566 mvn r1, r1 @ r0/r1<- op, r2-r3 changed 3567 GET_INST_OPCODE(ip) @ extract opcode from rINST 3568 stmia r9, {r0-r1} @ vAA<- r0/r1 3569 GOTO_OPCODE(ip) @ jump to next instruction 3570 /* 12-13 instructions */ 3571 3572 3573/* ------------------------------ */ 3574 .balign 64 3575.L_OP_NEG_FLOAT: /* 0x7f */ 3576/* File: armv5te/OP_NEG_FLOAT.S */ 3577/* File: armv5te/unop.S */ 3578 /* 3579 * Generic 32-bit unary operation. Provide an "instr" line that 3580 * specifies an instruction that performs "result = op r0". 3581 * This could be an ARM instruction or a function call. 3582 * 3583 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3584 * int-to-byte, int-to-char, int-to-short 3585 */ 3586 /* unop vA, vB */ 3587 mov r3, rINST, lsr #12 @ r3<- B 3588 mov r9, rINST, lsr #8 @ r9<- A+ 3589 GET_VREG(r0, r3) @ r0<- vB 3590 and r9, r9, #15 3591 @ optional op; may set condition codes 3592 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3593 add r0, r0, #0x80000000 @ r0<- op, r0-r3 changed 3594 GET_INST_OPCODE(ip) @ extract opcode from rINST 3595 SET_VREG(r0, r9) @ vAA<- r0 3596 GOTO_OPCODE(ip) @ jump to next instruction 3597 /* 9-10 instructions */ 3598 3599 3600/* ------------------------------ */ 3601 .balign 64 3602.L_OP_NEG_DOUBLE: /* 0x80 */ 3603/* File: armv5te/OP_NEG_DOUBLE.S */ 3604/* File: armv5te/unopWide.S */ 3605 /* 3606 * Generic 64-bit unary operation. Provide an "instr" line that 3607 * specifies an instruction that performs "result = op r0/r1". 3608 * This could be an ARM instruction or a function call. 3609 * 3610 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3611 */ 3612 /* unop vA, vB */ 3613 mov r9, rINST, lsr #8 @ r9<- A+ 3614 mov r3, rINST, lsr #12 @ r3<- B 3615 and r9, r9, #15 3616 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3617 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3618 ldmia r3, {r0-r1} @ r0/r1<- vAA 3619 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3620 @ optional op; may set condition codes 3621 add r1, r1, #0x80000000 @ r0/r1<- op, r2-r3 changed 3622 GET_INST_OPCODE(ip) @ extract opcode from rINST 3623 stmia r9, {r0-r1} @ vAA<- r0/r1 3624 GOTO_OPCODE(ip) @ jump to next instruction 3625 /* 12-13 instructions */ 3626 3627 3628/* ------------------------------ */ 3629 .balign 64 3630.L_OP_INT_TO_LONG: /* 0x81 */ 3631/* File: armv5te/OP_INT_TO_LONG.S */ 3632/* File: armv5te/unopWider.S */ 3633 /* 3634 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3635 * that specifies an instruction that performs "result = op r0", where 3636 * "result" is a 64-bit quantity in r0/r1. 3637 * 3638 * For: int-to-long, int-to-double, float-to-long, float-to-double 3639 */ 3640 /* unop vA, vB */ 3641 mov r9, rINST, lsr #8 @ r9<- A+ 3642 mov r3, rINST, lsr #12 @ r3<- B 3643 and r9, r9, #15 3644 GET_VREG(r0, r3) @ r0<- vB 3645 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3646 @ optional op; may set condition codes 3647 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3648 mov r1, r0, asr #31 @ r0<- op, r0-r3 changed 3649 GET_INST_OPCODE(ip) @ extract opcode from rINST 3650 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3651 GOTO_OPCODE(ip) @ jump to next instruction 3652 /* 10-11 instructions */ 3653 3654 3655/* ------------------------------ */ 3656 .balign 64 3657.L_OP_INT_TO_FLOAT: /* 0x82 */ 3658/* File: arm-vfp/OP_INT_TO_FLOAT.S */ 3659/* File: arm-vfp/funop.S */ 3660 /* 3661 * Generic 32-bit unary floating-point operation. Provide an "instr" 3662 * line that specifies an instruction that performs "s1 = op s0". 3663 * 3664 * for: int-to-float, float-to-int 3665 */ 3666 /* unop vA, vB */ 3667 mov r3, rINST, lsr #12 @ r3<- B 3668 mov r9, rINST, lsr #8 @ r9<- A+ 3669 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3670 flds s0, [r3] @ s0<- vB 3671 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3672 and r9, r9, #15 @ r9<- A 3673 fsitos s1, s0 @ s1<- op 3674 GET_INST_OPCODE(ip) @ extract opcode from rINST 3675 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3676 fsts s1, [r9] @ vA<- s1 3677 GOTO_OPCODE(ip) @ jump to next instruction 3678 3679 3680/* ------------------------------ */ 3681 .balign 64 3682.L_OP_INT_TO_DOUBLE: /* 0x83 */ 3683/* File: arm-vfp/OP_INT_TO_DOUBLE.S */ 3684/* File: arm-vfp/funopWider.S */ 3685 /* 3686 * Generic 32bit-to-64bit floating point unary operation. Provide an 3687 * "instr" line that specifies an instruction that performs "d0 = op s0". 3688 * 3689 * For: int-to-double, float-to-double 3690 */ 3691 /* unop vA, vB */ 3692 mov r3, rINST, lsr #12 @ r3<- B 3693 mov r9, rINST, lsr #8 @ r9<- A+ 3694 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3695 flds s0, [r3] @ s0<- vB 3696 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3697 and r9, r9, #15 @ r9<- A 3698 fsitod d0, s0 @ d0<- op 3699 GET_INST_OPCODE(ip) @ extract opcode from rINST 3700 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3701 fstd d0, [r9] @ vA<- d0 3702 GOTO_OPCODE(ip) @ jump to next instruction 3703 3704 3705/* ------------------------------ */ 3706 .balign 64 3707.L_OP_LONG_TO_INT: /* 0x84 */ 3708/* File: armv5te/OP_LONG_TO_INT.S */ 3709/* we ignore the high word, making this equivalent to a 32-bit reg move */ 3710/* File: armv5te/OP_MOVE.S */ 3711 /* for move, move-object, long-to-int */ 3712 /* op vA, vB */ 3713 mov r1, rINST, lsr #12 @ r1<- B from 15:12 3714 mov r0, rINST, lsr #8 @ r0<- A from 11:8 3715 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3716 GET_VREG(r2, r1) @ r2<- fp[B] 3717 and r0, r0, #15 3718 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 3719 SET_VREG(r2, r0) @ fp[A]<- r2 3720 GOTO_OPCODE(ip) @ execute next instruction 3721 3722 3723/* ------------------------------ */ 3724 .balign 64 3725.L_OP_LONG_TO_FLOAT: /* 0x85 */ 3726/* File: armv5te/OP_LONG_TO_FLOAT.S */ 3727/* File: armv5te/unopNarrower.S */ 3728 /* 3729 * Generic 64bit-to-32bit unary operation. Provide an "instr" line 3730 * that specifies an instruction that performs "result = op r0/r1", where 3731 * "result" is a 32-bit quantity in r0. 3732 * 3733 * For: long-to-float, double-to-int, double-to-float 3734 * 3735 * (This would work for long-to-int, but that instruction is actually 3736 * an exact match for OP_MOVE.) 3737 */ 3738 /* unop vA, vB */ 3739 mov r3, rINST, lsr #12 @ r3<- B 3740 mov r9, rINST, lsr #8 @ r9<- A+ 3741 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3742 and r9, r9, #15 3743 ldmia r3, {r0-r1} @ r0/r1<- vB/vB+1 3744 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3745 @ optional op; may set condition codes 3746 bl __aeabi_l2f @ r0<- op, r0-r3 changed 3747 GET_INST_OPCODE(ip) @ extract opcode from rINST 3748 SET_VREG(r0, r9) @ vA<- r0 3749 GOTO_OPCODE(ip) @ jump to next instruction 3750 /* 10-11 instructions */ 3751 3752 3753/* ------------------------------ */ 3754 .balign 64 3755.L_OP_LONG_TO_DOUBLE: /* 0x86 */ 3756/* File: armv5te/OP_LONG_TO_DOUBLE.S */ 3757/* File: armv5te/unopWide.S */ 3758 /* 3759 * Generic 64-bit unary operation. Provide an "instr" line that 3760 * specifies an instruction that performs "result = op r0/r1". 3761 * This could be an ARM instruction or a function call. 3762 * 3763 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3764 */ 3765 /* unop vA, vB */ 3766 mov r9, rINST, lsr #8 @ r9<- A+ 3767 mov r3, rINST, lsr #12 @ r3<- B 3768 and r9, r9, #15 3769 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3770 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3771 ldmia r3, {r0-r1} @ r0/r1<- vAA 3772 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3773 @ optional op; may set condition codes 3774 bl __aeabi_l2d @ r0/r1<- op, r2-r3 changed 3775 GET_INST_OPCODE(ip) @ extract opcode from rINST 3776 stmia r9, {r0-r1} @ vAA<- r0/r1 3777 GOTO_OPCODE(ip) @ jump to next instruction 3778 /* 12-13 instructions */ 3779 3780 3781/* ------------------------------ */ 3782 .balign 64 3783.L_OP_FLOAT_TO_INT: /* 0x87 */ 3784/* File: arm-vfp/OP_FLOAT_TO_INT.S */ 3785/* File: arm-vfp/funop.S */ 3786 /* 3787 * Generic 32-bit unary floating-point operation. Provide an "instr" 3788 * line that specifies an instruction that performs "s1 = op s0". 3789 * 3790 * for: int-to-float, float-to-int 3791 */ 3792 /* unop vA, vB */ 3793 mov r3, rINST, lsr #12 @ r3<- B 3794 mov r9, rINST, lsr #8 @ r9<- A+ 3795 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3796 flds s0, [r3] @ s0<- vB 3797 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3798 and r9, r9, #15 @ r9<- A 3799 ftosizs s1, s0 @ s1<- op 3800 GET_INST_OPCODE(ip) @ extract opcode from rINST 3801 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3802 fsts s1, [r9] @ vA<- s1 3803 GOTO_OPCODE(ip) @ jump to next instruction 3804 3805 3806/* ------------------------------ */ 3807 .balign 64 3808.L_OP_FLOAT_TO_LONG: /* 0x88 */ 3809/* File: armv5te/OP_FLOAT_TO_LONG.S */ 3810@include "armv5te/unopWider.S" {"instr":"bl __aeabi_f2lz"} 3811/* File: armv5te/unopWider.S */ 3812 /* 3813 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3814 * that specifies an instruction that performs "result = op r0", where 3815 * "result" is a 64-bit quantity in r0/r1. 3816 * 3817 * For: int-to-long, int-to-double, float-to-long, float-to-double 3818 */ 3819 /* unop vA, vB */ 3820 mov r9, rINST, lsr #8 @ r9<- A+ 3821 mov r3, rINST, lsr #12 @ r3<- B 3822 and r9, r9, #15 3823 GET_VREG(r0, r3) @ r0<- vB 3824 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3825 @ optional op; may set condition codes 3826 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3827 bl f2l_doconv @ r0<- op, r0-r3 changed 3828 GET_INST_OPCODE(ip) @ extract opcode from rINST 3829 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3830 GOTO_OPCODE(ip) @ jump to next instruction 3831 /* 10-11 instructions */ 3832 3833 3834 3835/* ------------------------------ */ 3836 .balign 64 3837.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */ 3838/* File: arm-vfp/OP_FLOAT_TO_DOUBLE.S */ 3839/* File: arm-vfp/funopWider.S */ 3840 /* 3841 * Generic 32bit-to-64bit floating point unary operation. Provide an 3842 * "instr" line that specifies an instruction that performs "d0 = op s0". 3843 * 3844 * For: int-to-double, float-to-double 3845 */ 3846 /* unop vA, vB */ 3847 mov r3, rINST, lsr #12 @ r3<- B 3848 mov r9, rINST, lsr #8 @ r9<- A+ 3849 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3850 flds s0, [r3] @ s0<- vB 3851 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3852 and r9, r9, #15 @ r9<- A 3853 fcvtds d0, s0 @ d0<- op 3854 GET_INST_OPCODE(ip) @ extract opcode from rINST 3855 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3856 fstd d0, [r9] @ vA<- d0 3857 GOTO_OPCODE(ip) @ jump to next instruction 3858 3859 3860/* ------------------------------ */ 3861 .balign 64 3862.L_OP_DOUBLE_TO_INT: /* 0x8a */ 3863/* File: arm-vfp/OP_DOUBLE_TO_INT.S */ 3864/* File: arm-vfp/funopNarrower.S */ 3865 /* 3866 * Generic 64bit-to-32bit unary floating point operation. Provide an 3867 * "instr" line that specifies an instruction that performs "s0 = op d0". 3868 * 3869 * For: double-to-int, double-to-float 3870 */ 3871 /* unop vA, vB */ 3872 mov r3, rINST, lsr #12 @ r3<- B 3873 mov r9, rINST, lsr #8 @ r9<- A+ 3874 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3875 fldd d0, [r3] @ d0<- vB 3876 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3877 and r9, r9, #15 @ r9<- A 3878 ftosizd s0, d0 @ s0<- op 3879 GET_INST_OPCODE(ip) @ extract opcode from rINST 3880 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3881 fsts s0, [r9] @ vA<- s0 3882 GOTO_OPCODE(ip) @ jump to next instruction 3883 3884 3885/* ------------------------------ */ 3886 .balign 64 3887.L_OP_DOUBLE_TO_LONG: /* 0x8b */ 3888/* File: armv5te/OP_DOUBLE_TO_LONG.S */ 3889@include "armv5te/unopWide.S" {"instr":"bl __aeabi_d2lz"} 3890/* File: armv5te/unopWide.S */ 3891 /* 3892 * Generic 64-bit unary operation. Provide an "instr" line that 3893 * specifies an instruction that performs "result = op r0/r1". 3894 * This could be an ARM instruction or a function call. 3895 * 3896 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3897 */ 3898 /* unop vA, vB */ 3899 mov r9, rINST, lsr #8 @ r9<- A+ 3900 mov r3, rINST, lsr #12 @ r3<- B 3901 and r9, r9, #15 3902 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3903 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3904 ldmia r3, {r0-r1} @ r0/r1<- vAA 3905 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3906 @ optional op; may set condition codes 3907 bl d2l_doconv @ r0/r1<- op, r2-r3 changed 3908 GET_INST_OPCODE(ip) @ extract opcode from rINST 3909 stmia r9, {r0-r1} @ vAA<- r0/r1 3910 GOTO_OPCODE(ip) @ jump to next instruction 3911 /* 12-13 instructions */ 3912 3913 3914 3915/* ------------------------------ */ 3916 .balign 64 3917.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */ 3918/* File: arm-vfp/OP_DOUBLE_TO_FLOAT.S */ 3919/* File: arm-vfp/funopNarrower.S */ 3920 /* 3921 * Generic 64bit-to-32bit unary floating point operation. Provide an 3922 * "instr" line that specifies an instruction that performs "s0 = op d0". 3923 * 3924 * For: double-to-int, double-to-float 3925 */ 3926 /* unop vA, vB */ 3927 mov r3, rINST, lsr #12 @ r3<- B 3928 mov r9, rINST, lsr #8 @ r9<- A+ 3929 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3930 fldd d0, [r3] @ d0<- vB 3931 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3932 and r9, r9, #15 @ r9<- A 3933 fcvtsd s0, d0 @ s0<- op 3934 GET_INST_OPCODE(ip) @ extract opcode from rINST 3935 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3936 fsts s0, [r9] @ vA<- s0 3937 GOTO_OPCODE(ip) @ jump to next instruction 3938 3939 3940/* ------------------------------ */ 3941 .balign 64 3942.L_OP_INT_TO_BYTE: /* 0x8d */ 3943/* File: armv5te/OP_INT_TO_BYTE.S */ 3944/* File: armv5te/unop.S */ 3945 /* 3946 * Generic 32-bit unary operation. Provide an "instr" line that 3947 * specifies an instruction that performs "result = op r0". 3948 * This could be an ARM instruction or a function call. 3949 * 3950 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3951 * int-to-byte, int-to-char, int-to-short 3952 */ 3953 /* unop vA, vB */ 3954 mov r3, rINST, lsr #12 @ r3<- B 3955 mov r9, rINST, lsr #8 @ r9<- A+ 3956 GET_VREG(r0, r3) @ r0<- vB 3957 and r9, r9, #15 3958 mov r0, r0, asl #24 @ optional op; may set condition codes 3959 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3960 mov r0, r0, asr #24 @ r0<- op, r0-r3 changed 3961 GET_INST_OPCODE(ip) @ extract opcode from rINST 3962 SET_VREG(r0, r9) @ vAA<- r0 3963 GOTO_OPCODE(ip) @ jump to next instruction 3964 /* 9-10 instructions */ 3965 3966 3967/* ------------------------------ */ 3968 .balign 64 3969.L_OP_INT_TO_CHAR: /* 0x8e */ 3970/* File: armv5te/OP_INT_TO_CHAR.S */ 3971/* File: armv5te/unop.S */ 3972 /* 3973 * Generic 32-bit unary operation. Provide an "instr" line that 3974 * specifies an instruction that performs "result = op r0". 3975 * This could be an ARM instruction or a function call. 3976 * 3977 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3978 * int-to-byte, int-to-char, int-to-short 3979 */ 3980 /* unop vA, vB */ 3981 mov r3, rINST, lsr #12 @ r3<- B 3982 mov r9, rINST, lsr #8 @ r9<- A+ 3983 GET_VREG(r0, r3) @ r0<- vB 3984 and r9, r9, #15 3985 mov r0, r0, asl #16 @ optional op; may set condition codes 3986 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3987 mov r0, r0, lsr #16 @ r0<- op, r0-r3 changed 3988 GET_INST_OPCODE(ip) @ extract opcode from rINST 3989 SET_VREG(r0, r9) @ vAA<- r0 3990 GOTO_OPCODE(ip) @ jump to next instruction 3991 /* 9-10 instructions */ 3992 3993 3994/* ------------------------------ */ 3995 .balign 64 3996.L_OP_INT_TO_SHORT: /* 0x8f */ 3997/* File: armv5te/OP_INT_TO_SHORT.S */ 3998/* File: armv5te/unop.S */ 3999 /* 4000 * Generic 32-bit unary operation. Provide an "instr" line that 4001 * specifies an instruction that performs "result = op r0". 4002 * This could be an ARM instruction or a function call. 4003 * 4004 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 4005 * int-to-byte, int-to-char, int-to-short 4006 */ 4007 /* unop vA, vB */ 4008 mov r3, rINST, lsr #12 @ r3<- B 4009 mov r9, rINST, lsr #8 @ r9<- A+ 4010 GET_VREG(r0, r3) @ r0<- vB 4011 and r9, r9, #15 4012 mov r0, r0, asl #16 @ optional op; may set condition codes 4013 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 4014 mov r0, r0, asr #16 @ r0<- op, r0-r3 changed 4015 GET_INST_OPCODE(ip) @ extract opcode from rINST 4016 SET_VREG(r0, r9) @ vAA<- r0 4017 GOTO_OPCODE(ip) @ jump to next instruction 4018 /* 9-10 instructions */ 4019 4020 4021/* ------------------------------ */ 4022 .balign 64 4023.L_OP_ADD_INT: /* 0x90 */ 4024/* File: armv5te/OP_ADD_INT.S */ 4025/* File: armv5te/binop.S */ 4026 /* 4027 * Generic 32-bit binary operation. Provide an "instr" line that 4028 * specifies an instruction that performs "result = r0 op r1". 4029 * This could be an ARM instruction or a function call. (If the result 4030 * comes back in a register other than r0, you can override "result".) 4031 * 4032 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4033 * vCC (r1). Useful for integer division and modulus. Note that we 4034 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4035 * handles it correctly. 4036 * 4037 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4038 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4039 * mul-float, div-float, rem-float 4040 */ 4041 /* binop vAA, vBB, vCC */ 4042 FETCH(r0, 1) @ r0<- CCBB 4043 mov r9, rINST, lsr #8 @ r9<- AA 4044 mov r3, r0, lsr #8 @ r3<- CC 4045 and r2, r0, #255 @ r2<- BB 4046 GET_VREG(r1, r3) @ r1<- vCC 4047 GET_VREG(r0, r2) @ r0<- vBB 4048 .if 0 4049 cmp r1, #0 @ is second operand zero? 4050 beq common_errDivideByZero 4051 .endif 4052 4053 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4054 @ optional op; may set condition codes 4055 add r0, r0, r1 @ r0<- op, r0-r3 changed 4056 GET_INST_OPCODE(ip) @ extract opcode from rINST 4057 SET_VREG(r0, r9) @ vAA<- r0 4058 GOTO_OPCODE(ip) @ jump to next instruction 4059 /* 11-14 instructions */ 4060 4061 4062/* ------------------------------ */ 4063 .balign 64 4064.L_OP_SUB_INT: /* 0x91 */ 4065/* File: armv5te/OP_SUB_INT.S */ 4066/* File: armv5te/binop.S */ 4067 /* 4068 * Generic 32-bit binary operation. Provide an "instr" line that 4069 * specifies an instruction that performs "result = r0 op r1". 4070 * This could be an ARM instruction or a function call. (If the result 4071 * comes back in a register other than r0, you can override "result".) 4072 * 4073 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4074 * vCC (r1). Useful for integer division and modulus. Note that we 4075 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4076 * handles it correctly. 4077 * 4078 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4079 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4080 * mul-float, div-float, rem-float 4081 */ 4082 /* binop vAA, vBB, vCC */ 4083 FETCH(r0, 1) @ r0<- CCBB 4084 mov r9, rINST, lsr #8 @ r9<- AA 4085 mov r3, r0, lsr #8 @ r3<- CC 4086 and r2, r0, #255 @ r2<- BB 4087 GET_VREG(r1, r3) @ r1<- vCC 4088 GET_VREG(r0, r2) @ r0<- vBB 4089 .if 0 4090 cmp r1, #0 @ is second operand zero? 4091 beq common_errDivideByZero 4092 .endif 4093 4094 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4095 @ optional op; may set condition codes 4096 sub r0, r0, r1 @ r0<- op, r0-r3 changed 4097 GET_INST_OPCODE(ip) @ extract opcode from rINST 4098 SET_VREG(r0, r9) @ vAA<- r0 4099 GOTO_OPCODE(ip) @ jump to next instruction 4100 /* 11-14 instructions */ 4101 4102 4103/* ------------------------------ */ 4104 .balign 64 4105.L_OP_MUL_INT: /* 0x92 */ 4106/* File: armv5te/OP_MUL_INT.S */ 4107/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 4108/* File: armv5te/binop.S */ 4109 /* 4110 * Generic 32-bit binary operation. Provide an "instr" line that 4111 * specifies an instruction that performs "result = r0 op r1". 4112 * This could be an ARM instruction or a function call. (If the result 4113 * comes back in a register other than r0, you can override "result".) 4114 * 4115 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4116 * vCC (r1). Useful for integer division and modulus. Note that we 4117 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4118 * handles it correctly. 4119 * 4120 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4121 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4122 * mul-float, div-float, rem-float 4123 */ 4124 /* binop vAA, vBB, vCC */ 4125 FETCH(r0, 1) @ r0<- CCBB 4126 mov r9, rINST, lsr #8 @ r9<- AA 4127 mov r3, r0, lsr #8 @ r3<- CC 4128 and r2, r0, #255 @ r2<- BB 4129 GET_VREG(r1, r3) @ r1<- vCC 4130 GET_VREG(r0, r2) @ r0<- vBB 4131 .if 0 4132 cmp r1, #0 @ is second operand zero? 4133 beq common_errDivideByZero 4134 .endif 4135 4136 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4137 @ optional op; may set condition codes 4138 mul r0, r1, r0 @ r0<- op, r0-r3 changed 4139 GET_INST_OPCODE(ip) @ extract opcode from rINST 4140 SET_VREG(r0, r9) @ vAA<- r0 4141 GOTO_OPCODE(ip) @ jump to next instruction 4142 /* 11-14 instructions */ 4143 4144 4145/* ------------------------------ */ 4146 .balign 64 4147.L_OP_DIV_INT: /* 0x93 */ 4148/* File: armv5te/OP_DIV_INT.S */ 4149/* File: armv5te/binop.S */ 4150 /* 4151 * Generic 32-bit binary operation. Provide an "instr" line that 4152 * specifies an instruction that performs "result = r0 op r1". 4153 * This could be an ARM instruction or a function call. (If the result 4154 * comes back in a register other than r0, you can override "result".) 4155 * 4156 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4157 * vCC (r1). Useful for integer division and modulus. Note that we 4158 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4159 * handles it correctly. 4160 * 4161 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4162 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4163 * mul-float, div-float, rem-float 4164 */ 4165 /* binop vAA, vBB, vCC */ 4166 FETCH(r0, 1) @ r0<- CCBB 4167 mov r9, rINST, lsr #8 @ r9<- AA 4168 mov r3, r0, lsr #8 @ r3<- CC 4169 and r2, r0, #255 @ r2<- BB 4170 GET_VREG(r1, r3) @ r1<- vCC 4171 GET_VREG(r0, r2) @ r0<- vBB 4172 .if 1 4173 cmp r1, #0 @ is second operand zero? 4174 beq common_errDivideByZero 4175 .endif 4176 4177 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4178 @ optional op; may set condition codes 4179 bl __aeabi_idiv @ r0<- op, r0-r3 changed 4180 GET_INST_OPCODE(ip) @ extract opcode from rINST 4181 SET_VREG(r0, r9) @ vAA<- r0 4182 GOTO_OPCODE(ip) @ jump to next instruction 4183 /* 11-14 instructions */ 4184 4185 4186/* ------------------------------ */ 4187 .balign 64 4188.L_OP_REM_INT: /* 0x94 */ 4189/* File: armv5te/OP_REM_INT.S */ 4190/* idivmod returns quotient in r0 and remainder in r1 */ 4191/* File: armv5te/binop.S */ 4192 /* 4193 * Generic 32-bit binary operation. Provide an "instr" line that 4194 * specifies an instruction that performs "result = r0 op r1". 4195 * This could be an ARM instruction or a function call. (If the result 4196 * comes back in a register other than r0, you can override "result".) 4197 * 4198 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4199 * vCC (r1). Useful for integer division and modulus. Note that we 4200 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4201 * handles it correctly. 4202 * 4203 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4204 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4205 * mul-float, div-float, rem-float 4206 */ 4207 /* binop vAA, vBB, vCC */ 4208 FETCH(r0, 1) @ r0<- CCBB 4209 mov r9, rINST, lsr #8 @ r9<- AA 4210 mov r3, r0, lsr #8 @ r3<- CC 4211 and r2, r0, #255 @ r2<- BB 4212 GET_VREG(r1, r3) @ r1<- vCC 4213 GET_VREG(r0, r2) @ r0<- vBB 4214 .if 1 4215 cmp r1, #0 @ is second operand zero? 4216 beq common_errDivideByZero 4217 .endif 4218 4219 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4220 @ optional op; may set condition codes 4221 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 4222 GET_INST_OPCODE(ip) @ extract opcode from rINST 4223 SET_VREG(r1, r9) @ vAA<- r1 4224 GOTO_OPCODE(ip) @ jump to next instruction 4225 /* 11-14 instructions */ 4226 4227 4228/* ------------------------------ */ 4229 .balign 64 4230.L_OP_AND_INT: /* 0x95 */ 4231/* File: armv5te/OP_AND_INT.S */ 4232/* File: armv5te/binop.S */ 4233 /* 4234 * Generic 32-bit binary operation. Provide an "instr" line that 4235 * specifies an instruction that performs "result = r0 op r1". 4236 * This could be an ARM instruction or a function call. (If the result 4237 * comes back in a register other than r0, you can override "result".) 4238 * 4239 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4240 * vCC (r1). Useful for integer division and modulus. Note that we 4241 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4242 * handles it correctly. 4243 * 4244 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4245 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4246 * mul-float, div-float, rem-float 4247 */ 4248 /* binop vAA, vBB, vCC */ 4249 FETCH(r0, 1) @ r0<- CCBB 4250 mov r9, rINST, lsr #8 @ r9<- AA 4251 mov r3, r0, lsr #8 @ r3<- CC 4252 and r2, r0, #255 @ r2<- BB 4253 GET_VREG(r1, r3) @ r1<- vCC 4254 GET_VREG(r0, r2) @ r0<- vBB 4255 .if 0 4256 cmp r1, #0 @ is second operand zero? 4257 beq common_errDivideByZero 4258 .endif 4259 4260 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4261 @ optional op; may set condition codes 4262 and r0, r0, r1 @ r0<- op, r0-r3 changed 4263 GET_INST_OPCODE(ip) @ extract opcode from rINST 4264 SET_VREG(r0, r9) @ vAA<- r0 4265 GOTO_OPCODE(ip) @ jump to next instruction 4266 /* 11-14 instructions */ 4267 4268 4269/* ------------------------------ */ 4270 .balign 64 4271.L_OP_OR_INT: /* 0x96 */ 4272/* File: armv5te/OP_OR_INT.S */ 4273/* File: armv5te/binop.S */ 4274 /* 4275 * Generic 32-bit binary operation. Provide an "instr" line that 4276 * specifies an instruction that performs "result = r0 op r1". 4277 * This could be an ARM instruction or a function call. (If the result 4278 * comes back in a register other than r0, you can override "result".) 4279 * 4280 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4281 * vCC (r1). Useful for integer division and modulus. Note that we 4282 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4283 * handles it correctly. 4284 * 4285 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4286 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4287 * mul-float, div-float, rem-float 4288 */ 4289 /* binop vAA, vBB, vCC */ 4290 FETCH(r0, 1) @ r0<- CCBB 4291 mov r9, rINST, lsr #8 @ r9<- AA 4292 mov r3, r0, lsr #8 @ r3<- CC 4293 and r2, r0, #255 @ r2<- BB 4294 GET_VREG(r1, r3) @ r1<- vCC 4295 GET_VREG(r0, r2) @ r0<- vBB 4296 .if 0 4297 cmp r1, #0 @ is second operand zero? 4298 beq common_errDivideByZero 4299 .endif 4300 4301 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4302 @ optional op; may set condition codes 4303 orr r0, r0, r1 @ r0<- op, r0-r3 changed 4304 GET_INST_OPCODE(ip) @ extract opcode from rINST 4305 SET_VREG(r0, r9) @ vAA<- r0 4306 GOTO_OPCODE(ip) @ jump to next instruction 4307 /* 11-14 instructions */ 4308 4309 4310/* ------------------------------ */ 4311 .balign 64 4312.L_OP_XOR_INT: /* 0x97 */ 4313/* File: armv5te/OP_XOR_INT.S */ 4314/* File: armv5te/binop.S */ 4315 /* 4316 * Generic 32-bit binary operation. Provide an "instr" line that 4317 * specifies an instruction that performs "result = r0 op r1". 4318 * This could be an ARM instruction or a function call. (If the result 4319 * comes back in a register other than r0, you can override "result".) 4320 * 4321 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4322 * vCC (r1). Useful for integer division and modulus. Note that we 4323 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4324 * handles it correctly. 4325 * 4326 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4327 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4328 * mul-float, div-float, rem-float 4329 */ 4330 /* binop vAA, vBB, vCC */ 4331 FETCH(r0, 1) @ r0<- CCBB 4332 mov r9, rINST, lsr #8 @ r9<- AA 4333 mov r3, r0, lsr #8 @ r3<- CC 4334 and r2, r0, #255 @ r2<- BB 4335 GET_VREG(r1, r3) @ r1<- vCC 4336 GET_VREG(r0, r2) @ r0<- vBB 4337 .if 0 4338 cmp r1, #0 @ is second operand zero? 4339 beq common_errDivideByZero 4340 .endif 4341 4342 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4343 @ optional op; may set condition codes 4344 eor r0, r0, r1 @ r0<- op, r0-r3 changed 4345 GET_INST_OPCODE(ip) @ extract opcode from rINST 4346 SET_VREG(r0, r9) @ vAA<- r0 4347 GOTO_OPCODE(ip) @ jump to next instruction 4348 /* 11-14 instructions */ 4349 4350 4351/* ------------------------------ */ 4352 .balign 64 4353.L_OP_SHL_INT: /* 0x98 */ 4354/* File: armv5te/OP_SHL_INT.S */ 4355/* File: armv5te/binop.S */ 4356 /* 4357 * Generic 32-bit binary operation. Provide an "instr" line that 4358 * specifies an instruction that performs "result = r0 op r1". 4359 * This could be an ARM instruction or a function call. (If the result 4360 * comes back in a register other than r0, you can override "result".) 4361 * 4362 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4363 * vCC (r1). Useful for integer division and modulus. Note that we 4364 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4365 * handles it correctly. 4366 * 4367 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4368 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4369 * mul-float, div-float, rem-float 4370 */ 4371 /* binop vAA, vBB, vCC */ 4372 FETCH(r0, 1) @ r0<- CCBB 4373 mov r9, rINST, lsr #8 @ r9<- AA 4374 mov r3, r0, lsr #8 @ r3<- CC 4375 and r2, r0, #255 @ r2<- BB 4376 GET_VREG(r1, r3) @ r1<- vCC 4377 GET_VREG(r0, r2) @ r0<- vBB 4378 .if 0 4379 cmp r1, #0 @ is second operand zero? 4380 beq common_errDivideByZero 4381 .endif 4382 4383 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4384 and r1, r1, #31 @ optional op; may set condition codes 4385 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 4386 GET_INST_OPCODE(ip) @ extract opcode from rINST 4387 SET_VREG(r0, r9) @ vAA<- r0 4388 GOTO_OPCODE(ip) @ jump to next instruction 4389 /* 11-14 instructions */ 4390 4391 4392/* ------------------------------ */ 4393 .balign 64 4394.L_OP_SHR_INT: /* 0x99 */ 4395/* File: armv5te/OP_SHR_INT.S */ 4396/* File: armv5te/binop.S */ 4397 /* 4398 * Generic 32-bit binary operation. Provide an "instr" line that 4399 * specifies an instruction that performs "result = r0 op r1". 4400 * This could be an ARM instruction or a function call. (If the result 4401 * comes back in a register other than r0, you can override "result".) 4402 * 4403 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4404 * vCC (r1). Useful for integer division and modulus. Note that we 4405 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4406 * handles it correctly. 4407 * 4408 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4409 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4410 * mul-float, div-float, rem-float 4411 */ 4412 /* binop vAA, vBB, vCC */ 4413 FETCH(r0, 1) @ r0<- CCBB 4414 mov r9, rINST, lsr #8 @ r9<- AA 4415 mov r3, r0, lsr #8 @ r3<- CC 4416 and r2, r0, #255 @ r2<- BB 4417 GET_VREG(r1, r3) @ r1<- vCC 4418 GET_VREG(r0, r2) @ r0<- vBB 4419 .if 0 4420 cmp r1, #0 @ is second operand zero? 4421 beq common_errDivideByZero 4422 .endif 4423 4424 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4425 and r1, r1, #31 @ optional op; may set condition codes 4426 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 4427 GET_INST_OPCODE(ip) @ extract opcode from rINST 4428 SET_VREG(r0, r9) @ vAA<- r0 4429 GOTO_OPCODE(ip) @ jump to next instruction 4430 /* 11-14 instructions */ 4431 4432 4433/* ------------------------------ */ 4434 .balign 64 4435.L_OP_USHR_INT: /* 0x9a */ 4436/* File: armv5te/OP_USHR_INT.S */ 4437/* File: armv5te/binop.S */ 4438 /* 4439 * Generic 32-bit binary operation. Provide an "instr" line that 4440 * specifies an instruction that performs "result = r0 op r1". 4441 * This could be an ARM instruction or a function call. (If the result 4442 * comes back in a register other than r0, you can override "result".) 4443 * 4444 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4445 * vCC (r1). Useful for integer division and modulus. Note that we 4446 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4447 * handles it correctly. 4448 * 4449 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4450 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4451 * mul-float, div-float, rem-float 4452 */ 4453 /* binop vAA, vBB, vCC */ 4454 FETCH(r0, 1) @ r0<- CCBB 4455 mov r9, rINST, lsr #8 @ r9<- AA 4456 mov r3, r0, lsr #8 @ r3<- CC 4457 and r2, r0, #255 @ r2<- BB 4458 GET_VREG(r1, r3) @ r1<- vCC 4459 GET_VREG(r0, r2) @ r0<- vBB 4460 .if 0 4461 cmp r1, #0 @ is second operand zero? 4462 beq common_errDivideByZero 4463 .endif 4464 4465 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4466 and r1, r1, #31 @ optional op; may set condition codes 4467 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 4468 GET_INST_OPCODE(ip) @ extract opcode from rINST 4469 SET_VREG(r0, r9) @ vAA<- r0 4470 GOTO_OPCODE(ip) @ jump to next instruction 4471 /* 11-14 instructions */ 4472 4473 4474/* ------------------------------ */ 4475 .balign 64 4476.L_OP_ADD_LONG: /* 0x9b */ 4477/* File: armv5te/OP_ADD_LONG.S */ 4478/* File: armv5te/binopWide.S */ 4479 /* 4480 * Generic 64-bit binary operation. Provide an "instr" line that 4481 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4482 * This could be an ARM instruction or a function call. (If the result 4483 * comes back in a register other than r0, you can override "result".) 4484 * 4485 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4486 * vCC (r1). Useful for integer division and modulus. 4487 * 4488 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4489 * xor-long, add-double, sub-double, mul-double, div-double, 4490 * rem-double 4491 * 4492 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4493 */ 4494 /* binop vAA, vBB, vCC */ 4495 FETCH(r0, 1) @ r0<- CCBB 4496 mov r9, rINST, lsr #8 @ r9<- AA 4497 and r2, r0, #255 @ r2<- BB 4498 mov r3, r0, lsr #8 @ r3<- CC 4499 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4500 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4501 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4502 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4503 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4504 .if 0 4505 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4506 beq common_errDivideByZero 4507 .endif 4508 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4509 4510 adds r0, r0, r2 @ optional op; may set condition codes 4511 adc r1, r1, r3 @ result<- op, r0-r3 changed 4512 GET_INST_OPCODE(ip) @ extract opcode from rINST 4513 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4514 GOTO_OPCODE(ip) @ jump to next instruction 4515 /* 14-17 instructions */ 4516 4517 4518/* ------------------------------ */ 4519 .balign 64 4520.L_OP_SUB_LONG: /* 0x9c */ 4521/* File: armv5te/OP_SUB_LONG.S */ 4522/* File: armv5te/binopWide.S */ 4523 /* 4524 * Generic 64-bit binary operation. Provide an "instr" line that 4525 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4526 * This could be an ARM instruction or a function call. (If the result 4527 * comes back in a register other than r0, you can override "result".) 4528 * 4529 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4530 * vCC (r1). Useful for integer division and modulus. 4531 * 4532 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4533 * xor-long, add-double, sub-double, mul-double, div-double, 4534 * rem-double 4535 * 4536 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4537 */ 4538 /* binop vAA, vBB, vCC */ 4539 FETCH(r0, 1) @ r0<- CCBB 4540 mov r9, rINST, lsr #8 @ r9<- AA 4541 and r2, r0, #255 @ r2<- BB 4542 mov r3, r0, lsr #8 @ r3<- CC 4543 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4544 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4545 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4546 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4547 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4548 .if 0 4549 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4550 beq common_errDivideByZero 4551 .endif 4552 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4553 4554 subs r0, r0, r2 @ optional op; may set condition codes 4555 sbc r1, r1, r3 @ result<- op, r0-r3 changed 4556 GET_INST_OPCODE(ip) @ extract opcode from rINST 4557 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4558 GOTO_OPCODE(ip) @ jump to next instruction 4559 /* 14-17 instructions */ 4560 4561 4562/* ------------------------------ */ 4563 .balign 64 4564.L_OP_MUL_LONG: /* 0x9d */ 4565/* File: armv5te/OP_MUL_LONG.S */ 4566 /* 4567 * Signed 64-bit integer multiply. 4568 * 4569 * Consider WXxYZ (r1r0 x r3r2) with a long multiply: 4570 * WX 4571 * x YZ 4572 * -------- 4573 * ZW ZX 4574 * YW YX 4575 * 4576 * The low word of the result holds ZX, the high word holds 4577 * (ZW+YX) + (the high overflow from ZX). YW doesn't matter because 4578 * it doesn't fit in the low 64 bits. 4579 * 4580 * Unlike most ARM math operations, multiply instructions have 4581 * restrictions on using the same register more than once (Rd and Rm 4582 * cannot be the same). 4583 */ 4584 /* mul-long vAA, vBB, vCC */ 4585 FETCH(r0, 1) @ r0<- CCBB 4586 and r2, r0, #255 @ r2<- BB 4587 mov r3, r0, lsr #8 @ r3<- CC 4588 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4589 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4590 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4591 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4592 mul ip, r2, r1 @ ip<- ZxW 4593 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 4594 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 4595 mov r0, rINST, lsr #8 @ r0<- AA 4596 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 4597 add r0, rFP, r0, lsl #2 @ r0<- &fp[AA] 4598 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4599 b .LOP_MUL_LONG_finish 4600 4601/* ------------------------------ */ 4602 .balign 64 4603.L_OP_DIV_LONG: /* 0x9e */ 4604/* File: armv5te/OP_DIV_LONG.S */ 4605/* File: armv5te/binopWide.S */ 4606 /* 4607 * Generic 64-bit binary operation. Provide an "instr" line that 4608 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4609 * This could be an ARM instruction or a function call. (If the result 4610 * comes back in a register other than r0, you can override "result".) 4611 * 4612 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4613 * vCC (r1). Useful for integer division and modulus. 4614 * 4615 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4616 * xor-long, add-double, sub-double, mul-double, div-double, 4617 * rem-double 4618 * 4619 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4620 */ 4621 /* binop vAA, vBB, vCC */ 4622 FETCH(r0, 1) @ r0<- CCBB 4623 mov r9, rINST, lsr #8 @ r9<- AA 4624 and r2, r0, #255 @ r2<- BB 4625 mov r3, r0, lsr #8 @ r3<- CC 4626 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4627 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4628 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4629 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4630 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4631 .if 1 4632 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4633 beq common_errDivideByZero 4634 .endif 4635 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4636 4637 @ optional op; may set condition codes 4638 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4639 GET_INST_OPCODE(ip) @ extract opcode from rINST 4640 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4641 GOTO_OPCODE(ip) @ jump to next instruction 4642 /* 14-17 instructions */ 4643 4644 4645/* ------------------------------ */ 4646 .balign 64 4647.L_OP_REM_LONG: /* 0x9f */ 4648/* File: armv5te/OP_REM_LONG.S */ 4649/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 4650/* File: armv5te/binopWide.S */ 4651 /* 4652 * Generic 64-bit binary operation. Provide an "instr" line that 4653 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4654 * This could be an ARM instruction or a function call. (If the result 4655 * comes back in a register other than r0, you can override "result".) 4656 * 4657 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4658 * vCC (r1). Useful for integer division and modulus. 4659 * 4660 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4661 * xor-long, add-double, sub-double, mul-double, div-double, 4662 * rem-double 4663 * 4664 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4665 */ 4666 /* binop vAA, vBB, vCC */ 4667 FETCH(r0, 1) @ r0<- CCBB 4668 mov r9, rINST, lsr #8 @ r9<- AA 4669 and r2, r0, #255 @ r2<- BB 4670 mov r3, r0, lsr #8 @ r3<- CC 4671 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4672 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4673 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4674 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4675 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4676 .if 1 4677 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4678 beq common_errDivideByZero 4679 .endif 4680 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4681 4682 @ optional op; may set condition codes 4683 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4684 GET_INST_OPCODE(ip) @ extract opcode from rINST 4685 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 4686 GOTO_OPCODE(ip) @ jump to next instruction 4687 /* 14-17 instructions */ 4688 4689 4690/* ------------------------------ */ 4691 .balign 64 4692.L_OP_AND_LONG: /* 0xa0 */ 4693/* File: armv5te/OP_AND_LONG.S */ 4694/* File: armv5te/binopWide.S */ 4695 /* 4696 * Generic 64-bit binary operation. Provide an "instr" line that 4697 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4698 * This could be an ARM instruction or a function call. (If the result 4699 * comes back in a register other than r0, you can override "result".) 4700 * 4701 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4702 * vCC (r1). Useful for integer division and modulus. 4703 * 4704 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4705 * xor-long, add-double, sub-double, mul-double, div-double, 4706 * rem-double 4707 * 4708 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4709 */ 4710 /* binop vAA, vBB, vCC */ 4711 FETCH(r0, 1) @ r0<- CCBB 4712 mov r9, rINST, lsr #8 @ r9<- AA 4713 and r2, r0, #255 @ r2<- BB 4714 mov r3, r0, lsr #8 @ r3<- CC 4715 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4716 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4717 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4718 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4719 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4720 .if 0 4721 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4722 beq common_errDivideByZero 4723 .endif 4724 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4725 4726 and r0, r0, r2 @ optional op; may set condition codes 4727 and r1, r1, r3 @ result<- op, r0-r3 changed 4728 GET_INST_OPCODE(ip) @ extract opcode from rINST 4729 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4730 GOTO_OPCODE(ip) @ jump to next instruction 4731 /* 14-17 instructions */ 4732 4733 4734/* ------------------------------ */ 4735 .balign 64 4736.L_OP_OR_LONG: /* 0xa1 */ 4737/* File: armv5te/OP_OR_LONG.S */ 4738/* File: armv5te/binopWide.S */ 4739 /* 4740 * Generic 64-bit binary operation. Provide an "instr" line that 4741 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4742 * This could be an ARM instruction or a function call. (If the result 4743 * comes back in a register other than r0, you can override "result".) 4744 * 4745 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4746 * vCC (r1). Useful for integer division and modulus. 4747 * 4748 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4749 * xor-long, add-double, sub-double, mul-double, div-double, 4750 * rem-double 4751 * 4752 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4753 */ 4754 /* binop vAA, vBB, vCC */ 4755 FETCH(r0, 1) @ r0<- CCBB 4756 mov r9, rINST, lsr #8 @ r9<- AA 4757 and r2, r0, #255 @ r2<- BB 4758 mov r3, r0, lsr #8 @ r3<- CC 4759 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4760 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4761 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4762 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4763 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4764 .if 0 4765 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4766 beq common_errDivideByZero 4767 .endif 4768 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4769 4770 orr r0, r0, r2 @ optional op; may set condition codes 4771 orr r1, r1, r3 @ result<- op, r0-r3 changed 4772 GET_INST_OPCODE(ip) @ extract opcode from rINST 4773 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4774 GOTO_OPCODE(ip) @ jump to next instruction 4775 /* 14-17 instructions */ 4776 4777 4778/* ------------------------------ */ 4779 .balign 64 4780.L_OP_XOR_LONG: /* 0xa2 */ 4781/* File: armv5te/OP_XOR_LONG.S */ 4782/* File: armv5te/binopWide.S */ 4783 /* 4784 * Generic 64-bit binary operation. Provide an "instr" line that 4785 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4786 * This could be an ARM instruction or a function call. (If the result 4787 * comes back in a register other than r0, you can override "result".) 4788 * 4789 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4790 * vCC (r1). Useful for integer division and modulus. 4791 * 4792 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4793 * xor-long, add-double, sub-double, mul-double, div-double, 4794 * rem-double 4795 * 4796 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4797 */ 4798 /* binop vAA, vBB, vCC */ 4799 FETCH(r0, 1) @ r0<- CCBB 4800 mov r9, rINST, lsr #8 @ r9<- AA 4801 and r2, r0, #255 @ r2<- BB 4802 mov r3, r0, lsr #8 @ r3<- CC 4803 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4804 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4805 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4806 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4807 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4808 .if 0 4809 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4810 beq common_errDivideByZero 4811 .endif 4812 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4813 4814 eor r0, r0, r2 @ optional op; may set condition codes 4815 eor r1, r1, r3 @ result<- op, r0-r3 changed 4816 GET_INST_OPCODE(ip) @ extract opcode from rINST 4817 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4818 GOTO_OPCODE(ip) @ jump to next instruction 4819 /* 14-17 instructions */ 4820 4821 4822/* ------------------------------ */ 4823 .balign 64 4824.L_OP_SHL_LONG: /* 0xa3 */ 4825/* File: armv5te/OP_SHL_LONG.S */ 4826 /* 4827 * Long integer shift. This is different from the generic 32/64-bit 4828 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4829 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4830 * 6 bits of the shift distance. 4831 */ 4832 /* shl-long vAA, vBB, vCC */ 4833 FETCH(r0, 1) @ r0<- CCBB 4834 mov r9, rINST, lsr #8 @ r9<- AA 4835 and r3, r0, #255 @ r3<- BB 4836 mov r0, r0, lsr #8 @ r0<- CC 4837 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4838 GET_VREG(r2, r0) @ r2<- vCC 4839 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4840 and r2, r2, #63 @ r2<- r2 & 0x3f 4841 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4842 4843 mov r1, r1, asl r2 @ r1<- r1 << r2 4844 rsb r3, r2, #32 @ r3<- 32 - r2 4845 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 4846 subs ip, r2, #32 @ ip<- r2 - 32 4847 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 4848 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4849 b .LOP_SHL_LONG_finish 4850 4851/* ------------------------------ */ 4852 .balign 64 4853.L_OP_SHR_LONG: /* 0xa4 */ 4854/* File: armv5te/OP_SHR_LONG.S */ 4855 /* 4856 * Long integer shift. This is different from the generic 32/64-bit 4857 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4858 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4859 * 6 bits of the shift distance. 4860 */ 4861 /* shr-long vAA, vBB, vCC */ 4862 FETCH(r0, 1) @ r0<- CCBB 4863 mov r9, rINST, lsr #8 @ r9<- AA 4864 and r3, r0, #255 @ r3<- BB 4865 mov r0, r0, lsr #8 @ r0<- CC 4866 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4867 GET_VREG(r2, r0) @ r2<- vCC 4868 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4869 and r2, r2, #63 @ r0<- r0 & 0x3f 4870 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4871 4872 mov r0, r0, lsr r2 @ r0<- r2 >> r2 4873 rsb r3, r2, #32 @ r3<- 32 - r2 4874 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 4875 subs ip, r2, #32 @ ip<- r2 - 32 4876 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 4877 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4878 b .LOP_SHR_LONG_finish 4879 4880/* ------------------------------ */ 4881 .balign 64 4882.L_OP_USHR_LONG: /* 0xa5 */ 4883/* File: armv5te/OP_USHR_LONG.S */ 4884 /* 4885 * Long integer shift. This is different from the generic 32/64-bit 4886 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4887 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4888 * 6 bits of the shift distance. 4889 */ 4890 /* ushr-long vAA, vBB, vCC */ 4891 FETCH(r0, 1) @ r0<- CCBB 4892 mov r9, rINST, lsr #8 @ r9<- AA 4893 and r3, r0, #255 @ r3<- BB 4894 mov r0, r0, lsr #8 @ r0<- CC 4895 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4896 GET_VREG(r2, r0) @ r2<- vCC 4897 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4898 and r2, r2, #63 @ r0<- r0 & 0x3f 4899 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4900 4901 mov r0, r0, lsr r2 @ r0<- r2 >> r2 4902 rsb r3, r2, #32 @ r3<- 32 - r2 4903 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 4904 subs ip, r2, #32 @ ip<- r2 - 32 4905 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 4906 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4907 b .LOP_USHR_LONG_finish 4908 4909/* ------------------------------ */ 4910 .balign 64 4911.L_OP_ADD_FLOAT: /* 0xa6 */ 4912/* File: arm-vfp/OP_ADD_FLOAT.S */ 4913/* File: arm-vfp/fbinop.S */ 4914 /* 4915 * Generic 32-bit floating-point operation. Provide an "instr" line that 4916 * specifies an instruction that performs "s2 = s0 op s1". Because we 4917 * use the "softfp" ABI, this must be an instruction, not a function call. 4918 * 4919 * For: add-float, sub-float, mul-float, div-float 4920 */ 4921 /* floatop vAA, vBB, vCC */ 4922 FETCH(r0, 1) @ r0<- CCBB 4923 mov r9, rINST, lsr #8 @ r9<- AA 4924 mov r3, r0, lsr #8 @ r3<- CC 4925 and r2, r0, #255 @ r2<- BB 4926 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4927 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4928 flds s1, [r3] @ s1<- vCC 4929 flds s0, [r2] @ s0<- vBB 4930 4931 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4932 fadds s2, s0, s1 @ s2<- op 4933 GET_INST_OPCODE(ip) @ extract opcode from rINST 4934 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4935 fsts s2, [r9] @ vAA<- s2 4936 GOTO_OPCODE(ip) @ jump to next instruction 4937 4938 4939/* ------------------------------ */ 4940 .balign 64 4941.L_OP_SUB_FLOAT: /* 0xa7 */ 4942/* File: arm-vfp/OP_SUB_FLOAT.S */ 4943/* File: arm-vfp/fbinop.S */ 4944 /* 4945 * Generic 32-bit floating-point operation. Provide an "instr" line that 4946 * specifies an instruction that performs "s2 = s0 op s1". Because we 4947 * use the "softfp" ABI, this must be an instruction, not a function call. 4948 * 4949 * For: add-float, sub-float, mul-float, div-float 4950 */ 4951 /* floatop vAA, vBB, vCC */ 4952 FETCH(r0, 1) @ r0<- CCBB 4953 mov r9, rINST, lsr #8 @ r9<- AA 4954 mov r3, r0, lsr #8 @ r3<- CC 4955 and r2, r0, #255 @ r2<- BB 4956 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4957 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4958 flds s1, [r3] @ s1<- vCC 4959 flds s0, [r2] @ s0<- vBB 4960 4961 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4962 fsubs s2, s0, s1 @ s2<- op 4963 GET_INST_OPCODE(ip) @ extract opcode from rINST 4964 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4965 fsts s2, [r9] @ vAA<- s2 4966 GOTO_OPCODE(ip) @ jump to next instruction 4967 4968 4969/* ------------------------------ */ 4970 .balign 64 4971.L_OP_MUL_FLOAT: /* 0xa8 */ 4972/* File: arm-vfp/OP_MUL_FLOAT.S */ 4973/* File: arm-vfp/fbinop.S */ 4974 /* 4975 * Generic 32-bit floating-point operation. Provide an "instr" line that 4976 * specifies an instruction that performs "s2 = s0 op s1". Because we 4977 * use the "softfp" ABI, this must be an instruction, not a function call. 4978 * 4979 * For: add-float, sub-float, mul-float, div-float 4980 */ 4981 /* floatop vAA, vBB, vCC */ 4982 FETCH(r0, 1) @ r0<- CCBB 4983 mov r9, rINST, lsr #8 @ r9<- AA 4984 mov r3, r0, lsr #8 @ r3<- CC 4985 and r2, r0, #255 @ r2<- BB 4986 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4987 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4988 flds s1, [r3] @ s1<- vCC 4989 flds s0, [r2] @ s0<- vBB 4990 4991 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4992 fmuls s2, s0, s1 @ s2<- op 4993 GET_INST_OPCODE(ip) @ extract opcode from rINST 4994 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4995 fsts s2, [r9] @ vAA<- s2 4996 GOTO_OPCODE(ip) @ jump to next instruction 4997 4998 4999/* ------------------------------ */ 5000 .balign 64 5001.L_OP_DIV_FLOAT: /* 0xa9 */ 5002/* File: arm-vfp/OP_DIV_FLOAT.S */ 5003/* File: arm-vfp/fbinop.S */ 5004 /* 5005 * Generic 32-bit floating-point operation. Provide an "instr" line that 5006 * specifies an instruction that performs "s2 = s0 op s1". Because we 5007 * use the "softfp" ABI, this must be an instruction, not a function call. 5008 * 5009 * For: add-float, sub-float, mul-float, div-float 5010 */ 5011 /* floatop vAA, vBB, vCC */ 5012 FETCH(r0, 1) @ r0<- CCBB 5013 mov r9, rINST, lsr #8 @ r9<- AA 5014 mov r3, r0, lsr #8 @ r3<- CC 5015 and r2, r0, #255 @ r2<- BB 5016 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5017 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5018 flds s1, [r3] @ s1<- vCC 5019 flds s0, [r2] @ s0<- vBB 5020 5021 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5022 fdivs s2, s0, s1 @ s2<- op 5023 GET_INST_OPCODE(ip) @ extract opcode from rINST 5024 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5025 fsts s2, [r9] @ vAA<- s2 5026 GOTO_OPCODE(ip) @ jump to next instruction 5027 5028 5029/* ------------------------------ */ 5030 .balign 64 5031.L_OP_REM_FLOAT: /* 0xaa */ 5032/* File: armv5te/OP_REM_FLOAT.S */ 5033/* EABI doesn't define a float remainder function, but libm does */ 5034/* File: armv5te/binop.S */ 5035 /* 5036 * Generic 32-bit binary operation. Provide an "instr" line that 5037 * specifies an instruction that performs "result = r0 op r1". 5038 * This could be an ARM instruction or a function call. (If the result 5039 * comes back in a register other than r0, you can override "result".) 5040 * 5041 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5042 * vCC (r1). Useful for integer division and modulus. Note that we 5043 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 5044 * handles it correctly. 5045 * 5046 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 5047 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 5048 * mul-float, div-float, rem-float 5049 */ 5050 /* binop vAA, vBB, vCC */ 5051 FETCH(r0, 1) @ r0<- CCBB 5052 mov r9, rINST, lsr #8 @ r9<- AA 5053 mov r3, r0, lsr #8 @ r3<- CC 5054 and r2, r0, #255 @ r2<- BB 5055 GET_VREG(r1, r3) @ r1<- vCC 5056 GET_VREG(r0, r2) @ r0<- vBB 5057 .if 0 5058 cmp r1, #0 @ is second operand zero? 5059 beq common_errDivideByZero 5060 .endif 5061 5062 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5063 @ optional op; may set condition codes 5064 bl fmodf @ r0<- op, r0-r3 changed 5065 GET_INST_OPCODE(ip) @ extract opcode from rINST 5066 SET_VREG(r0, r9) @ vAA<- r0 5067 GOTO_OPCODE(ip) @ jump to next instruction 5068 /* 11-14 instructions */ 5069 5070 5071/* ------------------------------ */ 5072 .balign 64 5073.L_OP_ADD_DOUBLE: /* 0xab */ 5074/* File: arm-vfp/OP_ADD_DOUBLE.S */ 5075/* File: arm-vfp/fbinopWide.S */ 5076 /* 5077 * Generic 64-bit double-precision floating point binary operation. 5078 * Provide an "instr" line that specifies an instruction that performs 5079 * "d2 = d0 op d1". 5080 * 5081 * for: add-double, sub-double, mul-double, div-double 5082 */ 5083 /* doubleop vAA, vBB, vCC */ 5084 FETCH(r0, 1) @ r0<- CCBB 5085 mov r9, rINST, lsr #8 @ r9<- AA 5086 mov r3, r0, lsr #8 @ r3<- CC 5087 and r2, r0, #255 @ r2<- BB 5088 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5089 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5090 fldd d1, [r3] @ d1<- vCC 5091 fldd d0, [r2] @ d0<- vBB 5092 5093 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5094 faddd d2, d0, d1 @ s2<- op 5095 GET_INST_OPCODE(ip) @ extract opcode from rINST 5096 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5097 fstd d2, [r9] @ vAA<- d2 5098 GOTO_OPCODE(ip) @ jump to next instruction 5099 5100 5101/* ------------------------------ */ 5102 .balign 64 5103.L_OP_SUB_DOUBLE: /* 0xac */ 5104/* File: arm-vfp/OP_SUB_DOUBLE.S */ 5105/* File: arm-vfp/fbinopWide.S */ 5106 /* 5107 * Generic 64-bit double-precision floating point binary operation. 5108 * Provide an "instr" line that specifies an instruction that performs 5109 * "d2 = d0 op d1". 5110 * 5111 * for: add-double, sub-double, mul-double, div-double 5112 */ 5113 /* doubleop vAA, vBB, vCC */ 5114 FETCH(r0, 1) @ r0<- CCBB 5115 mov r9, rINST, lsr #8 @ r9<- AA 5116 mov r3, r0, lsr #8 @ r3<- CC 5117 and r2, r0, #255 @ r2<- BB 5118 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5119 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5120 fldd d1, [r3] @ d1<- vCC 5121 fldd d0, [r2] @ d0<- vBB 5122 5123 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5124 fsubd d2, d0, d1 @ s2<- op 5125 GET_INST_OPCODE(ip) @ extract opcode from rINST 5126 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5127 fstd d2, [r9] @ vAA<- d2 5128 GOTO_OPCODE(ip) @ jump to next instruction 5129 5130 5131/* ------------------------------ */ 5132 .balign 64 5133.L_OP_MUL_DOUBLE: /* 0xad */ 5134/* File: arm-vfp/OP_MUL_DOUBLE.S */ 5135/* File: arm-vfp/fbinopWide.S */ 5136 /* 5137 * Generic 64-bit double-precision floating point binary operation. 5138 * Provide an "instr" line that specifies an instruction that performs 5139 * "d2 = d0 op d1". 5140 * 5141 * for: add-double, sub-double, mul-double, div-double 5142 */ 5143 /* doubleop vAA, vBB, vCC */ 5144 FETCH(r0, 1) @ r0<- CCBB 5145 mov r9, rINST, lsr #8 @ r9<- AA 5146 mov r3, r0, lsr #8 @ r3<- CC 5147 and r2, r0, #255 @ r2<- BB 5148 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5149 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5150 fldd d1, [r3] @ d1<- vCC 5151 fldd d0, [r2] @ d0<- vBB 5152 5153 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5154 fmuld d2, d0, d1 @ s2<- op 5155 GET_INST_OPCODE(ip) @ extract opcode from rINST 5156 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5157 fstd d2, [r9] @ vAA<- d2 5158 GOTO_OPCODE(ip) @ jump to next instruction 5159 5160 5161/* ------------------------------ */ 5162 .balign 64 5163.L_OP_DIV_DOUBLE: /* 0xae */ 5164/* File: arm-vfp/OP_DIV_DOUBLE.S */ 5165/* File: arm-vfp/fbinopWide.S */ 5166 /* 5167 * Generic 64-bit double-precision floating point binary operation. 5168 * Provide an "instr" line that specifies an instruction that performs 5169 * "d2 = d0 op d1". 5170 * 5171 * for: add-double, sub-double, mul-double, div-double 5172 */ 5173 /* doubleop vAA, vBB, vCC */ 5174 FETCH(r0, 1) @ r0<- CCBB 5175 mov r9, rINST, lsr #8 @ r9<- AA 5176 mov r3, r0, lsr #8 @ r3<- CC 5177 and r2, r0, #255 @ r2<- BB 5178 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5179 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5180 fldd d1, [r3] @ d1<- vCC 5181 fldd d0, [r2] @ d0<- vBB 5182 5183 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5184 fdivd d2, d0, d1 @ s2<- op 5185 GET_INST_OPCODE(ip) @ extract opcode from rINST 5186 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5187 fstd d2, [r9] @ vAA<- d2 5188 GOTO_OPCODE(ip) @ jump to next instruction 5189 5190 5191/* ------------------------------ */ 5192 .balign 64 5193.L_OP_REM_DOUBLE: /* 0xaf */ 5194/* File: armv5te/OP_REM_DOUBLE.S */ 5195/* EABI doesn't define a double remainder function, but libm does */ 5196/* File: armv5te/binopWide.S */ 5197 /* 5198 * Generic 64-bit binary operation. Provide an "instr" line that 5199 * specifies an instruction that performs "result = r0-r1 op r2-r3". 5200 * This could be an ARM instruction or a function call. (If the result 5201 * comes back in a register other than r0, you can override "result".) 5202 * 5203 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5204 * vCC (r1). Useful for integer division and modulus. 5205 * 5206 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 5207 * xor-long, add-double, sub-double, mul-double, div-double, 5208 * rem-double 5209 * 5210 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 5211 */ 5212 /* binop vAA, vBB, vCC */ 5213 FETCH(r0, 1) @ r0<- CCBB 5214 mov r9, rINST, lsr #8 @ r9<- AA 5215 and r2, r0, #255 @ r2<- BB 5216 mov r3, r0, lsr #8 @ r3<- CC 5217 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 5218 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 5219 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 5220 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 5221 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 5222 .if 0 5223 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5224 beq common_errDivideByZero 5225 .endif 5226 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5227 5228 @ optional op; may set condition codes 5229 bl fmod @ result<- op, r0-r3 changed 5230 GET_INST_OPCODE(ip) @ extract opcode from rINST 5231 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5232 GOTO_OPCODE(ip) @ jump to next instruction 5233 /* 14-17 instructions */ 5234 5235 5236/* ------------------------------ */ 5237 .balign 64 5238.L_OP_ADD_INT_2ADDR: /* 0xb0 */ 5239/* File: armv5te/OP_ADD_INT_2ADDR.S */ 5240/* File: armv5te/binop2addr.S */ 5241 /* 5242 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5243 * that specifies an instruction that performs "result = r0 op r1". 5244 * This could be an ARM instruction or a function call. (If the result 5245 * comes back in a register other than r0, you can override "result".) 5246 * 5247 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5248 * vCC (r1). Useful for integer division and modulus. 5249 * 5250 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5251 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5252 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5253 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5254 */ 5255 /* binop/2addr vA, vB */ 5256 mov r9, rINST, lsr #8 @ r9<- A+ 5257 mov r3, rINST, lsr #12 @ r3<- B 5258 and r9, r9, #15 5259 GET_VREG(r1, r3) @ r1<- vB 5260 GET_VREG(r0, r9) @ r0<- vA 5261 .if 0 5262 cmp r1, #0 @ is second operand zero? 5263 beq common_errDivideByZero 5264 .endif 5265 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5266 5267 @ optional op; may set condition codes 5268 add r0, r0, r1 @ r0<- op, r0-r3 changed 5269 GET_INST_OPCODE(ip) @ extract opcode from rINST 5270 SET_VREG(r0, r9) @ vAA<- r0 5271 GOTO_OPCODE(ip) @ jump to next instruction 5272 /* 10-13 instructions */ 5273 5274 5275/* ------------------------------ */ 5276 .balign 64 5277.L_OP_SUB_INT_2ADDR: /* 0xb1 */ 5278/* File: armv5te/OP_SUB_INT_2ADDR.S */ 5279/* File: armv5te/binop2addr.S */ 5280 /* 5281 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5282 * that specifies an instruction that performs "result = r0 op r1". 5283 * This could be an ARM instruction or a function call. (If the result 5284 * comes back in a register other than r0, you can override "result".) 5285 * 5286 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5287 * vCC (r1). Useful for integer division and modulus. 5288 * 5289 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5290 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5291 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5292 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5293 */ 5294 /* binop/2addr vA, vB */ 5295 mov r9, rINST, lsr #8 @ r9<- A+ 5296 mov r3, rINST, lsr #12 @ r3<- B 5297 and r9, r9, #15 5298 GET_VREG(r1, r3) @ r1<- vB 5299 GET_VREG(r0, r9) @ r0<- vA 5300 .if 0 5301 cmp r1, #0 @ is second operand zero? 5302 beq common_errDivideByZero 5303 .endif 5304 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5305 5306 @ optional op; may set condition codes 5307 sub r0, r0, r1 @ r0<- op, r0-r3 changed 5308 GET_INST_OPCODE(ip) @ extract opcode from rINST 5309 SET_VREG(r0, r9) @ vAA<- r0 5310 GOTO_OPCODE(ip) @ jump to next instruction 5311 /* 10-13 instructions */ 5312 5313 5314/* ------------------------------ */ 5315 .balign 64 5316.L_OP_MUL_INT_2ADDR: /* 0xb2 */ 5317/* File: armv5te/OP_MUL_INT_2ADDR.S */ 5318/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 5319/* File: armv5te/binop2addr.S */ 5320 /* 5321 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5322 * that specifies an instruction that performs "result = r0 op r1". 5323 * This could be an ARM instruction or a function call. (If the result 5324 * comes back in a register other than r0, you can override "result".) 5325 * 5326 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5327 * vCC (r1). Useful for integer division and modulus. 5328 * 5329 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5330 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5331 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5332 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5333 */ 5334 /* binop/2addr vA, vB */ 5335 mov r9, rINST, lsr #8 @ r9<- A+ 5336 mov r3, rINST, lsr #12 @ r3<- B 5337 and r9, r9, #15 5338 GET_VREG(r1, r3) @ r1<- vB 5339 GET_VREG(r0, r9) @ r0<- vA 5340 .if 0 5341 cmp r1, #0 @ is second operand zero? 5342 beq common_errDivideByZero 5343 .endif 5344 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5345 5346 @ optional op; may set condition codes 5347 mul r0, r1, r0 @ r0<- op, r0-r3 changed 5348 GET_INST_OPCODE(ip) @ extract opcode from rINST 5349 SET_VREG(r0, r9) @ vAA<- r0 5350 GOTO_OPCODE(ip) @ jump to next instruction 5351 /* 10-13 instructions */ 5352 5353 5354/* ------------------------------ */ 5355 .balign 64 5356.L_OP_DIV_INT_2ADDR: /* 0xb3 */ 5357/* File: armv5te/OP_DIV_INT_2ADDR.S */ 5358/* File: armv5te/binop2addr.S */ 5359 /* 5360 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5361 * that specifies an instruction that performs "result = r0 op r1". 5362 * This could be an ARM instruction or a function call. (If the result 5363 * comes back in a register other than r0, you can override "result".) 5364 * 5365 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5366 * vCC (r1). Useful for integer division and modulus. 5367 * 5368 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5369 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5370 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5371 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5372 */ 5373 /* binop/2addr vA, vB */ 5374 mov r9, rINST, lsr #8 @ r9<- A+ 5375 mov r3, rINST, lsr #12 @ r3<- B 5376 and r9, r9, #15 5377 GET_VREG(r1, r3) @ r1<- vB 5378 GET_VREG(r0, r9) @ r0<- vA 5379 .if 1 5380 cmp r1, #0 @ is second operand zero? 5381 beq common_errDivideByZero 5382 .endif 5383 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5384 5385 @ optional op; may set condition codes 5386 bl __aeabi_idiv @ r0<- op, r0-r3 changed 5387 GET_INST_OPCODE(ip) @ extract opcode from rINST 5388 SET_VREG(r0, r9) @ vAA<- r0 5389 GOTO_OPCODE(ip) @ jump to next instruction 5390 /* 10-13 instructions */ 5391 5392 5393/* ------------------------------ */ 5394 .balign 64 5395.L_OP_REM_INT_2ADDR: /* 0xb4 */ 5396/* File: armv5te/OP_REM_INT_2ADDR.S */ 5397/* idivmod returns quotient in r0 and remainder in r1 */ 5398/* File: armv5te/binop2addr.S */ 5399 /* 5400 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5401 * that specifies an instruction that performs "result = r0 op r1". 5402 * This could be an ARM instruction or a function call. (If the result 5403 * comes back in a register other than r0, you can override "result".) 5404 * 5405 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5406 * vCC (r1). Useful for integer division and modulus. 5407 * 5408 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5409 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5410 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5411 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5412 */ 5413 /* binop/2addr vA, vB */ 5414 mov r9, rINST, lsr #8 @ r9<- A+ 5415 mov r3, rINST, lsr #12 @ r3<- B 5416 and r9, r9, #15 5417 GET_VREG(r1, r3) @ r1<- vB 5418 GET_VREG(r0, r9) @ r0<- vA 5419 .if 1 5420 cmp r1, #0 @ is second operand zero? 5421 beq common_errDivideByZero 5422 .endif 5423 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5424 5425 @ optional op; may set condition codes 5426 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 5427 GET_INST_OPCODE(ip) @ extract opcode from rINST 5428 SET_VREG(r1, r9) @ vAA<- r1 5429 GOTO_OPCODE(ip) @ jump to next instruction 5430 /* 10-13 instructions */ 5431 5432 5433/* ------------------------------ */ 5434 .balign 64 5435.L_OP_AND_INT_2ADDR: /* 0xb5 */ 5436/* File: armv5te/OP_AND_INT_2ADDR.S */ 5437/* File: armv5te/binop2addr.S */ 5438 /* 5439 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5440 * that specifies an instruction that performs "result = r0 op r1". 5441 * This could be an ARM instruction or a function call. (If the result 5442 * comes back in a register other than r0, you can override "result".) 5443 * 5444 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5445 * vCC (r1). Useful for integer division and modulus. 5446 * 5447 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5448 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5449 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5450 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5451 */ 5452 /* binop/2addr vA, vB */ 5453 mov r9, rINST, lsr #8 @ r9<- A+ 5454 mov r3, rINST, lsr #12 @ r3<- B 5455 and r9, r9, #15 5456 GET_VREG(r1, r3) @ r1<- vB 5457 GET_VREG(r0, r9) @ r0<- vA 5458 .if 0 5459 cmp r1, #0 @ is second operand zero? 5460 beq common_errDivideByZero 5461 .endif 5462 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5463 5464 @ optional op; may set condition codes 5465 and r0, r0, r1 @ r0<- op, r0-r3 changed 5466 GET_INST_OPCODE(ip) @ extract opcode from rINST 5467 SET_VREG(r0, r9) @ vAA<- r0 5468 GOTO_OPCODE(ip) @ jump to next instruction 5469 /* 10-13 instructions */ 5470 5471 5472/* ------------------------------ */ 5473 .balign 64 5474.L_OP_OR_INT_2ADDR: /* 0xb6 */ 5475/* File: armv5te/OP_OR_INT_2ADDR.S */ 5476/* File: armv5te/binop2addr.S */ 5477 /* 5478 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5479 * that specifies an instruction that performs "result = r0 op r1". 5480 * This could be an ARM instruction or a function call. (If the result 5481 * comes back in a register other than r0, you can override "result".) 5482 * 5483 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5484 * vCC (r1). Useful for integer division and modulus. 5485 * 5486 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5487 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5488 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5489 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5490 */ 5491 /* binop/2addr vA, vB */ 5492 mov r9, rINST, lsr #8 @ r9<- A+ 5493 mov r3, rINST, lsr #12 @ r3<- B 5494 and r9, r9, #15 5495 GET_VREG(r1, r3) @ r1<- vB 5496 GET_VREG(r0, r9) @ r0<- vA 5497 .if 0 5498 cmp r1, #0 @ is second operand zero? 5499 beq common_errDivideByZero 5500 .endif 5501 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5502 5503 @ optional op; may set condition codes 5504 orr r0, r0, r1 @ r0<- op, r0-r3 changed 5505 GET_INST_OPCODE(ip) @ extract opcode from rINST 5506 SET_VREG(r0, r9) @ vAA<- r0 5507 GOTO_OPCODE(ip) @ jump to next instruction 5508 /* 10-13 instructions */ 5509 5510 5511/* ------------------------------ */ 5512 .balign 64 5513.L_OP_XOR_INT_2ADDR: /* 0xb7 */ 5514/* File: armv5te/OP_XOR_INT_2ADDR.S */ 5515/* File: armv5te/binop2addr.S */ 5516 /* 5517 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5518 * that specifies an instruction that performs "result = r0 op r1". 5519 * This could be an ARM instruction or a function call. (If the result 5520 * comes back in a register other than r0, you can override "result".) 5521 * 5522 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5523 * vCC (r1). Useful for integer division and modulus. 5524 * 5525 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5526 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5527 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5528 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5529 */ 5530 /* binop/2addr vA, vB */ 5531 mov r9, rINST, lsr #8 @ r9<- A+ 5532 mov r3, rINST, lsr #12 @ r3<- B 5533 and r9, r9, #15 5534 GET_VREG(r1, r3) @ r1<- vB 5535 GET_VREG(r0, r9) @ r0<- vA 5536 .if 0 5537 cmp r1, #0 @ is second operand zero? 5538 beq common_errDivideByZero 5539 .endif 5540 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5541 5542 @ optional op; may set condition codes 5543 eor r0, r0, r1 @ r0<- op, r0-r3 changed 5544 GET_INST_OPCODE(ip) @ extract opcode from rINST 5545 SET_VREG(r0, r9) @ vAA<- r0 5546 GOTO_OPCODE(ip) @ jump to next instruction 5547 /* 10-13 instructions */ 5548 5549 5550/* ------------------------------ */ 5551 .balign 64 5552.L_OP_SHL_INT_2ADDR: /* 0xb8 */ 5553/* File: armv5te/OP_SHL_INT_2ADDR.S */ 5554/* File: armv5te/binop2addr.S */ 5555 /* 5556 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5557 * that specifies an instruction that performs "result = r0 op r1". 5558 * This could be an ARM instruction or a function call. (If the result 5559 * comes back in a register other than r0, you can override "result".) 5560 * 5561 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5562 * vCC (r1). Useful for integer division and modulus. 5563 * 5564 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5565 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5566 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5567 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5568 */ 5569 /* binop/2addr vA, vB */ 5570 mov r9, rINST, lsr #8 @ r9<- A+ 5571 mov r3, rINST, lsr #12 @ r3<- B 5572 and r9, r9, #15 5573 GET_VREG(r1, r3) @ r1<- vB 5574 GET_VREG(r0, r9) @ r0<- vA 5575 .if 0 5576 cmp r1, #0 @ is second operand zero? 5577 beq common_errDivideByZero 5578 .endif 5579 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5580 5581 and r1, r1, #31 @ optional op; may set condition codes 5582 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 5583 GET_INST_OPCODE(ip) @ extract opcode from rINST 5584 SET_VREG(r0, r9) @ vAA<- r0 5585 GOTO_OPCODE(ip) @ jump to next instruction 5586 /* 10-13 instructions */ 5587 5588 5589/* ------------------------------ */ 5590 .balign 64 5591.L_OP_SHR_INT_2ADDR: /* 0xb9 */ 5592/* File: armv5te/OP_SHR_INT_2ADDR.S */ 5593/* File: armv5te/binop2addr.S */ 5594 /* 5595 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5596 * that specifies an instruction that performs "result = r0 op r1". 5597 * This could be an ARM instruction or a function call. (If the result 5598 * comes back in a register other than r0, you can override "result".) 5599 * 5600 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5601 * vCC (r1). Useful for integer division and modulus. 5602 * 5603 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5604 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5605 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5606 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5607 */ 5608 /* binop/2addr vA, vB */ 5609 mov r9, rINST, lsr #8 @ r9<- A+ 5610 mov r3, rINST, lsr #12 @ r3<- B 5611 and r9, r9, #15 5612 GET_VREG(r1, r3) @ r1<- vB 5613 GET_VREG(r0, r9) @ r0<- vA 5614 .if 0 5615 cmp r1, #0 @ is second operand zero? 5616 beq common_errDivideByZero 5617 .endif 5618 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5619 5620 and r1, r1, #31 @ optional op; may set condition codes 5621 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 5622 GET_INST_OPCODE(ip) @ extract opcode from rINST 5623 SET_VREG(r0, r9) @ vAA<- r0 5624 GOTO_OPCODE(ip) @ jump to next instruction 5625 /* 10-13 instructions */ 5626 5627 5628/* ------------------------------ */ 5629 .balign 64 5630.L_OP_USHR_INT_2ADDR: /* 0xba */ 5631/* File: armv5te/OP_USHR_INT_2ADDR.S */ 5632/* File: armv5te/binop2addr.S */ 5633 /* 5634 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5635 * that specifies an instruction that performs "result = r0 op r1". 5636 * This could be an ARM instruction or a function call. (If the result 5637 * comes back in a register other than r0, you can override "result".) 5638 * 5639 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5640 * vCC (r1). Useful for integer division and modulus. 5641 * 5642 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5643 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5644 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5645 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5646 */ 5647 /* binop/2addr vA, vB */ 5648 mov r9, rINST, lsr #8 @ r9<- A+ 5649 mov r3, rINST, lsr #12 @ r3<- B 5650 and r9, r9, #15 5651 GET_VREG(r1, r3) @ r1<- vB 5652 GET_VREG(r0, r9) @ r0<- vA 5653 .if 0 5654 cmp r1, #0 @ is second operand zero? 5655 beq common_errDivideByZero 5656 .endif 5657 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5658 5659 and r1, r1, #31 @ optional op; may set condition codes 5660 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 5661 GET_INST_OPCODE(ip) @ extract opcode from rINST 5662 SET_VREG(r0, r9) @ vAA<- r0 5663 GOTO_OPCODE(ip) @ jump to next instruction 5664 /* 10-13 instructions */ 5665 5666 5667/* ------------------------------ */ 5668 .balign 64 5669.L_OP_ADD_LONG_2ADDR: /* 0xbb */ 5670/* File: armv5te/OP_ADD_LONG_2ADDR.S */ 5671/* File: armv5te/binopWide2addr.S */ 5672 /* 5673 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5674 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5675 * This could be an ARM instruction or a function call. (If the result 5676 * comes back in a register other than r0, you can override "result".) 5677 * 5678 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5679 * vCC (r1). Useful for integer division and modulus. 5680 * 5681 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5682 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5683 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5684 * rem-double/2addr 5685 */ 5686 /* binop/2addr vA, vB */ 5687 mov r9, rINST, lsr #8 @ r9<- A+ 5688 mov r1, rINST, lsr #12 @ r1<- B 5689 and r9, r9, #15 5690 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5691 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5692 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5693 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5694 .if 0 5695 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5696 beq common_errDivideByZero 5697 .endif 5698 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5699 5700 adds r0, r0, r2 @ optional op; may set condition codes 5701 adc r1, r1, r3 @ result<- op, r0-r3 changed 5702 GET_INST_OPCODE(ip) @ extract opcode from rINST 5703 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5704 GOTO_OPCODE(ip) @ jump to next instruction 5705 /* 12-15 instructions */ 5706 5707 5708/* ------------------------------ */ 5709 .balign 64 5710.L_OP_SUB_LONG_2ADDR: /* 0xbc */ 5711/* File: armv5te/OP_SUB_LONG_2ADDR.S */ 5712/* File: armv5te/binopWide2addr.S */ 5713 /* 5714 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5715 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5716 * This could be an ARM instruction or a function call. (If the result 5717 * comes back in a register other than r0, you can override "result".) 5718 * 5719 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5720 * vCC (r1). Useful for integer division and modulus. 5721 * 5722 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5723 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5724 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5725 * rem-double/2addr 5726 */ 5727 /* binop/2addr vA, vB */ 5728 mov r9, rINST, lsr #8 @ r9<- A+ 5729 mov r1, rINST, lsr #12 @ r1<- B 5730 and r9, r9, #15 5731 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5732 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5733 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5734 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5735 .if 0 5736 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5737 beq common_errDivideByZero 5738 .endif 5739 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5740 5741 subs r0, r0, r2 @ optional op; may set condition codes 5742 sbc r1, r1, r3 @ result<- op, r0-r3 changed 5743 GET_INST_OPCODE(ip) @ extract opcode from rINST 5744 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5745 GOTO_OPCODE(ip) @ jump to next instruction 5746 /* 12-15 instructions */ 5747 5748 5749/* ------------------------------ */ 5750 .balign 64 5751.L_OP_MUL_LONG_2ADDR: /* 0xbd */ 5752/* File: armv5te/OP_MUL_LONG_2ADDR.S */ 5753 /* 5754 * Signed 64-bit integer multiply, "/2addr" version. 5755 * 5756 * See OP_MUL_LONG for an explanation. 5757 * 5758 * We get a little tight on registers, so to avoid looking up &fp[A] 5759 * again we stuff it into rINST. 5760 */ 5761 /* mul-long/2addr vA, vB */ 5762 mov r9, rINST, lsr #8 @ r9<- A+ 5763 mov r1, rINST, lsr #12 @ r1<- B 5764 and r9, r9, #15 5765 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5766 add rINST, rFP, r9, lsl #2 @ rINST<- &fp[A] 5767 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5768 ldmia rINST, {r0-r1} @ r0/r1<- vAA/vAA+1 5769 mul ip, r2, r1 @ ip<- ZxW 5770 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 5771 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 5772 mov r0, rINST @ r0<- &fp[A] (free up rINST) 5773 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5774 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 5775 GET_INST_OPCODE(ip) @ extract opcode from rINST 5776 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 5777 GOTO_OPCODE(ip) @ jump to next instruction 5778 5779/* ------------------------------ */ 5780 .balign 64 5781.L_OP_DIV_LONG_2ADDR: /* 0xbe */ 5782/* File: armv5te/OP_DIV_LONG_2ADDR.S */ 5783/* File: armv5te/binopWide2addr.S */ 5784 /* 5785 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5786 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5787 * This could be an ARM instruction or a function call. (If the result 5788 * comes back in a register other than r0, you can override "result".) 5789 * 5790 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5791 * vCC (r1). Useful for integer division and modulus. 5792 * 5793 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5794 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5795 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5796 * rem-double/2addr 5797 */ 5798 /* binop/2addr vA, vB */ 5799 mov r9, rINST, lsr #8 @ r9<- A+ 5800 mov r1, rINST, lsr #12 @ r1<- B 5801 and r9, r9, #15 5802 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5803 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5804 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5805 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5806 .if 1 5807 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5808 beq common_errDivideByZero 5809 .endif 5810 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5811 5812 @ optional op; may set condition codes 5813 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 5814 GET_INST_OPCODE(ip) @ extract opcode from rINST 5815 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5816 GOTO_OPCODE(ip) @ jump to next instruction 5817 /* 12-15 instructions */ 5818 5819 5820/* ------------------------------ */ 5821 .balign 64 5822.L_OP_REM_LONG_2ADDR: /* 0xbf */ 5823/* File: armv5te/OP_REM_LONG_2ADDR.S */ 5824/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 5825/* File: armv5te/binopWide2addr.S */ 5826 /* 5827 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5828 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5829 * This could be an ARM instruction or a function call. (If the result 5830 * comes back in a register other than r0, you can override "result".) 5831 * 5832 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5833 * vCC (r1). Useful for integer division and modulus. 5834 * 5835 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5836 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5837 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5838 * rem-double/2addr 5839 */ 5840 /* binop/2addr vA, vB */ 5841 mov r9, rINST, lsr #8 @ r9<- A+ 5842 mov r1, rINST, lsr #12 @ r1<- B 5843 and r9, r9, #15 5844 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5845 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5846 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5847 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5848 .if 1 5849 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5850 beq common_errDivideByZero 5851 .endif 5852 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5853 5854 @ optional op; may set condition codes 5855 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 5856 GET_INST_OPCODE(ip) @ extract opcode from rINST 5857 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 5858 GOTO_OPCODE(ip) @ jump to next instruction 5859 /* 12-15 instructions */ 5860 5861 5862/* ------------------------------ */ 5863 .balign 64 5864.L_OP_AND_LONG_2ADDR: /* 0xc0 */ 5865/* File: armv5te/OP_AND_LONG_2ADDR.S */ 5866/* File: armv5te/binopWide2addr.S */ 5867 /* 5868 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5869 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5870 * This could be an ARM instruction or a function call. (If the result 5871 * comes back in a register other than r0, you can override "result".) 5872 * 5873 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5874 * vCC (r1). Useful for integer division and modulus. 5875 * 5876 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5877 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5878 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5879 * rem-double/2addr 5880 */ 5881 /* binop/2addr vA, vB */ 5882 mov r9, rINST, lsr #8 @ r9<- A+ 5883 mov r1, rINST, lsr #12 @ r1<- B 5884 and r9, r9, #15 5885 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5886 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5887 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5888 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5889 .if 0 5890 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5891 beq common_errDivideByZero 5892 .endif 5893 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5894 5895 and r0, r0, r2 @ optional op; may set condition codes 5896 and r1, r1, r3 @ result<- op, r0-r3 changed 5897 GET_INST_OPCODE(ip) @ extract opcode from rINST 5898 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5899 GOTO_OPCODE(ip) @ jump to next instruction 5900 /* 12-15 instructions */ 5901 5902 5903/* ------------------------------ */ 5904 .balign 64 5905.L_OP_OR_LONG_2ADDR: /* 0xc1 */ 5906/* File: armv5te/OP_OR_LONG_2ADDR.S */ 5907/* File: armv5te/binopWide2addr.S */ 5908 /* 5909 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5910 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5911 * This could be an ARM instruction or a function call. (If the result 5912 * comes back in a register other than r0, you can override "result".) 5913 * 5914 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5915 * vCC (r1). Useful for integer division and modulus. 5916 * 5917 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5918 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5919 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5920 * rem-double/2addr 5921 */ 5922 /* binop/2addr vA, vB */ 5923 mov r9, rINST, lsr #8 @ r9<- A+ 5924 mov r1, rINST, lsr #12 @ r1<- B 5925 and r9, r9, #15 5926 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5927 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5928 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5929 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5930 .if 0 5931 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5932 beq common_errDivideByZero 5933 .endif 5934 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5935 5936 orr r0, r0, r2 @ optional op; may set condition codes 5937 orr r1, r1, r3 @ result<- op, r0-r3 changed 5938 GET_INST_OPCODE(ip) @ extract opcode from rINST 5939 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5940 GOTO_OPCODE(ip) @ jump to next instruction 5941 /* 12-15 instructions */ 5942 5943 5944/* ------------------------------ */ 5945 .balign 64 5946.L_OP_XOR_LONG_2ADDR: /* 0xc2 */ 5947/* File: armv5te/OP_XOR_LONG_2ADDR.S */ 5948/* File: armv5te/binopWide2addr.S */ 5949 /* 5950 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5951 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5952 * This could be an ARM instruction or a function call. (If the result 5953 * comes back in a register other than r0, you can override "result".) 5954 * 5955 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5956 * vCC (r1). Useful for integer division and modulus. 5957 * 5958 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5959 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5960 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5961 * rem-double/2addr 5962 */ 5963 /* binop/2addr vA, vB */ 5964 mov r9, rINST, lsr #8 @ r9<- A+ 5965 mov r1, rINST, lsr #12 @ r1<- B 5966 and r9, r9, #15 5967 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5968 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5969 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5970 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5971 .if 0 5972 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5973 beq common_errDivideByZero 5974 .endif 5975 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5976 5977 eor r0, r0, r2 @ optional op; may set condition codes 5978 eor r1, r1, r3 @ result<- op, r0-r3 changed 5979 GET_INST_OPCODE(ip) @ extract opcode from rINST 5980 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5981 GOTO_OPCODE(ip) @ jump to next instruction 5982 /* 12-15 instructions */ 5983 5984 5985/* ------------------------------ */ 5986 .balign 64 5987.L_OP_SHL_LONG_2ADDR: /* 0xc3 */ 5988/* File: armv5te/OP_SHL_LONG_2ADDR.S */ 5989 /* 5990 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5991 * 32-bit shift distance. 5992 */ 5993 /* shl-long/2addr vA, vB */ 5994 mov r9, rINST, lsr #8 @ r9<- A+ 5995 mov r3, rINST, lsr #12 @ r3<- B 5996 and r9, r9, #15 5997 GET_VREG(r2, r3) @ r2<- vB 5998 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5999 and r2, r2, #63 @ r2<- r2 & 0x3f 6000 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6001 6002 mov r1, r1, asl r2 @ r1<- r1 << r2 6003 rsb r3, r2, #32 @ r3<- 32 - r2 6004 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 6005 subs ip, r2, #32 @ ip<- r2 - 32 6006 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6007 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 6008 mov r0, r0, asl r2 @ r0<- r0 << r2 6009 b .LOP_SHL_LONG_2ADDR_finish 6010 6011/* ------------------------------ */ 6012 .balign 64 6013.L_OP_SHR_LONG_2ADDR: /* 0xc4 */ 6014/* File: armv5te/OP_SHR_LONG_2ADDR.S */ 6015 /* 6016 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 6017 * 32-bit shift distance. 6018 */ 6019 /* shr-long/2addr vA, vB */ 6020 mov r9, rINST, lsr #8 @ r9<- A+ 6021 mov r3, rINST, lsr #12 @ r3<- B 6022 and r9, r9, #15 6023 GET_VREG(r2, r3) @ r2<- vB 6024 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6025 and r2, r2, #63 @ r2<- r2 & 0x3f 6026 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6027 6028 mov r0, r0, lsr r2 @ r0<- r2 >> r2 6029 rsb r3, r2, #32 @ r3<- 32 - r2 6030 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 6031 subs ip, r2, #32 @ ip<- r2 - 32 6032 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6033 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 6034 mov r1, r1, asr r2 @ r1<- r1 >> r2 6035 b .LOP_SHR_LONG_2ADDR_finish 6036 6037/* ------------------------------ */ 6038 .balign 64 6039.L_OP_USHR_LONG_2ADDR: /* 0xc5 */ 6040/* File: armv5te/OP_USHR_LONG_2ADDR.S */ 6041 /* 6042 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 6043 * 32-bit shift distance. 6044 */ 6045 /* ushr-long/2addr vA, vB */ 6046 mov r9, rINST, lsr #8 @ r9<- A+ 6047 mov r3, rINST, lsr #12 @ r3<- B 6048 and r9, r9, #15 6049 GET_VREG(r2, r3) @ r2<- vB 6050 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6051 and r2, r2, #63 @ r2<- r2 & 0x3f 6052 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6053 6054 mov r0, r0, lsr r2 @ r0<- r2 >> r2 6055 rsb r3, r2, #32 @ r3<- 32 - r2 6056 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 6057 subs ip, r2, #32 @ ip<- r2 - 32 6058 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6059 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 6060 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 6061 b .LOP_USHR_LONG_2ADDR_finish 6062 6063/* ------------------------------ */ 6064 .balign 64 6065.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */ 6066/* File: arm-vfp/OP_ADD_FLOAT_2ADDR.S */ 6067/* File: arm-vfp/fbinop2addr.S */ 6068 /* 6069 * Generic 32-bit floating point "/2addr" binary operation. Provide 6070 * an "instr" line that specifies an instruction that performs 6071 * "s2 = s0 op s1". 6072 * 6073 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6074 */ 6075 /* binop/2addr vA, vB */ 6076 mov r3, rINST, lsr #12 @ r3<- B 6077 mov r9, rINST, lsr #8 @ r9<- A+ 6078 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6079 and r9, r9, #15 @ r9<- A 6080 flds s1, [r3] @ s1<- vB 6081 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6082 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6083 flds s0, [r9] @ s0<- vA 6084 6085 fadds s2, s0, s1 @ s2<- op 6086 GET_INST_OPCODE(ip) @ extract opcode from rINST 6087 fsts s2, [r9] @ vAA<- s2 6088 GOTO_OPCODE(ip) @ jump to next instruction 6089 6090 6091/* ------------------------------ */ 6092 .balign 64 6093.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */ 6094/* File: arm-vfp/OP_SUB_FLOAT_2ADDR.S */ 6095/* File: arm-vfp/fbinop2addr.S */ 6096 /* 6097 * Generic 32-bit floating point "/2addr" binary operation. Provide 6098 * an "instr" line that specifies an instruction that performs 6099 * "s2 = s0 op s1". 6100 * 6101 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6102 */ 6103 /* binop/2addr vA, vB */ 6104 mov r3, rINST, lsr #12 @ r3<- B 6105 mov r9, rINST, lsr #8 @ r9<- A+ 6106 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6107 and r9, r9, #15 @ r9<- A 6108 flds s1, [r3] @ s1<- vB 6109 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6110 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6111 flds s0, [r9] @ s0<- vA 6112 6113 fsubs s2, s0, s1 @ s2<- op 6114 GET_INST_OPCODE(ip) @ extract opcode from rINST 6115 fsts s2, [r9] @ vAA<- s2 6116 GOTO_OPCODE(ip) @ jump to next instruction 6117 6118 6119/* ------------------------------ */ 6120 .balign 64 6121.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */ 6122/* File: arm-vfp/OP_MUL_FLOAT_2ADDR.S */ 6123/* File: arm-vfp/fbinop2addr.S */ 6124 /* 6125 * Generic 32-bit floating point "/2addr" binary operation. Provide 6126 * an "instr" line that specifies an instruction that performs 6127 * "s2 = s0 op s1". 6128 * 6129 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6130 */ 6131 /* binop/2addr vA, vB */ 6132 mov r3, rINST, lsr #12 @ r3<- B 6133 mov r9, rINST, lsr #8 @ r9<- A+ 6134 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6135 and r9, r9, #15 @ r9<- A 6136 flds s1, [r3] @ s1<- vB 6137 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6138 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6139 flds s0, [r9] @ s0<- vA 6140 6141 fmuls s2, s0, s1 @ s2<- op 6142 GET_INST_OPCODE(ip) @ extract opcode from rINST 6143 fsts s2, [r9] @ vAA<- s2 6144 GOTO_OPCODE(ip) @ jump to next instruction 6145 6146 6147/* ------------------------------ */ 6148 .balign 64 6149.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */ 6150/* File: arm-vfp/OP_DIV_FLOAT_2ADDR.S */ 6151/* File: arm-vfp/fbinop2addr.S */ 6152 /* 6153 * Generic 32-bit floating point "/2addr" binary operation. Provide 6154 * an "instr" line that specifies an instruction that performs 6155 * "s2 = s0 op s1". 6156 * 6157 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6158 */ 6159 /* binop/2addr vA, vB */ 6160 mov r3, rINST, lsr #12 @ r3<- B 6161 mov r9, rINST, lsr #8 @ r9<- A+ 6162 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6163 and r9, r9, #15 @ r9<- A 6164 flds s1, [r3] @ s1<- vB 6165 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6166 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6167 flds s0, [r9] @ s0<- vA 6168 6169 fdivs s2, s0, s1 @ s2<- op 6170 GET_INST_OPCODE(ip) @ extract opcode from rINST 6171 fsts s2, [r9] @ vAA<- s2 6172 GOTO_OPCODE(ip) @ jump to next instruction 6173 6174 6175/* ------------------------------ */ 6176 .balign 64 6177.L_OP_REM_FLOAT_2ADDR: /* 0xca */ 6178/* File: armv5te/OP_REM_FLOAT_2ADDR.S */ 6179/* EABI doesn't define a float remainder function, but libm does */ 6180/* File: armv5te/binop2addr.S */ 6181 /* 6182 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6183 * that specifies an instruction that performs "result = r0 op r1". 6184 * This could be an ARM instruction or a function call. (If the result 6185 * comes back in a register other than r0, you can override "result".) 6186 * 6187 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6188 * vCC (r1). Useful for integer division and modulus. 6189 * 6190 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6191 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6192 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6193 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6194 */ 6195 /* binop/2addr vA, vB */ 6196 mov r9, rINST, lsr #8 @ r9<- A+ 6197 mov r3, rINST, lsr #12 @ r3<- B 6198 and r9, r9, #15 6199 GET_VREG(r1, r3) @ r1<- vB 6200 GET_VREG(r0, r9) @ r0<- vA 6201 .if 0 6202 cmp r1, #0 @ is second operand zero? 6203 beq common_errDivideByZero 6204 .endif 6205 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6206 6207 @ optional op; may set condition codes 6208 bl fmodf @ r0<- op, r0-r3 changed 6209 GET_INST_OPCODE(ip) @ extract opcode from rINST 6210 SET_VREG(r0, r9) @ vAA<- r0 6211 GOTO_OPCODE(ip) @ jump to next instruction 6212 /* 10-13 instructions */ 6213 6214 6215/* ------------------------------ */ 6216 .balign 64 6217.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */ 6218/* File: arm-vfp/OP_ADD_DOUBLE_2ADDR.S */ 6219/* File: arm-vfp/fbinopWide2addr.S */ 6220 /* 6221 * Generic 64-bit floating point "/2addr" binary operation. Provide 6222 * an "instr" line that specifies an instruction that performs 6223 * "d2 = d0 op d1". 6224 * 6225 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6226 * div-double/2addr 6227 */ 6228 /* binop/2addr vA, vB */ 6229 mov r3, rINST, lsr #12 @ r3<- B 6230 mov r9, rINST, lsr #8 @ r9<- A+ 6231 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6232 and r9, r9, #15 @ r9<- A 6233 fldd d1, [r3] @ d1<- vB 6234 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6235 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6236 fldd d0, [r9] @ d0<- vA 6237 6238 faddd d2, d0, d1 @ d2<- op 6239 GET_INST_OPCODE(ip) @ extract opcode from rINST 6240 fstd d2, [r9] @ vAA<- d2 6241 GOTO_OPCODE(ip) @ jump to next instruction 6242 6243 6244/* ------------------------------ */ 6245 .balign 64 6246.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */ 6247/* File: arm-vfp/OP_SUB_DOUBLE_2ADDR.S */ 6248/* File: arm-vfp/fbinopWide2addr.S */ 6249 /* 6250 * Generic 64-bit floating point "/2addr" binary operation. Provide 6251 * an "instr" line that specifies an instruction that performs 6252 * "d2 = d0 op d1". 6253 * 6254 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6255 * div-double/2addr 6256 */ 6257 /* binop/2addr vA, vB */ 6258 mov r3, rINST, lsr #12 @ r3<- B 6259 mov r9, rINST, lsr #8 @ r9<- A+ 6260 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6261 and r9, r9, #15 @ r9<- A 6262 fldd d1, [r3] @ d1<- vB 6263 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6264 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6265 fldd d0, [r9] @ d0<- vA 6266 6267 fsubd d2, d0, d1 @ d2<- op 6268 GET_INST_OPCODE(ip) @ extract opcode from rINST 6269 fstd d2, [r9] @ vAA<- d2 6270 GOTO_OPCODE(ip) @ jump to next instruction 6271 6272 6273/* ------------------------------ */ 6274 .balign 64 6275.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */ 6276/* File: arm-vfp/OP_MUL_DOUBLE_2ADDR.S */ 6277/* File: arm-vfp/fbinopWide2addr.S */ 6278 /* 6279 * Generic 64-bit floating point "/2addr" binary operation. Provide 6280 * an "instr" line that specifies an instruction that performs 6281 * "d2 = d0 op d1". 6282 * 6283 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6284 * div-double/2addr 6285 */ 6286 /* binop/2addr vA, vB */ 6287 mov r3, rINST, lsr #12 @ r3<- B 6288 mov r9, rINST, lsr #8 @ r9<- A+ 6289 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6290 and r9, r9, #15 @ r9<- A 6291 fldd d1, [r3] @ d1<- vB 6292 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6293 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6294 fldd d0, [r9] @ d0<- vA 6295 6296 fmuld d2, d0, d1 @ d2<- op 6297 GET_INST_OPCODE(ip) @ extract opcode from rINST 6298 fstd d2, [r9] @ vAA<- d2 6299 GOTO_OPCODE(ip) @ jump to next instruction 6300 6301 6302/* ------------------------------ */ 6303 .balign 64 6304.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */ 6305/* File: arm-vfp/OP_DIV_DOUBLE_2ADDR.S */ 6306/* File: arm-vfp/fbinopWide2addr.S */ 6307 /* 6308 * Generic 64-bit floating point "/2addr" binary operation. Provide 6309 * an "instr" line that specifies an instruction that performs 6310 * "d2 = d0 op d1". 6311 * 6312 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6313 * div-double/2addr 6314 */ 6315 /* binop/2addr vA, vB */ 6316 mov r3, rINST, lsr #12 @ r3<- B 6317 mov r9, rINST, lsr #8 @ r9<- A+ 6318 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6319 and r9, r9, #15 @ r9<- A 6320 fldd d1, [r3] @ d1<- vB 6321 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6322 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6323 fldd d0, [r9] @ d0<- vA 6324 6325 fdivd d2, d0, d1 @ d2<- op 6326 GET_INST_OPCODE(ip) @ extract opcode from rINST 6327 fstd d2, [r9] @ vAA<- d2 6328 GOTO_OPCODE(ip) @ jump to next instruction 6329 6330 6331/* ------------------------------ */ 6332 .balign 64 6333.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */ 6334/* File: armv5te/OP_REM_DOUBLE_2ADDR.S */ 6335/* EABI doesn't define a double remainder function, but libm does */ 6336/* File: armv5te/binopWide2addr.S */ 6337 /* 6338 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6339 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6340 * This could be an ARM instruction or a function call. (If the result 6341 * comes back in a register other than r0, you can override "result".) 6342 * 6343 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6344 * vCC (r1). Useful for integer division and modulus. 6345 * 6346 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6347 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6348 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6349 * rem-double/2addr 6350 */ 6351 /* binop/2addr vA, vB */ 6352 mov r9, rINST, lsr #8 @ r9<- A+ 6353 mov r1, rINST, lsr #12 @ r1<- B 6354 and r9, r9, #15 6355 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6356 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6357 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6358 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6359 .if 0 6360 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6361 beq common_errDivideByZero 6362 .endif 6363 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6364 6365 @ optional op; may set condition codes 6366 bl fmod @ result<- op, r0-r3 changed 6367 GET_INST_OPCODE(ip) @ extract opcode from rINST 6368 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6369 GOTO_OPCODE(ip) @ jump to next instruction 6370 /* 12-15 instructions */ 6371 6372 6373/* ------------------------------ */ 6374 .balign 64 6375.L_OP_ADD_INT_LIT16: /* 0xd0 */ 6376/* File: armv5te/OP_ADD_INT_LIT16.S */ 6377/* File: armv5te/binopLit16.S */ 6378 /* 6379 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6380 * that specifies an instruction that performs "result = r0 op r1". 6381 * This could be an ARM instruction or a function call. (If the result 6382 * comes back in a register other than r0, you can override "result".) 6383 * 6384 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6385 * vCC (r1). Useful for integer division and modulus. 6386 * 6387 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6388 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6389 */ 6390 /* binop/lit16 vA, vB, #+CCCC */ 6391 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6392 mov r2, rINST, lsr #12 @ r2<- B 6393 mov r9, rINST, lsr #8 @ r9<- A+ 6394 GET_VREG(r0, r2) @ r0<- vB 6395 and r9, r9, #15 6396 .if 0 6397 cmp r1, #0 @ is second operand zero? 6398 beq common_errDivideByZero 6399 .endif 6400 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6401 6402 add r0, r0, r1 @ r0<- op, r0-r3 changed 6403 GET_INST_OPCODE(ip) @ extract opcode from rINST 6404 SET_VREG(r0, r9) @ vAA<- r0 6405 GOTO_OPCODE(ip) @ jump to next instruction 6406 /* 10-13 instructions */ 6407 6408 6409/* ------------------------------ */ 6410 .balign 64 6411.L_OP_RSUB_INT: /* 0xd1 */ 6412/* File: armv5te/OP_RSUB_INT.S */ 6413/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */ 6414/* File: armv5te/binopLit16.S */ 6415 /* 6416 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6417 * that specifies an instruction that performs "result = r0 op r1". 6418 * This could be an ARM instruction or a function call. (If the result 6419 * comes back in a register other than r0, you can override "result".) 6420 * 6421 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6422 * vCC (r1). Useful for integer division and modulus. 6423 * 6424 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6425 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6426 */ 6427 /* binop/lit16 vA, vB, #+CCCC */ 6428 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6429 mov r2, rINST, lsr #12 @ r2<- B 6430 mov r9, rINST, lsr #8 @ r9<- A+ 6431 GET_VREG(r0, r2) @ r0<- vB 6432 and r9, r9, #15 6433 .if 0 6434 cmp r1, #0 @ is second operand zero? 6435 beq common_errDivideByZero 6436 .endif 6437 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6438 6439 rsb r0, r0, r1 @ r0<- op, r0-r3 changed 6440 GET_INST_OPCODE(ip) @ extract opcode from rINST 6441 SET_VREG(r0, r9) @ vAA<- r0 6442 GOTO_OPCODE(ip) @ jump to next instruction 6443 /* 10-13 instructions */ 6444 6445 6446/* ------------------------------ */ 6447 .balign 64 6448.L_OP_MUL_INT_LIT16: /* 0xd2 */ 6449/* File: armv5te/OP_MUL_INT_LIT16.S */ 6450/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 6451/* File: armv5te/binopLit16.S */ 6452 /* 6453 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6454 * that specifies an instruction that performs "result = r0 op r1". 6455 * This could be an ARM instruction or a function call. (If the result 6456 * comes back in a register other than r0, you can override "result".) 6457 * 6458 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6459 * vCC (r1). Useful for integer division and modulus. 6460 * 6461 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6462 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6463 */ 6464 /* binop/lit16 vA, vB, #+CCCC */ 6465 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6466 mov r2, rINST, lsr #12 @ r2<- B 6467 mov r9, rINST, lsr #8 @ r9<- A+ 6468 GET_VREG(r0, r2) @ r0<- vB 6469 and r9, r9, #15 6470 .if 0 6471 cmp r1, #0 @ is second operand zero? 6472 beq common_errDivideByZero 6473 .endif 6474 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6475 6476 mul r0, r1, r0 @ r0<- op, r0-r3 changed 6477 GET_INST_OPCODE(ip) @ extract opcode from rINST 6478 SET_VREG(r0, r9) @ vAA<- r0 6479 GOTO_OPCODE(ip) @ jump to next instruction 6480 /* 10-13 instructions */ 6481 6482 6483/* ------------------------------ */ 6484 .balign 64 6485.L_OP_DIV_INT_LIT16: /* 0xd3 */ 6486/* File: armv5te/OP_DIV_INT_LIT16.S */ 6487/* File: armv5te/binopLit16.S */ 6488 /* 6489 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6490 * that specifies an instruction that performs "result = r0 op r1". 6491 * This could be an ARM instruction or a function call. (If the result 6492 * comes back in a register other than r0, you can override "result".) 6493 * 6494 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6495 * vCC (r1). Useful for integer division and modulus. 6496 * 6497 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6498 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6499 */ 6500 /* binop/lit16 vA, vB, #+CCCC */ 6501 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6502 mov r2, rINST, lsr #12 @ r2<- B 6503 mov r9, rINST, lsr #8 @ r9<- A+ 6504 GET_VREG(r0, r2) @ r0<- vB 6505 and r9, r9, #15 6506 .if 1 6507 cmp r1, #0 @ is second operand zero? 6508 beq common_errDivideByZero 6509 .endif 6510 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6511 6512 bl __aeabi_idiv @ r0<- op, r0-r3 changed 6513 GET_INST_OPCODE(ip) @ extract opcode from rINST 6514 SET_VREG(r0, r9) @ vAA<- r0 6515 GOTO_OPCODE(ip) @ jump to next instruction 6516 /* 10-13 instructions */ 6517 6518 6519/* ------------------------------ */ 6520 .balign 64 6521.L_OP_REM_INT_LIT16: /* 0xd4 */ 6522/* File: armv5te/OP_REM_INT_LIT16.S */ 6523/* idivmod returns quotient in r0 and remainder in r1 */ 6524/* File: armv5te/binopLit16.S */ 6525 /* 6526 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6527 * that specifies an instruction that performs "result = r0 op r1". 6528 * This could be an ARM instruction or a function call. (If the result 6529 * comes back in a register other than r0, you can override "result".) 6530 * 6531 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6532 * vCC (r1). Useful for integer division and modulus. 6533 * 6534 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6535 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6536 */ 6537 /* binop/lit16 vA, vB, #+CCCC */ 6538 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6539 mov r2, rINST, lsr #12 @ r2<- B 6540 mov r9, rINST, lsr #8 @ r9<- A+ 6541 GET_VREG(r0, r2) @ r0<- vB 6542 and r9, r9, #15 6543 .if 1 6544 cmp r1, #0 @ is second operand zero? 6545 beq common_errDivideByZero 6546 .endif 6547 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6548 6549 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 6550 GET_INST_OPCODE(ip) @ extract opcode from rINST 6551 SET_VREG(r1, r9) @ vAA<- r1 6552 GOTO_OPCODE(ip) @ jump to next instruction 6553 /* 10-13 instructions */ 6554 6555 6556/* ------------------------------ */ 6557 .balign 64 6558.L_OP_AND_INT_LIT16: /* 0xd5 */ 6559/* File: armv5te/OP_AND_INT_LIT16.S */ 6560/* File: armv5te/binopLit16.S */ 6561 /* 6562 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6563 * that specifies an instruction that performs "result = r0 op r1". 6564 * This could be an ARM instruction or a function call. (If the result 6565 * comes back in a register other than r0, you can override "result".) 6566 * 6567 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6568 * vCC (r1). Useful for integer division and modulus. 6569 * 6570 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6571 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6572 */ 6573 /* binop/lit16 vA, vB, #+CCCC */ 6574 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6575 mov r2, rINST, lsr #12 @ r2<- B 6576 mov r9, rINST, lsr #8 @ r9<- A+ 6577 GET_VREG(r0, r2) @ r0<- vB 6578 and r9, r9, #15 6579 .if 0 6580 cmp r1, #0 @ is second operand zero? 6581 beq common_errDivideByZero 6582 .endif 6583 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6584 6585 and r0, r0, r1 @ r0<- op, r0-r3 changed 6586 GET_INST_OPCODE(ip) @ extract opcode from rINST 6587 SET_VREG(r0, r9) @ vAA<- r0 6588 GOTO_OPCODE(ip) @ jump to next instruction 6589 /* 10-13 instructions */ 6590 6591 6592/* ------------------------------ */ 6593 .balign 64 6594.L_OP_OR_INT_LIT16: /* 0xd6 */ 6595/* File: armv5te/OP_OR_INT_LIT16.S */ 6596/* File: armv5te/binopLit16.S */ 6597 /* 6598 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6599 * that specifies an instruction that performs "result = r0 op r1". 6600 * This could be an ARM instruction or a function call. (If the result 6601 * comes back in a register other than r0, you can override "result".) 6602 * 6603 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6604 * vCC (r1). Useful for integer division and modulus. 6605 * 6606 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6607 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6608 */ 6609 /* binop/lit16 vA, vB, #+CCCC */ 6610 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6611 mov r2, rINST, lsr #12 @ r2<- B 6612 mov r9, rINST, lsr #8 @ r9<- A+ 6613 GET_VREG(r0, r2) @ r0<- vB 6614 and r9, r9, #15 6615 .if 0 6616 cmp r1, #0 @ is second operand zero? 6617 beq common_errDivideByZero 6618 .endif 6619 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6620 6621 orr r0, r0, r1 @ r0<- op, r0-r3 changed 6622 GET_INST_OPCODE(ip) @ extract opcode from rINST 6623 SET_VREG(r0, r9) @ vAA<- r0 6624 GOTO_OPCODE(ip) @ jump to next instruction 6625 /* 10-13 instructions */ 6626 6627 6628/* ------------------------------ */ 6629 .balign 64 6630.L_OP_XOR_INT_LIT16: /* 0xd7 */ 6631/* File: armv5te/OP_XOR_INT_LIT16.S */ 6632/* File: armv5te/binopLit16.S */ 6633 /* 6634 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6635 * that specifies an instruction that performs "result = r0 op r1". 6636 * This could be an ARM instruction or a function call. (If the result 6637 * comes back in a register other than r0, you can override "result".) 6638 * 6639 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6640 * vCC (r1). Useful for integer division and modulus. 6641 * 6642 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6643 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6644 */ 6645 /* binop/lit16 vA, vB, #+CCCC */ 6646 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6647 mov r2, rINST, lsr #12 @ r2<- B 6648 mov r9, rINST, lsr #8 @ r9<- A+ 6649 GET_VREG(r0, r2) @ r0<- vB 6650 and r9, r9, #15 6651 .if 0 6652 cmp r1, #0 @ is second operand zero? 6653 beq common_errDivideByZero 6654 .endif 6655 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6656 6657 eor r0, r0, r1 @ r0<- op, r0-r3 changed 6658 GET_INST_OPCODE(ip) @ extract opcode from rINST 6659 SET_VREG(r0, r9) @ vAA<- r0 6660 GOTO_OPCODE(ip) @ jump to next instruction 6661 /* 10-13 instructions */ 6662 6663 6664/* ------------------------------ */ 6665 .balign 64 6666.L_OP_ADD_INT_LIT8: /* 0xd8 */ 6667/* File: armv5te/OP_ADD_INT_LIT8.S */ 6668/* File: armv5te/binopLit8.S */ 6669 /* 6670 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6671 * that specifies an instruction that performs "result = r0 op r1". 6672 * This could be an ARM instruction or a function call. (If the result 6673 * comes back in a register other than r0, you can override "result".) 6674 * 6675 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6676 * vCC (r1). Useful for integer division and modulus. 6677 * 6678 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6679 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6680 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6681 */ 6682 /* binop/lit8 vAA, vBB, #+CC */ 6683 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6684 mov r9, rINST, lsr #8 @ r9<- AA 6685 and r2, r3, #255 @ r2<- BB 6686 GET_VREG(r0, r2) @ r0<- vBB 6687 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6688 .if 0 6689 @cmp r1, #0 @ is second operand zero? 6690 beq common_errDivideByZero 6691 .endif 6692 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6693 6694 @ optional op; may set condition codes 6695 add r0, r0, r1 @ r0<- op, r0-r3 changed 6696 GET_INST_OPCODE(ip) @ extract opcode from rINST 6697 SET_VREG(r0, r9) @ vAA<- r0 6698 GOTO_OPCODE(ip) @ jump to next instruction 6699 /* 10-12 instructions */ 6700 6701 6702/* ------------------------------ */ 6703 .balign 64 6704.L_OP_RSUB_INT_LIT8: /* 0xd9 */ 6705/* File: armv5te/OP_RSUB_INT_LIT8.S */ 6706/* File: armv5te/binopLit8.S */ 6707 /* 6708 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6709 * that specifies an instruction that performs "result = r0 op r1". 6710 * This could be an ARM instruction or a function call. (If the result 6711 * comes back in a register other than r0, you can override "result".) 6712 * 6713 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6714 * vCC (r1). Useful for integer division and modulus. 6715 * 6716 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6717 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6718 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6719 */ 6720 /* binop/lit8 vAA, vBB, #+CC */ 6721 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6722 mov r9, rINST, lsr #8 @ r9<- AA 6723 and r2, r3, #255 @ r2<- BB 6724 GET_VREG(r0, r2) @ r0<- vBB 6725 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6726 .if 0 6727 @cmp r1, #0 @ is second operand zero? 6728 beq common_errDivideByZero 6729 .endif 6730 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6731 6732 @ optional op; may set condition codes 6733 rsb r0, r0, r1 @ r0<- op, r0-r3 changed 6734 GET_INST_OPCODE(ip) @ extract opcode from rINST 6735 SET_VREG(r0, r9) @ vAA<- r0 6736 GOTO_OPCODE(ip) @ jump to next instruction 6737 /* 10-12 instructions */ 6738 6739 6740/* ------------------------------ */ 6741 .balign 64 6742.L_OP_MUL_INT_LIT8: /* 0xda */ 6743/* File: armv5te/OP_MUL_INT_LIT8.S */ 6744/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 6745/* File: armv5te/binopLit8.S */ 6746 /* 6747 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6748 * that specifies an instruction that performs "result = r0 op r1". 6749 * This could be an ARM instruction or a function call. (If the result 6750 * comes back in a register other than r0, you can override "result".) 6751 * 6752 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6753 * vCC (r1). Useful for integer division and modulus. 6754 * 6755 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6756 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6757 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6758 */ 6759 /* binop/lit8 vAA, vBB, #+CC */ 6760 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6761 mov r9, rINST, lsr #8 @ r9<- AA 6762 and r2, r3, #255 @ r2<- BB 6763 GET_VREG(r0, r2) @ r0<- vBB 6764 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6765 .if 0 6766 @cmp r1, #0 @ is second operand zero? 6767 beq common_errDivideByZero 6768 .endif 6769 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6770 6771 @ optional op; may set condition codes 6772 mul r0, r1, r0 @ r0<- op, r0-r3 changed 6773 GET_INST_OPCODE(ip) @ extract opcode from rINST 6774 SET_VREG(r0, r9) @ vAA<- r0 6775 GOTO_OPCODE(ip) @ jump to next instruction 6776 /* 10-12 instructions */ 6777 6778 6779/* ------------------------------ */ 6780 .balign 64 6781.L_OP_DIV_INT_LIT8: /* 0xdb */ 6782/* File: armv5te/OP_DIV_INT_LIT8.S */ 6783/* File: armv5te/binopLit8.S */ 6784 /* 6785 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6786 * that specifies an instruction that performs "result = r0 op r1". 6787 * This could be an ARM instruction or a function call. (If the result 6788 * comes back in a register other than r0, you can override "result".) 6789 * 6790 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6791 * vCC (r1). Useful for integer division and modulus. 6792 * 6793 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6794 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6795 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6796 */ 6797 /* binop/lit8 vAA, vBB, #+CC */ 6798 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6799 mov r9, rINST, lsr #8 @ r9<- AA 6800 and r2, r3, #255 @ r2<- BB 6801 GET_VREG(r0, r2) @ r0<- vBB 6802 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6803 .if 1 6804 @cmp r1, #0 @ is second operand zero? 6805 beq common_errDivideByZero 6806 .endif 6807 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6808 6809 @ optional op; may set condition codes 6810 bl __aeabi_idiv @ r0<- op, r0-r3 changed 6811 GET_INST_OPCODE(ip) @ extract opcode from rINST 6812 SET_VREG(r0, r9) @ vAA<- r0 6813 GOTO_OPCODE(ip) @ jump to next instruction 6814 /* 10-12 instructions */ 6815 6816 6817/* ------------------------------ */ 6818 .balign 64 6819.L_OP_REM_INT_LIT8: /* 0xdc */ 6820/* File: armv5te/OP_REM_INT_LIT8.S */ 6821/* idivmod returns quotient in r0 and remainder in r1 */ 6822/* File: armv5te/binopLit8.S */ 6823 /* 6824 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6825 * that specifies an instruction that performs "result = r0 op r1". 6826 * This could be an ARM instruction or a function call. (If the result 6827 * comes back in a register other than r0, you can override "result".) 6828 * 6829 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6830 * vCC (r1). Useful for integer division and modulus. 6831 * 6832 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6833 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6834 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6835 */ 6836 /* binop/lit8 vAA, vBB, #+CC */ 6837 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6838 mov r9, rINST, lsr #8 @ r9<- AA 6839 and r2, r3, #255 @ r2<- BB 6840 GET_VREG(r0, r2) @ r0<- vBB 6841 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6842 .if 1 6843 @cmp r1, #0 @ is second operand zero? 6844 beq common_errDivideByZero 6845 .endif 6846 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6847 6848 @ optional op; may set condition codes 6849 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 6850 GET_INST_OPCODE(ip) @ extract opcode from rINST 6851 SET_VREG(r1, r9) @ vAA<- r1 6852 GOTO_OPCODE(ip) @ jump to next instruction 6853 /* 10-12 instructions */ 6854 6855 6856/* ------------------------------ */ 6857 .balign 64 6858.L_OP_AND_INT_LIT8: /* 0xdd */ 6859/* File: armv5te/OP_AND_INT_LIT8.S */ 6860/* File: armv5te/binopLit8.S */ 6861 /* 6862 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6863 * that specifies an instruction that performs "result = r0 op r1". 6864 * This could be an ARM instruction or a function call. (If the result 6865 * comes back in a register other than r0, you can override "result".) 6866 * 6867 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6868 * vCC (r1). Useful for integer division and modulus. 6869 * 6870 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6871 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6872 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6873 */ 6874 /* binop/lit8 vAA, vBB, #+CC */ 6875 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6876 mov r9, rINST, lsr #8 @ r9<- AA 6877 and r2, r3, #255 @ r2<- BB 6878 GET_VREG(r0, r2) @ r0<- vBB 6879 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6880 .if 0 6881 @cmp r1, #0 @ is second operand zero? 6882 beq common_errDivideByZero 6883 .endif 6884 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6885 6886 @ optional op; may set condition codes 6887 and r0, r0, r1 @ r0<- op, r0-r3 changed 6888 GET_INST_OPCODE(ip) @ extract opcode from rINST 6889 SET_VREG(r0, r9) @ vAA<- r0 6890 GOTO_OPCODE(ip) @ jump to next instruction 6891 /* 10-12 instructions */ 6892 6893 6894/* ------------------------------ */ 6895 .balign 64 6896.L_OP_OR_INT_LIT8: /* 0xde */ 6897/* File: armv5te/OP_OR_INT_LIT8.S */ 6898/* File: armv5te/binopLit8.S */ 6899 /* 6900 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6901 * that specifies an instruction that performs "result = r0 op r1". 6902 * This could be an ARM instruction or a function call. (If the result 6903 * comes back in a register other than r0, you can override "result".) 6904 * 6905 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6906 * vCC (r1). Useful for integer division and modulus. 6907 * 6908 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6909 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6910 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6911 */ 6912 /* binop/lit8 vAA, vBB, #+CC */ 6913 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6914 mov r9, rINST, lsr #8 @ r9<- AA 6915 and r2, r3, #255 @ r2<- BB 6916 GET_VREG(r0, r2) @ r0<- vBB 6917 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6918 .if 0 6919 @cmp r1, #0 @ is second operand zero? 6920 beq common_errDivideByZero 6921 .endif 6922 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6923 6924 @ optional op; may set condition codes 6925 orr r0, r0, r1 @ r0<- op, r0-r3 changed 6926 GET_INST_OPCODE(ip) @ extract opcode from rINST 6927 SET_VREG(r0, r9) @ vAA<- r0 6928 GOTO_OPCODE(ip) @ jump to next instruction 6929 /* 10-12 instructions */ 6930 6931 6932/* ------------------------------ */ 6933 .balign 64 6934.L_OP_XOR_INT_LIT8: /* 0xdf */ 6935/* File: armv5te/OP_XOR_INT_LIT8.S */ 6936/* File: armv5te/binopLit8.S */ 6937 /* 6938 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6939 * that specifies an instruction that performs "result = r0 op r1". 6940 * This could be an ARM instruction or a function call. (If the result 6941 * comes back in a register other than r0, you can override "result".) 6942 * 6943 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6944 * vCC (r1). Useful for integer division and modulus. 6945 * 6946 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6947 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6948 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6949 */ 6950 /* binop/lit8 vAA, vBB, #+CC */ 6951 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6952 mov r9, rINST, lsr #8 @ r9<- AA 6953 and r2, r3, #255 @ r2<- BB 6954 GET_VREG(r0, r2) @ r0<- vBB 6955 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6956 .if 0 6957 @cmp r1, #0 @ is second operand zero? 6958 beq common_errDivideByZero 6959 .endif 6960 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6961 6962 @ optional op; may set condition codes 6963 eor r0, r0, r1 @ r0<- op, r0-r3 changed 6964 GET_INST_OPCODE(ip) @ extract opcode from rINST 6965 SET_VREG(r0, r9) @ vAA<- r0 6966 GOTO_OPCODE(ip) @ jump to next instruction 6967 /* 10-12 instructions */ 6968 6969 6970/* ------------------------------ */ 6971 .balign 64 6972.L_OP_SHL_INT_LIT8: /* 0xe0 */ 6973/* File: armv5te/OP_SHL_INT_LIT8.S */ 6974/* File: armv5te/binopLit8.S */ 6975 /* 6976 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6977 * that specifies an instruction that performs "result = r0 op r1". 6978 * This could be an ARM instruction or a function call. (If the result 6979 * comes back in a register other than r0, you can override "result".) 6980 * 6981 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6982 * vCC (r1). Useful for integer division and modulus. 6983 * 6984 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6985 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6986 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6987 */ 6988 /* binop/lit8 vAA, vBB, #+CC */ 6989 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6990 mov r9, rINST, lsr #8 @ r9<- AA 6991 and r2, r3, #255 @ r2<- BB 6992 GET_VREG(r0, r2) @ r0<- vBB 6993 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6994 .if 0 6995 @cmp r1, #0 @ is second operand zero? 6996 beq common_errDivideByZero 6997 .endif 6998 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6999 7000 and r1, r1, #31 @ optional op; may set condition codes 7001 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 7002 GET_INST_OPCODE(ip) @ extract opcode from rINST 7003 SET_VREG(r0, r9) @ vAA<- r0 7004 GOTO_OPCODE(ip) @ jump to next instruction 7005 /* 10-12 instructions */ 7006 7007 7008/* ------------------------------ */ 7009 .balign 64 7010.L_OP_SHR_INT_LIT8: /* 0xe1 */ 7011/* File: armv5te/OP_SHR_INT_LIT8.S */ 7012/* File: armv5te/binopLit8.S */ 7013 /* 7014 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7015 * that specifies an instruction that performs "result = r0 op r1". 7016 * This could be an ARM instruction or a function call. (If the result 7017 * comes back in a register other than r0, you can override "result".) 7018 * 7019 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7020 * vCC (r1). Useful for integer division and modulus. 7021 * 7022 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7023 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7024 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7025 */ 7026 /* binop/lit8 vAA, vBB, #+CC */ 7027 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7028 mov r9, rINST, lsr #8 @ r9<- AA 7029 and r2, r3, #255 @ r2<- BB 7030 GET_VREG(r0, r2) @ r0<- vBB 7031 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7032 .if 0 7033 @cmp r1, #0 @ is second operand zero? 7034 beq common_errDivideByZero 7035 .endif 7036 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7037 7038 and r1, r1, #31 @ optional op; may set condition codes 7039 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 7040 GET_INST_OPCODE(ip) @ extract opcode from rINST 7041 SET_VREG(r0, r9) @ vAA<- r0 7042 GOTO_OPCODE(ip) @ jump to next instruction 7043 /* 10-12 instructions */ 7044 7045 7046/* ------------------------------ */ 7047 .balign 64 7048.L_OP_USHR_INT_LIT8: /* 0xe2 */ 7049/* File: armv5te/OP_USHR_INT_LIT8.S */ 7050/* File: armv5te/binopLit8.S */ 7051 /* 7052 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7053 * that specifies an instruction that performs "result = r0 op r1". 7054 * This could be an ARM instruction or a function call. (If the result 7055 * comes back in a register other than r0, you can override "result".) 7056 * 7057 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7058 * vCC (r1). Useful for integer division and modulus. 7059 * 7060 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7061 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7062 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7063 */ 7064 /* binop/lit8 vAA, vBB, #+CC */ 7065 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7066 mov r9, rINST, lsr #8 @ r9<- AA 7067 and r2, r3, #255 @ r2<- BB 7068 GET_VREG(r0, r2) @ r0<- vBB 7069 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7070 .if 0 7071 @cmp r1, #0 @ is second operand zero? 7072 beq common_errDivideByZero 7073 .endif 7074 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7075 7076 and r1, r1, #31 @ optional op; may set condition codes 7077 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 7078 GET_INST_OPCODE(ip) @ extract opcode from rINST 7079 SET_VREG(r0, r9) @ vAA<- r0 7080 GOTO_OPCODE(ip) @ jump to next instruction 7081 /* 10-12 instructions */ 7082 7083 7084/* ------------------------------ */ 7085 .balign 64 7086.L_OP_IGET_VOLATILE: /* 0xe3 */ 7087/* File: armv5te/OP_IGET_VOLATILE.S */ 7088/* File: armv5te/OP_IGET.S */ 7089 /* 7090 * General 32-bit instance field get. 7091 * 7092 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7093 */ 7094 /* op vA, vB, field@CCCC */ 7095 mov r0, rINST, lsr #12 @ r0<- B 7096 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7097 FETCH(r1, 1) @ r1<- field ref CCCC 7098 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7099 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7100 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7101 cmp r0, #0 @ is resolved entry null? 7102 bne .LOP_IGET_VOLATILE_finish @ no, already resolved 71038: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7104 EXPORT_PC() @ resolve() could throw 7105 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7106 bl dvmResolveInstField @ r0<- resolved InstField ptr 7107 cmp r0, #0 7108 bne .LOP_IGET_VOLATILE_finish 7109 b common_exceptionThrown 7110 7111 7112/* ------------------------------ */ 7113 .balign 64 7114.L_OP_IPUT_VOLATILE: /* 0xe4 */ 7115/* File: armv5te/OP_IPUT_VOLATILE.S */ 7116/* File: armv5te/OP_IPUT.S */ 7117 /* 7118 * General 32-bit instance field put. 7119 * 7120 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 7121 */ 7122 /* op vA, vB, field@CCCC */ 7123 mov r0, rINST, lsr #12 @ r0<- B 7124 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7125 FETCH(r1, 1) @ r1<- field ref CCCC 7126 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7127 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7128 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7129 cmp r0, #0 @ is resolved entry null? 7130 bne .LOP_IPUT_VOLATILE_finish @ no, already resolved 71318: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7132 EXPORT_PC() @ resolve() could throw 7133 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7134 bl dvmResolveInstField @ r0<- resolved InstField ptr 7135 cmp r0, #0 @ success? 7136 bne .LOP_IPUT_VOLATILE_finish @ yes, finish up 7137 b common_exceptionThrown 7138 7139 7140/* ------------------------------ */ 7141 .balign 64 7142.L_OP_SGET_VOLATILE: /* 0xe5 */ 7143/* File: armv5te/OP_SGET_VOLATILE.S */ 7144/* File: armv5te/OP_SGET.S */ 7145 /* 7146 * General 32-bit SGET handler. 7147 * 7148 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7149 */ 7150 /* op vAA, field@BBBB */ 7151 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 7152 FETCH(r1, 1) @ r1<- field ref BBBB 7153 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7154 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7155 cmp r0, #0 @ is resolved entry null? 7156 beq .LOP_SGET_VOLATILE_resolve @ yes, do resolve 7157.LOP_SGET_VOLATILE_finish: @ field ptr in r0 7158 ldr r1, [r0, #offStaticField_value] @ r1<- field value 7159 SMP_DMB @ acquiring load 7160 mov r2, rINST, lsr #8 @ r2<- AA 7161 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7162 SET_VREG(r1, r2) @ fp[AA]<- r1 7163 GET_INST_OPCODE(ip) @ extract opcode from rINST 7164 GOTO_OPCODE(ip) @ jump to next instruction 7165 7166 7167/* ------------------------------ */ 7168 .balign 64 7169.L_OP_SPUT_VOLATILE: /* 0xe6 */ 7170/* File: armv5te/OP_SPUT_VOLATILE.S */ 7171/* File: armv5te/OP_SPUT.S */ 7172 /* 7173 * General 32-bit SPUT handler. 7174 * 7175 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 7176 */ 7177 /* op vAA, field@BBBB */ 7178 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 7179 FETCH(r1, 1) @ r1<- field ref BBBB 7180 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7181 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7182 cmp r0, #0 @ is resolved entry null? 7183 beq .LOP_SPUT_VOLATILE_resolve @ yes, do resolve 7184.LOP_SPUT_VOLATILE_finish: @ field ptr in r0 7185 mov r2, rINST, lsr #8 @ r2<- AA 7186 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7187 GET_VREG(r1, r2) @ r1<- fp[AA] 7188 GET_INST_OPCODE(ip) @ extract opcode from rINST 7189 SMP_DMB @ releasing store 7190 str r1, [r0, #offStaticField_value] @ field<- vAA 7191 GOTO_OPCODE(ip) @ jump to next instruction 7192 7193 7194/* ------------------------------ */ 7195 .balign 64 7196.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */ 7197/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */ 7198/* File: armv5te/OP_IGET.S */ 7199 /* 7200 * General 32-bit instance field get. 7201 * 7202 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7203 */ 7204 /* op vA, vB, field@CCCC */ 7205 mov r0, rINST, lsr #12 @ r0<- B 7206 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7207 FETCH(r1, 1) @ r1<- field ref CCCC 7208 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7209 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7210 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7211 cmp r0, #0 @ is resolved entry null? 7212 bne .LOP_IGET_OBJECT_VOLATILE_finish @ no, already resolved 72138: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7214 EXPORT_PC() @ resolve() could throw 7215 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7216 bl dvmResolveInstField @ r0<- resolved InstField ptr 7217 cmp r0, #0 7218 bne .LOP_IGET_OBJECT_VOLATILE_finish 7219 b common_exceptionThrown 7220 7221 7222/* ------------------------------ */ 7223 .balign 64 7224.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */ 7225/* File: armv5te/OP_IGET_WIDE_VOLATILE.S */ 7226/* File: armv5te/OP_IGET_WIDE.S */ 7227 /* 7228 * Wide 32-bit instance field get. 7229 */ 7230 /* iget-wide vA, vB, field@CCCC */ 7231 mov r0, rINST, lsr #12 @ r0<- B 7232 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7233 FETCH(r1, 1) @ r1<- field ref CCCC 7234 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7235 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7236 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7237 cmp r0, #0 @ is resolved entry null? 7238 bne .LOP_IGET_WIDE_VOLATILE_finish @ no, already resolved 72398: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7240 EXPORT_PC() @ resolve() could throw 7241 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7242 bl dvmResolveInstField @ r0<- resolved InstField ptr 7243 cmp r0, #0 7244 bne .LOP_IGET_WIDE_VOLATILE_finish 7245 b common_exceptionThrown 7246 7247 7248/* ------------------------------ */ 7249 .balign 64 7250.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */ 7251/* File: armv5te/OP_IPUT_WIDE_VOLATILE.S */ 7252/* File: armv5te/OP_IPUT_WIDE.S */ 7253 /* iput-wide vA, vB, field@CCCC */ 7254 mov r0, rINST, lsr #12 @ r0<- B 7255 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7256 FETCH(r1, 1) @ r1<- field ref CCCC 7257 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7258 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7259 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7260 cmp r0, #0 @ is resolved entry null? 7261 bne .LOP_IPUT_WIDE_VOLATILE_finish @ no, already resolved 72628: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7263 EXPORT_PC() @ resolve() could throw 7264 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7265 bl dvmResolveInstField @ r0<- resolved InstField ptr 7266 cmp r0, #0 @ success? 7267 bne .LOP_IPUT_WIDE_VOLATILE_finish @ yes, finish up 7268 b common_exceptionThrown 7269 7270 7271/* ------------------------------ */ 7272 .balign 64 7273.L_OP_SGET_WIDE_VOLATILE: /* 0xea */ 7274/* File: armv5te/OP_SGET_WIDE_VOLATILE.S */ 7275/* File: armv5te/OP_SGET_WIDE.S */ 7276 /* 7277 * 64-bit SGET handler. 7278 */ 7279 /* sget-wide vAA, field@BBBB */ 7280 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 7281 FETCH(r1, 1) @ r1<- field ref BBBB 7282 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7283 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7284 cmp r0, #0 @ is resolved entry null? 7285 beq .LOP_SGET_WIDE_VOLATILE_resolve @ yes, do resolve 7286.LOP_SGET_WIDE_VOLATILE_finish: 7287 mov r9, rINST, lsr #8 @ r9<- AA 7288 .if 1 7289 add r0, r0, #offStaticField_value @ r0<- pointer to data 7290 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 7291 .else 7292 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 7293 .endif 7294 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7295 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7296 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 7297 GET_INST_OPCODE(ip) @ extract opcode from rINST 7298 GOTO_OPCODE(ip) @ jump to next instruction 7299 7300 7301/* ------------------------------ */ 7302 .balign 64 7303.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */ 7304/* File: armv5te/OP_SPUT_WIDE_VOLATILE.S */ 7305/* File: armv5te/OP_SPUT_WIDE.S */ 7306 /* 7307 * 64-bit SPUT handler. 7308 */ 7309 /* sput-wide vAA, field@BBBB */ 7310 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- DvmDex 7311 FETCH(r1, 1) @ r1<- field ref BBBB 7312 ldr r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields 7313 mov r9, rINST, lsr #8 @ r9<- AA 7314 ldr r2, [r0, r1, lsl #2] @ r2<- resolved StaticField ptr 7315 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7316 cmp r2, #0 @ is resolved entry null? 7317 beq .LOP_SPUT_WIDE_VOLATILE_resolve @ yes, do resolve 7318.LOP_SPUT_WIDE_VOLATILE_finish: @ field ptr in r2, AA in r9 7319 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7320 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 7321 GET_INST_OPCODE(r10) @ extract opcode from rINST 7322 .if 1 7323 add r2, r2, #offStaticField_value @ r2<- pointer to data 7324 bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2 7325 .else 7326 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 7327 .endif 7328 GOTO_OPCODE(r10) @ jump to next instruction 7329 7330 7331/* ------------------------------ */ 7332 .balign 64 7333.L_OP_BREAKPOINT: /* 0xec */ 7334/* File: armv5te/OP_BREAKPOINT.S */ 7335/* File: armv5te/unused.S */ 7336 bl common_abort 7337 7338 7339/* ------------------------------ */ 7340 .balign 64 7341.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */ 7342/* File: armv5te/OP_THROW_VERIFICATION_ERROR.S */ 7343 /* 7344 * Handle a throw-verification-error instruction. This throws an 7345 * exception for an error discovered during verification. The 7346 * exception is indicated by AA, with some detail provided by BBBB. 7347 */ 7348 /* op AA, ref@BBBB */ 7349 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 7350 FETCH(r2, 1) @ r2<- BBBB 7351 EXPORT_PC() @ export the PC 7352 mov r1, rINST, lsr #8 @ r1<- AA 7353 bl dvmThrowVerificationError @ always throws 7354 b common_exceptionThrown @ handle exception 7355 7356/* ------------------------------ */ 7357 .balign 64 7358.L_OP_EXECUTE_INLINE: /* 0xee */ 7359/* File: armv5te/OP_EXECUTE_INLINE.S */ 7360 /* 7361 * Execute a "native inline" instruction. 7362 * 7363 * We need to call an InlineOp4Func: 7364 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7365 * 7366 * The first four args are in r0-r3, pointer to return value storage 7367 * is on the stack. The function's return value is a flag that tells 7368 * us if an exception was thrown. 7369 */ 7370 /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */ 7371 FETCH(r10, 1) @ r10<- BBBB 7372 add r1, rGLUE, #offGlue_retval @ r1<- &glue->retval 7373 EXPORT_PC() @ can throw 7374 sub sp, sp, #8 @ make room for arg, +64 bit align 7375 mov r0, rINST, lsr #12 @ r0<- B 7376 str r1, [sp] @ push &glue->retval 7377 bl .LOP_EXECUTE_INLINE_continue @ make call; will return after 7378 add sp, sp, #8 @ pop stack 7379 cmp r0, #0 @ test boolean result of inline 7380 beq common_exceptionThrown @ returned false, handle exception 7381 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7382 GET_INST_OPCODE(ip) @ extract opcode from rINST 7383 GOTO_OPCODE(ip) @ jump to next instruction 7384 7385/* ------------------------------ */ 7386 .balign 64 7387.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */ 7388/* File: armv5te/OP_EXECUTE_INLINE_RANGE.S */ 7389 /* 7390 * Execute a "native inline" instruction, using "/range" semantics. 7391 * Same idea as execute-inline, but we get the args differently. 7392 * 7393 * We need to call an InlineOp4Func: 7394 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7395 * 7396 * The first four args are in r0-r3, pointer to return value storage 7397 * is on the stack. The function's return value is a flag that tells 7398 * us if an exception was thrown. 7399 */ 7400 /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */ 7401 FETCH(r10, 1) @ r10<- BBBB 7402 add r1, rGLUE, #offGlue_retval @ r1<- &glue->retval 7403 EXPORT_PC() @ can throw 7404 sub sp, sp, #8 @ make room for arg, +64 bit align 7405 mov r0, rINST, lsr #8 @ r0<- AA 7406 str r1, [sp] @ push &glue->retval 7407 bl .LOP_EXECUTE_INLINE_RANGE_continue @ make call; will return after 7408 add sp, sp, #8 @ pop stack 7409 cmp r0, #0 @ test boolean result of inline 7410 beq common_exceptionThrown @ returned false, handle exception 7411 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7412 GET_INST_OPCODE(ip) @ extract opcode from rINST 7413 GOTO_OPCODE(ip) @ jump to next instruction 7414 7415/* ------------------------------ */ 7416 .balign 64 7417.L_OP_INVOKE_DIRECT_EMPTY: /* 0xf0 */ 7418/* File: armv5te/OP_INVOKE_DIRECT_EMPTY.S */ 7419 /* 7420 * invoke-direct-empty is a no-op in a "standard" interpreter. 7421 */ 7422 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 7423 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 7424 GOTO_OPCODE(ip) @ execute it 7425 7426/* ------------------------------ */ 7427 .balign 64 7428.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */ 7429/* File: armv5te/OP_RETURN_VOID_BARRIER.S */ 7430 SMP_DMB_ST 7431 b common_returnFromMethod 7432 7433/* ------------------------------ */ 7434 .balign 64 7435.L_OP_IGET_QUICK: /* 0xf2 */ 7436/* File: armv5te/OP_IGET_QUICK.S */ 7437 /* For: iget-quick, iget-object-quick */ 7438 /* op vA, vB, offset@CCCC */ 7439 mov r2, rINST, lsr #12 @ r2<- B 7440 GET_VREG(r3, r2) @ r3<- object we're operating on 7441 FETCH(r1, 1) @ r1<- field byte offset 7442 cmp r3, #0 @ check object for null 7443 mov r2, rINST, lsr #8 @ r2<- A(+) 7444 beq common_errNullObject @ object was null 7445 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7446 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7447 and r2, r2, #15 7448 GET_INST_OPCODE(ip) @ extract opcode from rINST 7449 SET_VREG(r0, r2) @ fp[A]<- r0 7450 GOTO_OPCODE(ip) @ jump to next instruction 7451 7452/* ------------------------------ */ 7453 .balign 64 7454.L_OP_IGET_WIDE_QUICK: /* 0xf3 */ 7455/* File: armv5te/OP_IGET_WIDE_QUICK.S */ 7456 /* iget-wide-quick vA, vB, offset@CCCC */ 7457 mov r2, rINST, lsr #12 @ r2<- B 7458 GET_VREG(r3, r2) @ r3<- object we're operating on 7459 FETCH(ip, 1) @ ip<- field byte offset 7460 cmp r3, #0 @ check object for null 7461 mov r2, rINST, lsr #8 @ r2<- A(+) 7462 beq common_errNullObject @ object was null 7463 ldrd r0, [r3, ip] @ r0<- obj.field (64 bits, aligned) 7464 and r2, r2, #15 7465 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7466 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 7467 GET_INST_OPCODE(ip) @ extract opcode from rINST 7468 stmia r3, {r0-r1} @ fp[A]<- r0/r1 7469 GOTO_OPCODE(ip) @ jump to next instruction 7470 7471/* ------------------------------ */ 7472 .balign 64 7473.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */ 7474/* File: armv5te/OP_IGET_OBJECT_QUICK.S */ 7475/* File: armv5te/OP_IGET_QUICK.S */ 7476 /* For: iget-quick, iget-object-quick */ 7477 /* op vA, vB, offset@CCCC */ 7478 mov r2, rINST, lsr #12 @ r2<- B 7479 GET_VREG(r3, r2) @ r3<- object we're operating on 7480 FETCH(r1, 1) @ r1<- field byte offset 7481 cmp r3, #0 @ check object for null 7482 mov r2, rINST, lsr #8 @ r2<- A(+) 7483 beq common_errNullObject @ object was null 7484 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7485 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7486 and r2, r2, #15 7487 GET_INST_OPCODE(ip) @ extract opcode from rINST 7488 SET_VREG(r0, r2) @ fp[A]<- r0 7489 GOTO_OPCODE(ip) @ jump to next instruction 7490 7491 7492/* ------------------------------ */ 7493 .balign 64 7494.L_OP_IPUT_QUICK: /* 0xf5 */ 7495/* File: armv5te/OP_IPUT_QUICK.S */ 7496 /* For: iput-quick */ 7497 /* op vA, vB, offset@CCCC */ 7498 mov r2, rINST, lsr #12 @ r2<- B 7499 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7500 FETCH(r1, 1) @ r1<- field byte offset 7501 cmp r3, #0 @ check object for null 7502 mov r2, rINST, lsr #8 @ r2<- A(+) 7503 beq common_errNullObject @ object was null 7504 and r2, r2, #15 7505 GET_VREG(r0, r2) @ r0<- fp[A] 7506 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7507 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7508 GET_INST_OPCODE(ip) @ extract opcode from rINST 7509 GOTO_OPCODE(ip) @ jump to next instruction 7510 7511/* ------------------------------ */ 7512 .balign 64 7513.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */ 7514/* File: armv5te/OP_IPUT_WIDE_QUICK.S */ 7515 /* iput-wide-quick vA, vB, offset@CCCC */ 7516 mov r0, rINST, lsr #8 @ r0<- A(+) 7517 mov r1, rINST, lsr #12 @ r1<- B 7518 and r0, r0, #15 7519 GET_VREG(r2, r1) @ r2<- fp[B], the object pointer 7520 add r3, rFP, r0, lsl #2 @ r3<- &fp[A] 7521 cmp r2, #0 @ check object for null 7522 ldmia r3, {r0-r1} @ r0/r1<- fp[A] 7523 beq common_errNullObject @ object was null 7524 FETCH(r3, 1) @ r3<- field byte offset 7525 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7526 strd r0, [r2, r3] @ obj.field (64 bits, aligned)<- r0/r1 7527 GET_INST_OPCODE(ip) @ extract opcode from rINST 7528 GOTO_OPCODE(ip) @ jump to next instruction 7529 7530/* ------------------------------ */ 7531 .balign 64 7532.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */ 7533/* File: armv5te/OP_IPUT_OBJECT_QUICK.S */ 7534 /* For: iput-object-quick */ 7535 /* op vA, vB, offset@CCCC */ 7536 mov r2, rINST, lsr #12 @ r2<- B 7537 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7538 FETCH(r1, 1) @ r1<- field byte offset 7539 cmp r3, #0 @ check object for null 7540 mov r2, rINST, lsr #8 @ r2<- A(+) 7541 beq common_errNullObject @ object was null 7542 and r2, r2, #15 7543 GET_VREG(r0, r2) @ r0<- fp[A] 7544 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 7545 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7546 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7547 cmp r0, #0 7548 strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head 7549 GET_INST_OPCODE(ip) @ extract opcode from rINST 7550 GOTO_OPCODE(ip) @ jump to next instruction 7551 7552/* ------------------------------ */ 7553 .balign 64 7554.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */ 7555/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7556 /* 7557 * Handle an optimized virtual method call. 7558 * 7559 * for: [opt] invoke-virtual-quick, invoke-virtual-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(r3, 2) @ r3<- FEDC or CCCC 7564 FETCH(r1, 1) @ r1<- BBBB 7565 .if (!0) 7566 and r3, r3, #15 @ r3<- C (or stays CCCC) 7567 .endif 7568 GET_VREG(r2, r3) @ r2<- vC ("this" ptr) 7569 cmp r2, #0 @ is "this" null? 7570 beq common_errNullObject @ null "this", throw exception 7571 ldr r2, [r2, #offObject_clazz] @ r2<- thisPtr->clazz 7572 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7573 EXPORT_PC() @ invoke must export 7574 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7575 bl common_invokeMethodNoRange @ continue on 7576 7577/* ------------------------------ */ 7578 .balign 64 7579.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */ 7580/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */ 7581/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7582 /* 7583 * Handle an optimized virtual method call. 7584 * 7585 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 7586 */ 7587 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7588 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7589 FETCH(r3, 2) @ r3<- FEDC or CCCC 7590 FETCH(r1, 1) @ r1<- BBBB 7591 .if (!1) 7592 and r3, r3, #15 @ r3<- C (or stays CCCC) 7593 .endif 7594 GET_VREG(r2, r3) @ r2<- vC ("this" ptr) 7595 cmp r2, #0 @ is "this" null? 7596 beq common_errNullObject @ null "this", throw exception 7597 ldr r2, [r2, #offObject_clazz] @ r2<- thisPtr->clazz 7598 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7599 EXPORT_PC() @ invoke must export 7600 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7601 bl common_invokeMethodRange @ continue on 7602 7603 7604/* ------------------------------ */ 7605 .balign 64 7606.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */ 7607/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7608 /* 7609 * Handle an optimized "super" method call. 7610 * 7611 * for: [opt] invoke-super-quick, invoke-super-quick/range 7612 */ 7613 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7614 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7615 FETCH(r10, 2) @ r10<- GFED or CCCC 7616 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7617 .if (!0) 7618 and r10, r10, #15 @ r10<- D (or stays CCCC) 7619 .endif 7620 FETCH(r1, 1) @ r1<- BBBB 7621 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7622 EXPORT_PC() @ must export for invoke 7623 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7624 GET_VREG(r3, r10) @ r3<- "this" 7625 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7626 cmp r3, #0 @ null "this" ref? 7627 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7628 beq common_errNullObject @ "this" is null, throw exception 7629 bl common_invokeMethodNoRange @ continue on 7630 7631/* ------------------------------ */ 7632 .balign 64 7633.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */ 7634/* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */ 7635/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7636 /* 7637 * Handle an optimized "super" method call. 7638 * 7639 * for: [opt] invoke-super-quick, invoke-super-quick/range 7640 */ 7641 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7642 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7643 FETCH(r10, 2) @ r10<- GFED or CCCC 7644 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7645 .if (!1) 7646 and r10, r10, #15 @ r10<- D (or stays CCCC) 7647 .endif 7648 FETCH(r1, 1) @ r1<- BBBB 7649 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7650 EXPORT_PC() @ must export for invoke 7651 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7652 GET_VREG(r3, r10) @ r3<- "this" 7653 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7654 cmp r3, #0 @ null "this" ref? 7655 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7656 beq common_errNullObject @ "this" is null, throw exception 7657 bl common_invokeMethodRange @ continue on 7658 7659 7660/* ------------------------------ */ 7661 .balign 64 7662.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */ 7663/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */ 7664/* File: armv5te/OP_IPUT_OBJECT.S */ 7665 /* 7666 * 32-bit instance field put. 7667 * 7668 * for: iput-object, iput-object-volatile 7669 */ 7670 /* op vA, vB, field@CCCC */ 7671 mov r0, rINST, lsr #12 @ r0<- B 7672 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7673 FETCH(r1, 1) @ r1<- field ref CCCC 7674 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7675 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7676 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7677 cmp r0, #0 @ is resolved entry null? 7678 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ no, already resolved 76798: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7680 EXPORT_PC() @ resolve() could throw 7681 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7682 bl dvmResolveInstField @ r0<- resolved InstField ptr 7683 cmp r0, #0 @ success? 7684 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ yes, finish up 7685 b common_exceptionThrown 7686 7687 7688/* ------------------------------ */ 7689 .balign 64 7690.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */ 7691/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */ 7692/* File: armv5te/OP_SGET.S */ 7693 /* 7694 * General 32-bit SGET handler. 7695 * 7696 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7697 */ 7698 /* op vAA, field@BBBB */ 7699 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 7700 FETCH(r1, 1) @ r1<- field ref BBBB 7701 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7702 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7703 cmp r0, #0 @ is resolved entry null? 7704 beq .LOP_SGET_OBJECT_VOLATILE_resolve @ yes, do resolve 7705.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0 7706 ldr r1, [r0, #offStaticField_value] @ r1<- field value 7707 SMP_DMB @ acquiring load 7708 mov r2, rINST, lsr #8 @ r2<- AA 7709 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7710 SET_VREG(r1, r2) @ fp[AA]<- r1 7711 GET_INST_OPCODE(ip) @ extract opcode from rINST 7712 GOTO_OPCODE(ip) @ jump to next instruction 7713 7714 7715/* ------------------------------ */ 7716 .balign 64 7717.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */ 7718/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */ 7719/* File: armv5te/OP_SPUT_OBJECT.S */ 7720 /* 7721 * 32-bit SPUT handler for objects 7722 * 7723 * for: sput-object, sput-object-volatile 7724 */ 7725 /* op vAA, field@BBBB */ 7726 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 7727 FETCH(r1, 1) @ r1<- field ref BBBB 7728 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7729 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7730 cmp r0, #0 @ is resolved entry null? 7731 bne .LOP_SPUT_OBJECT_VOLATILE_finish @ no, continue 7732 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 7733 EXPORT_PC() @ resolve() could throw, so export now 7734 ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz 7735 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 7736 cmp r0, #0 @ success? 7737 bne .LOP_SPUT_OBJECT_VOLATILE_finish @ yes, finish 7738 b common_exceptionThrown @ no, handle exception 7739 7740 7741 7742/* ------------------------------ */ 7743 .balign 64 7744.L_OP_DISPATCH_FF: /* 0xff */ 7745/* File: armv5te/OP_DISPATCH_FF.S */ 7746 mov ip, rINST, lsr #8 @ r9<- extended opcode 7747 add ip, ip, #256 @ add offset for extended opcodes 7748 GOTO_OPCODE(ip) @ go to proper extended handler 7749 7750 7751/* ------------------------------ */ 7752 .balign 64 7753.L_OP_CONST_CLASS_JUMBO: /* 0x100 */ 7754/* File: armv5te/OP_CONST_CLASS_JUMBO.S */ 7755 /* const-class/jumbo vBBBB, Class@AAAAAAAA */ 7756 FETCH(r0, 1) @ r0<- aaaa (lo) 7757 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- glue->methodClassDex 7758 FETCH(r1, 2) @ r1<- AAAA (hi) 7759 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- dvmDex->pResClasses 7760 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 7761 FETCH(r9, 3) @ r9<- BBBB 7762 ldr r0, [r2, r1, lsl #2] @ r0<- pResClasses[AAAAaaaa] 7763 cmp r0, #0 @ not yet resolved? 7764 beq .LOP_CONST_CLASS_JUMBO_resolve 7765 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 7766 GET_INST_OPCODE(ip) @ extract opcode from rINST 7767 SET_VREG(r0, r9) @ vBBBB<- r0 7768 GOTO_OPCODE(ip) @ jump to next instruction 7769 7770/* ------------------------------ */ 7771 .balign 64 7772.L_OP_CHECK_CAST_JUMBO: /* 0x101 */ 7773/* File: armv5te/OP_CHECK_CAST_JUMBO.S */ 7774 /* 7775 * Check to see if a cast from one class to another is allowed. 7776 */ 7777 /* check-cast/jumbo vBBBB, class@AAAAAAAA */ 7778 FETCH(r0, 1) @ r0<- aaaa (lo) 7779 FETCH(r2, 2) @ r2<- AAAA (hi) 7780 FETCH(r3, 3) @ r3<- BBBB 7781 orr r2, r0, r2, lsl #16 @ r2<- AAAAaaaa 7782 GET_VREG(r9, r3) @ r9<- object 7783 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- pDvmDex 7784 cmp r9, #0 @ is object null? 7785 ldr r0, [r0, #offDvmDex_pResClasses] @ r0<- pDvmDex->pResClasses 7786 beq .LOP_CHECK_CAST_JUMBO_okay @ null obj, cast always succeeds 7787 ldr r1, [r0, r2, lsl #2] @ r1<- resolved class 7788 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 7789 cmp r1, #0 @ have we resolved this before? 7790 beq .LOP_CHECK_CAST_JUMBO_resolve @ not resolved, do it now 7791.LOP_CHECK_CAST_JUMBO_resolved: 7792 cmp r0, r1 @ same class (trivial success)? 7793 bne .LOP_CHECK_CAST_JUMBO_fullcheck @ no, do full check 7794 b .LOP_CHECK_CAST_JUMBO_okay @ yes, finish up 7795 7796/* ------------------------------ */ 7797 .balign 64 7798.L_OP_INSTANCE_OF_JUMBO: /* 0x102 */ 7799/* File: armv5te/OP_INSTANCE_OF_JUMBO.S */ 7800 /* 7801 * Check to see if an object reference is an instance of a class. 7802 * 7803 * Most common situation is a non-null object, being compared against 7804 * an already-resolved class. 7805 * 7806 * TODO: convert most of this into a common subroutine, shared with 7807 * OP_INSTANCE_OF.S. 7808 */ 7809 /* instance-of/jumbo vBBBB, vCCCC, class@AAAAAAAA */ 7810 FETCH(r3, 4) @ r3<- vCCCC 7811 FETCH(r9, 3) @ r9<- vBBBB 7812 GET_VREG(r0, r3) @ r0<- vCCCC (object) 7813 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- pDvmDex 7814 cmp r0, #0 @ is object null? 7815 beq .LOP_INSTANCE_OF_JUMBO_store @ null obj, not an instance, store r0 7816 FETCH(r1, 1) @ r1<- aaaa (lo) 7817 FETCH(r3, 2) @ r3<- AAAA (hi) 7818 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- pDvmDex->pResClasses 7819 orr r3, r1, r3, lsl #16 @ r3<- AAAAaaaa 7820 ldr r1, [r2, r3, lsl #2] @ r1<- resolved class 7821 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 7822 cmp r1, #0 @ have we resolved this before? 7823 beq .LOP_INSTANCE_OF_JUMBO_resolve @ not resolved, do it now 7824 b .LOP_INSTANCE_OF_JUMBO_resolved @ resolved, continue 7825 7826/* ------------------------------ */ 7827 .balign 64 7828.L_OP_NEW_INSTANCE_JUMBO: /* 0x103 */ 7829/* File: armv5te/OP_NEW_INSTANCE_JUMBO.S */ 7830 /* 7831 * Create a new instance of a class. 7832 */ 7833 /* new-instance/jumbo vBBBB, class@AAAAAAAA */ 7834 FETCH(r0, 1) @ r0<- aaaa (lo) 7835 FETCH(r1, 2) @ r1<- AAAA (hi) 7836 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 7837 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 7838 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 7839 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 7840 EXPORT_PC() @ req'd for init, resolve, alloc 7841 cmp r0, #0 @ already resolved? 7842 beq .LOP_NEW_INSTANCE_JUMBO_resolve @ no, resolve it now 7843.LOP_NEW_INSTANCE_JUMBO_resolved: @ r0=class 7844 ldrb r1, [r0, #offClassObject_status] @ r1<- ClassStatus enum 7845 cmp r1, #CLASS_INITIALIZED @ has class been initialized? 7846 bne .LOP_NEW_INSTANCE_JUMBO_needinit @ no, init class now 7847.LOP_NEW_INSTANCE_JUMBO_initialized: @ r0=class 7848 mov r1, #ALLOC_DONT_TRACK @ flags for alloc call 7849 bl dvmAllocObject @ r0<- new object 7850 b .LOP_NEW_INSTANCE_JUMBO_finish @ continue 7851 7852/* ------------------------------ */ 7853 .balign 64 7854.L_OP_NEW_ARRAY_JUMBO: /* 0x104 */ 7855/* File: armv5te/OP_NEW_ARRAY_JUMBO.S */ 7856 /* 7857 * Allocate an array of objects, specified with the array class 7858 * and a count. 7859 * 7860 * The verifier guarantees that this is an array class, so we don't 7861 * check for it here. 7862 */ 7863 /* new-array/jumbo vBBBB, vCCCC, class@AAAAAAAA */ 7864 FETCH(r2, 1) @ r2<- aaaa (lo) 7865 FETCH(r3, 2) @ r3<- AAAA (hi) 7866 FETCH(r0, 4) @ r0<- vCCCC 7867 orr r2, r2, r3, lsl #16 @ r2<- AAAAaaaa 7868 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 7869 GET_VREG(r1, r0) @ r1<- vCCCC (array length) 7870 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 7871 cmp r1, #0 @ check length 7872 ldr r0, [r3, r2, lsl #2] @ r0<- resolved class 7873 bmi common_errNegativeArraySize @ negative length, bail 7874 cmp r0, #0 @ already resolved? 7875 EXPORT_PC() @ req'd for resolve, alloc 7876 bne .LOP_NEW_ARRAY_JUMBO_finish @ resolved, continue 7877 b .LOP_NEW_ARRAY_JUMBO_resolve @ do resolve now 7878 7879/* ------------------------------ */ 7880 .balign 64 7881.L_OP_FILLED_NEW_ARRAY_JUMBO: /* 0x105 */ 7882/* File: armv5te/OP_FILLED_NEW_ARRAY_JUMBO.S */ 7883 /* 7884 * Create a new array with elements filled from registers. 7885 * 7886 * TODO: convert most of this into a common subroutine, shared with 7887 * OP_FILLED_NEW_ARRAY.S. 7888 */ 7889 /* filled-new-array/jumbo {vCCCC..v(CCCC+BBBB-1)}, type@AAAAAAAA */ 7890 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 7891 FETCH(r0, 1) @ r0<- aaaa (lo) 7892 FETCH(r1, 2) @ r1<- AAAA (hi) 7893 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 7894 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 7895 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 7896 EXPORT_PC() @ need for resolve and alloc 7897 cmp r0, #0 @ already resolved? 7898 bne .LOP_FILLED_NEW_ARRAY_JUMBO_continue @ yes, continue on 78998: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 7900 mov r2, #0 @ r2<- false 7901 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 7902 bl dvmResolveClass @ r0<- call(clazz, ref) 7903 cmp r0, #0 @ got null? 7904 beq common_exceptionThrown @ yes, handle exception 7905 b .LOP_FILLED_NEW_ARRAY_JUMBO_continue 7906 7907/* ------------------------------ */ 7908 .balign 64 7909.L_OP_IGET_JUMBO: /* 0x106 */ 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_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_JUMBO_resolved @ resolved, continue 7933 7934/* ------------------------------ */ 7935 .balign 64 7936.L_OP_IGET_WIDE_JUMBO: /* 0x107 */ 7937/* File: armv5te/OP_IGET_WIDE_JUMBO.S */ 7938 /* 7939 * Jumbo 64-bit instance field get. 7940 */ 7941 /* iget-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */ 7942 FETCH(r1, 1) @ r1<- aaaa (lo) 7943 FETCH(r2, 2) @ r2<- AAAA (hi) 7944 FETCH(r0, 4) @ r0<- CCCC 7945 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7946 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 7947 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7948 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 7949 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7950 cmp r0, #0 @ is resolved entry null? 7951 bne .LOP_IGET_WIDE_JUMBO_finish @ no, already resolved 79528: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7953 EXPORT_PC() @ resolve() could throw 7954 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7955 bl dvmResolveInstField @ r0<- resolved InstField ptr 7956 b .LOP_IGET_WIDE_JUMBO_resolved @ resolved, continue 7957 7958/* ------------------------------ */ 7959 .balign 64 7960.L_OP_IGET_OBJECT_JUMBO: /* 0x108 */ 7961/* File: armv5te/OP_IGET_OBJECT_JUMBO.S */ 7962/* File: armv5te/OP_IGET_JUMBO.S */ 7963 /* 7964 * Jumbo 32-bit instance field get. 7965 * 7966 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 7967 * iget-char/jumbo, iget-short/jumbo 7968 */ 7969 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 7970 FETCH(r1, 1) @ r1<- aaaa (lo) 7971 FETCH(r2, 2) @ r2<- AAAA (hi) 7972 FETCH(r0, 4) @ r0<- CCCC 7973 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7974 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 7975 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7976 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 7977 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7978 cmp r0, #0 @ is resolved entry null? 7979 bne .LOP_IGET_OBJECT_JUMBO_finish @ no, already resolved 79808: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7981 EXPORT_PC() @ resolve() could throw 7982 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7983 bl dvmResolveInstField @ r0<- resolved InstField ptr 7984 b .LOP_IGET_OBJECT_JUMBO_resolved @ resolved, continue 7985 7986 7987/* ------------------------------ */ 7988 .balign 64 7989.L_OP_IGET_BOOLEAN_JUMBO: /* 0x109 */ 7990/* File: armv5te/OP_IGET_BOOLEAN_JUMBO.S */ 7991@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrb", "sqnum":"1" } 7992/* File: armv5te/OP_IGET_JUMBO.S */ 7993 /* 7994 * Jumbo 32-bit instance field get. 7995 * 7996 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 7997 * iget-char/jumbo, iget-short/jumbo 7998 */ 7999 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8000 FETCH(r1, 1) @ r1<- aaaa (lo) 8001 FETCH(r2, 2) @ r2<- AAAA (hi) 8002 FETCH(r0, 4) @ r0<- CCCC 8003 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8004 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8005 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8006 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8007 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8008 cmp r0, #0 @ is resolved entry null? 8009 bne .LOP_IGET_BOOLEAN_JUMBO_finish @ no, already resolved 80108: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8011 EXPORT_PC() @ resolve() could throw 8012 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8013 bl dvmResolveInstField @ r0<- resolved InstField ptr 8014 b .LOP_IGET_BOOLEAN_JUMBO_resolved @ resolved, continue 8015 8016 8017/* ------------------------------ */ 8018 .balign 64 8019.L_OP_IGET_BYTE_JUMBO: /* 0x10a */ 8020/* File: armv5te/OP_IGET_BYTE_JUMBO.S */ 8021@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsb", "sqnum":"2" } 8022/* File: armv5te/OP_IGET_JUMBO.S */ 8023 /* 8024 * Jumbo 32-bit instance field get. 8025 * 8026 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 8027 * iget-char/jumbo, iget-short/jumbo 8028 */ 8029 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8030 FETCH(r1, 1) @ r1<- aaaa (lo) 8031 FETCH(r2, 2) @ r2<- AAAA (hi) 8032 FETCH(r0, 4) @ r0<- CCCC 8033 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8034 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8035 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8036 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8037 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8038 cmp r0, #0 @ is resolved entry null? 8039 bne .LOP_IGET_BYTE_JUMBO_finish @ no, already resolved 80408: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8041 EXPORT_PC() @ resolve() could throw 8042 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8043 bl dvmResolveInstField @ r0<- resolved InstField ptr 8044 b .LOP_IGET_BYTE_JUMBO_resolved @ resolved, continue 8045 8046 8047/* ------------------------------ */ 8048 .balign 64 8049.L_OP_IGET_CHAR_JUMBO: /* 0x10b */ 8050/* File: armv5te/OP_IGET_CHAR_JUMBO.S */ 8051@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrh", "sqnum":"3" } 8052/* File: armv5te/OP_IGET_JUMBO.S */ 8053 /* 8054 * Jumbo 32-bit instance field get. 8055 * 8056 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 8057 * iget-char/jumbo, iget-short/jumbo 8058 */ 8059 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8060 FETCH(r1, 1) @ r1<- aaaa (lo) 8061 FETCH(r2, 2) @ r2<- AAAA (hi) 8062 FETCH(r0, 4) @ r0<- CCCC 8063 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8064 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8065 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8066 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8067 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8068 cmp r0, #0 @ is resolved entry null? 8069 bne .LOP_IGET_CHAR_JUMBO_finish @ no, already resolved 80708: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8071 EXPORT_PC() @ resolve() could throw 8072 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8073 bl dvmResolveInstField @ r0<- resolved InstField ptr 8074 b .LOP_IGET_CHAR_JUMBO_resolved @ resolved, continue 8075 8076 8077/* ------------------------------ */ 8078 .balign 64 8079.L_OP_IGET_SHORT_JUMBO: /* 0x10c */ 8080/* File: armv5te/OP_IGET_SHORT_JUMBO.S */ 8081@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsh", "sqnum":"4" } 8082/* File: armv5te/OP_IGET_JUMBO.S */ 8083 /* 8084 * Jumbo 32-bit instance field get. 8085 * 8086 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 8087 * iget-char/jumbo, iget-short/jumbo 8088 */ 8089 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8090 FETCH(r1, 1) @ r1<- aaaa (lo) 8091 FETCH(r2, 2) @ r2<- AAAA (hi) 8092 FETCH(r0, 4) @ r0<- CCCC 8093 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8094 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8095 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8096 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8097 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8098 cmp r0, #0 @ is resolved entry null? 8099 bne .LOP_IGET_SHORT_JUMBO_finish @ no, already resolved 81008: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8101 EXPORT_PC() @ resolve() could throw 8102 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8103 bl dvmResolveInstField @ r0<- resolved InstField ptr 8104 b .LOP_IGET_SHORT_JUMBO_resolved @ resolved, continue 8105 8106 8107/* ------------------------------ */ 8108 .balign 64 8109.L_OP_IPUT_JUMBO: /* 0x10d */ 8110/* File: armv5te/OP_IPUT_JUMBO.S */ 8111 /* 8112 * Jumbo 32-bit instance field put. 8113 * 8114 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8115 * iput-short/jumbo 8116 */ 8117 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8118 FETCH(r1, 1) @ r1<- aaaa (lo) 8119 FETCH(r2, 2) @ r2<- AAAA (hi) 8120 FETCH(r0, 4) @ r0<- CCCC 8121 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8122 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8123 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8124 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8125 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8126 cmp r0, #0 @ is resolved entry null? 8127 bne .LOP_IPUT_JUMBO_finish @ no, already resolved 81288: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8129 EXPORT_PC() @ resolve() could throw 8130 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8131 bl dvmResolveInstField @ r0<- resolved InstField ptr 8132 b .LOP_IPUT_JUMBO_resolved @ resolved, continue 8133 8134/* ------------------------------ */ 8135 .balign 64 8136.L_OP_IPUT_WIDE_JUMBO: /* 0x10e */ 8137/* File: armv5te/OP_IPUT_WIDE_JUMBO.S */ 8138 /* iput-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */ 8139 FETCH(r1, 1) @ r1<- aaaa (lo) 8140 FETCH(r2, 2) @ r2<- AAAA (hi) 8141 FETCH(r0, 4) @ r0<- CCCC 8142 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8143 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8144 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 8145 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 8146 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8147 cmp r0, #0 @ is resolved entry null? 8148 bne .LOP_IPUT_WIDE_JUMBO_finish @ no, already resolved 81498: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8150 EXPORT_PC() @ resolve() could throw 8151 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8152 bl dvmResolveInstField @ r0<- resolved InstField ptr 8153 b .LOP_IPUT_WIDE_JUMBO_resolved @ resolved, continue 8154 8155/* ------------------------------ */ 8156 .balign 64 8157.L_OP_IPUT_OBJECT_JUMBO: /* 0x10f */ 8158/* File: armv5te/OP_IPUT_OBJECT_JUMBO.S */ 8159 /* 8160 * Jumbo 32-bit instance field put. 8161 */ 8162 /* iput-object/jumbo vBBBB, vCCCC, field@AAAAAAAA */ 8163 FETCH(r1, 1) @ r1<- aaaa (lo) 8164 FETCH(r2, 2) @ r2<- AAAA (hi) 8165 FETCH(r0, 4) @ r0<- CCCC 8166 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8167 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8168 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8169 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8170 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8171 cmp r0, #0 @ is resolved entry null? 8172 bne .LOP_IPUT_OBJECT_JUMBO_finish @ no, already resolved 81738: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8174 EXPORT_PC() @ resolve() could throw 8175 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8176 bl dvmResolveInstField @ r0<- resolved InstField ptr 8177 b .LOP_IPUT_OBJECT_JUMBO_resolved @ resolved, continue 8178 8179/* ------------------------------ */ 8180 .balign 64 8181.L_OP_IPUT_BOOLEAN_JUMBO: /* 0x110 */ 8182/* File: armv5te/OP_IPUT_BOOLEAN_JUMBO.S */ 8183@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"1" } 8184/* File: armv5te/OP_IPUT_JUMBO.S */ 8185 /* 8186 * Jumbo 32-bit instance field put. 8187 * 8188 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8189 * iput-short/jumbo 8190 */ 8191 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8192 FETCH(r1, 1) @ r1<- aaaa (lo) 8193 FETCH(r2, 2) @ r2<- AAAA (hi) 8194 FETCH(r0, 4) @ r0<- CCCC 8195 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8196 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8197 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8198 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8199 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8200 cmp r0, #0 @ is resolved entry null? 8201 bne .LOP_IPUT_BOOLEAN_JUMBO_finish @ no, already resolved 82028: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8203 EXPORT_PC() @ resolve() could throw 8204 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8205 bl dvmResolveInstField @ r0<- resolved InstField ptr 8206 b .LOP_IPUT_BOOLEAN_JUMBO_resolved @ resolved, continue 8207 8208 8209/* ------------------------------ */ 8210 .balign 64 8211.L_OP_IPUT_BYTE_JUMBO: /* 0x111 */ 8212/* File: armv5te/OP_IPUT_BYTE_JUMBO.S */ 8213@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"2" } 8214/* File: armv5te/OP_IPUT_JUMBO.S */ 8215 /* 8216 * Jumbo 32-bit instance field put. 8217 * 8218 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8219 * iput-short/jumbo 8220 */ 8221 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8222 FETCH(r1, 1) @ r1<- aaaa (lo) 8223 FETCH(r2, 2) @ r2<- AAAA (hi) 8224 FETCH(r0, 4) @ r0<- CCCC 8225 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8226 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8227 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8228 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8229 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8230 cmp r0, #0 @ is resolved entry null? 8231 bne .LOP_IPUT_BYTE_JUMBO_finish @ no, already resolved 82328: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8233 EXPORT_PC() @ resolve() could throw 8234 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8235 bl dvmResolveInstField @ r0<- resolved InstField ptr 8236 b .LOP_IPUT_BYTE_JUMBO_resolved @ resolved, continue 8237 8238 8239/* ------------------------------ */ 8240 .balign 64 8241.L_OP_IPUT_CHAR_JUMBO: /* 0x112 */ 8242/* File: armv5te/OP_IPUT_CHAR_JUMBO.S */ 8243@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"3" } 8244/* File: armv5te/OP_IPUT_JUMBO.S */ 8245 /* 8246 * Jumbo 32-bit instance field put. 8247 * 8248 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8249 * iput-short/jumbo 8250 */ 8251 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8252 FETCH(r1, 1) @ r1<- aaaa (lo) 8253 FETCH(r2, 2) @ r2<- AAAA (hi) 8254 FETCH(r0, 4) @ r0<- CCCC 8255 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8256 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8257 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8258 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8259 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8260 cmp r0, #0 @ is resolved entry null? 8261 bne .LOP_IPUT_CHAR_JUMBO_finish @ no, already resolved 82628: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8263 EXPORT_PC() @ resolve() could throw 8264 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8265 bl dvmResolveInstField @ r0<- resolved InstField ptr 8266 b .LOP_IPUT_CHAR_JUMBO_resolved @ resolved, continue 8267 8268 8269/* ------------------------------ */ 8270 .balign 64 8271.L_OP_IPUT_SHORT_JUMBO: /* 0x113 */ 8272/* File: armv5te/OP_IPUT_SHORT_JUMBO.S */ 8273@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"4" } 8274/* File: armv5te/OP_IPUT_JUMBO.S */ 8275 /* 8276 * Jumbo 32-bit instance field put. 8277 * 8278 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8279 * iput-short/jumbo 8280 */ 8281 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8282 FETCH(r1, 1) @ r1<- aaaa (lo) 8283 FETCH(r2, 2) @ r2<- AAAA (hi) 8284 FETCH(r0, 4) @ r0<- CCCC 8285 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8286 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8287 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8288 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8289 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8290 cmp r0, #0 @ is resolved entry null? 8291 bne .LOP_IPUT_SHORT_JUMBO_finish @ no, already resolved 82928: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8293 EXPORT_PC() @ resolve() could throw 8294 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8295 bl dvmResolveInstField @ r0<- resolved InstField ptr 8296 b .LOP_IPUT_SHORT_JUMBO_resolved @ resolved, continue 8297 8298 8299/* ------------------------------ */ 8300 .balign 64 8301.L_OP_SGET_JUMBO: /* 0x114 */ 8302/* File: armv5te/OP_SGET_JUMBO.S */ 8303 /* 8304 * Jumbo 32-bit SGET handler. 8305 * 8306 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8307 * sget-char/jumbo, sget-short/jumbo 8308 */ 8309 /* exop vBBBB, field@AAAAAAAA */ 8310 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8311 FETCH(r0, 1) @ r0<- aaaa (lo) 8312 FETCH(r1, 2) @ r1<- AAAA (hi) 8313 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8314 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8315 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8316 cmp r0, #0 @ is resolved entry null? 8317 beq .LOP_SGET_JUMBO_resolve @ yes, do resolve 8318.LOP_SGET_JUMBO_finish: @ field ptr in r0 8319 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8320 @ no-op @ acquiring load 8321 FETCH(r2, 3) @ r2<- BBBB 8322 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8323 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8324 GET_INST_OPCODE(ip) @ extract opcode from rINST 8325 GOTO_OPCODE(ip) @ jump to next instruction 8326 8327/* ------------------------------ */ 8328 .balign 64 8329.L_OP_SGET_WIDE_JUMBO: /* 0x115 */ 8330/* File: armv5te/OP_SGET_WIDE_JUMBO.S */ 8331 /* 8332 * Jumbo 64-bit SGET handler. 8333 */ 8334 /* sget-wide/jumbo vBBBB, field@AAAAAAAA */ 8335 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8336 FETCH(r0, 1) @ r0<- aaaa (lo) 8337 FETCH(r1, 2) @ r1<- AAAA (hi) 8338 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8339 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8340 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8341 cmp r0, #0 @ is resolved entry null? 8342 beq .LOP_SGET_WIDE_JUMBO_resolve @ yes, do resolve 8343.LOP_SGET_WIDE_JUMBO_finish: 8344 FETCH(r9, 3) @ r9<- BBBB 8345 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 8346 add r9, rFP, r9, lsl #2 @ r9<- &fp[BBBB] 8347 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8348 stmia r9, {r0-r1} @ vBBBB/vBBBB+1<- r0/r1 8349 GET_INST_OPCODE(ip) @ extract opcode from rINST 8350 GOTO_OPCODE(ip) @ jump to next instruction 8351 8352/* ------------------------------ */ 8353 .balign 64 8354.L_OP_SGET_OBJECT_JUMBO: /* 0x116 */ 8355/* File: armv5te/OP_SGET_OBJECT_JUMBO.S */ 8356/* File: armv5te/OP_SGET_JUMBO.S */ 8357 /* 8358 * Jumbo 32-bit SGET handler. 8359 * 8360 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8361 * sget-char/jumbo, sget-short/jumbo 8362 */ 8363 /* exop vBBBB, field@AAAAAAAA */ 8364 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8365 FETCH(r0, 1) @ r0<- aaaa (lo) 8366 FETCH(r1, 2) @ r1<- AAAA (hi) 8367 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8368 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8369 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8370 cmp r0, #0 @ is resolved entry null? 8371 beq .LOP_SGET_OBJECT_JUMBO_resolve @ yes, do resolve 8372.LOP_SGET_OBJECT_JUMBO_finish: @ field ptr in r0 8373 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8374 @ no-op @ acquiring load 8375 FETCH(r2, 3) @ r2<- BBBB 8376 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8377 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8378 GET_INST_OPCODE(ip) @ extract opcode from rINST 8379 GOTO_OPCODE(ip) @ jump to next instruction 8380 8381 8382/* ------------------------------ */ 8383 .balign 64 8384.L_OP_SGET_BOOLEAN_JUMBO: /* 0x117 */ 8385/* File: armv5te/OP_SGET_BOOLEAN_JUMBO.S */ 8386/* File: armv5te/OP_SGET_JUMBO.S */ 8387 /* 8388 * Jumbo 32-bit SGET handler. 8389 * 8390 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8391 * sget-char/jumbo, sget-short/jumbo 8392 */ 8393 /* exop vBBBB, field@AAAAAAAA */ 8394 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8395 FETCH(r0, 1) @ r0<- aaaa (lo) 8396 FETCH(r1, 2) @ r1<- AAAA (hi) 8397 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8398 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8399 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8400 cmp r0, #0 @ is resolved entry null? 8401 beq .LOP_SGET_BOOLEAN_JUMBO_resolve @ yes, do resolve 8402.LOP_SGET_BOOLEAN_JUMBO_finish: @ field ptr in r0 8403 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8404 @ no-op @ acquiring load 8405 FETCH(r2, 3) @ r2<- BBBB 8406 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8407 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8408 GET_INST_OPCODE(ip) @ extract opcode from rINST 8409 GOTO_OPCODE(ip) @ jump to next instruction 8410 8411 8412/* ------------------------------ */ 8413 .balign 64 8414.L_OP_SGET_BYTE_JUMBO: /* 0x118 */ 8415/* File: armv5te/OP_SGET_BYTE_JUMBO.S */ 8416/* File: armv5te/OP_SGET_JUMBO.S */ 8417 /* 8418 * Jumbo 32-bit SGET handler. 8419 * 8420 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8421 * sget-char/jumbo, sget-short/jumbo 8422 */ 8423 /* exop vBBBB, field@AAAAAAAA */ 8424 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8425 FETCH(r0, 1) @ r0<- aaaa (lo) 8426 FETCH(r1, 2) @ r1<- AAAA (hi) 8427 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8428 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8429 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8430 cmp r0, #0 @ is resolved entry null? 8431 beq .LOP_SGET_BYTE_JUMBO_resolve @ yes, do resolve 8432.LOP_SGET_BYTE_JUMBO_finish: @ field ptr in r0 8433 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8434 @ no-op @ acquiring load 8435 FETCH(r2, 3) @ r2<- BBBB 8436 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8437 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8438 GET_INST_OPCODE(ip) @ extract opcode from rINST 8439 GOTO_OPCODE(ip) @ jump to next instruction 8440 8441 8442/* ------------------------------ */ 8443 .balign 64 8444.L_OP_SGET_CHAR_JUMBO: /* 0x119 */ 8445/* File: armv5te/OP_SGET_CHAR_JUMBO.S */ 8446/* File: armv5te/OP_SGET_JUMBO.S */ 8447 /* 8448 * Jumbo 32-bit SGET handler. 8449 * 8450 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8451 * sget-char/jumbo, sget-short/jumbo 8452 */ 8453 /* exop vBBBB, field@AAAAAAAA */ 8454 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8455 FETCH(r0, 1) @ r0<- aaaa (lo) 8456 FETCH(r1, 2) @ r1<- AAAA (hi) 8457 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8458 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8459 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8460 cmp r0, #0 @ is resolved entry null? 8461 beq .LOP_SGET_CHAR_JUMBO_resolve @ yes, do resolve 8462.LOP_SGET_CHAR_JUMBO_finish: @ field ptr in r0 8463 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8464 @ no-op @ acquiring load 8465 FETCH(r2, 3) @ r2<- BBBB 8466 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8467 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8468 GET_INST_OPCODE(ip) @ extract opcode from rINST 8469 GOTO_OPCODE(ip) @ jump to next instruction 8470 8471 8472/* ------------------------------ */ 8473 .balign 64 8474.L_OP_SGET_SHORT_JUMBO: /* 0x11a */ 8475/* File: armv5te/OP_SGET_SHORT_JUMBO.S */ 8476/* File: armv5te/OP_SGET_JUMBO.S */ 8477 /* 8478 * Jumbo 32-bit SGET handler. 8479 * 8480 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8481 * sget-char/jumbo, sget-short/jumbo 8482 */ 8483 /* exop vBBBB, field@AAAAAAAA */ 8484 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8485 FETCH(r0, 1) @ r0<- aaaa (lo) 8486 FETCH(r1, 2) @ r1<- AAAA (hi) 8487 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8488 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8489 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8490 cmp r0, #0 @ is resolved entry null? 8491 beq .LOP_SGET_SHORT_JUMBO_resolve @ yes, do resolve 8492.LOP_SGET_SHORT_JUMBO_finish: @ field ptr in r0 8493 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8494 @ no-op @ acquiring load 8495 FETCH(r2, 3) @ r2<- BBBB 8496 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8497 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8498 GET_INST_OPCODE(ip) @ extract opcode from rINST 8499 GOTO_OPCODE(ip) @ jump to next instruction 8500 8501 8502/* ------------------------------ */ 8503 .balign 64 8504.L_OP_SPUT_JUMBO: /* 0x11b */ 8505/* File: armv5te/OP_SPUT_JUMBO.S */ 8506 /* 8507 * Jumbo 32-bit SPUT handler. 8508 * 8509 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8510 * sput-short/jumbo 8511 */ 8512 /* exop vBBBB, field@AAAAAAAA */ 8513 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8514 FETCH(r0, 1) @ r0<- aaaa (lo) 8515 FETCH(r1, 2) @ r1<- AAAA (hi) 8516 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8517 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8518 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8519 cmp r0, #0 @ is resolved entry null? 8520 beq .LOP_SPUT_JUMBO_resolve @ yes, do resolve 8521.LOP_SPUT_JUMBO_finish: @ field ptr in r0 8522 FETCH(r2, 3) @ r2<- BBBB 8523 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8524 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8525 GET_INST_OPCODE(ip) @ extract opcode from rINST 8526 @ no-op @ releasing store 8527 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8528 GOTO_OPCODE(ip) @ jump to next instruction 8529 8530/* ------------------------------ */ 8531 .balign 64 8532.L_OP_SPUT_WIDE_JUMBO: /* 0x11c */ 8533/* File: armv5te/OP_SPUT_WIDE_JUMBO.S */ 8534 /* 8535 * Jumbo 64-bit SPUT handler. 8536 */ 8537 /* sput-wide/jumbo vBBBB, field@AAAAAAAA */ 8538 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- DvmDex 8539 FETCH(r1, 1) @ r1<- aaaa (lo) 8540 FETCH(r2, 2) @ r2<- AAAA (hi) 8541 ldr r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields 8542 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8543 FETCH(r9, 3) @ r9<- BBBB 8544 ldr r2, [r0, r1, lsl #2] @ r2<- resolved StaticField ptr 8545 add r9, rFP, r9, lsl #2 @ r9<- &fp[BBBB] 8546 cmp r2, #0 @ is resolved entry null? 8547 beq .LOP_SPUT_WIDE_JUMBO_resolve @ yes, do resolve 8548.LOP_SPUT_WIDE_JUMBO_finish: @ field ptr in r2, BBBB in r9 8549 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8550 ldmia r9, {r0-r1} @ r0/r1<- vBBBB/vBBBB+1 8551 GET_INST_OPCODE(r10) @ extract opcode from rINST 8552 strd r0, [r2, #offStaticField_value] @ field<- vBBBB/vBBBB+1 8553 GOTO_OPCODE(r10) @ jump to next instruction 8554 8555/* ------------------------------ */ 8556 .balign 64 8557.L_OP_SPUT_OBJECT_JUMBO: /* 0x11d */ 8558/* File: armv5te/OP_SPUT_OBJECT_JUMBO.S */ 8559 /* 8560 * Jumbo 32-bit SPUT handler for objects 8561 */ 8562 /* sput-object/jumbo vBBBB, field@AAAAAAAA */ 8563 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8564 FETCH(r0, 1) @ r0<- aaaa (lo) 8565 FETCH(r1, 2) @ r1<- AAAA (hi) 8566 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8567 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8568 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8569 cmp r0, #0 @ is resolved entry null? 8570 bne .LOP_SPUT_OBJECT_JUMBO_finish @ no, continue 8571 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 8572 EXPORT_PC() @ resolve() could throw, so export now 8573 ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz 8574 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8575 cmp r0, #0 @ success? 8576 bne .LOP_SPUT_OBJECT_JUMBO_finish @ yes, finish 8577 b common_exceptionThrown @ no, handle exception 8578 8579/* ------------------------------ */ 8580 .balign 64 8581.L_OP_SPUT_BOOLEAN_JUMBO: /* 0x11e */ 8582/* File: armv5te/OP_SPUT_BOOLEAN_JUMBO.S */ 8583/* File: armv5te/OP_SPUT_JUMBO.S */ 8584 /* 8585 * Jumbo 32-bit SPUT handler. 8586 * 8587 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8588 * sput-short/jumbo 8589 */ 8590 /* exop vBBBB, field@AAAAAAAA */ 8591 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8592 FETCH(r0, 1) @ r0<- aaaa (lo) 8593 FETCH(r1, 2) @ r1<- AAAA (hi) 8594 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8595 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8596 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8597 cmp r0, #0 @ is resolved entry null? 8598 beq .LOP_SPUT_BOOLEAN_JUMBO_resolve @ yes, do resolve 8599.LOP_SPUT_BOOLEAN_JUMBO_finish: @ field ptr in r0 8600 FETCH(r2, 3) @ r2<- BBBB 8601 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8602 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8603 GET_INST_OPCODE(ip) @ extract opcode from rINST 8604 @ no-op @ releasing store 8605 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8606 GOTO_OPCODE(ip) @ jump to next instruction 8607 8608 8609/* ------------------------------ */ 8610 .balign 64 8611.L_OP_SPUT_BYTE_JUMBO: /* 0x11f */ 8612/* File: armv5te/OP_SPUT_BYTE_JUMBO.S */ 8613/* File: armv5te/OP_SPUT_JUMBO.S */ 8614 /* 8615 * Jumbo 32-bit SPUT handler. 8616 * 8617 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8618 * sput-short/jumbo 8619 */ 8620 /* exop vBBBB, field@AAAAAAAA */ 8621 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8622 FETCH(r0, 1) @ r0<- aaaa (lo) 8623 FETCH(r1, 2) @ r1<- AAAA (hi) 8624 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8625 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8626 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8627 cmp r0, #0 @ is resolved entry null? 8628 beq .LOP_SPUT_BYTE_JUMBO_resolve @ yes, do resolve 8629.LOP_SPUT_BYTE_JUMBO_finish: @ field ptr in r0 8630 FETCH(r2, 3) @ r2<- BBBB 8631 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8632 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8633 GET_INST_OPCODE(ip) @ extract opcode from rINST 8634 @ no-op @ releasing store 8635 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8636 GOTO_OPCODE(ip) @ jump to next instruction 8637 8638 8639/* ------------------------------ */ 8640 .balign 64 8641.L_OP_SPUT_CHAR_JUMBO: /* 0x120 */ 8642/* File: armv5te/OP_SPUT_CHAR_JUMBO.S */ 8643/* File: armv5te/OP_SPUT_JUMBO.S */ 8644 /* 8645 * Jumbo 32-bit SPUT handler. 8646 * 8647 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8648 * sput-short/jumbo 8649 */ 8650 /* exop vBBBB, field@AAAAAAAA */ 8651 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8652 FETCH(r0, 1) @ r0<- aaaa (lo) 8653 FETCH(r1, 2) @ r1<- AAAA (hi) 8654 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8655 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8656 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8657 cmp r0, #0 @ is resolved entry null? 8658 beq .LOP_SPUT_CHAR_JUMBO_resolve @ yes, do resolve 8659.LOP_SPUT_CHAR_JUMBO_finish: @ field ptr in r0 8660 FETCH(r2, 3) @ r2<- BBBB 8661 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8662 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8663 GET_INST_OPCODE(ip) @ extract opcode from rINST 8664 @ no-op @ releasing store 8665 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8666 GOTO_OPCODE(ip) @ jump to next instruction 8667 8668 8669/* ------------------------------ */ 8670 .balign 64 8671.L_OP_SPUT_SHORT_JUMBO: /* 0x121 */ 8672/* File: armv5te/OP_SPUT_SHORT_JUMBO.S */ 8673/* File: armv5te/OP_SPUT_JUMBO.S */ 8674 /* 8675 * Jumbo 32-bit SPUT handler. 8676 * 8677 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8678 * sput-short/jumbo 8679 */ 8680 /* exop vBBBB, field@AAAAAAAA */ 8681 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8682 FETCH(r0, 1) @ r0<- aaaa (lo) 8683 FETCH(r1, 2) @ r1<- AAAA (hi) 8684 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8685 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8686 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8687 cmp r0, #0 @ is resolved entry null? 8688 beq .LOP_SPUT_SHORT_JUMBO_resolve @ yes, do resolve 8689.LOP_SPUT_SHORT_JUMBO_finish: @ field ptr in r0 8690 FETCH(r2, 3) @ r2<- BBBB 8691 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8692 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8693 GET_INST_OPCODE(ip) @ extract opcode from rINST 8694 @ no-op @ releasing store 8695 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8696 GOTO_OPCODE(ip) @ jump to next instruction 8697 8698 8699/* ------------------------------ */ 8700 .balign 64 8701.L_OP_INVOKE_VIRTUAL_JUMBO: /* 0x122 */ 8702/* File: armv5te/OP_INVOKE_VIRTUAL_JUMBO.S */ 8703 /* 8704 * Handle a virtual method call. 8705 */ 8706 /* invoke-virtual/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8707 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 8708 FETCH(r0, 1) @ r1<- aaaa (lo) 8709 FETCH(r1, 2) @ r1<- AAAA (hi) 8710 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 8711 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8712 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 8713 cmp r0, #0 @ already resolved? 8714 EXPORT_PC() @ must export for invoke 8715 bne .LOP_INVOKE_VIRTUAL_JUMBO_continue @ yes, continue on 8716 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 8717 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 8718 mov r2, #METHOD_VIRTUAL @ resolver method type 8719 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 8720 cmp r0, #0 @ got null? 8721 bne .LOP_INVOKE_VIRTUAL_JUMBO_continue @ no, continue 8722 b common_exceptionThrown @ yes, handle exception 8723 8724/* ------------------------------ */ 8725 .balign 64 8726.L_OP_INVOKE_SUPER_JUMBO: /* 0x123 */ 8727/* File: armv5te/OP_INVOKE_SUPER_JUMBO.S */ 8728 /* 8729 * Handle a "super" method call. 8730 */ 8731 /* invoke-super/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8732 FETCH(r10, 4) @ r10<- CCCC 8733 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 8734 FETCH(r0, 1) @ r1<- aaaa (lo) 8735 FETCH(r1, 2) @ r1<- AAAA (hi) 8736 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 8737 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8738 GET_VREG(r2, r10) @ r2<- "this" ptr 8739 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 8740 cmp r2, #0 @ null "this"? 8741 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 8742 beq common_errNullObject @ null "this", throw exception 8743 cmp r0, #0 @ already resolved? 8744 ldr r9, [r9, #offMethod_clazz] @ r9<- method->clazz 8745 EXPORT_PC() @ must export for invoke 8746 bne .LOP_INVOKE_SUPER_JUMBO_continue @ resolved, continue on 8747 b .LOP_INVOKE_SUPER_JUMBO_resolve @ do resolve now 8748 8749/* ------------------------------ */ 8750 .balign 64 8751.L_OP_INVOKE_DIRECT_JUMBO: /* 0x124 */ 8752/* File: armv5te/OP_INVOKE_DIRECT_JUMBO.S */ 8753 /* 8754 * Handle a direct method call. 8755 * 8756 * (We could defer the "is 'this' pointer null" test to the common 8757 * method invocation code, and use a flag to indicate that static 8758 * calls don't count. If we do this as part of copying the arguments 8759 * out we could avoiding loading the first arg twice.) 8760 * 8761 */ 8762 /* invoke-direct/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8763 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 8764 FETCH(r0, 1) @ r1<- aaaa (lo) 8765 FETCH(r1, 2) @ r1<- AAAA (hi) 8766 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 8767 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8768 FETCH(r10, 4) @ r10<- CCCC 8769 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 8770 cmp r0, #0 @ already resolved? 8771 EXPORT_PC() @ must export for invoke 8772 GET_VREG(r2, r10) @ r2<- "this" ptr 8773 beq .LOP_INVOKE_DIRECT_JUMBO_resolve @ not resolved, do it now 8774.LOP_INVOKE_DIRECT_JUMBO_finish: 8775 cmp r2, #0 @ null "this" ref? 8776 bne common_invokeMethodJumbo @ no, continue on 8777 b common_errNullObject @ yes, throw exception 8778 8779/* ------------------------------ */ 8780 .balign 64 8781.L_OP_INVOKE_STATIC_JUMBO: /* 0x125 */ 8782/* File: armv5te/OP_INVOKE_STATIC_JUMBO.S */ 8783 /* 8784 * Handle a static method call. 8785 */ 8786 /* invoke-static/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8787 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 8788 FETCH(r0, 1) @ r1<- aaaa (lo) 8789 FETCH(r1, 2) @ r1<- AAAA (hi) 8790 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 8791 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8792 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 8793 cmp r0, #0 @ already resolved? 8794 EXPORT_PC() @ must export for invoke 8795 bne common_invokeMethodJumbo @ yes, continue on 87960: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 8797 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 8798 mov r2, #METHOD_STATIC @ resolver method type 8799 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 8800 cmp r0, #0 @ got null? 8801 bne common_invokeMethodJumbo @ no, continue 8802 b common_exceptionThrown @ yes, handle exception 8803 8804/* ------------------------------ */ 8805 .balign 64 8806.L_OP_INVOKE_INTERFACE_JUMBO: /* 0x126 */ 8807/* File: armv5te/OP_INVOKE_INTERFACE_JUMBO.S */ 8808 /* 8809 * Handle an interface method call. 8810 */ 8811 /* invoke-interface/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8812 FETCH(r2, 4) @ r2<- CCCC 8813 FETCH(r0, 1) @ r0<- aaaa (lo) 8814 FETCH(r1, 2) @ r1<- AAAA (hi) 8815 EXPORT_PC() @ must export for invoke 8816 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8817 GET_VREG(r0, r2) @ r0<- first arg ("this") 8818 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- methodClassDex 8819 cmp r0, #0 @ null obj? 8820 ldr r2, [rGLUE, #offGlue_method] @ r2<- method 8821 beq common_errNullObject @ yes, fail 8822 ldr r0, [r0, #offObject_clazz] @ r0<- thisPtr->clazz 8823 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 8824 cmp r0, #0 @ failed? 8825 beq common_exceptionThrown @ yes, handle exception 8826 b common_invokeMethodJumbo @ jump to common handler 8827 8828/* ------------------------------ */ 8829 .balign 64 8830.L_OP_UNUSED_27FF: /* 0x127 */ 8831/* File: armv5te/OP_UNUSED_27FF.S */ 8832/* File: armv5te/unused.S */ 8833 bl common_abort 8834 8835 8836/* ------------------------------ */ 8837 .balign 64 8838.L_OP_UNUSED_28FF: /* 0x128 */ 8839/* File: armv5te/OP_UNUSED_28FF.S */ 8840/* File: armv5te/unused.S */ 8841 bl common_abort 8842 8843 8844/* ------------------------------ */ 8845 .balign 64 8846.L_OP_UNUSED_29FF: /* 0x129 */ 8847/* File: armv5te/OP_UNUSED_29FF.S */ 8848/* File: armv5te/unused.S */ 8849 bl common_abort 8850 8851 8852/* ------------------------------ */ 8853 .balign 64 8854.L_OP_UNUSED_2AFF: /* 0x12a */ 8855/* File: armv5te/OP_UNUSED_2AFF.S */ 8856/* File: armv5te/unused.S */ 8857 bl common_abort 8858 8859 8860/* ------------------------------ */ 8861 .balign 64 8862.L_OP_UNUSED_2BFF: /* 0x12b */ 8863/* File: armv5te/OP_UNUSED_2BFF.S */ 8864/* File: armv5te/unused.S */ 8865 bl common_abort 8866 8867 8868/* ------------------------------ */ 8869 .balign 64 8870.L_OP_UNUSED_2CFF: /* 0x12c */ 8871/* File: armv5te/OP_UNUSED_2CFF.S */ 8872/* File: armv5te/unused.S */ 8873 bl common_abort 8874 8875 8876/* ------------------------------ */ 8877 .balign 64 8878.L_OP_UNUSED_2DFF: /* 0x12d */ 8879/* File: armv5te/OP_UNUSED_2DFF.S */ 8880/* File: armv5te/unused.S */ 8881 bl common_abort 8882 8883 8884/* ------------------------------ */ 8885 .balign 64 8886.L_OP_UNUSED_2EFF: /* 0x12e */ 8887/* File: armv5te/OP_UNUSED_2EFF.S */ 8888/* File: armv5te/unused.S */ 8889 bl common_abort 8890 8891 8892/* ------------------------------ */ 8893 .balign 64 8894.L_OP_UNUSED_2FFF: /* 0x12f */ 8895/* File: armv5te/OP_UNUSED_2FFF.S */ 8896/* File: armv5te/unused.S */ 8897 bl common_abort 8898 8899 8900/* ------------------------------ */ 8901 .balign 64 8902.L_OP_UNUSED_30FF: /* 0x130 */ 8903/* File: armv5te/OP_UNUSED_30FF.S */ 8904/* File: armv5te/unused.S */ 8905 bl common_abort 8906 8907 8908/* ------------------------------ */ 8909 .balign 64 8910.L_OP_UNUSED_31FF: /* 0x131 */ 8911/* File: armv5te/OP_UNUSED_31FF.S */ 8912/* File: armv5te/unused.S */ 8913 bl common_abort 8914 8915 8916/* ------------------------------ */ 8917 .balign 64 8918.L_OP_UNUSED_32FF: /* 0x132 */ 8919/* File: armv5te/OP_UNUSED_32FF.S */ 8920/* File: armv5te/unused.S */ 8921 bl common_abort 8922 8923 8924/* ------------------------------ */ 8925 .balign 64 8926.L_OP_UNUSED_33FF: /* 0x133 */ 8927/* File: armv5te/OP_UNUSED_33FF.S */ 8928/* File: armv5te/unused.S */ 8929 bl common_abort 8930 8931 8932/* ------------------------------ */ 8933 .balign 64 8934.L_OP_UNUSED_34FF: /* 0x134 */ 8935/* File: armv5te/OP_UNUSED_34FF.S */ 8936/* File: armv5te/unused.S */ 8937 bl common_abort 8938 8939 8940/* ------------------------------ */ 8941 .balign 64 8942.L_OP_UNUSED_35FF: /* 0x135 */ 8943/* File: armv5te/OP_UNUSED_35FF.S */ 8944/* File: armv5te/unused.S */ 8945 bl common_abort 8946 8947 8948/* ------------------------------ */ 8949 .balign 64 8950.L_OP_UNUSED_36FF: /* 0x136 */ 8951/* File: armv5te/OP_UNUSED_36FF.S */ 8952/* File: armv5te/unused.S */ 8953 bl common_abort 8954 8955 8956/* ------------------------------ */ 8957 .balign 64 8958.L_OP_UNUSED_37FF: /* 0x137 */ 8959/* File: armv5te/OP_UNUSED_37FF.S */ 8960/* File: armv5te/unused.S */ 8961 bl common_abort 8962 8963 8964/* ------------------------------ */ 8965 .balign 64 8966.L_OP_UNUSED_38FF: /* 0x138 */ 8967/* File: armv5te/OP_UNUSED_38FF.S */ 8968/* File: armv5te/unused.S */ 8969 bl common_abort 8970 8971 8972/* ------------------------------ */ 8973 .balign 64 8974.L_OP_UNUSED_39FF: /* 0x139 */ 8975/* File: armv5te/OP_UNUSED_39FF.S */ 8976/* File: armv5te/unused.S */ 8977 bl common_abort 8978 8979 8980/* ------------------------------ */ 8981 .balign 64 8982.L_OP_UNUSED_3AFF: /* 0x13a */ 8983/* File: armv5te/OP_UNUSED_3AFF.S */ 8984/* File: armv5te/unused.S */ 8985 bl common_abort 8986 8987 8988/* ------------------------------ */ 8989 .balign 64 8990.L_OP_UNUSED_3BFF: /* 0x13b */ 8991/* File: armv5te/OP_UNUSED_3BFF.S */ 8992/* File: armv5te/unused.S */ 8993 bl common_abort 8994 8995 8996/* ------------------------------ */ 8997 .balign 64 8998.L_OP_UNUSED_3CFF: /* 0x13c */ 8999/* File: armv5te/OP_UNUSED_3CFF.S */ 9000/* File: armv5te/unused.S */ 9001 bl common_abort 9002 9003 9004/* ------------------------------ */ 9005 .balign 64 9006.L_OP_UNUSED_3DFF: /* 0x13d */ 9007/* File: armv5te/OP_UNUSED_3DFF.S */ 9008/* File: armv5te/unused.S */ 9009 bl common_abort 9010 9011 9012/* ------------------------------ */ 9013 .balign 64 9014.L_OP_UNUSED_3EFF: /* 0x13e */ 9015/* File: armv5te/OP_UNUSED_3EFF.S */ 9016/* File: armv5te/unused.S */ 9017 bl common_abort 9018 9019 9020/* ------------------------------ */ 9021 .balign 64 9022.L_OP_UNUSED_3FFF: /* 0x13f */ 9023/* File: armv5te/OP_UNUSED_3FFF.S */ 9024/* File: armv5te/unused.S */ 9025 bl common_abort 9026 9027 9028/* ------------------------------ */ 9029 .balign 64 9030.L_OP_UNUSED_40FF: /* 0x140 */ 9031/* File: armv5te/OP_UNUSED_40FF.S */ 9032/* File: armv5te/unused.S */ 9033 bl common_abort 9034 9035 9036/* ------------------------------ */ 9037 .balign 64 9038.L_OP_UNUSED_41FF: /* 0x141 */ 9039/* File: armv5te/OP_UNUSED_41FF.S */ 9040/* File: armv5te/unused.S */ 9041 bl common_abort 9042 9043 9044/* ------------------------------ */ 9045 .balign 64 9046.L_OP_UNUSED_42FF: /* 0x142 */ 9047/* File: armv5te/OP_UNUSED_42FF.S */ 9048/* File: armv5te/unused.S */ 9049 bl common_abort 9050 9051 9052/* ------------------------------ */ 9053 .balign 64 9054.L_OP_UNUSED_43FF: /* 0x143 */ 9055/* File: armv5te/OP_UNUSED_43FF.S */ 9056/* File: armv5te/unused.S */ 9057 bl common_abort 9058 9059 9060/* ------------------------------ */ 9061 .balign 64 9062.L_OP_UNUSED_44FF: /* 0x144 */ 9063/* File: armv5te/OP_UNUSED_44FF.S */ 9064/* File: armv5te/unused.S */ 9065 bl common_abort 9066 9067 9068/* ------------------------------ */ 9069 .balign 64 9070.L_OP_UNUSED_45FF: /* 0x145 */ 9071/* File: armv5te/OP_UNUSED_45FF.S */ 9072/* File: armv5te/unused.S */ 9073 bl common_abort 9074 9075 9076/* ------------------------------ */ 9077 .balign 64 9078.L_OP_UNUSED_46FF: /* 0x146 */ 9079/* File: armv5te/OP_UNUSED_46FF.S */ 9080/* File: armv5te/unused.S */ 9081 bl common_abort 9082 9083 9084/* ------------------------------ */ 9085 .balign 64 9086.L_OP_UNUSED_47FF: /* 0x147 */ 9087/* File: armv5te/OP_UNUSED_47FF.S */ 9088/* File: armv5te/unused.S */ 9089 bl common_abort 9090 9091 9092/* ------------------------------ */ 9093 .balign 64 9094.L_OP_UNUSED_48FF: /* 0x148 */ 9095/* File: armv5te/OP_UNUSED_48FF.S */ 9096/* File: armv5te/unused.S */ 9097 bl common_abort 9098 9099 9100/* ------------------------------ */ 9101 .balign 64 9102.L_OP_UNUSED_49FF: /* 0x149 */ 9103/* File: armv5te/OP_UNUSED_49FF.S */ 9104/* File: armv5te/unused.S */ 9105 bl common_abort 9106 9107 9108/* ------------------------------ */ 9109 .balign 64 9110.L_OP_UNUSED_4AFF: /* 0x14a */ 9111/* File: armv5te/OP_UNUSED_4AFF.S */ 9112/* File: armv5te/unused.S */ 9113 bl common_abort 9114 9115 9116/* ------------------------------ */ 9117 .balign 64 9118.L_OP_UNUSED_4BFF: /* 0x14b */ 9119/* File: armv5te/OP_UNUSED_4BFF.S */ 9120/* File: armv5te/unused.S */ 9121 bl common_abort 9122 9123 9124/* ------------------------------ */ 9125 .balign 64 9126.L_OP_UNUSED_4CFF: /* 0x14c */ 9127/* File: armv5te/OP_UNUSED_4CFF.S */ 9128/* File: armv5te/unused.S */ 9129 bl common_abort 9130 9131 9132/* ------------------------------ */ 9133 .balign 64 9134.L_OP_UNUSED_4DFF: /* 0x14d */ 9135/* File: armv5te/OP_UNUSED_4DFF.S */ 9136/* File: armv5te/unused.S */ 9137 bl common_abort 9138 9139 9140/* ------------------------------ */ 9141 .balign 64 9142.L_OP_UNUSED_4EFF: /* 0x14e */ 9143/* File: armv5te/OP_UNUSED_4EFF.S */ 9144/* File: armv5te/unused.S */ 9145 bl common_abort 9146 9147 9148/* ------------------------------ */ 9149 .balign 64 9150.L_OP_UNUSED_4FFF: /* 0x14f */ 9151/* File: armv5te/OP_UNUSED_4FFF.S */ 9152/* File: armv5te/unused.S */ 9153 bl common_abort 9154 9155 9156/* ------------------------------ */ 9157 .balign 64 9158.L_OP_UNUSED_50FF: /* 0x150 */ 9159/* File: armv5te/OP_UNUSED_50FF.S */ 9160/* File: armv5te/unused.S */ 9161 bl common_abort 9162 9163 9164/* ------------------------------ */ 9165 .balign 64 9166.L_OP_UNUSED_51FF: /* 0x151 */ 9167/* File: armv5te/OP_UNUSED_51FF.S */ 9168/* File: armv5te/unused.S */ 9169 bl common_abort 9170 9171 9172/* ------------------------------ */ 9173 .balign 64 9174.L_OP_UNUSED_52FF: /* 0x152 */ 9175/* File: armv5te/OP_UNUSED_52FF.S */ 9176/* File: armv5te/unused.S */ 9177 bl common_abort 9178 9179 9180/* ------------------------------ */ 9181 .balign 64 9182.L_OP_UNUSED_53FF: /* 0x153 */ 9183/* File: armv5te/OP_UNUSED_53FF.S */ 9184/* File: armv5te/unused.S */ 9185 bl common_abort 9186 9187 9188/* ------------------------------ */ 9189 .balign 64 9190.L_OP_UNUSED_54FF: /* 0x154 */ 9191/* File: armv5te/OP_UNUSED_54FF.S */ 9192/* File: armv5te/unused.S */ 9193 bl common_abort 9194 9195 9196/* ------------------------------ */ 9197 .balign 64 9198.L_OP_UNUSED_55FF: /* 0x155 */ 9199/* File: armv5te/OP_UNUSED_55FF.S */ 9200/* File: armv5te/unused.S */ 9201 bl common_abort 9202 9203 9204/* ------------------------------ */ 9205 .balign 64 9206.L_OP_UNUSED_56FF: /* 0x156 */ 9207/* File: armv5te/OP_UNUSED_56FF.S */ 9208/* File: armv5te/unused.S */ 9209 bl common_abort 9210 9211 9212/* ------------------------------ */ 9213 .balign 64 9214.L_OP_UNUSED_57FF: /* 0x157 */ 9215/* File: armv5te/OP_UNUSED_57FF.S */ 9216/* File: armv5te/unused.S */ 9217 bl common_abort 9218 9219 9220/* ------------------------------ */ 9221 .balign 64 9222.L_OP_UNUSED_58FF: /* 0x158 */ 9223/* File: armv5te/OP_UNUSED_58FF.S */ 9224/* File: armv5te/unused.S */ 9225 bl common_abort 9226 9227 9228/* ------------------------------ */ 9229 .balign 64 9230.L_OP_UNUSED_59FF: /* 0x159 */ 9231/* File: armv5te/OP_UNUSED_59FF.S */ 9232/* File: armv5te/unused.S */ 9233 bl common_abort 9234 9235 9236/* ------------------------------ */ 9237 .balign 64 9238.L_OP_UNUSED_5AFF: /* 0x15a */ 9239/* File: armv5te/OP_UNUSED_5AFF.S */ 9240/* File: armv5te/unused.S */ 9241 bl common_abort 9242 9243 9244/* ------------------------------ */ 9245 .balign 64 9246.L_OP_UNUSED_5BFF: /* 0x15b */ 9247/* File: armv5te/OP_UNUSED_5BFF.S */ 9248/* File: armv5te/unused.S */ 9249 bl common_abort 9250 9251 9252/* ------------------------------ */ 9253 .balign 64 9254.L_OP_UNUSED_5CFF: /* 0x15c */ 9255/* File: armv5te/OP_UNUSED_5CFF.S */ 9256/* File: armv5te/unused.S */ 9257 bl common_abort 9258 9259 9260/* ------------------------------ */ 9261 .balign 64 9262.L_OP_UNUSED_5DFF: /* 0x15d */ 9263/* File: armv5te/OP_UNUSED_5DFF.S */ 9264/* File: armv5te/unused.S */ 9265 bl common_abort 9266 9267 9268/* ------------------------------ */ 9269 .balign 64 9270.L_OP_UNUSED_5EFF: /* 0x15e */ 9271/* File: armv5te/OP_UNUSED_5EFF.S */ 9272/* File: armv5te/unused.S */ 9273 bl common_abort 9274 9275 9276/* ------------------------------ */ 9277 .balign 64 9278.L_OP_UNUSED_5FFF: /* 0x15f */ 9279/* File: armv5te/OP_UNUSED_5FFF.S */ 9280/* File: armv5te/unused.S */ 9281 bl common_abort 9282 9283 9284/* ------------------------------ */ 9285 .balign 64 9286.L_OP_UNUSED_60FF: /* 0x160 */ 9287/* File: armv5te/OP_UNUSED_60FF.S */ 9288/* File: armv5te/unused.S */ 9289 bl common_abort 9290 9291 9292/* ------------------------------ */ 9293 .balign 64 9294.L_OP_UNUSED_61FF: /* 0x161 */ 9295/* File: armv5te/OP_UNUSED_61FF.S */ 9296/* File: armv5te/unused.S */ 9297 bl common_abort 9298 9299 9300/* ------------------------------ */ 9301 .balign 64 9302.L_OP_UNUSED_62FF: /* 0x162 */ 9303/* File: armv5te/OP_UNUSED_62FF.S */ 9304/* File: armv5te/unused.S */ 9305 bl common_abort 9306 9307 9308/* ------------------------------ */ 9309 .balign 64 9310.L_OP_UNUSED_63FF: /* 0x163 */ 9311/* File: armv5te/OP_UNUSED_63FF.S */ 9312/* File: armv5te/unused.S */ 9313 bl common_abort 9314 9315 9316/* ------------------------------ */ 9317 .balign 64 9318.L_OP_UNUSED_64FF: /* 0x164 */ 9319/* File: armv5te/OP_UNUSED_64FF.S */ 9320/* File: armv5te/unused.S */ 9321 bl common_abort 9322 9323 9324/* ------------------------------ */ 9325 .balign 64 9326.L_OP_UNUSED_65FF: /* 0x165 */ 9327/* File: armv5te/OP_UNUSED_65FF.S */ 9328/* File: armv5te/unused.S */ 9329 bl common_abort 9330 9331 9332/* ------------------------------ */ 9333 .balign 64 9334.L_OP_UNUSED_66FF: /* 0x166 */ 9335/* File: armv5te/OP_UNUSED_66FF.S */ 9336/* File: armv5te/unused.S */ 9337 bl common_abort 9338 9339 9340/* ------------------------------ */ 9341 .balign 64 9342.L_OP_UNUSED_67FF: /* 0x167 */ 9343/* File: armv5te/OP_UNUSED_67FF.S */ 9344/* File: armv5te/unused.S */ 9345 bl common_abort 9346 9347 9348/* ------------------------------ */ 9349 .balign 64 9350.L_OP_UNUSED_68FF: /* 0x168 */ 9351/* File: armv5te/OP_UNUSED_68FF.S */ 9352/* File: armv5te/unused.S */ 9353 bl common_abort 9354 9355 9356/* ------------------------------ */ 9357 .balign 64 9358.L_OP_UNUSED_69FF: /* 0x169 */ 9359/* File: armv5te/OP_UNUSED_69FF.S */ 9360/* File: armv5te/unused.S */ 9361 bl common_abort 9362 9363 9364/* ------------------------------ */ 9365 .balign 64 9366.L_OP_UNUSED_6AFF: /* 0x16a */ 9367/* File: armv5te/OP_UNUSED_6AFF.S */ 9368/* File: armv5te/unused.S */ 9369 bl common_abort 9370 9371 9372/* ------------------------------ */ 9373 .balign 64 9374.L_OP_UNUSED_6BFF: /* 0x16b */ 9375/* File: armv5te/OP_UNUSED_6BFF.S */ 9376/* File: armv5te/unused.S */ 9377 bl common_abort 9378 9379 9380/* ------------------------------ */ 9381 .balign 64 9382.L_OP_UNUSED_6CFF: /* 0x16c */ 9383/* File: armv5te/OP_UNUSED_6CFF.S */ 9384/* File: armv5te/unused.S */ 9385 bl common_abort 9386 9387 9388/* ------------------------------ */ 9389 .balign 64 9390.L_OP_UNUSED_6DFF: /* 0x16d */ 9391/* File: armv5te/OP_UNUSED_6DFF.S */ 9392/* File: armv5te/unused.S */ 9393 bl common_abort 9394 9395 9396/* ------------------------------ */ 9397 .balign 64 9398.L_OP_UNUSED_6EFF: /* 0x16e */ 9399/* File: armv5te/OP_UNUSED_6EFF.S */ 9400/* File: armv5te/unused.S */ 9401 bl common_abort 9402 9403 9404/* ------------------------------ */ 9405 .balign 64 9406.L_OP_UNUSED_6FFF: /* 0x16f */ 9407/* File: armv5te/OP_UNUSED_6FFF.S */ 9408/* File: armv5te/unused.S */ 9409 bl common_abort 9410 9411 9412/* ------------------------------ */ 9413 .balign 64 9414.L_OP_UNUSED_70FF: /* 0x170 */ 9415/* File: armv5te/OP_UNUSED_70FF.S */ 9416/* File: armv5te/unused.S */ 9417 bl common_abort 9418 9419 9420/* ------------------------------ */ 9421 .balign 64 9422.L_OP_UNUSED_71FF: /* 0x171 */ 9423/* File: armv5te/OP_UNUSED_71FF.S */ 9424/* File: armv5te/unused.S */ 9425 bl common_abort 9426 9427 9428/* ------------------------------ */ 9429 .balign 64 9430.L_OP_UNUSED_72FF: /* 0x172 */ 9431/* File: armv5te/OP_UNUSED_72FF.S */ 9432/* File: armv5te/unused.S */ 9433 bl common_abort 9434 9435 9436/* ------------------------------ */ 9437 .balign 64 9438.L_OP_UNUSED_73FF: /* 0x173 */ 9439/* File: armv5te/OP_UNUSED_73FF.S */ 9440/* File: armv5te/unused.S */ 9441 bl common_abort 9442 9443 9444/* ------------------------------ */ 9445 .balign 64 9446.L_OP_UNUSED_74FF: /* 0x174 */ 9447/* File: armv5te/OP_UNUSED_74FF.S */ 9448/* File: armv5te/unused.S */ 9449 bl common_abort 9450 9451 9452/* ------------------------------ */ 9453 .balign 64 9454.L_OP_UNUSED_75FF: /* 0x175 */ 9455/* File: armv5te/OP_UNUSED_75FF.S */ 9456/* File: armv5te/unused.S */ 9457 bl common_abort 9458 9459 9460/* ------------------------------ */ 9461 .balign 64 9462.L_OP_UNUSED_76FF: /* 0x176 */ 9463/* File: armv5te/OP_UNUSED_76FF.S */ 9464/* File: armv5te/unused.S */ 9465 bl common_abort 9466 9467 9468/* ------------------------------ */ 9469 .balign 64 9470.L_OP_UNUSED_77FF: /* 0x177 */ 9471/* File: armv5te/OP_UNUSED_77FF.S */ 9472/* File: armv5te/unused.S */ 9473 bl common_abort 9474 9475 9476/* ------------------------------ */ 9477 .balign 64 9478.L_OP_UNUSED_78FF: /* 0x178 */ 9479/* File: armv5te/OP_UNUSED_78FF.S */ 9480/* File: armv5te/unused.S */ 9481 bl common_abort 9482 9483 9484/* ------------------------------ */ 9485 .balign 64 9486.L_OP_UNUSED_79FF: /* 0x179 */ 9487/* File: armv5te/OP_UNUSED_79FF.S */ 9488/* File: armv5te/unused.S */ 9489 bl common_abort 9490 9491 9492/* ------------------------------ */ 9493 .balign 64 9494.L_OP_UNUSED_7AFF: /* 0x17a */ 9495/* File: armv5te/OP_UNUSED_7AFF.S */ 9496/* File: armv5te/unused.S */ 9497 bl common_abort 9498 9499 9500/* ------------------------------ */ 9501 .balign 64 9502.L_OP_UNUSED_7BFF: /* 0x17b */ 9503/* File: armv5te/OP_UNUSED_7BFF.S */ 9504/* File: armv5te/unused.S */ 9505 bl common_abort 9506 9507 9508/* ------------------------------ */ 9509 .balign 64 9510.L_OP_UNUSED_7CFF: /* 0x17c */ 9511/* File: armv5te/OP_UNUSED_7CFF.S */ 9512/* File: armv5te/unused.S */ 9513 bl common_abort 9514 9515 9516/* ------------------------------ */ 9517 .balign 64 9518.L_OP_UNUSED_7DFF: /* 0x17d */ 9519/* File: armv5te/OP_UNUSED_7DFF.S */ 9520/* File: armv5te/unused.S */ 9521 bl common_abort 9522 9523 9524/* ------------------------------ */ 9525 .balign 64 9526.L_OP_UNUSED_7EFF: /* 0x17e */ 9527/* File: armv5te/OP_UNUSED_7EFF.S */ 9528/* File: armv5te/unused.S */ 9529 bl common_abort 9530 9531 9532/* ------------------------------ */ 9533 .balign 64 9534.L_OP_UNUSED_7FFF: /* 0x17f */ 9535/* File: armv5te/OP_UNUSED_7FFF.S */ 9536/* File: armv5te/unused.S */ 9537 bl common_abort 9538 9539 9540/* ------------------------------ */ 9541 .balign 64 9542.L_OP_UNUSED_80FF: /* 0x180 */ 9543/* File: armv5te/OP_UNUSED_80FF.S */ 9544/* File: armv5te/unused.S */ 9545 bl common_abort 9546 9547 9548/* ------------------------------ */ 9549 .balign 64 9550.L_OP_UNUSED_81FF: /* 0x181 */ 9551/* File: armv5te/OP_UNUSED_81FF.S */ 9552/* File: armv5te/unused.S */ 9553 bl common_abort 9554 9555 9556/* ------------------------------ */ 9557 .balign 64 9558.L_OP_UNUSED_82FF: /* 0x182 */ 9559/* File: armv5te/OP_UNUSED_82FF.S */ 9560/* File: armv5te/unused.S */ 9561 bl common_abort 9562 9563 9564/* ------------------------------ */ 9565 .balign 64 9566.L_OP_UNUSED_83FF: /* 0x183 */ 9567/* File: armv5te/OP_UNUSED_83FF.S */ 9568/* File: armv5te/unused.S */ 9569 bl common_abort 9570 9571 9572/* ------------------------------ */ 9573 .balign 64 9574.L_OP_UNUSED_84FF: /* 0x184 */ 9575/* File: armv5te/OP_UNUSED_84FF.S */ 9576/* File: armv5te/unused.S */ 9577 bl common_abort 9578 9579 9580/* ------------------------------ */ 9581 .balign 64 9582.L_OP_UNUSED_85FF: /* 0x185 */ 9583/* File: armv5te/OP_UNUSED_85FF.S */ 9584/* File: armv5te/unused.S */ 9585 bl common_abort 9586 9587 9588/* ------------------------------ */ 9589 .balign 64 9590.L_OP_UNUSED_86FF: /* 0x186 */ 9591/* File: armv5te/OP_UNUSED_86FF.S */ 9592/* File: armv5te/unused.S */ 9593 bl common_abort 9594 9595 9596/* ------------------------------ */ 9597 .balign 64 9598.L_OP_UNUSED_87FF: /* 0x187 */ 9599/* File: armv5te/OP_UNUSED_87FF.S */ 9600/* File: armv5te/unused.S */ 9601 bl common_abort 9602 9603 9604/* ------------------------------ */ 9605 .balign 64 9606.L_OP_UNUSED_88FF: /* 0x188 */ 9607/* File: armv5te/OP_UNUSED_88FF.S */ 9608/* File: armv5te/unused.S */ 9609 bl common_abort 9610 9611 9612/* ------------------------------ */ 9613 .balign 64 9614.L_OP_UNUSED_89FF: /* 0x189 */ 9615/* File: armv5te/OP_UNUSED_89FF.S */ 9616/* File: armv5te/unused.S */ 9617 bl common_abort 9618 9619 9620/* ------------------------------ */ 9621 .balign 64 9622.L_OP_UNUSED_8AFF: /* 0x18a */ 9623/* File: armv5te/OP_UNUSED_8AFF.S */ 9624/* File: armv5te/unused.S */ 9625 bl common_abort 9626 9627 9628/* ------------------------------ */ 9629 .balign 64 9630.L_OP_UNUSED_8BFF: /* 0x18b */ 9631/* File: armv5te/OP_UNUSED_8BFF.S */ 9632/* File: armv5te/unused.S */ 9633 bl common_abort 9634 9635 9636/* ------------------------------ */ 9637 .balign 64 9638.L_OP_UNUSED_8CFF: /* 0x18c */ 9639/* File: armv5te/OP_UNUSED_8CFF.S */ 9640/* File: armv5te/unused.S */ 9641 bl common_abort 9642 9643 9644/* ------------------------------ */ 9645 .balign 64 9646.L_OP_UNUSED_8DFF: /* 0x18d */ 9647/* File: armv5te/OP_UNUSED_8DFF.S */ 9648/* File: armv5te/unused.S */ 9649 bl common_abort 9650 9651 9652/* ------------------------------ */ 9653 .balign 64 9654.L_OP_UNUSED_8EFF: /* 0x18e */ 9655/* File: armv5te/OP_UNUSED_8EFF.S */ 9656/* File: armv5te/unused.S */ 9657 bl common_abort 9658 9659 9660/* ------------------------------ */ 9661 .balign 64 9662.L_OP_UNUSED_8FFF: /* 0x18f */ 9663/* File: armv5te/OP_UNUSED_8FFF.S */ 9664/* File: armv5te/unused.S */ 9665 bl common_abort 9666 9667 9668/* ------------------------------ */ 9669 .balign 64 9670.L_OP_UNUSED_90FF: /* 0x190 */ 9671/* File: armv5te/OP_UNUSED_90FF.S */ 9672/* File: armv5te/unused.S */ 9673 bl common_abort 9674 9675 9676/* ------------------------------ */ 9677 .balign 64 9678.L_OP_UNUSED_91FF: /* 0x191 */ 9679/* File: armv5te/OP_UNUSED_91FF.S */ 9680/* File: armv5te/unused.S */ 9681 bl common_abort 9682 9683 9684/* ------------------------------ */ 9685 .balign 64 9686.L_OP_UNUSED_92FF: /* 0x192 */ 9687/* File: armv5te/OP_UNUSED_92FF.S */ 9688/* File: armv5te/unused.S */ 9689 bl common_abort 9690 9691 9692/* ------------------------------ */ 9693 .balign 64 9694.L_OP_UNUSED_93FF: /* 0x193 */ 9695/* File: armv5te/OP_UNUSED_93FF.S */ 9696/* File: armv5te/unused.S */ 9697 bl common_abort 9698 9699 9700/* ------------------------------ */ 9701 .balign 64 9702.L_OP_UNUSED_94FF: /* 0x194 */ 9703/* File: armv5te/OP_UNUSED_94FF.S */ 9704/* File: armv5te/unused.S */ 9705 bl common_abort 9706 9707 9708/* ------------------------------ */ 9709 .balign 64 9710.L_OP_UNUSED_95FF: /* 0x195 */ 9711/* File: armv5te/OP_UNUSED_95FF.S */ 9712/* File: armv5te/unused.S */ 9713 bl common_abort 9714 9715 9716/* ------------------------------ */ 9717 .balign 64 9718.L_OP_UNUSED_96FF: /* 0x196 */ 9719/* File: armv5te/OP_UNUSED_96FF.S */ 9720/* File: armv5te/unused.S */ 9721 bl common_abort 9722 9723 9724/* ------------------------------ */ 9725 .balign 64 9726.L_OP_UNUSED_97FF: /* 0x197 */ 9727/* File: armv5te/OP_UNUSED_97FF.S */ 9728/* File: armv5te/unused.S */ 9729 bl common_abort 9730 9731 9732/* ------------------------------ */ 9733 .balign 64 9734.L_OP_UNUSED_98FF: /* 0x198 */ 9735/* File: armv5te/OP_UNUSED_98FF.S */ 9736/* File: armv5te/unused.S */ 9737 bl common_abort 9738 9739 9740/* ------------------------------ */ 9741 .balign 64 9742.L_OP_UNUSED_99FF: /* 0x199 */ 9743/* File: armv5te/OP_UNUSED_99FF.S */ 9744/* File: armv5te/unused.S */ 9745 bl common_abort 9746 9747 9748/* ------------------------------ */ 9749 .balign 64 9750.L_OP_UNUSED_9AFF: /* 0x19a */ 9751/* File: armv5te/OP_UNUSED_9AFF.S */ 9752/* File: armv5te/unused.S */ 9753 bl common_abort 9754 9755 9756/* ------------------------------ */ 9757 .balign 64 9758.L_OP_UNUSED_9BFF: /* 0x19b */ 9759/* File: armv5te/OP_UNUSED_9BFF.S */ 9760/* File: armv5te/unused.S */ 9761 bl common_abort 9762 9763 9764/* ------------------------------ */ 9765 .balign 64 9766.L_OP_UNUSED_9CFF: /* 0x19c */ 9767/* File: armv5te/OP_UNUSED_9CFF.S */ 9768/* File: armv5te/unused.S */ 9769 bl common_abort 9770 9771 9772/* ------------------------------ */ 9773 .balign 64 9774.L_OP_UNUSED_9DFF: /* 0x19d */ 9775/* File: armv5te/OP_UNUSED_9DFF.S */ 9776/* File: armv5te/unused.S */ 9777 bl common_abort 9778 9779 9780/* ------------------------------ */ 9781 .balign 64 9782.L_OP_UNUSED_9EFF: /* 0x19e */ 9783/* File: armv5te/OP_UNUSED_9EFF.S */ 9784/* File: armv5te/unused.S */ 9785 bl common_abort 9786 9787 9788/* ------------------------------ */ 9789 .balign 64 9790.L_OP_UNUSED_9FFF: /* 0x19f */ 9791/* File: armv5te/OP_UNUSED_9FFF.S */ 9792/* File: armv5te/unused.S */ 9793 bl common_abort 9794 9795 9796/* ------------------------------ */ 9797 .balign 64 9798.L_OP_UNUSED_A0FF: /* 0x1a0 */ 9799/* File: armv5te/OP_UNUSED_A0FF.S */ 9800/* File: armv5te/unused.S */ 9801 bl common_abort 9802 9803 9804/* ------------------------------ */ 9805 .balign 64 9806.L_OP_UNUSED_A1FF: /* 0x1a1 */ 9807/* File: armv5te/OP_UNUSED_A1FF.S */ 9808/* File: armv5te/unused.S */ 9809 bl common_abort 9810 9811 9812/* ------------------------------ */ 9813 .balign 64 9814.L_OP_UNUSED_A2FF: /* 0x1a2 */ 9815/* File: armv5te/OP_UNUSED_A2FF.S */ 9816/* File: armv5te/unused.S */ 9817 bl common_abort 9818 9819 9820/* ------------------------------ */ 9821 .balign 64 9822.L_OP_UNUSED_A3FF: /* 0x1a3 */ 9823/* File: armv5te/OP_UNUSED_A3FF.S */ 9824/* File: armv5te/unused.S */ 9825 bl common_abort 9826 9827 9828/* ------------------------------ */ 9829 .balign 64 9830.L_OP_UNUSED_A4FF: /* 0x1a4 */ 9831/* File: armv5te/OP_UNUSED_A4FF.S */ 9832/* File: armv5te/unused.S */ 9833 bl common_abort 9834 9835 9836/* ------------------------------ */ 9837 .balign 64 9838.L_OP_UNUSED_A5FF: /* 0x1a5 */ 9839/* File: armv5te/OP_UNUSED_A5FF.S */ 9840/* File: armv5te/unused.S */ 9841 bl common_abort 9842 9843 9844/* ------------------------------ */ 9845 .balign 64 9846.L_OP_UNUSED_A6FF: /* 0x1a6 */ 9847/* File: armv5te/OP_UNUSED_A6FF.S */ 9848/* File: armv5te/unused.S */ 9849 bl common_abort 9850 9851 9852/* ------------------------------ */ 9853 .balign 64 9854.L_OP_UNUSED_A7FF: /* 0x1a7 */ 9855/* File: armv5te/OP_UNUSED_A7FF.S */ 9856/* File: armv5te/unused.S */ 9857 bl common_abort 9858 9859 9860/* ------------------------------ */ 9861 .balign 64 9862.L_OP_UNUSED_A8FF: /* 0x1a8 */ 9863/* File: armv5te/OP_UNUSED_A8FF.S */ 9864/* File: armv5te/unused.S */ 9865 bl common_abort 9866 9867 9868/* ------------------------------ */ 9869 .balign 64 9870.L_OP_UNUSED_A9FF: /* 0x1a9 */ 9871/* File: armv5te/OP_UNUSED_A9FF.S */ 9872/* File: armv5te/unused.S */ 9873 bl common_abort 9874 9875 9876/* ------------------------------ */ 9877 .balign 64 9878.L_OP_UNUSED_AAFF: /* 0x1aa */ 9879/* File: armv5te/OP_UNUSED_AAFF.S */ 9880/* File: armv5te/unused.S */ 9881 bl common_abort 9882 9883 9884/* ------------------------------ */ 9885 .balign 64 9886.L_OP_UNUSED_ABFF: /* 0x1ab */ 9887/* File: armv5te/OP_UNUSED_ABFF.S */ 9888/* File: armv5te/unused.S */ 9889 bl common_abort 9890 9891 9892/* ------------------------------ */ 9893 .balign 64 9894.L_OP_UNUSED_ACFF: /* 0x1ac */ 9895/* File: armv5te/OP_UNUSED_ACFF.S */ 9896/* File: armv5te/unused.S */ 9897 bl common_abort 9898 9899 9900/* ------------------------------ */ 9901 .balign 64 9902.L_OP_UNUSED_ADFF: /* 0x1ad */ 9903/* File: armv5te/OP_UNUSED_ADFF.S */ 9904/* File: armv5te/unused.S */ 9905 bl common_abort 9906 9907 9908/* ------------------------------ */ 9909 .balign 64 9910.L_OP_UNUSED_AEFF: /* 0x1ae */ 9911/* File: armv5te/OP_UNUSED_AEFF.S */ 9912/* File: armv5te/unused.S */ 9913 bl common_abort 9914 9915 9916/* ------------------------------ */ 9917 .balign 64 9918.L_OP_UNUSED_AFFF: /* 0x1af */ 9919/* File: armv5te/OP_UNUSED_AFFF.S */ 9920/* File: armv5te/unused.S */ 9921 bl common_abort 9922 9923 9924/* ------------------------------ */ 9925 .balign 64 9926.L_OP_UNUSED_B0FF: /* 0x1b0 */ 9927/* File: armv5te/OP_UNUSED_B0FF.S */ 9928/* File: armv5te/unused.S */ 9929 bl common_abort 9930 9931 9932/* ------------------------------ */ 9933 .balign 64 9934.L_OP_UNUSED_B1FF: /* 0x1b1 */ 9935/* File: armv5te/OP_UNUSED_B1FF.S */ 9936/* File: armv5te/unused.S */ 9937 bl common_abort 9938 9939 9940/* ------------------------------ */ 9941 .balign 64 9942.L_OP_UNUSED_B2FF: /* 0x1b2 */ 9943/* File: armv5te/OP_UNUSED_B2FF.S */ 9944/* File: armv5te/unused.S */ 9945 bl common_abort 9946 9947 9948/* ------------------------------ */ 9949 .balign 64 9950.L_OP_UNUSED_B3FF: /* 0x1b3 */ 9951/* File: armv5te/OP_UNUSED_B3FF.S */ 9952/* File: armv5te/unused.S */ 9953 bl common_abort 9954 9955 9956/* ------------------------------ */ 9957 .balign 64 9958.L_OP_UNUSED_B4FF: /* 0x1b4 */ 9959/* File: armv5te/OP_UNUSED_B4FF.S */ 9960/* File: armv5te/unused.S */ 9961 bl common_abort 9962 9963 9964/* ------------------------------ */ 9965 .balign 64 9966.L_OP_UNUSED_B5FF: /* 0x1b5 */ 9967/* File: armv5te/OP_UNUSED_B5FF.S */ 9968/* File: armv5te/unused.S */ 9969 bl common_abort 9970 9971 9972/* ------------------------------ */ 9973 .balign 64 9974.L_OP_UNUSED_B6FF: /* 0x1b6 */ 9975/* File: armv5te/OP_UNUSED_B6FF.S */ 9976/* File: armv5te/unused.S */ 9977 bl common_abort 9978 9979 9980/* ------------------------------ */ 9981 .balign 64 9982.L_OP_UNUSED_B7FF: /* 0x1b7 */ 9983/* File: armv5te/OP_UNUSED_B7FF.S */ 9984/* File: armv5te/unused.S */ 9985 bl common_abort 9986 9987 9988/* ------------------------------ */ 9989 .balign 64 9990.L_OP_UNUSED_B8FF: /* 0x1b8 */ 9991/* File: armv5te/OP_UNUSED_B8FF.S */ 9992/* File: armv5te/unused.S */ 9993 bl common_abort 9994 9995 9996/* ------------------------------ */ 9997 .balign 64 9998.L_OP_UNUSED_B9FF: /* 0x1b9 */ 9999/* File: armv5te/OP_UNUSED_B9FF.S */ 10000/* File: armv5te/unused.S */ 10001 bl common_abort 10002 10003 10004/* ------------------------------ */ 10005 .balign 64 10006.L_OP_UNUSED_BAFF: /* 0x1ba */ 10007/* File: armv5te/OP_UNUSED_BAFF.S */ 10008/* File: armv5te/unused.S */ 10009 bl common_abort 10010 10011 10012/* ------------------------------ */ 10013 .balign 64 10014.L_OP_UNUSED_BBFF: /* 0x1bb */ 10015/* File: armv5te/OP_UNUSED_BBFF.S */ 10016/* File: armv5te/unused.S */ 10017 bl common_abort 10018 10019 10020/* ------------------------------ */ 10021 .balign 64 10022.L_OP_UNUSED_BCFF: /* 0x1bc */ 10023/* File: armv5te/OP_UNUSED_BCFF.S */ 10024/* File: armv5te/unused.S */ 10025 bl common_abort 10026 10027 10028/* ------------------------------ */ 10029 .balign 64 10030.L_OP_UNUSED_BDFF: /* 0x1bd */ 10031/* File: armv5te/OP_UNUSED_BDFF.S */ 10032/* File: armv5te/unused.S */ 10033 bl common_abort 10034 10035 10036/* ------------------------------ */ 10037 .balign 64 10038.L_OP_UNUSED_BEFF: /* 0x1be */ 10039/* File: armv5te/OP_UNUSED_BEFF.S */ 10040/* File: armv5te/unused.S */ 10041 bl common_abort 10042 10043 10044/* ------------------------------ */ 10045 .balign 64 10046.L_OP_UNUSED_BFFF: /* 0x1bf */ 10047/* File: armv5te/OP_UNUSED_BFFF.S */ 10048/* File: armv5te/unused.S */ 10049 bl common_abort 10050 10051 10052/* ------------------------------ */ 10053 .balign 64 10054.L_OP_UNUSED_C0FF: /* 0x1c0 */ 10055/* File: armv5te/OP_UNUSED_C0FF.S */ 10056/* File: armv5te/unused.S */ 10057 bl common_abort 10058 10059 10060/* ------------------------------ */ 10061 .balign 64 10062.L_OP_UNUSED_C1FF: /* 0x1c1 */ 10063/* File: armv5te/OP_UNUSED_C1FF.S */ 10064/* File: armv5te/unused.S */ 10065 bl common_abort 10066 10067 10068/* ------------------------------ */ 10069 .balign 64 10070.L_OP_UNUSED_C2FF: /* 0x1c2 */ 10071/* File: armv5te/OP_UNUSED_C2FF.S */ 10072/* File: armv5te/unused.S */ 10073 bl common_abort 10074 10075 10076/* ------------------------------ */ 10077 .balign 64 10078.L_OP_UNUSED_C3FF: /* 0x1c3 */ 10079/* File: armv5te/OP_UNUSED_C3FF.S */ 10080/* File: armv5te/unused.S */ 10081 bl common_abort 10082 10083 10084/* ------------------------------ */ 10085 .balign 64 10086.L_OP_UNUSED_C4FF: /* 0x1c4 */ 10087/* File: armv5te/OP_UNUSED_C4FF.S */ 10088/* File: armv5te/unused.S */ 10089 bl common_abort 10090 10091 10092/* ------------------------------ */ 10093 .balign 64 10094.L_OP_UNUSED_C5FF: /* 0x1c5 */ 10095/* File: armv5te/OP_UNUSED_C5FF.S */ 10096/* File: armv5te/unused.S */ 10097 bl common_abort 10098 10099 10100/* ------------------------------ */ 10101 .balign 64 10102.L_OP_UNUSED_C6FF: /* 0x1c6 */ 10103/* File: armv5te/OP_UNUSED_C6FF.S */ 10104/* File: armv5te/unused.S */ 10105 bl common_abort 10106 10107 10108/* ------------------------------ */ 10109 .balign 64 10110.L_OP_UNUSED_C7FF: /* 0x1c7 */ 10111/* File: armv5te/OP_UNUSED_C7FF.S */ 10112/* File: armv5te/unused.S */ 10113 bl common_abort 10114 10115 10116/* ------------------------------ */ 10117 .balign 64 10118.L_OP_UNUSED_C8FF: /* 0x1c8 */ 10119/* File: armv5te/OP_UNUSED_C8FF.S */ 10120/* File: armv5te/unused.S */ 10121 bl common_abort 10122 10123 10124/* ------------------------------ */ 10125 .balign 64 10126.L_OP_UNUSED_C9FF: /* 0x1c9 */ 10127/* File: armv5te/OP_UNUSED_C9FF.S */ 10128/* File: armv5te/unused.S */ 10129 bl common_abort 10130 10131 10132/* ------------------------------ */ 10133 .balign 64 10134.L_OP_UNUSED_CAFF: /* 0x1ca */ 10135/* File: armv5te/OP_UNUSED_CAFF.S */ 10136/* File: armv5te/unused.S */ 10137 bl common_abort 10138 10139 10140/* ------------------------------ */ 10141 .balign 64 10142.L_OP_UNUSED_CBFF: /* 0x1cb */ 10143/* File: armv5te/OP_UNUSED_CBFF.S */ 10144/* File: armv5te/unused.S */ 10145 bl common_abort 10146 10147 10148/* ------------------------------ */ 10149 .balign 64 10150.L_OP_UNUSED_CCFF: /* 0x1cc */ 10151/* File: armv5te/OP_UNUSED_CCFF.S */ 10152/* File: armv5te/unused.S */ 10153 bl common_abort 10154 10155 10156/* ------------------------------ */ 10157 .balign 64 10158.L_OP_UNUSED_CDFF: /* 0x1cd */ 10159/* File: armv5te/OP_UNUSED_CDFF.S */ 10160/* File: armv5te/unused.S */ 10161 bl common_abort 10162 10163 10164/* ------------------------------ */ 10165 .balign 64 10166.L_OP_UNUSED_CEFF: /* 0x1ce */ 10167/* File: armv5te/OP_UNUSED_CEFF.S */ 10168/* File: armv5te/unused.S */ 10169 bl common_abort 10170 10171 10172/* ------------------------------ */ 10173 .balign 64 10174.L_OP_UNUSED_CFFF: /* 0x1cf */ 10175/* File: armv5te/OP_UNUSED_CFFF.S */ 10176/* File: armv5te/unused.S */ 10177 bl common_abort 10178 10179 10180/* ------------------------------ */ 10181 .balign 64 10182.L_OP_UNUSED_D0FF: /* 0x1d0 */ 10183/* File: armv5te/OP_UNUSED_D0FF.S */ 10184/* File: armv5te/unused.S */ 10185 bl common_abort 10186 10187 10188/* ------------------------------ */ 10189 .balign 64 10190.L_OP_UNUSED_D1FF: /* 0x1d1 */ 10191/* File: armv5te/OP_UNUSED_D1FF.S */ 10192/* File: armv5te/unused.S */ 10193 bl common_abort 10194 10195 10196/* ------------------------------ */ 10197 .balign 64 10198.L_OP_UNUSED_D2FF: /* 0x1d2 */ 10199/* File: armv5te/OP_UNUSED_D2FF.S */ 10200/* File: armv5te/unused.S */ 10201 bl common_abort 10202 10203 10204/* ------------------------------ */ 10205 .balign 64 10206.L_OP_UNUSED_D3FF: /* 0x1d3 */ 10207/* File: armv5te/OP_UNUSED_D3FF.S */ 10208/* File: armv5te/unused.S */ 10209 bl common_abort 10210 10211 10212/* ------------------------------ */ 10213 .balign 64 10214.L_OP_UNUSED_D4FF: /* 0x1d4 */ 10215/* File: armv5te/OP_UNUSED_D4FF.S */ 10216/* File: armv5te/unused.S */ 10217 bl common_abort 10218 10219 10220/* ------------------------------ */ 10221 .balign 64 10222.L_OP_UNUSED_D5FF: /* 0x1d5 */ 10223/* File: armv5te/OP_UNUSED_D5FF.S */ 10224/* File: armv5te/unused.S */ 10225 bl common_abort 10226 10227 10228/* ------------------------------ */ 10229 .balign 64 10230.L_OP_UNUSED_D6FF: /* 0x1d6 */ 10231/* File: armv5te/OP_UNUSED_D6FF.S */ 10232/* File: armv5te/unused.S */ 10233 bl common_abort 10234 10235 10236/* ------------------------------ */ 10237 .balign 64 10238.L_OP_UNUSED_D7FF: /* 0x1d7 */ 10239/* File: armv5te/OP_UNUSED_D7FF.S */ 10240/* File: armv5te/unused.S */ 10241 bl common_abort 10242 10243 10244/* ------------------------------ */ 10245 .balign 64 10246.L_OP_UNUSED_D8FF: /* 0x1d8 */ 10247/* File: armv5te/OP_UNUSED_D8FF.S */ 10248/* File: armv5te/unused.S */ 10249 bl common_abort 10250 10251 10252/* ------------------------------ */ 10253 .balign 64 10254.L_OP_UNUSED_D9FF: /* 0x1d9 */ 10255/* File: armv5te/OP_UNUSED_D9FF.S */ 10256/* File: armv5te/unused.S */ 10257 bl common_abort 10258 10259 10260/* ------------------------------ */ 10261 .balign 64 10262.L_OP_UNUSED_DAFF: /* 0x1da */ 10263/* File: armv5te/OP_UNUSED_DAFF.S */ 10264/* File: armv5te/unused.S */ 10265 bl common_abort 10266 10267 10268/* ------------------------------ */ 10269 .balign 64 10270.L_OP_UNUSED_DBFF: /* 0x1db */ 10271/* File: armv5te/OP_UNUSED_DBFF.S */ 10272/* File: armv5te/unused.S */ 10273 bl common_abort 10274 10275 10276/* ------------------------------ */ 10277 .balign 64 10278.L_OP_UNUSED_DCFF: /* 0x1dc */ 10279/* File: armv5te/OP_UNUSED_DCFF.S */ 10280/* File: armv5te/unused.S */ 10281 bl common_abort 10282 10283 10284/* ------------------------------ */ 10285 .balign 64 10286.L_OP_UNUSED_DDFF: /* 0x1dd */ 10287/* File: armv5te/OP_UNUSED_DDFF.S */ 10288/* File: armv5te/unused.S */ 10289 bl common_abort 10290 10291 10292/* ------------------------------ */ 10293 .balign 64 10294.L_OP_UNUSED_DEFF: /* 0x1de */ 10295/* File: armv5te/OP_UNUSED_DEFF.S */ 10296/* File: armv5te/unused.S */ 10297 bl common_abort 10298 10299 10300/* ------------------------------ */ 10301 .balign 64 10302.L_OP_UNUSED_DFFF: /* 0x1df */ 10303/* File: armv5te/OP_UNUSED_DFFF.S */ 10304/* File: armv5te/unused.S */ 10305 bl common_abort 10306 10307 10308/* ------------------------------ */ 10309 .balign 64 10310.L_OP_UNUSED_E0FF: /* 0x1e0 */ 10311/* File: armv5te/OP_UNUSED_E0FF.S */ 10312/* File: armv5te/unused.S */ 10313 bl common_abort 10314 10315 10316/* ------------------------------ */ 10317 .balign 64 10318.L_OP_UNUSED_E1FF: /* 0x1e1 */ 10319/* File: armv5te/OP_UNUSED_E1FF.S */ 10320/* File: armv5te/unused.S */ 10321 bl common_abort 10322 10323 10324/* ------------------------------ */ 10325 .balign 64 10326.L_OP_UNUSED_E2FF: /* 0x1e2 */ 10327/* File: armv5te/OP_UNUSED_E2FF.S */ 10328/* File: armv5te/unused.S */ 10329 bl common_abort 10330 10331 10332/* ------------------------------ */ 10333 .balign 64 10334.L_OP_UNUSED_E3FF: /* 0x1e3 */ 10335/* File: armv5te/OP_UNUSED_E3FF.S */ 10336/* File: armv5te/unused.S */ 10337 bl common_abort 10338 10339 10340/* ------------------------------ */ 10341 .balign 64 10342.L_OP_UNUSED_E4FF: /* 0x1e4 */ 10343/* File: armv5te/OP_UNUSED_E4FF.S */ 10344/* File: armv5te/unused.S */ 10345 bl common_abort 10346 10347 10348/* ------------------------------ */ 10349 .balign 64 10350.L_OP_UNUSED_E5FF: /* 0x1e5 */ 10351/* File: armv5te/OP_UNUSED_E5FF.S */ 10352/* File: armv5te/unused.S */ 10353 bl common_abort 10354 10355 10356/* ------------------------------ */ 10357 .balign 64 10358.L_OP_UNUSED_E6FF: /* 0x1e6 */ 10359/* File: armv5te/OP_UNUSED_E6FF.S */ 10360/* File: armv5te/unused.S */ 10361 bl common_abort 10362 10363 10364/* ------------------------------ */ 10365 .balign 64 10366.L_OP_UNUSED_E7FF: /* 0x1e7 */ 10367/* File: armv5te/OP_UNUSED_E7FF.S */ 10368/* File: armv5te/unused.S */ 10369 bl common_abort 10370 10371 10372/* ------------------------------ */ 10373 .balign 64 10374.L_OP_UNUSED_E8FF: /* 0x1e8 */ 10375/* File: armv5te/OP_UNUSED_E8FF.S */ 10376/* File: armv5te/unused.S */ 10377 bl common_abort 10378 10379 10380/* ------------------------------ */ 10381 .balign 64 10382.L_OP_UNUSED_E9FF: /* 0x1e9 */ 10383/* File: armv5te/OP_UNUSED_E9FF.S */ 10384/* File: armv5te/unused.S */ 10385 bl common_abort 10386 10387 10388/* ------------------------------ */ 10389 .balign 64 10390.L_OP_UNUSED_EAFF: /* 0x1ea */ 10391/* File: armv5te/OP_UNUSED_EAFF.S */ 10392/* File: armv5te/unused.S */ 10393 bl common_abort 10394 10395 10396/* ------------------------------ */ 10397 .balign 64 10398.L_OP_UNUSED_EBFF: /* 0x1eb */ 10399/* File: armv5te/OP_UNUSED_EBFF.S */ 10400/* File: armv5te/unused.S */ 10401 bl common_abort 10402 10403 10404/* ------------------------------ */ 10405 .balign 64 10406.L_OP_UNUSED_ECFF: /* 0x1ec */ 10407/* File: armv5te/OP_UNUSED_ECFF.S */ 10408/* File: armv5te/unused.S */ 10409 bl common_abort 10410 10411 10412/* ------------------------------ */ 10413 .balign 64 10414.L_OP_UNUSED_EDFF: /* 0x1ed */ 10415/* File: armv5te/OP_UNUSED_EDFF.S */ 10416/* File: armv5te/unused.S */ 10417 bl common_abort 10418 10419 10420/* ------------------------------ */ 10421 .balign 64 10422.L_OP_UNUSED_EEFF: /* 0x1ee */ 10423/* File: armv5te/OP_UNUSED_EEFF.S */ 10424/* File: armv5te/unused.S */ 10425 bl common_abort 10426 10427 10428/* ------------------------------ */ 10429 .balign 64 10430.L_OP_UNUSED_EFFF: /* 0x1ef */ 10431/* File: armv5te/OP_UNUSED_EFFF.S */ 10432/* File: armv5te/unused.S */ 10433 bl common_abort 10434 10435 10436/* ------------------------------ */ 10437 .balign 64 10438.L_OP_UNUSED_F0FF: /* 0x1f0 */ 10439/* File: armv5te/OP_UNUSED_F0FF.S */ 10440/* File: armv5te/unused.S */ 10441 bl common_abort 10442 10443 10444/* ------------------------------ */ 10445 .balign 64 10446.L_OP_UNUSED_F1FF: /* 0x1f1 */ 10447/* File: armv5te/OP_UNUSED_F1FF.S */ 10448/* File: armv5te/unused.S */ 10449 bl common_abort 10450 10451 10452/* ------------------------------ */ 10453 .balign 64 10454.L_OP_UNUSED_F2FF: /* 0x1f2 */ 10455/* File: armv5te/OP_UNUSED_F2FF.S */ 10456/* File: armv5te/unused.S */ 10457 bl common_abort 10458 10459 10460/* ------------------------------ */ 10461 .balign 64 10462.L_OP_UNUSED_F3FF: /* 0x1f3 */ 10463/* File: armv5te/OP_UNUSED_F3FF.S */ 10464/* File: armv5te/unused.S */ 10465 bl common_abort 10466 10467 10468/* ------------------------------ */ 10469 .balign 64 10470.L_OP_UNUSED_F4FF: /* 0x1f4 */ 10471/* File: armv5te/OP_UNUSED_F4FF.S */ 10472/* File: armv5te/unused.S */ 10473 bl common_abort 10474 10475 10476/* ------------------------------ */ 10477 .balign 64 10478.L_OP_UNUSED_F5FF: /* 0x1f5 */ 10479/* File: armv5te/OP_UNUSED_F5FF.S */ 10480/* File: armv5te/unused.S */ 10481 bl common_abort 10482 10483 10484/* ------------------------------ */ 10485 .balign 64 10486.L_OP_UNUSED_F6FF: /* 0x1f6 */ 10487/* File: armv5te/OP_UNUSED_F6FF.S */ 10488/* File: armv5te/unused.S */ 10489 bl common_abort 10490 10491 10492/* ------------------------------ */ 10493 .balign 64 10494.L_OP_UNUSED_F7FF: /* 0x1f7 */ 10495/* File: armv5te/OP_UNUSED_F7FF.S */ 10496/* File: armv5te/unused.S */ 10497 bl common_abort 10498 10499 10500/* ------------------------------ */ 10501 .balign 64 10502.L_OP_UNUSED_F8FF: /* 0x1f8 */ 10503/* File: armv5te/OP_UNUSED_F8FF.S */ 10504/* File: armv5te/unused.S */ 10505 bl common_abort 10506 10507 10508/* ------------------------------ */ 10509 .balign 64 10510.L_OP_UNUSED_F9FF: /* 0x1f9 */ 10511/* File: armv5te/OP_UNUSED_F9FF.S */ 10512/* File: armv5te/unused.S */ 10513 bl common_abort 10514 10515 10516/* ------------------------------ */ 10517 .balign 64 10518.L_OP_UNUSED_FAFF: /* 0x1fa */ 10519/* File: armv5te/OP_UNUSED_FAFF.S */ 10520/* File: armv5te/unused.S */ 10521 bl common_abort 10522 10523 10524/* ------------------------------ */ 10525 .balign 64 10526.L_OP_UNUSED_FBFF: /* 0x1fb */ 10527/* File: armv5te/OP_UNUSED_FBFF.S */ 10528/* File: armv5te/unused.S */ 10529 bl common_abort 10530 10531 10532/* ------------------------------ */ 10533 .balign 64 10534.L_OP_UNUSED_FCFF: /* 0x1fc */ 10535/* File: armv5te/OP_UNUSED_FCFF.S */ 10536/* File: armv5te/unused.S */ 10537 bl common_abort 10538 10539 10540/* ------------------------------ */ 10541 .balign 64 10542.L_OP_UNUSED_FDFF: /* 0x1fd */ 10543/* File: armv5te/OP_UNUSED_FDFF.S */ 10544/* File: armv5te/unused.S */ 10545 bl common_abort 10546 10547 10548/* ------------------------------ */ 10549 .balign 64 10550.L_OP_UNUSED_FEFF: /* 0x1fe */ 10551/* File: armv5te/OP_UNUSED_FEFF.S */ 10552/* File: armv5te/unused.S */ 10553 bl common_abort 10554 10555 10556/* ------------------------------ */ 10557 .balign 64 10558.L_OP_THROW_VERIFICATION_ERROR_JUMBO: /* 0x1ff */ 10559/* File: armv5te/OP_THROW_VERIFICATION_ERROR_JUMBO.S */ 10560 /* 10561 * Handle a jumbo throw-verification-error instruction. This throws an 10562 * exception for an error discovered during verification. The 10563 * exception is indicated by BBBB, with some detail provided by AAAAAAAA. 10564 */ 10565 /* exop BBBB, Class@AAAAAAAA */ 10566 FETCH(r1, 1) @ r1<- aaaa (lo) 10567 FETCH(r2, 2) @ r2<- AAAA (hi) 10568 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 10569 orr r2, r1, r2, lsl #16 @ r2<- AAAAaaaa 10570 EXPORT_PC() @ export the PC 10571 FETCH(r1, 3) @ r1<- BBBB 10572 bl dvmThrowVerificationError @ always throws 10573 b common_exceptionThrown @ handle exception 10574 10575 10576 .balign 64 10577 .size dvmAsmInstructionStart, .-dvmAsmInstructionStart 10578 .global dvmAsmInstructionEnd 10579dvmAsmInstructionEnd: 10580 10581/* 10582 * =========================================================================== 10583 * Sister implementations 10584 * =========================================================================== 10585 */ 10586 .global dvmAsmSisterStart 10587 .type dvmAsmSisterStart, %function 10588 .text 10589 .balign 4 10590dvmAsmSisterStart: 10591 10592/* continuation for OP_CONST_STRING */ 10593 10594 /* 10595 * Continuation if the String has not yet been resolved. 10596 * r1: BBBB (String ref) 10597 * r9: target register 10598 */ 10599.LOP_CONST_STRING_resolve: 10600 EXPORT_PC() 10601 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 10602 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 10603 bl dvmResolveString @ r0<- String reference 10604 cmp r0, #0 @ failed? 10605 beq common_exceptionThrown @ yup, handle the exception 10606 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10607 GET_INST_OPCODE(ip) @ extract opcode from rINST 10608 SET_VREG(r0, r9) @ vAA<- r0 10609 GOTO_OPCODE(ip) @ jump to next instruction 10610 10611/* continuation for OP_CONST_STRING_JUMBO */ 10612 10613 /* 10614 * Continuation if the String has not yet been resolved. 10615 * r1: BBBBBBBB (String ref) 10616 * r9: target register 10617 */ 10618.LOP_CONST_STRING_JUMBO_resolve: 10619 EXPORT_PC() 10620 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 10621 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 10622 bl dvmResolveString @ r0<- String reference 10623 cmp r0, #0 @ failed? 10624 beq common_exceptionThrown @ yup, handle the exception 10625 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 10626 GET_INST_OPCODE(ip) @ extract opcode from rINST 10627 SET_VREG(r0, r9) @ vAA<- r0 10628 GOTO_OPCODE(ip) @ jump to next instruction 10629 10630/* continuation for OP_CONST_CLASS */ 10631 10632 /* 10633 * Continuation if the Class has not yet been resolved. 10634 * r1: BBBB (Class ref) 10635 * r9: target register 10636 */ 10637.LOP_CONST_CLASS_resolve: 10638 EXPORT_PC() 10639 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 10640 mov r2, #1 @ r2<- true 10641 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 10642 bl dvmResolveClass @ r0<- Class reference 10643 cmp r0, #0 @ failed? 10644 beq common_exceptionThrown @ yup, handle the exception 10645 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10646 GET_INST_OPCODE(ip) @ extract opcode from rINST 10647 SET_VREG(r0, r9) @ vAA<- r0 10648 GOTO_OPCODE(ip) @ jump to next instruction 10649 10650/* continuation for OP_CHECK_CAST */ 10651 10652 /* 10653 * Trivial test failed, need to perform full check. This is common. 10654 * r0 holds obj->clazz 10655 * r1 holds desired class resolved from BBBB 10656 * r9 holds object 10657 */ 10658.LOP_CHECK_CAST_fullcheck: 10659 mov r10, r1 @ avoid ClassObject getting clobbered 10660 bl dvmInstanceofNonTrivial @ r0<- boolean result 10661 cmp r0, #0 @ failed? 10662 bne .LOP_CHECK_CAST_okay @ no, success 10663 10664 @ A cast has failed. We need to throw a ClassCastException. 10665 EXPORT_PC() @ about to throw 10666 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class) 10667 mov r1, r10 @ r1<- desired class 10668 bl dvmThrowClassCastException 10669 b common_exceptionThrown 10670 10671 /* 10672 * Resolution required. This is the least-likely path. 10673 * 10674 * r2 holds BBBB 10675 * r9 holds object 10676 */ 10677.LOP_CHECK_CAST_resolve: 10678 EXPORT_PC() @ resolve() could throw 10679 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 10680 mov r1, r2 @ r1<- BBBB 10681 mov r2, #0 @ r2<- false 10682 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 10683 bl dvmResolveClass @ r0<- resolved ClassObject ptr 10684 cmp r0, #0 @ got null? 10685 beq common_exceptionThrown @ yes, handle exception 10686 mov r1, r0 @ r1<- class resolved from BBB 10687 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 10688 b .LOP_CHECK_CAST_resolved @ pick up where we left off 10689 10690/* continuation for OP_INSTANCE_OF */ 10691 10692 /* 10693 * Trivial test failed, need to perform full check. This is common. 10694 * r0 holds obj->clazz 10695 * r1 holds class resolved from BBBB 10696 * r9 holds A 10697 */ 10698.LOP_INSTANCE_OF_fullcheck: 10699 bl dvmInstanceofNonTrivial @ r0<- boolean result 10700 @ fall through to OP_INSTANCE_OF_store 10701 10702 /* 10703 * r0 holds boolean result 10704 * r9 holds A 10705 */ 10706.LOP_INSTANCE_OF_store: 10707 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10708 SET_VREG(r0, r9) @ vA<- r0 10709 GET_INST_OPCODE(ip) @ extract opcode from rINST 10710 GOTO_OPCODE(ip) @ jump to next instruction 10711 10712 /* 10713 * Trivial test succeeded, save and bail. 10714 * r9 holds A 10715 */ 10716.LOP_INSTANCE_OF_trivial: 10717 mov r0, #1 @ indicate success 10718 @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper 10719 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10720 SET_VREG(r0, r9) @ vA<- r0 10721 GET_INST_OPCODE(ip) @ extract opcode from rINST 10722 GOTO_OPCODE(ip) @ jump to next instruction 10723 10724 /* 10725 * Resolution required. This is the least-likely path. 10726 * 10727 * r3 holds BBBB 10728 * r9 holds A 10729 */ 10730.LOP_INSTANCE_OF_resolve: 10731 EXPORT_PC() @ resolve() could throw 10732 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 10733 mov r1, r3 @ r1<- BBBB 10734 mov r2, #1 @ r2<- true 10735 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 10736 bl dvmResolveClass @ r0<- resolved ClassObject ptr 10737 cmp r0, #0 @ got null? 10738 beq common_exceptionThrown @ yes, handle exception 10739 mov r1, r0 @ r1<- class resolved from BBB 10740 mov r3, rINST, lsr #12 @ r3<- B 10741 GET_VREG(r0, r3) @ r0<- vB (object) 10742 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 10743 b .LOP_INSTANCE_OF_resolved @ pick up where we left off 10744 10745/* continuation for OP_NEW_INSTANCE */ 10746 10747 .balign 32 @ minimize cache lines 10748.LOP_NEW_INSTANCE_finish: @ r0=new object 10749 mov r3, rINST, lsr #8 @ r3<- AA 10750 cmp r0, #0 @ failed? 10751 beq common_exceptionThrown @ yes, handle the exception 10752 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10753 GET_INST_OPCODE(ip) @ extract opcode from rINST 10754 SET_VREG(r0, r3) @ vAA<- r0 10755 GOTO_OPCODE(ip) @ jump to next instruction 10756 10757 /* 10758 * Class initialization required. 10759 * 10760 * r0 holds class object 10761 */ 10762.LOP_NEW_INSTANCE_needinit: 10763 mov r9, r0 @ save r0 10764 bl dvmInitClass @ initialize class 10765 cmp r0, #0 @ check boolean result 10766 mov r0, r9 @ restore r0 10767 bne .LOP_NEW_INSTANCE_initialized @ success, continue 10768 b common_exceptionThrown @ failed, deal with init exception 10769 10770 /* 10771 * Resolution required. This is the least-likely path. 10772 * 10773 * r1 holds BBBB 10774 */ 10775.LOP_NEW_INSTANCE_resolve: 10776 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 10777 mov r2, #0 @ r2<- false 10778 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 10779 bl dvmResolveClass @ r0<- resolved ClassObject ptr 10780 cmp r0, #0 @ got null? 10781 bne .LOP_NEW_INSTANCE_resolved @ no, continue 10782 b common_exceptionThrown @ yes, handle exception 10783 10784.LstrInstantiationErrorPtr: 10785 .word .LstrInstantiationError 10786 10787/* continuation for OP_NEW_ARRAY */ 10788 10789 10790 /* 10791 * Resolve class. (This is an uncommon case.) 10792 * 10793 * r1 holds array length 10794 * r2 holds class ref CCCC 10795 */ 10796.LOP_NEW_ARRAY_resolve: 10797 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 10798 mov r9, r1 @ r9<- length (save) 10799 mov r1, r2 @ r1<- CCCC 10800 mov r2, #0 @ r2<- false 10801 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 10802 bl dvmResolveClass @ r0<- call(clazz, ref) 10803 cmp r0, #0 @ got null? 10804 mov r1, r9 @ r1<- length (restore) 10805 beq common_exceptionThrown @ yes, handle exception 10806 @ fall through to OP_NEW_ARRAY_finish 10807 10808 /* 10809 * Finish allocation. 10810 * 10811 * r0 holds class 10812 * r1 holds array length 10813 */ 10814.LOP_NEW_ARRAY_finish: 10815 mov r2, #ALLOC_DONT_TRACK @ don't track in local refs table 10816 bl dvmAllocArrayByClass @ r0<- call(clazz, length, flags) 10817 cmp r0, #0 @ failed? 10818 mov r2, rINST, lsr #8 @ r2<- A+ 10819 beq common_exceptionThrown @ yes, handle the exception 10820 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10821 and r2, r2, #15 @ r2<- A 10822 GET_INST_OPCODE(ip) @ extract opcode from rINST 10823 SET_VREG(r0, r2) @ vA<- r0 10824 GOTO_OPCODE(ip) @ jump to next instruction 10825 10826/* continuation for OP_FILLED_NEW_ARRAY */ 10827 10828 /* 10829 * On entry: 10830 * r0 holds array class 10831 * r10 holds AA or BA 10832 */ 10833.LOP_FILLED_NEW_ARRAY_continue: 10834 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 10835 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 10836 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 10837 .if 0 10838 mov r1, r10 @ r1<- AA (length) 10839 .else 10840 mov r1, r10, lsr #4 @ r1<- B (length) 10841 .endif 10842 cmp rINST, #'I' @ array of ints? 10843 cmpne rINST, #'L' @ array of objects? 10844 cmpne rINST, #'[' @ array of arrays? 10845 mov r9, r1 @ save length in r9 10846 bne .LOP_FILLED_NEW_ARRAY_notimpl @ no, not handled yet 10847 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 10848 cmp r0, #0 @ null return? 10849 beq common_exceptionThrown @ alloc failed, handle exception 10850 10851 FETCH(r1, 2) @ r1<- FEDC or CCCC 10852 str r0, [rGLUE, #offGlue_retval] @ retval.l <- new array 10853 str rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type 10854 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 10855 subs r9, r9, #1 @ length--, check for neg 10856 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 10857 bmi 2f @ was zero, bail 10858 10859 @ copy values from registers into the array 10860 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 10861 .if 0 10862 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 108631: ldr r3, [r2], #4 @ r3<- *r2++ 10864 subs r9, r9, #1 @ count-- 10865 str r3, [r0], #4 @ *contents++ = vX 10866 bpl 1b 10867 @ continue at 2 10868 .else 10869 cmp r9, #4 @ length was initially 5? 10870 and r2, r10, #15 @ r2<- A 10871 bne 1f @ <= 4 args, branch 10872 GET_VREG(r3, r2) @ r3<- vA 10873 sub r9, r9, #1 @ count-- 10874 str r3, [r0, #16] @ contents[4] = vA 108751: and r2, r1, #15 @ r2<- F/E/D/C 10876 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 10877 mov r1, r1, lsr #4 @ r1<- next reg in low 4 10878 subs r9, r9, #1 @ count-- 10879 str r3, [r0], #4 @ *contents++ = vX 10880 bpl 1b 10881 @ continue at 2 10882 .endif 10883 108842: 10885 ldr r0, [rGLUE, #offGlue_retval] @ r0<- object 10886 ldr r1, [rGLUE, #offGlue_retval+4] @ r1<- type 10887 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 10888 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 10889 cmp r1, #'I' @ Is int array? 10890 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 10891 GOTO_OPCODE(ip) @ execute it 10892 10893 /* 10894 * Throw an exception indicating that we have not implemented this 10895 * mode of filled-new-array. 10896 */ 10897.LOP_FILLED_NEW_ARRAY_notimpl: 10898 ldr r0, .L_strInternalError 10899 ldr r1, .L_strFilledNewArrayNotImpl 10900 bl dvmThrowException 10901 b common_exceptionThrown 10902 10903 .if (!0) @ define in one or the other, not both 10904.L_strFilledNewArrayNotImpl: 10905 .word .LstrFilledNewArrayNotImpl 10906.L_strInternalError: 10907 .word .LstrInternalError 10908 .endif 10909 10910/* continuation for OP_FILLED_NEW_ARRAY_RANGE */ 10911 10912 /* 10913 * On entry: 10914 * r0 holds array class 10915 * r10 holds AA or BA 10916 */ 10917.LOP_FILLED_NEW_ARRAY_RANGE_continue: 10918 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 10919 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 10920 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 10921 .if 1 10922 mov r1, r10 @ r1<- AA (length) 10923 .else 10924 mov r1, r10, lsr #4 @ r1<- B (length) 10925 .endif 10926 cmp rINST, #'I' @ array of ints? 10927 cmpne rINST, #'L' @ array of objects? 10928 cmpne rINST, #'[' @ array of arrays? 10929 mov r9, r1 @ save length in r9 10930 bne .LOP_FILLED_NEW_ARRAY_RANGE_notimpl @ no, not handled yet 10931 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 10932 cmp r0, #0 @ null return? 10933 beq common_exceptionThrown @ alloc failed, handle exception 10934 10935 FETCH(r1, 2) @ r1<- FEDC or CCCC 10936 str r0, [rGLUE, #offGlue_retval] @ retval.l <- new array 10937 str rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type 10938 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 10939 subs r9, r9, #1 @ length--, check for neg 10940 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 10941 bmi 2f @ was zero, bail 10942 10943 @ copy values from registers into the array 10944 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 10945 .if 1 10946 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 109471: ldr r3, [r2], #4 @ r3<- *r2++ 10948 subs r9, r9, #1 @ count-- 10949 str r3, [r0], #4 @ *contents++ = vX 10950 bpl 1b 10951 @ continue at 2 10952 .else 10953 cmp r9, #4 @ length was initially 5? 10954 and r2, r10, #15 @ r2<- A 10955 bne 1f @ <= 4 args, branch 10956 GET_VREG(r3, r2) @ r3<- vA 10957 sub r9, r9, #1 @ count-- 10958 str r3, [r0, #16] @ contents[4] = vA 109591: and r2, r1, #15 @ r2<- F/E/D/C 10960 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 10961 mov r1, r1, lsr #4 @ r1<- next reg in low 4 10962 subs r9, r9, #1 @ count-- 10963 str r3, [r0], #4 @ *contents++ = vX 10964 bpl 1b 10965 @ continue at 2 10966 .endif 10967 109682: 10969 ldr r0, [rGLUE, #offGlue_retval] @ r0<- object 10970 ldr r1, [rGLUE, #offGlue_retval+4] @ r1<- type 10971 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 10972 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 10973 cmp r1, #'I' @ Is int array? 10974 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 10975 GOTO_OPCODE(ip) @ execute it 10976 10977 /* 10978 * Throw an exception indicating that we have not implemented this 10979 * mode of filled-new-array. 10980 */ 10981.LOP_FILLED_NEW_ARRAY_RANGE_notimpl: 10982 ldr r0, .L_strInternalError 10983 ldr r1, .L_strFilledNewArrayNotImpl 10984 bl dvmThrowException 10985 b common_exceptionThrown 10986 10987 .if (!1) @ define in one or the other, not both 10988.L_strFilledNewArrayNotImpl: 10989 .word .LstrFilledNewArrayNotImpl 10990.L_strInternalError: 10991 .word .LstrInternalError 10992 .endif 10993 10994/* continuation for OP_CMPL_FLOAT */ 10995.LOP_CMPL_FLOAT_finish: 10996 SET_VREG(r0, r9) @ vAA<- r0 10997 GOTO_OPCODE(ip) @ jump to next instruction 10998 10999/* continuation for OP_CMPG_FLOAT */ 11000.LOP_CMPG_FLOAT_finish: 11001 SET_VREG(r0, r9) @ vAA<- r0 11002 GOTO_OPCODE(ip) @ jump to next instruction 11003 11004/* continuation for OP_CMPL_DOUBLE */ 11005.LOP_CMPL_DOUBLE_finish: 11006 SET_VREG(r0, r9) @ vAA<- r0 11007 GOTO_OPCODE(ip) @ jump to next instruction 11008 11009/* continuation for OP_CMPG_DOUBLE */ 11010.LOP_CMPG_DOUBLE_finish: 11011 SET_VREG(r0, r9) @ vAA<- r0 11012 GOTO_OPCODE(ip) @ jump to next instruction 11013 11014/* continuation for OP_CMP_LONG */ 11015 11016.LOP_CMP_LONG_less: 11017 mvn r1, #0 @ r1<- -1 11018 @ Want to cond code the next mov so we can avoid branch, but don't see it; 11019 @ instead, we just replicate the tail end. 11020 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11021 SET_VREG(r1, r9) @ vAA<- r1 11022 GET_INST_OPCODE(ip) @ extract opcode from rINST 11023 GOTO_OPCODE(ip) @ jump to next instruction 11024 11025.LOP_CMP_LONG_greater: 11026 mov r1, #1 @ r1<- 1 11027 @ fall through to _finish 11028 11029.LOP_CMP_LONG_finish: 11030 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11031 SET_VREG(r1, r9) @ vAA<- r1 11032 GET_INST_OPCODE(ip) @ extract opcode from rINST 11033 GOTO_OPCODE(ip) @ jump to next instruction 11034 11035/* continuation for OP_AGET_WIDE */ 11036 11037.LOP_AGET_WIDE_finish: 11038 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11039 ldrd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 11040 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 11041 GET_INST_OPCODE(ip) @ extract opcode from rINST 11042 stmia r9, {r2-r3} @ vAA/vAA+1<- r2/r3 11043 GOTO_OPCODE(ip) @ jump to next instruction 11044 11045/* continuation for OP_APUT_WIDE */ 11046 11047.LOP_APUT_WIDE_finish: 11048 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11049 ldmia r9, {r2-r3} @ r2/r3<- vAA/vAA+1 11050 GET_INST_OPCODE(ip) @ extract opcode from rINST 11051 strd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 11052 GOTO_OPCODE(ip) @ jump to next instruction 11053 11054/* continuation for OP_APUT_OBJECT */ 11055 /* 11056 * On entry: 11057 * rINST = vBB (arrayObj) 11058 * r9 = vAA (obj) 11059 * r10 = offset into array (vBB + vCC * width) 11060 */ 11061.LOP_APUT_OBJECT_finish: 11062 cmp r9, #0 @ storing null reference? 11063 beq .LOP_APUT_OBJECT_skip_check @ yes, skip type checks 11064 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 11065 ldr r1, [rINST, #offObject_clazz] @ r1<- arrayObj->clazz 11066 bl dvmCanPutArrayElement @ test object type vs. array type 11067 cmp r0, #0 @ okay? 11068 beq .LOP_APUT_OBJECT_throw @ no 11069 mov r1, rINST @ r1<- arrayObj 11070 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11071 ldr r2, [rGLUE, #offGlue_cardTable] @ get biased CT base 11072 add r10, #offArrayObject_contents @ r0<- pointer to slot 11073 GET_INST_OPCODE(ip) @ extract opcode from rINST 11074 str r9, [r10] @ vBB[vCC]<- vAA 11075 strb r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head 11076 GOTO_OPCODE(ip) @ jump to next instruction 11077.LOP_APUT_OBJECT_skip_check: 11078 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11079 GET_INST_OPCODE(ip) @ extract opcode from rINST 11080 str r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA 11081 GOTO_OPCODE(ip) @ jump to next instruction 11082.LOP_APUT_OBJECT_throw: 11083 @ The types don't match. We need to throw an ArrayStoreException. 11084 ldr r0, [r9, #offObject_clazz] 11085 ldr r1, [rINST, #offObject_clazz] 11086 EXPORT_PC() 11087 bl dvmThrowArrayStoreException 11088 b common_exceptionThrown 11089 11090/* continuation for OP_IGET */ 11091 11092 /* 11093 * Currently: 11094 * r0 holds resolved field 11095 * r9 holds object 11096 */ 11097.LOP_IGET_finish: 11098 @bl common_squeak0 11099 cmp r9, #0 @ check object for null 11100 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11101 beq common_errNullObject @ object was null 11102 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11103 @ no-op @ acquiring load 11104 mov r2, rINST, lsr #8 @ r2<- A+ 11105 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11106 and r2, r2, #15 @ r2<- A 11107 GET_INST_OPCODE(ip) @ extract opcode from rINST 11108 SET_VREG(r0, r2) @ fp[A]<- r0 11109 GOTO_OPCODE(ip) @ jump to next instruction 11110 11111/* continuation for OP_IGET_WIDE */ 11112 11113 /* 11114 * Currently: 11115 * r0 holds resolved field 11116 * r9 holds object 11117 */ 11118.LOP_IGET_WIDE_finish: 11119 cmp r9, #0 @ check object for null 11120 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11121 beq common_errNullObject @ object was null 11122 .if 0 11123 add r0, r9, r3 @ r0<- address of field 11124 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 11125 .else 11126 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 11127 .endif 11128 mov r2, rINST, lsr #8 @ r2<- A+ 11129 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11130 and r2, r2, #15 @ r2<- A 11131 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 11132 GET_INST_OPCODE(ip) @ extract opcode from rINST 11133 stmia r3, {r0-r1} @ fp[A]<- r0/r1 11134 GOTO_OPCODE(ip) @ jump to next instruction 11135 11136/* continuation for OP_IGET_OBJECT */ 11137 11138 /* 11139 * Currently: 11140 * r0 holds resolved field 11141 * r9 holds object 11142 */ 11143.LOP_IGET_OBJECT_finish: 11144 @bl common_squeak0 11145 cmp r9, #0 @ check object for null 11146 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11147 beq common_errNullObject @ object was null 11148 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11149 @ no-op @ acquiring load 11150 mov r2, rINST, lsr #8 @ r2<- A+ 11151 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11152 and r2, r2, #15 @ r2<- A 11153 GET_INST_OPCODE(ip) @ extract opcode from rINST 11154 SET_VREG(r0, r2) @ fp[A]<- r0 11155 GOTO_OPCODE(ip) @ jump to next instruction 11156 11157/* continuation for OP_IGET_BOOLEAN */ 11158 11159 /* 11160 * Currently: 11161 * r0 holds resolved field 11162 * r9 holds object 11163 */ 11164.LOP_IGET_BOOLEAN_finish: 11165 @bl common_squeak1 11166 cmp r9, #0 @ check object for null 11167 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11168 beq common_errNullObject @ object was null 11169 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11170 @ no-op @ acquiring load 11171 mov r2, rINST, lsr #8 @ r2<- A+ 11172 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11173 and r2, r2, #15 @ r2<- A 11174 GET_INST_OPCODE(ip) @ extract opcode from rINST 11175 SET_VREG(r0, r2) @ fp[A]<- r0 11176 GOTO_OPCODE(ip) @ jump to next instruction 11177 11178/* continuation for OP_IGET_BYTE */ 11179 11180 /* 11181 * Currently: 11182 * r0 holds resolved field 11183 * r9 holds object 11184 */ 11185.LOP_IGET_BYTE_finish: 11186 @bl common_squeak2 11187 cmp r9, #0 @ check object for null 11188 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11189 beq common_errNullObject @ object was null 11190 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11191 @ no-op @ acquiring load 11192 mov r2, rINST, lsr #8 @ r2<- A+ 11193 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11194 and r2, r2, #15 @ r2<- A 11195 GET_INST_OPCODE(ip) @ extract opcode from rINST 11196 SET_VREG(r0, r2) @ fp[A]<- r0 11197 GOTO_OPCODE(ip) @ jump to next instruction 11198 11199/* continuation for OP_IGET_CHAR */ 11200 11201 /* 11202 * Currently: 11203 * r0 holds resolved field 11204 * r9 holds object 11205 */ 11206.LOP_IGET_CHAR_finish: 11207 @bl common_squeak3 11208 cmp r9, #0 @ check object for null 11209 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11210 beq common_errNullObject @ object was null 11211 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11212 @ no-op @ acquiring load 11213 mov r2, rINST, lsr #8 @ r2<- A+ 11214 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11215 and r2, r2, #15 @ r2<- A 11216 GET_INST_OPCODE(ip) @ extract opcode from rINST 11217 SET_VREG(r0, r2) @ fp[A]<- r0 11218 GOTO_OPCODE(ip) @ jump to next instruction 11219 11220/* continuation for OP_IGET_SHORT */ 11221 11222 /* 11223 * Currently: 11224 * r0 holds resolved field 11225 * r9 holds object 11226 */ 11227.LOP_IGET_SHORT_finish: 11228 @bl common_squeak4 11229 cmp r9, #0 @ check object for null 11230 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11231 beq common_errNullObject @ object was null 11232 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11233 @ no-op @ acquiring load 11234 mov r2, rINST, lsr #8 @ r2<- A+ 11235 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11236 and r2, r2, #15 @ r2<- A 11237 GET_INST_OPCODE(ip) @ extract opcode from rINST 11238 SET_VREG(r0, r2) @ fp[A]<- r0 11239 GOTO_OPCODE(ip) @ jump to next instruction 11240 11241/* continuation for OP_IPUT */ 11242 11243 /* 11244 * Currently: 11245 * r0 holds resolved field 11246 * r9 holds object 11247 */ 11248.LOP_IPUT_finish: 11249 @bl common_squeak0 11250 mov r1, rINST, lsr #8 @ r1<- A+ 11251 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11252 and r1, r1, #15 @ r1<- A 11253 cmp r9, #0 @ check object for null 11254 GET_VREG(r0, r1) @ r0<- fp[A] 11255 beq common_errNullObject @ object was null 11256 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11257 GET_INST_OPCODE(ip) @ extract opcode from rINST 11258 @ no-op @ releasing store 11259 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11260 GOTO_OPCODE(ip) @ jump to next instruction 11261 11262/* continuation for OP_IPUT_WIDE */ 11263 11264 /* 11265 * Currently: 11266 * r0 holds resolved field 11267 * r9 holds object 11268 */ 11269.LOP_IPUT_WIDE_finish: 11270 mov r2, rINST, lsr #8 @ r2<- A+ 11271 cmp r9, #0 @ check object for null 11272 and r2, r2, #15 @ r2<- A 11273 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11274 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 11275 beq common_errNullObject @ object was null 11276 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11277 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 11278 GET_INST_OPCODE(r10) @ extract opcode from rINST 11279 .if 0 11280 add r2, r9, r3 @ r2<- target address 11281 bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2 11282 .else 11283 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 11284 .endif 11285 GOTO_OPCODE(r10) @ jump to next instruction 11286 11287/* continuation for OP_IPUT_OBJECT */ 11288 11289 /* 11290 * Currently: 11291 * r0 holds resolved field 11292 * r9 holds object 11293 */ 11294.LOP_IPUT_OBJECT_finish: 11295 @bl common_squeak0 11296 mov r1, rINST, lsr #8 @ r1<- A+ 11297 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11298 and r1, r1, #15 @ r1<- A 11299 cmp r9, #0 @ check object for null 11300 GET_VREG(r0, r1) @ r0<- fp[A] 11301 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 11302 beq common_errNullObject @ object was null 11303 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11304 GET_INST_OPCODE(ip) @ extract opcode from rINST 11305 @ no-op @ releasing store 11306 str r0, [r9, r3] @ obj.field (32 bits)<- r0 11307 cmp r0, #0 @ stored a null reference? 11308 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 11309 GOTO_OPCODE(ip) @ jump to next instruction 11310 11311/* continuation for OP_IPUT_BOOLEAN */ 11312 11313 /* 11314 * Currently: 11315 * r0 holds resolved field 11316 * r9 holds object 11317 */ 11318.LOP_IPUT_BOOLEAN_finish: 11319 @bl common_squeak1 11320 mov r1, rINST, lsr #8 @ r1<- A+ 11321 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11322 and r1, r1, #15 @ r1<- A 11323 cmp r9, #0 @ check object for null 11324 GET_VREG(r0, r1) @ r0<- fp[A] 11325 beq common_errNullObject @ object was null 11326 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11327 GET_INST_OPCODE(ip) @ extract opcode from rINST 11328 @ no-op @ releasing store 11329 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11330 GOTO_OPCODE(ip) @ jump to next instruction 11331 11332/* continuation for OP_IPUT_BYTE */ 11333 11334 /* 11335 * Currently: 11336 * r0 holds resolved field 11337 * r9 holds object 11338 */ 11339.LOP_IPUT_BYTE_finish: 11340 @bl common_squeak2 11341 mov r1, rINST, lsr #8 @ r1<- A+ 11342 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11343 and r1, r1, #15 @ r1<- A 11344 cmp r9, #0 @ check object for null 11345 GET_VREG(r0, r1) @ r0<- fp[A] 11346 beq common_errNullObject @ object was null 11347 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11348 GET_INST_OPCODE(ip) @ extract opcode from rINST 11349 @ no-op @ releasing store 11350 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11351 GOTO_OPCODE(ip) @ jump to next instruction 11352 11353/* continuation for OP_IPUT_CHAR */ 11354 11355 /* 11356 * Currently: 11357 * r0 holds resolved field 11358 * r9 holds object 11359 */ 11360.LOP_IPUT_CHAR_finish: 11361 @bl common_squeak3 11362 mov r1, rINST, lsr #8 @ r1<- A+ 11363 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11364 and r1, r1, #15 @ r1<- A 11365 cmp r9, #0 @ check object for null 11366 GET_VREG(r0, r1) @ r0<- fp[A] 11367 beq common_errNullObject @ object was null 11368 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11369 GET_INST_OPCODE(ip) @ extract opcode from rINST 11370 @ no-op @ releasing store 11371 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11372 GOTO_OPCODE(ip) @ jump to next instruction 11373 11374/* continuation for OP_IPUT_SHORT */ 11375 11376 /* 11377 * Currently: 11378 * r0 holds resolved field 11379 * r9 holds object 11380 */ 11381.LOP_IPUT_SHORT_finish: 11382 @bl common_squeak4 11383 mov r1, rINST, lsr #8 @ r1<- A+ 11384 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11385 and r1, r1, #15 @ r1<- A 11386 cmp r9, #0 @ check object for null 11387 GET_VREG(r0, r1) @ r0<- fp[A] 11388 beq common_errNullObject @ object was null 11389 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11390 GET_INST_OPCODE(ip) @ extract opcode from rINST 11391 @ no-op @ releasing store 11392 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11393 GOTO_OPCODE(ip) @ jump to next instruction 11394 11395/* continuation for OP_SGET */ 11396 11397 /* 11398 * Continuation if the field has not yet been resolved. 11399 * r1: BBBB field ref 11400 */ 11401.LOP_SGET_resolve: 11402 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11403 EXPORT_PC() @ resolve() could throw, so export now 11404 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11405 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11406 cmp r0, #0 @ success? 11407 bne .LOP_SGET_finish @ yes, finish 11408 b common_exceptionThrown @ no, handle exception 11409 11410/* continuation for OP_SGET_WIDE */ 11411 11412 /* 11413 * Continuation if the field has not yet been resolved. 11414 * r1: BBBB field ref 11415 * 11416 * Returns StaticField pointer in r0. 11417 */ 11418.LOP_SGET_WIDE_resolve: 11419 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11420 EXPORT_PC() @ resolve() could throw, so export now 11421 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11422 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11423 cmp r0, #0 @ success? 11424 bne .LOP_SGET_WIDE_finish @ yes, finish 11425 b common_exceptionThrown @ no, handle exception 11426 11427/* continuation for OP_SGET_OBJECT */ 11428 11429 /* 11430 * Continuation if the field has not yet been resolved. 11431 * r1: BBBB field ref 11432 */ 11433.LOP_SGET_OBJECT_resolve: 11434 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11435 EXPORT_PC() @ resolve() could throw, so export now 11436 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11437 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11438 cmp r0, #0 @ success? 11439 bne .LOP_SGET_OBJECT_finish @ yes, finish 11440 b common_exceptionThrown @ no, handle exception 11441 11442/* continuation for OP_SGET_BOOLEAN */ 11443 11444 /* 11445 * Continuation if the field has not yet been resolved. 11446 * r1: BBBB field ref 11447 */ 11448.LOP_SGET_BOOLEAN_resolve: 11449 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11450 EXPORT_PC() @ resolve() could throw, so export now 11451 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11452 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11453 cmp r0, #0 @ success? 11454 bne .LOP_SGET_BOOLEAN_finish @ yes, finish 11455 b common_exceptionThrown @ no, handle exception 11456 11457/* continuation for OP_SGET_BYTE */ 11458 11459 /* 11460 * Continuation if the field has not yet been resolved. 11461 * r1: BBBB field ref 11462 */ 11463.LOP_SGET_BYTE_resolve: 11464 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11465 EXPORT_PC() @ resolve() could throw, so export now 11466 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11467 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11468 cmp r0, #0 @ success? 11469 bne .LOP_SGET_BYTE_finish @ yes, finish 11470 b common_exceptionThrown @ no, handle exception 11471 11472/* continuation for OP_SGET_CHAR */ 11473 11474 /* 11475 * Continuation if the field has not yet been resolved. 11476 * r1: BBBB field ref 11477 */ 11478.LOP_SGET_CHAR_resolve: 11479 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11480 EXPORT_PC() @ resolve() could throw, so export now 11481 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11482 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11483 cmp r0, #0 @ success? 11484 bne .LOP_SGET_CHAR_finish @ yes, finish 11485 b common_exceptionThrown @ no, handle exception 11486 11487/* continuation for OP_SGET_SHORT */ 11488 11489 /* 11490 * Continuation if the field has not yet been resolved. 11491 * r1: BBBB field ref 11492 */ 11493.LOP_SGET_SHORT_resolve: 11494 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11495 EXPORT_PC() @ resolve() could throw, so export now 11496 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11497 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11498 cmp r0, #0 @ success? 11499 bne .LOP_SGET_SHORT_finish @ yes, finish 11500 b common_exceptionThrown @ no, handle exception 11501 11502/* continuation for OP_SPUT */ 11503 11504 /* 11505 * Continuation if the field has not yet been resolved. 11506 * r1: BBBB field ref 11507 */ 11508.LOP_SPUT_resolve: 11509 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11510 EXPORT_PC() @ resolve() could throw, so export now 11511 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11512 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11513 cmp r0, #0 @ success? 11514 bne .LOP_SPUT_finish @ yes, finish 11515 b common_exceptionThrown @ no, handle exception 11516 11517/* continuation for OP_SPUT_WIDE */ 11518 11519 /* 11520 * Continuation if the field has not yet been resolved. 11521 * r1: BBBB field ref 11522 * r9: &fp[AA] 11523 * 11524 * Returns StaticField pointer in r2. 11525 */ 11526.LOP_SPUT_WIDE_resolve: 11527 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11528 EXPORT_PC() @ resolve() could throw, so export now 11529 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11530 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11531 cmp r0, #0 @ success? 11532 mov r2, r0 @ copy to r2 11533 bne .LOP_SPUT_WIDE_finish @ yes, finish 11534 b common_exceptionThrown @ no, handle exception 11535 11536/* continuation for OP_SPUT_OBJECT */ 11537.LOP_SPUT_OBJECT_finish: @ field ptr in r0 11538 mov r2, rINST, lsr #8 @ r2<- AA 11539 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11540 GET_VREG(r1, r2) @ r1<- fp[AA] 11541 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 11542 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 11543 GET_INST_OPCODE(ip) @ extract opcode from rINST 11544 @ no-op @ releasing store 11545 str r1, [r0, #offStaticField_value] @ field<- vAA 11546 cmp r1, #0 @ stored a null object? 11547 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 11548 GOTO_OPCODE(ip) @ jump to next instruction 11549 11550/* continuation for OP_SPUT_BOOLEAN */ 11551 11552 /* 11553 * Continuation if the field has not yet been resolved. 11554 * r1: BBBB field ref 11555 */ 11556.LOP_SPUT_BOOLEAN_resolve: 11557 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11558 EXPORT_PC() @ resolve() could throw, so export now 11559 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11560 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11561 cmp r0, #0 @ success? 11562 bne .LOP_SPUT_BOOLEAN_finish @ yes, finish 11563 b common_exceptionThrown @ no, handle exception 11564 11565/* continuation for OP_SPUT_BYTE */ 11566 11567 /* 11568 * Continuation if the field has not yet been resolved. 11569 * r1: BBBB field ref 11570 */ 11571.LOP_SPUT_BYTE_resolve: 11572 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11573 EXPORT_PC() @ resolve() could throw, so export now 11574 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11575 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11576 cmp r0, #0 @ success? 11577 bne .LOP_SPUT_BYTE_finish @ yes, finish 11578 b common_exceptionThrown @ no, handle exception 11579 11580/* continuation for OP_SPUT_CHAR */ 11581 11582 /* 11583 * Continuation if the field has not yet been resolved. 11584 * r1: BBBB field ref 11585 */ 11586.LOP_SPUT_CHAR_resolve: 11587 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11588 EXPORT_PC() @ resolve() could throw, so export now 11589 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11590 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11591 cmp r0, #0 @ success? 11592 bne .LOP_SPUT_CHAR_finish @ yes, finish 11593 b common_exceptionThrown @ no, handle exception 11594 11595/* continuation for OP_SPUT_SHORT */ 11596 11597 /* 11598 * Continuation if the field has not yet been resolved. 11599 * r1: BBBB field ref 11600 */ 11601.LOP_SPUT_SHORT_resolve: 11602 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11603 EXPORT_PC() @ resolve() could throw, so export now 11604 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11605 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11606 cmp r0, #0 @ success? 11607 bne .LOP_SPUT_SHORT_finish @ yes, finish 11608 b common_exceptionThrown @ no, handle exception 11609 11610/* continuation for OP_INVOKE_VIRTUAL */ 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_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_invokeMethodNoRange @ continue on 11626 11627/* continuation for OP_INVOKE_SUPER */ 11628 11629 /* 11630 * At this point: 11631 * r0 = resolved base method 11632 * r9 = method->clazz 11633 */ 11634.LOP_INVOKE_SUPER_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_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_invokeMethodNoRange @ continue on 11644 11645.LOP_INVOKE_SUPER_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_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_nsm: 11658 ldr r1, [r0, #offMethod_name] @ r1<- method name 11659 b common_errNoSuchMethod 11660 11661/* continuation for OP_INVOKE_DIRECT */ 11662 11663 /* 11664 * On entry: 11665 * r1 = reference (BBBB or CCCC) 11666 * r10 = "this" register 11667 */ 11668.LOP_INVOKE_DIRECT_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_finish @ no, continue 11676 b common_exceptionThrown @ yes, handle exception 11677 11678/* continuation for OP_INVOKE_VIRTUAL_RANGE */ 11679 11680 /* 11681 * At this point: 11682 * r0 = resolved base method 11683 * r10 = C or CCCC (index of first arg, which is the "this" ptr) 11684 */ 11685.LOP_INVOKE_VIRTUAL_RANGE_continue: 11686 GET_VREG(r1, r10) @ r1<- "this" ptr 11687 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 11688 cmp r1, #0 @ is "this" null? 11689 beq common_errNullObject @ null "this", throw exception 11690 ldr r3, [r1, #offObject_clazz] @ r1<- thisPtr->clazz 11691 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 11692 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 11693 bl common_invokeMethodRange @ continue on 11694 11695/* continuation for OP_INVOKE_SUPER_RANGE */ 11696 11697 /* 11698 * At this point: 11699 * r0 = resolved base method 11700 * r9 = method->clazz 11701 */ 11702.LOP_INVOKE_SUPER_RANGE_continue: 11703 ldr r1, [r9, #offClassObject_super] @ r1<- method->clazz->super 11704 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 11705 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 11706 EXPORT_PC() @ must export for invoke 11707 cmp r2, r3 @ compare (methodIndex, vtableCount) 11708 bcs .LOP_INVOKE_SUPER_RANGE_nsm @ method not present in superclass 11709 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 11710 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 11711 bl common_invokeMethodRange @ continue on 11712 11713.LOP_INVOKE_SUPER_RANGE_resolve: 11714 mov r0, r9 @ r0<- method->clazz 11715 mov r2, #METHOD_VIRTUAL @ resolver method type 11716 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 11717 cmp r0, #0 @ got null? 11718 bne .LOP_INVOKE_SUPER_RANGE_continue @ no, continue 11719 b common_exceptionThrown @ yes, handle exception 11720 11721 /* 11722 * Throw a NoSuchMethodError with the method name as the message. 11723 * r0 = resolved base method 11724 */ 11725.LOP_INVOKE_SUPER_RANGE_nsm: 11726 ldr r1, [r0, #offMethod_name] @ r1<- method name 11727 b common_errNoSuchMethod 11728 11729/* continuation for OP_INVOKE_DIRECT_RANGE */ 11730 11731 /* 11732 * On entry: 11733 * r1 = reference (BBBB or CCCC) 11734 * r10 = "this" register 11735 */ 11736.LOP_INVOKE_DIRECT_RANGE_resolve: 11737 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 11738 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 11739 mov r2, #METHOD_DIRECT @ resolver method type 11740 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 11741 cmp r0, #0 @ got null? 11742 GET_VREG(r2, r10) @ r2<- "this" ptr (reload) 11743 bne .LOP_INVOKE_DIRECT_RANGE_finish @ no, continue 11744 b common_exceptionThrown @ yes, handle exception 11745 11746/* continuation for OP_FLOAT_TO_LONG */ 11747/* 11748 * Convert the float in r0 to a long in r0/r1. 11749 * 11750 * We have to clip values to long min/max per the specification. The 11751 * expected common case is a "reasonable" value that converts directly 11752 * to modest integer. The EABI convert function isn't doing this for us. 11753 */ 11754f2l_doconv: 11755 stmfd sp!, {r4, lr} 11756 mov r1, #0x5f000000 @ (float)maxlong 11757 mov r4, r0 11758 bl __aeabi_fcmpge @ is arg >= maxlong? 11759 cmp r0, #0 @ nonzero == yes 11760 mvnne r0, #0 @ return maxlong (7fffffff) 11761 mvnne r1, #0x80000000 11762 ldmnefd sp!, {r4, pc} 11763 11764 mov r0, r4 @ recover arg 11765 mov r1, #0xdf000000 @ (float)minlong 11766 bl __aeabi_fcmple @ is arg <= minlong? 11767 cmp r0, #0 @ nonzero == yes 11768 movne r0, #0 @ return minlong (80000000) 11769 movne r1, #0x80000000 11770 ldmnefd sp!, {r4, pc} 11771 11772 mov r0, r4 @ recover arg 11773 mov r1, r4 11774 bl __aeabi_fcmpeq @ is arg == self? 11775 cmp r0, #0 @ zero == no 11776 moveq r1, #0 @ return zero for NaN 11777 ldmeqfd sp!, {r4, pc} 11778 11779 mov r0, r4 @ recover arg 11780 bl __aeabi_f2lz @ convert float to long 11781 ldmfd sp!, {r4, pc} 11782 11783/* continuation for OP_DOUBLE_TO_LONG */ 11784/* 11785 * Convert the double in r0/r1 to a long in r0/r1. 11786 * 11787 * We have to clip values to long min/max per the specification. The 11788 * expected common case is a "reasonable" value that converts directly 11789 * to modest integer. The EABI convert function isn't doing this for us. 11790 */ 11791d2l_doconv: 11792 stmfd sp!, {r4, r5, lr} @ save regs 11793 mov r3, #0x43000000 @ maxlong, as a double (high word) 11794 add r3, #0x00e00000 @ 0x43e00000 11795 mov r2, #0 @ maxlong, as a double (low word) 11796 sub sp, sp, #4 @ align for EABI 11797 mov r4, r0 @ save a copy of r0 11798 mov r5, r1 @ and r1 11799 bl __aeabi_dcmpge @ is arg >= maxlong? 11800 cmp r0, #0 @ nonzero == yes 11801 mvnne r0, #0 @ return maxlong (7fffffffffffffff) 11802 mvnne r1, #0x80000000 11803 bne 1f 11804 11805 mov r0, r4 @ recover arg 11806 mov r1, r5 11807 mov r3, #0xc3000000 @ minlong, as a double (high word) 11808 add r3, #0x00e00000 @ 0xc3e00000 11809 mov r2, #0 @ minlong, as a double (low word) 11810 bl __aeabi_dcmple @ is arg <= minlong? 11811 cmp r0, #0 @ nonzero == yes 11812 movne r0, #0 @ return minlong (8000000000000000) 11813 movne r1, #0x80000000 11814 bne 1f 11815 11816 mov r0, r4 @ recover arg 11817 mov r1, r5 11818 mov r2, r4 @ compare against self 11819 mov r3, r5 11820 bl __aeabi_dcmpeq @ is arg == self? 11821 cmp r0, #0 @ zero == no 11822 moveq r1, #0 @ return zero for NaN 11823 beq 1f 11824 11825 mov r0, r4 @ recover arg 11826 mov r1, r5 11827 bl __aeabi_d2lz @ convert double to long 11828 118291: 11830 add sp, sp, #4 11831 ldmfd sp!, {r4, r5, pc} 11832 11833/* continuation for OP_MUL_LONG */ 11834 11835.LOP_MUL_LONG_finish: 11836 GET_INST_OPCODE(ip) @ extract opcode from rINST 11837 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 11838 GOTO_OPCODE(ip) @ jump to next instruction 11839 11840/* continuation for OP_SHL_LONG */ 11841 11842.LOP_SHL_LONG_finish: 11843 mov r0, r0, asl r2 @ r0<- r0 << r2 11844 GET_INST_OPCODE(ip) @ extract opcode from rINST 11845 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11846 GOTO_OPCODE(ip) @ jump to next instruction 11847 11848/* continuation for OP_SHR_LONG */ 11849 11850.LOP_SHR_LONG_finish: 11851 mov r1, r1, asr r2 @ r1<- r1 >> r2 11852 GET_INST_OPCODE(ip) @ extract opcode from rINST 11853 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11854 GOTO_OPCODE(ip) @ jump to next instruction 11855 11856/* continuation for OP_USHR_LONG */ 11857 11858.LOP_USHR_LONG_finish: 11859 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 11860 GET_INST_OPCODE(ip) @ extract opcode from rINST 11861 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11862 GOTO_OPCODE(ip) @ jump to next instruction 11863 11864/* continuation for OP_SHL_LONG_2ADDR */ 11865 11866.LOP_SHL_LONG_2ADDR_finish: 11867 GET_INST_OPCODE(ip) @ extract opcode from rINST 11868 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11869 GOTO_OPCODE(ip) @ jump to next instruction 11870 11871/* continuation for OP_SHR_LONG_2ADDR */ 11872 11873.LOP_SHR_LONG_2ADDR_finish: 11874 GET_INST_OPCODE(ip) @ extract opcode from rINST 11875 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11876 GOTO_OPCODE(ip) @ jump to next instruction 11877 11878/* continuation for OP_USHR_LONG_2ADDR */ 11879 11880.LOP_USHR_LONG_2ADDR_finish: 11881 GET_INST_OPCODE(ip) @ extract opcode from rINST 11882 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11883 GOTO_OPCODE(ip) @ jump to next instruction 11884 11885/* continuation for OP_IGET_VOLATILE */ 11886 11887 /* 11888 * Currently: 11889 * r0 holds resolved field 11890 * r9 holds object 11891 */ 11892.LOP_IGET_VOLATILE_finish: 11893 @bl common_squeak0 11894 cmp r9, #0 @ check object for null 11895 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11896 beq common_errNullObject @ object was null 11897 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11898 SMP_DMB @ acquiring load 11899 mov r2, rINST, lsr #8 @ r2<- A+ 11900 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11901 and r2, r2, #15 @ r2<- A 11902 GET_INST_OPCODE(ip) @ extract opcode from rINST 11903 SET_VREG(r0, r2) @ fp[A]<- r0 11904 GOTO_OPCODE(ip) @ jump to next instruction 11905 11906/* continuation for OP_IPUT_VOLATILE */ 11907 11908 /* 11909 * Currently: 11910 * r0 holds resolved field 11911 * r9 holds object 11912 */ 11913.LOP_IPUT_VOLATILE_finish: 11914 @bl common_squeak0 11915 mov r1, rINST, lsr #8 @ r1<- A+ 11916 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11917 and r1, r1, #15 @ r1<- A 11918 cmp r9, #0 @ check object for null 11919 GET_VREG(r0, r1) @ r0<- fp[A] 11920 beq common_errNullObject @ object was null 11921 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11922 GET_INST_OPCODE(ip) @ extract opcode from rINST 11923 SMP_DMB @ releasing store 11924 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11925 GOTO_OPCODE(ip) @ jump to next instruction 11926 11927/* continuation for OP_SGET_VOLATILE */ 11928 11929 /* 11930 * Continuation if the field has not yet been resolved. 11931 * r1: BBBB field ref 11932 */ 11933.LOP_SGET_VOLATILE_resolve: 11934 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11935 EXPORT_PC() @ resolve() could throw, so export now 11936 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11937 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11938 cmp r0, #0 @ success? 11939 bne .LOP_SGET_VOLATILE_finish @ yes, finish 11940 b common_exceptionThrown @ no, handle exception 11941 11942/* continuation for OP_SPUT_VOLATILE */ 11943 11944 /* 11945 * Continuation if the field has not yet been resolved. 11946 * r1: BBBB field ref 11947 */ 11948.LOP_SPUT_VOLATILE_resolve: 11949 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11950 EXPORT_PC() @ resolve() could throw, so export now 11951 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11952 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11953 cmp r0, #0 @ success? 11954 bne .LOP_SPUT_VOLATILE_finish @ yes, finish 11955 b common_exceptionThrown @ no, handle exception 11956 11957/* continuation for OP_IGET_OBJECT_VOLATILE */ 11958 11959 /* 11960 * Currently: 11961 * r0 holds resolved field 11962 * r9 holds object 11963 */ 11964.LOP_IGET_OBJECT_VOLATILE_finish: 11965 @bl common_squeak0 11966 cmp r9, #0 @ check object for null 11967 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11968 beq common_errNullObject @ object was null 11969 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11970 SMP_DMB @ acquiring load 11971 mov r2, rINST, lsr #8 @ r2<- A+ 11972 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11973 and r2, r2, #15 @ r2<- A 11974 GET_INST_OPCODE(ip) @ extract opcode from rINST 11975 SET_VREG(r0, r2) @ fp[A]<- r0 11976 GOTO_OPCODE(ip) @ jump to next instruction 11977 11978/* continuation for OP_IGET_WIDE_VOLATILE */ 11979 11980 /* 11981 * Currently: 11982 * r0 holds resolved field 11983 * r9 holds object 11984 */ 11985.LOP_IGET_WIDE_VOLATILE_finish: 11986 cmp r9, #0 @ check object for null 11987 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11988 beq common_errNullObject @ object was null 11989 .if 1 11990 add r0, r9, r3 @ r0<- address of field 11991 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 11992 .else 11993 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 11994 .endif 11995 mov r2, rINST, lsr #8 @ r2<- A+ 11996 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11997 and r2, r2, #15 @ r2<- A 11998 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 11999 GET_INST_OPCODE(ip) @ extract opcode from rINST 12000 stmia r3, {r0-r1} @ fp[A]<- r0/r1 12001 GOTO_OPCODE(ip) @ jump to next instruction 12002 12003/* continuation for OP_IPUT_WIDE_VOLATILE */ 12004 12005 /* 12006 * Currently: 12007 * r0 holds resolved field 12008 * r9 holds object 12009 */ 12010.LOP_IPUT_WIDE_VOLATILE_finish: 12011 mov r2, rINST, lsr #8 @ r2<- A+ 12012 cmp r9, #0 @ check object for null 12013 and r2, r2, #15 @ r2<- A 12014 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12015 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 12016 beq common_errNullObject @ object was null 12017 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 12018 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 12019 GET_INST_OPCODE(r10) @ extract opcode from rINST 12020 .if 1 12021 add r2, r9, r3 @ r2<- target address 12022 bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2 12023 .else 12024 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 12025 .endif 12026 GOTO_OPCODE(r10) @ jump to next instruction 12027 12028/* continuation for OP_SGET_WIDE_VOLATILE */ 12029 12030 /* 12031 * Continuation if the field has not yet been resolved. 12032 * r1: BBBB field ref 12033 * 12034 * Returns StaticField pointer in r0. 12035 */ 12036.LOP_SGET_WIDE_VOLATILE_resolve: 12037 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12038 EXPORT_PC() @ resolve() could throw, so export now 12039 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12040 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12041 cmp r0, #0 @ success? 12042 bne .LOP_SGET_WIDE_VOLATILE_finish @ yes, finish 12043 b common_exceptionThrown @ no, handle exception 12044 12045/* continuation for OP_SPUT_WIDE_VOLATILE */ 12046 12047 /* 12048 * Continuation if the field has not yet been resolved. 12049 * r1: BBBB field ref 12050 * r9: &fp[AA] 12051 * 12052 * Returns StaticField pointer in r2. 12053 */ 12054.LOP_SPUT_WIDE_VOLATILE_resolve: 12055 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12056 EXPORT_PC() @ resolve() could throw, so export now 12057 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12058 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12059 cmp r0, #0 @ success? 12060 mov r2, r0 @ copy to r2 12061 bne .LOP_SPUT_WIDE_VOLATILE_finish @ yes, finish 12062 b common_exceptionThrown @ no, handle exception 12063 12064/* continuation for OP_EXECUTE_INLINE */ 12065 12066 /* 12067 * Extract args, call function. 12068 * r0 = #of args (0-4) 12069 * r10 = call index 12070 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 12071 * 12072 * Other ideas: 12073 * - Use a jump table from the main piece to jump directly into the 12074 * AND/LDR pairs. Costs a data load, saves a branch. 12075 * - Have five separate pieces that do the loading, so we can work the 12076 * interleave a little better. Increases code size. 12077 */ 12078.LOP_EXECUTE_INLINE_continue: 12079 rsb r0, r0, #4 @ r0<- 4-r0 12080 FETCH(r9, 2) @ r9<- FEDC 12081 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 12082 bl common_abort @ (skipped due to ARM prefetch) 120834: and ip, r9, #0xf000 @ isolate F 12084 ldr r3, [rFP, ip, lsr #10] @ r3<- vF (shift right 12, left 2) 120853: and ip, r9, #0x0f00 @ isolate E 12086 ldr r2, [rFP, ip, lsr #6] @ r2<- vE 120872: and ip, r9, #0x00f0 @ isolate D 12088 ldr r1, [rFP, ip, lsr #2] @ r1<- vD 120891: and ip, r9, #0x000f @ isolate C 12090 ldr r0, [rFP, ip, lsl #2] @ r0<- vC 120910: 12092 ldr r9, .LOP_EXECUTE_INLINE_table @ table of InlineOperation 12093 ldr pc, [r9, r10, lsl #4] @ sizeof=16, "func" is first entry 12094 @ (not reached) 12095 12096.LOP_EXECUTE_INLINE_table: 12097 .word gDvmInlineOpsTable 12098 12099/* continuation for OP_EXECUTE_INLINE_RANGE */ 12100 12101 /* 12102 * Extract args, call function. 12103 * r0 = #of args (0-4) 12104 * r10 = call index 12105 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 12106 */ 12107.LOP_EXECUTE_INLINE_RANGE_continue: 12108 rsb r0, r0, #4 @ r0<- 4-r0 12109 FETCH(r9, 2) @ r9<- CCCC 12110 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 12111 bl common_abort @ (skipped due to ARM prefetch) 121124: add ip, r9, #3 @ base+3 12113 GET_VREG(r3, ip) @ r3<- vBase[3] 121143: add ip, r9, #2 @ base+2 12115 GET_VREG(r2, ip) @ r2<- vBase[2] 121162: add ip, r9, #1 @ base+1 12117 GET_VREG(r1, ip) @ r1<- vBase[1] 121181: add ip, r9, #0 @ (nop) 12119 GET_VREG(r0, ip) @ r0<- vBase[0] 121200: 12121 ldr r9, .LOP_EXECUTE_INLINE_RANGE_table @ table of InlineOperation 12122 ldr pc, [r9, r10, lsl #4] @ sizeof=16, "func" is first entry 12123 @ (not reached) 12124 12125.LOP_EXECUTE_INLINE_RANGE_table: 12126 .word gDvmInlineOpsTable 12127 12128/* continuation for OP_IPUT_OBJECT_VOLATILE */ 12129 12130 /* 12131 * Currently: 12132 * r0 holds resolved field 12133 * r9 holds object 12134 */ 12135.LOP_IPUT_OBJECT_VOLATILE_finish: 12136 @bl common_squeak0 12137 mov r1, rINST, lsr #8 @ r1<- A+ 12138 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12139 and r1, r1, #15 @ r1<- A 12140 cmp r9, #0 @ check object for null 12141 GET_VREG(r0, r1) @ r0<- fp[A] 12142 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 12143 beq common_errNullObject @ object was null 12144 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 12145 GET_INST_OPCODE(ip) @ extract opcode from rINST 12146 SMP_DMB @ releasing store 12147 str r0, [r9, r3] @ obj.field (32 bits)<- r0 12148 cmp r0, #0 @ stored a null reference? 12149 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 12150 GOTO_OPCODE(ip) @ jump to next instruction 12151 12152/* continuation for OP_SGET_OBJECT_VOLATILE */ 12153 12154 /* 12155 * Continuation if the field has not yet been resolved. 12156 * r1: BBBB field ref 12157 */ 12158.LOP_SGET_OBJECT_VOLATILE_resolve: 12159 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12160 EXPORT_PC() @ resolve() could throw, so export now 12161 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12162 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12163 cmp r0, #0 @ success? 12164 bne .LOP_SGET_OBJECT_VOLATILE_finish @ yes, finish 12165 b common_exceptionThrown @ no, handle exception 12166 12167/* continuation for OP_SPUT_OBJECT_VOLATILE */ 12168.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0 12169 mov r2, rINST, lsr #8 @ r2<- AA 12170 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 12171 GET_VREG(r1, r2) @ r1<- fp[AA] 12172 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 12173 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 12174 GET_INST_OPCODE(ip) @ extract opcode from rINST 12175 SMP_DMB @ releasing store 12176 str r1, [r0, #offStaticField_value] @ field<- vAA 12177 cmp r1, #0 @ stored a null object? 12178 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 12179 GOTO_OPCODE(ip) @ jump to next instruction 12180 12181/* continuation for OP_CONST_CLASS_JUMBO */ 12182 12183 /* 12184 * Continuation if the Class has not yet been resolved. 12185 * r1: AAAAAAAA (Class ref) 12186 * r9: target register 12187 */ 12188.LOP_CONST_CLASS_JUMBO_resolve: 12189 EXPORT_PC() 12190 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 12191 mov r2, #1 @ r2<- true 12192 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 12193 bl dvmResolveClass @ r0<- Class reference 12194 cmp r0, #0 @ failed? 12195 beq common_exceptionThrown @ yup, handle the exception 12196 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 12197 GET_INST_OPCODE(ip) @ extract opcode from rINST 12198 SET_VREG(r0, r9) @ vBBBB<- r0 12199 GOTO_OPCODE(ip) @ jump to next instruction 12200 12201/* continuation for OP_CHECK_CAST_JUMBO */ 12202 12203 /* 12204 * Trivial test failed, need to perform full check. This is common. 12205 * r0 holds obj->clazz 12206 * r1 holds desired class resolved from AAAAAAAA 12207 * r9 holds object 12208 */ 12209.LOP_CHECK_CAST_JUMBO_fullcheck: 12210 mov r10, r1 @ avoid ClassObject getting clobbered 12211 bl dvmInstanceofNonTrivial @ r0<- boolean result 12212 cmp r0, #0 @ failed? 12213 bne .LOP_CHECK_CAST_JUMBO_okay @ no, success 12214 12215 @ A cast has failed. We need to throw a ClassCastException. 12216 EXPORT_PC() @ about to throw 12217 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class) 12218 mov r1, r10 @ r1<- desired class 12219 bl dvmThrowClassCastException 12220 b common_exceptionThrown 12221 12222 /* 12223 * Advance PC and get the next opcode. 12224 */ 12225.LOP_CHECK_CAST_JUMBO_okay: 12226 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 12227 GET_INST_OPCODE(ip) @ extract opcode from rINST 12228 GOTO_OPCODE(ip) @ jump to next instruction 12229 12230 /* 12231 * Resolution required. This is the least-likely path. 12232 * 12233 * r2 holds AAAAAAAA 12234 * r9 holds object 12235 */ 12236.LOP_CHECK_CAST_JUMBO_resolve: 12237 EXPORT_PC() @ resolve() could throw 12238 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 12239 mov r1, r2 @ r1<- AAAAAAAA 12240 mov r2, #0 @ r2<- false 12241 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 12242 bl dvmResolveClass @ r0<- resolved ClassObject ptr 12243 cmp r0, #0 @ got null? 12244 beq common_exceptionThrown @ yes, handle exception 12245 mov r1, r0 @ r1<- class resolved from AAAAAAAA 12246 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 12247 b .LOP_CHECK_CAST_JUMBO_resolved @ pick up where we left off 12248 12249/* continuation for OP_INSTANCE_OF_JUMBO */ 12250 12251 /* 12252 * Class resolved, determine type of check necessary. This is common. 12253 * r0 holds obj->clazz 12254 * r1 holds class resolved from AAAAAAAA 12255 * r9 holds BBBB 12256 */ 12257.LOP_INSTANCE_OF_JUMBO_resolved: 12258 cmp r0, r1 @ same class (trivial success)? 12259 beq .LOP_INSTANCE_OF_JUMBO_trivial @ yes, trivial finish 12260 @ fall through to OP_INSTANCE_OF_JUMBO_fullcheck 12261 12262 /* 12263 * Trivial test failed, need to perform full check. This is common. 12264 * r0 holds obj->clazz 12265 * r1 holds class resolved from AAAAAAAA 12266 * r9 holds BBBB 12267 */ 12268.LOP_INSTANCE_OF_JUMBO_fullcheck: 12269 bl dvmInstanceofNonTrivial @ r0<- boolean result 12270 @ fall through to OP_INSTANCE_OF_JUMBO_store 12271 12272 /* 12273 * r0 holds boolean result 12274 * r9 holds BBBB 12275 */ 12276.LOP_INSTANCE_OF_JUMBO_store: 12277 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12278 SET_VREG(r0, r9) @ vBBBB<- r0 12279 GET_INST_OPCODE(ip) @ extract opcode from rINST 12280 GOTO_OPCODE(ip) @ jump to next instruction 12281 12282 /* 12283 * Trivial test succeeded, save and bail. 12284 * r9 holds BBBB 12285 */ 12286.LOP_INSTANCE_OF_JUMBO_trivial: 12287 mov r0, #1 @ indicate success 12288 @ could b OP_INSTANCE_OF_JUMBO_store, but copying is faster and cheaper 12289 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12290 SET_VREG(r0, r9) @ vBBBB<- r0 12291 GET_INST_OPCODE(ip) @ extract opcode from rINST 12292 GOTO_OPCODE(ip) @ jump to next instruction 12293 12294 /* 12295 * Resolution required. This is the least-likely path. 12296 * 12297 * r3 holds AAAAAAAA 12298 * r9 holds BBBB 12299 */ 12300 12301.LOP_INSTANCE_OF_JUMBO_resolve: 12302 EXPORT_PC() @ resolve() could throw 12303 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 12304 mov r1, r3 @ r1<- AAAAAAAA 12305 mov r2, #1 @ r2<- true 12306 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 12307 bl dvmResolveClass @ r0<- resolved ClassObject ptr 12308 cmp r0, #0 @ got null? 12309 beq common_exceptionThrown @ yes, handle exception 12310 FETCH(r3, 4) @ r3<- vCCCC 12311 mov r1, r0 @ r1<- class resolved from AAAAAAAA 12312 GET_VREG(r0, r3) @ r0<- vCCCC (object) 12313 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 12314 b .LOP_INSTANCE_OF_JUMBO_resolved @ pick up where we left off 12315 12316/* continuation for OP_NEW_INSTANCE_JUMBO */ 12317 12318 .balign 32 @ minimize cache lines 12319.LOP_NEW_INSTANCE_JUMBO_finish: @ r0=new object 12320 FETCH(r3, 3) @ r3<- BBBB 12321 cmp r0, #0 @ failed? 12322 beq common_exceptionThrown @ yes, handle the exception 12323 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 12324 GET_INST_OPCODE(ip) @ extract opcode from rINST 12325 SET_VREG(r0, r3) @ vBBBB<- r0 12326 GOTO_OPCODE(ip) @ jump to next instruction 12327 12328 /* 12329 * Class initialization required. 12330 * 12331 * r0 holds class object 12332 */ 12333.LOP_NEW_INSTANCE_JUMBO_needinit: 12334 mov r9, r0 @ save r0 12335 bl dvmInitClass @ initialize class 12336 cmp r0, #0 @ check boolean result 12337 mov r0, r9 @ restore r0 12338 bne .LOP_NEW_INSTANCE_JUMBO_initialized @ success, continue 12339 b common_exceptionThrown @ failed, deal with init exception 12340 12341 /* 12342 * Resolution required. This is the least-likely path. 12343 * 12344 * r1 holds AAAAAAAA 12345 */ 12346.LOP_NEW_INSTANCE_JUMBO_resolve: 12347 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 12348 mov r2, #0 @ r2<- false 12349 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 12350 bl dvmResolveClass @ r0<- resolved ClassObject ptr 12351 cmp r0, #0 @ got null? 12352 bne .LOP_NEW_INSTANCE_JUMBO_resolved @ no, continue 12353 b common_exceptionThrown @ yes, handle exception 12354 12355/* continuation for OP_NEW_ARRAY_JUMBO */ 12356 12357 12358 /* 12359 * Resolve class. (This is an uncommon case.) 12360 * 12361 * r1 holds array length 12362 * r2 holds class ref AAAAAAAA 12363 */ 12364.LOP_NEW_ARRAY_JUMBO_resolve: 12365 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 12366 mov r9, r1 @ r9<- length (save) 12367 mov r1, r2 @ r1<- AAAAAAAA 12368 mov r2, #0 @ r2<- false 12369 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 12370 bl dvmResolveClass @ r0<- call(clazz, ref) 12371 cmp r0, #0 @ got null? 12372 mov r1, r9 @ r1<- length (restore) 12373 beq common_exceptionThrown @ yes, handle exception 12374 @ fall through to OP_NEW_ARRAY_JUMBO_finish 12375 12376 /* 12377 * Finish allocation. 12378 * 12379 * r0 holds class 12380 * r1 holds array length 12381 */ 12382.LOP_NEW_ARRAY_JUMBO_finish: 12383 mov r2, #ALLOC_DONT_TRACK @ don't track in local refs table 12384 bl dvmAllocArrayByClass @ r0<- call(clazz, length, flags) 12385 cmp r0, #0 @ failed? 12386 FETCH(r2, 3) @ r2<- vBBBB 12387 beq common_exceptionThrown @ yes, handle the exception 12388 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12389 GET_INST_OPCODE(ip) @ extract opcode from rINST 12390 SET_VREG(r0, r2) @ vBBBB<- r0 12391 GOTO_OPCODE(ip) @ jump to next instruction 12392 12393/* continuation for OP_FILLED_NEW_ARRAY_JUMBO */ 12394 12395 /* 12396 * On entry: 12397 * r0 holds array class 12398 */ 12399.LOP_FILLED_NEW_ARRAY_JUMBO_continue: 12400 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 12401 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 12402 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 12403 FETCH(r1, 3) @ r1<- BBBB (length) 12404 cmp rINST, #'I' @ array of ints? 12405 cmpne rINST, #'L' @ array of objects? 12406 cmpne rINST, #'[' @ array of arrays? 12407 mov r9, r1 @ save length in r9 12408 bne .LOP_FILLED_NEW_ARRAY_JUMBO_notimpl @ no, not handled yet 12409 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 12410 cmp r0, #0 @ null return? 12411 beq common_exceptionThrown @ alloc failed, handle exception 12412 12413 FETCH(r1, 4) @ r1<- CCCC 12414 str r0, [rGLUE, #offGlue_retval] @ retval.l <- new array 12415 str rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type 12416 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 12417 subs r9, r9, #1 @ length--, check for neg 12418 FETCH_ADVANCE_INST(5) @ advance to next instr, load rINST 12419 bmi 2f @ was zero, bail 12420 12421 @ copy values from registers into the array 12422 @ r0=array, r1=CCCC, r9=BBBB (length) 12423 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 124241: ldr r3, [r2], #4 @ r3<- *r2++ 12425 subs r9, r9, #1 @ count-- 12426 str r3, [r0], #4 @ *contents++ = vX 12427 bpl 1b 12428 124292: ldr r0, [rGLUE, #offGlue_retval] @ r0<- object 12430 ldr r1, [rGLUE, #offGlue_retval+4] @ r1<- type 12431 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 12432 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 12433 cmp r1, #'I' @ Is int array? 12434 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 12435 GOTO_OPCODE(ip) @ execute it 12436 12437 /* 12438 * Throw an exception indicating that we have not implemented this 12439 * mode of filled-new-array. 12440 */ 12441.LOP_FILLED_NEW_ARRAY_JUMBO_notimpl: 12442 ldr r0, .L_strInternalError 12443 ldr r1, .L_strFilledNewArrayNotImpl 12444 bl dvmThrowException 12445 b common_exceptionThrown 12446 12447/* continuation for OP_IGET_JUMBO */ 12448 12449 /* 12450 * Currently: 12451 * r0 holds resolved field 12452 * r9 holds object 12453 */ 12454.LOP_IGET_JUMBO_resolved: 12455 cmp r0, #0 @ resolution unsuccessful? 12456 beq common_exceptionThrown @ yes, throw exception 12457 @ fall through to OP_IGET_JUMBO_finish 12458 12459 /* 12460 * Currently: 12461 * r0 holds resolved field 12462 * r9 holds object 12463 */ 12464.LOP_IGET_JUMBO_finish: 12465 @bl common_squeak0 12466 cmp r9, #0 @ check object for null 12467 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12468 beq common_errNullObject @ object was null 12469 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12470 @ no-op @ acquiring load 12471 FETCH(r2, 3) @ r2<- BBBB 12472 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12473 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12474 GET_INST_OPCODE(ip) @ extract opcode from rINST 12475 GOTO_OPCODE(ip) @ jump to next instruction 12476 12477/* continuation for OP_IGET_WIDE_JUMBO */ 12478 12479 /* 12480 * Currently: 12481 * r0 holds resolved field 12482 * r9 holds object 12483 */ 12484.LOP_IGET_WIDE_JUMBO_resolved: 12485 cmp r0, #0 @ resolution unsuccessful? 12486 beq common_exceptionThrown @ yes, throw exception 12487 @ fall through to OP_IGET_WIDE_JUMBO_finish 12488 12489 /* 12490 * Currently: 12491 * r0 holds resolved field 12492 * r9 holds object 12493 */ 12494.LOP_IGET_WIDE_JUMBO_finish: 12495 cmp r9, #0 @ check object for null 12496 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12497 beq common_errNullObject @ object was null 12498 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 12499 FETCH(r2, 3) @ r2<- BBBB 12500 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12501 add r3, rFP, r2, lsl #2 @ r3<- &fp[BBBB] 12502 GET_INST_OPCODE(ip) @ extract opcode from rINST 12503 stmia r3, {r0-r1} @ fp[BBBB]<- r0/r1 12504 GOTO_OPCODE(ip) @ jump to next instruction 12505 12506/* continuation for OP_IGET_OBJECT_JUMBO */ 12507 12508 /* 12509 * Currently: 12510 * r0 holds resolved field 12511 * r9 holds object 12512 */ 12513.LOP_IGET_OBJECT_JUMBO_resolved: 12514 cmp r0, #0 @ resolution unsuccessful? 12515 beq common_exceptionThrown @ yes, throw exception 12516 @ fall through to OP_IGET_OBJECT_JUMBO_finish 12517 12518 /* 12519 * Currently: 12520 * r0 holds resolved field 12521 * r9 holds object 12522 */ 12523.LOP_IGET_OBJECT_JUMBO_finish: 12524 @bl common_squeak0 12525 cmp r9, #0 @ check object for null 12526 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12527 beq common_errNullObject @ object was null 12528 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12529 @ no-op @ acquiring load 12530 FETCH(r2, 3) @ r2<- BBBB 12531 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12532 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12533 GET_INST_OPCODE(ip) @ extract opcode from rINST 12534 GOTO_OPCODE(ip) @ jump to next instruction 12535 12536/* continuation for OP_IGET_BOOLEAN_JUMBO */ 12537 12538 /* 12539 * Currently: 12540 * r0 holds resolved field 12541 * r9 holds object 12542 */ 12543.LOP_IGET_BOOLEAN_JUMBO_resolved: 12544 cmp r0, #0 @ resolution unsuccessful? 12545 beq common_exceptionThrown @ yes, throw exception 12546 @ fall through to OP_IGET_BOOLEAN_JUMBO_finish 12547 12548 /* 12549 * Currently: 12550 * r0 holds resolved field 12551 * r9 holds object 12552 */ 12553.LOP_IGET_BOOLEAN_JUMBO_finish: 12554 @bl common_squeak1 12555 cmp r9, #0 @ check object for null 12556 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12557 beq common_errNullObject @ object was null 12558 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12559 @ no-op @ acquiring load 12560 FETCH(r2, 3) @ r2<- BBBB 12561 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12562 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12563 GET_INST_OPCODE(ip) @ extract opcode from rINST 12564 GOTO_OPCODE(ip) @ jump to next instruction 12565 12566/* continuation for OP_IGET_BYTE_JUMBO */ 12567 12568 /* 12569 * Currently: 12570 * r0 holds resolved field 12571 * r9 holds object 12572 */ 12573.LOP_IGET_BYTE_JUMBO_resolved: 12574 cmp r0, #0 @ resolution unsuccessful? 12575 beq common_exceptionThrown @ yes, throw exception 12576 @ fall through to OP_IGET_BYTE_JUMBO_finish 12577 12578 /* 12579 * Currently: 12580 * r0 holds resolved field 12581 * r9 holds object 12582 */ 12583.LOP_IGET_BYTE_JUMBO_finish: 12584 @bl common_squeak2 12585 cmp r9, #0 @ check object for null 12586 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12587 beq common_errNullObject @ object was null 12588 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12589 @ no-op @ acquiring load 12590 FETCH(r2, 3) @ r2<- BBBB 12591 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12592 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12593 GET_INST_OPCODE(ip) @ extract opcode from rINST 12594 GOTO_OPCODE(ip) @ jump to next instruction 12595 12596/* continuation for OP_IGET_CHAR_JUMBO */ 12597 12598 /* 12599 * Currently: 12600 * r0 holds resolved field 12601 * r9 holds object 12602 */ 12603.LOP_IGET_CHAR_JUMBO_resolved: 12604 cmp r0, #0 @ resolution unsuccessful? 12605 beq common_exceptionThrown @ yes, throw exception 12606 @ fall through to OP_IGET_CHAR_JUMBO_finish 12607 12608 /* 12609 * Currently: 12610 * r0 holds resolved field 12611 * r9 holds object 12612 */ 12613.LOP_IGET_CHAR_JUMBO_finish: 12614 @bl common_squeak3 12615 cmp r9, #0 @ check object for null 12616 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12617 beq common_errNullObject @ object was null 12618 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12619 @ no-op @ acquiring load 12620 FETCH(r2, 3) @ r2<- BBBB 12621 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12622 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12623 GET_INST_OPCODE(ip) @ extract opcode from rINST 12624 GOTO_OPCODE(ip) @ jump to next instruction 12625 12626/* continuation for OP_IGET_SHORT_JUMBO */ 12627 12628 /* 12629 * Currently: 12630 * r0 holds resolved field 12631 * r9 holds object 12632 */ 12633.LOP_IGET_SHORT_JUMBO_resolved: 12634 cmp r0, #0 @ resolution unsuccessful? 12635 beq common_exceptionThrown @ yes, throw exception 12636 @ fall through to OP_IGET_SHORT_JUMBO_finish 12637 12638 /* 12639 * Currently: 12640 * r0 holds resolved field 12641 * r9 holds object 12642 */ 12643.LOP_IGET_SHORT_JUMBO_finish: 12644 @bl common_squeak4 12645 cmp r9, #0 @ check object for null 12646 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12647 beq common_errNullObject @ object was null 12648 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12649 @ no-op @ acquiring load 12650 FETCH(r2, 3) @ r2<- BBBB 12651 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12652 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12653 GET_INST_OPCODE(ip) @ extract opcode from rINST 12654 GOTO_OPCODE(ip) @ jump to next instruction 12655 12656/* continuation for OP_IPUT_JUMBO */ 12657 12658 /* 12659 * Currently: 12660 * r0 holds resolved field 12661 * r9 holds object 12662 */ 12663.LOP_IPUT_JUMBO_resolved: 12664 cmp r0, #0 @ resolution unsuccessful? 12665 beq common_exceptionThrown @ yes, throw exception 12666 @ fall through to OP_IPUT_JUMBO_finish 12667 12668 /* 12669 * Currently: 12670 * r0 holds resolved field 12671 * r9 holds object 12672 */ 12673.LOP_IPUT_JUMBO_finish: 12674 @bl common_squeak0 12675 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12676 FETCH(r1, 3) @ r1<- BBBB 12677 cmp r9, #0 @ check object for null 12678 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12679 beq common_errNullObject @ object was null 12680 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12681 GET_INST_OPCODE(ip) @ extract opcode from rINST 12682 @ no-op @ releasing store 12683 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12684 GOTO_OPCODE(ip) @ jump to next instruction 12685 12686/* continuation for OP_IPUT_WIDE_JUMBO */ 12687 12688 /* 12689 * Currently: 12690 * r0 holds resolved field 12691 * r9 holds object 12692 */ 12693.LOP_IPUT_WIDE_JUMBO_resolved: 12694 cmp r0, #0 @ resolution unsuccessful? 12695 beq common_exceptionThrown @ yes, throw exception 12696 @ fall through to OP_IPUT_WIDE_JUMBO_finish 12697 12698 /* 12699 * Currently: 12700 * r0 holds resolved field 12701 * r9 holds object 12702 */ 12703.LOP_IPUT_WIDE_JUMBO_finish: 12704 cmp r9, #0 @ check object for null 12705 FETCH(r2, 3) @ r1<- BBBB 12706 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12707 add r2, rFP, r2, lsl #2 @ r3<- &fp[BBBB] 12708 beq common_errNullObject @ object was null 12709 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12710 ldmia r2, {r0-r1} @ r0/r1<- fp[BBBB] 12711 GET_INST_OPCODE(r10) @ extract opcode from rINST 12712 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 12713 GOTO_OPCODE(r10) @ jump to next instruction 12714 12715/* continuation for OP_IPUT_OBJECT_JUMBO */ 12716 12717 /* 12718 * Currently: 12719 * r0 holds resolved field 12720 * r9 holds object 12721 */ 12722.LOP_IPUT_OBJECT_JUMBO_resolved: 12723 cmp r0, #0 @ resolution unsuccessful? 12724 beq common_exceptionThrown @ yes, throw exception 12725 @ fall through to OP_IPUT_OBJECT_JUMBO_finish 12726 12727 /* 12728 * Currently: 12729 * r0 holds resolved field 12730 * r9 holds object 12731 */ 12732.LOP_IPUT_OBJECT_JUMBO_finish: 12733 @bl common_squeak0 12734 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12735 FETCH(r1, 3) @ r1<- BBBB 12736 cmp r9, #0 @ check object for null 12737 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12738 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 12739 beq common_errNullObject @ object was null 12740 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12741 GET_INST_OPCODE(ip) @ extract opcode from rINST 12742 @ no-op @ releasing store 12743 str r0, [r9, r3] @ obj.field (32 bits)<- r0 12744 cmp r0, #0 @ stored a null reference? 12745 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 12746 GOTO_OPCODE(ip) @ jump to next instruction 12747 12748/* continuation for OP_IPUT_BOOLEAN_JUMBO */ 12749 12750 /* 12751 * Currently: 12752 * r0 holds resolved field 12753 * r9 holds object 12754 */ 12755.LOP_IPUT_BOOLEAN_JUMBO_resolved: 12756 cmp r0, #0 @ resolution unsuccessful? 12757 beq common_exceptionThrown @ yes, throw exception 12758 @ fall through to OP_IPUT_BOOLEAN_JUMBO_finish 12759 12760 /* 12761 * Currently: 12762 * r0 holds resolved field 12763 * r9 holds object 12764 */ 12765.LOP_IPUT_BOOLEAN_JUMBO_finish: 12766 @bl common_squeak1 12767 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12768 FETCH(r1, 3) @ r1<- BBBB 12769 cmp r9, #0 @ check object for null 12770 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12771 beq common_errNullObject @ object was null 12772 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12773 GET_INST_OPCODE(ip) @ extract opcode from rINST 12774 @ no-op @ releasing store 12775 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12776 GOTO_OPCODE(ip) @ jump to next instruction 12777 12778/* continuation for OP_IPUT_BYTE_JUMBO */ 12779 12780 /* 12781 * Currently: 12782 * r0 holds resolved field 12783 * r9 holds object 12784 */ 12785.LOP_IPUT_BYTE_JUMBO_resolved: 12786 cmp r0, #0 @ resolution unsuccessful? 12787 beq common_exceptionThrown @ yes, throw exception 12788 @ fall through to OP_IPUT_BYTE_JUMBO_finish 12789 12790 /* 12791 * Currently: 12792 * r0 holds resolved field 12793 * r9 holds object 12794 */ 12795.LOP_IPUT_BYTE_JUMBO_finish: 12796 @bl common_squeak2 12797 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12798 FETCH(r1, 3) @ r1<- BBBB 12799 cmp r9, #0 @ check object for null 12800 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12801 beq common_errNullObject @ object was null 12802 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12803 GET_INST_OPCODE(ip) @ extract opcode from rINST 12804 @ no-op @ releasing store 12805 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12806 GOTO_OPCODE(ip) @ jump to next instruction 12807 12808/* continuation for OP_IPUT_CHAR_JUMBO */ 12809 12810 /* 12811 * Currently: 12812 * r0 holds resolved field 12813 * r9 holds object 12814 */ 12815.LOP_IPUT_CHAR_JUMBO_resolved: 12816 cmp r0, #0 @ resolution unsuccessful? 12817 beq common_exceptionThrown @ yes, throw exception 12818 @ fall through to OP_IPUT_CHAR_JUMBO_finish 12819 12820 /* 12821 * Currently: 12822 * r0 holds resolved field 12823 * r9 holds object 12824 */ 12825.LOP_IPUT_CHAR_JUMBO_finish: 12826 @bl common_squeak3 12827 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12828 FETCH(r1, 3) @ r1<- BBBB 12829 cmp r9, #0 @ check object for null 12830 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12831 beq common_errNullObject @ object was null 12832 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12833 GET_INST_OPCODE(ip) @ extract opcode from rINST 12834 @ no-op @ releasing store 12835 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12836 GOTO_OPCODE(ip) @ jump to next instruction 12837 12838/* continuation for OP_IPUT_SHORT_JUMBO */ 12839 12840 /* 12841 * Currently: 12842 * r0 holds resolved field 12843 * r9 holds object 12844 */ 12845.LOP_IPUT_SHORT_JUMBO_resolved: 12846 cmp r0, #0 @ resolution unsuccessful? 12847 beq common_exceptionThrown @ yes, throw exception 12848 @ fall through to OP_IPUT_SHORT_JUMBO_finish 12849 12850 /* 12851 * Currently: 12852 * r0 holds resolved field 12853 * r9 holds object 12854 */ 12855.LOP_IPUT_SHORT_JUMBO_finish: 12856 @bl common_squeak4 12857 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12858 FETCH(r1, 3) @ r1<- BBBB 12859 cmp r9, #0 @ check object for null 12860 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12861 beq common_errNullObject @ object was null 12862 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12863 GET_INST_OPCODE(ip) @ extract opcode from rINST 12864 @ no-op @ releasing store 12865 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12866 GOTO_OPCODE(ip) @ jump to next instruction 12867 12868/* continuation for OP_SGET_JUMBO */ 12869 12870 /* 12871 * Continuation if the field has not yet been resolved. 12872 * r1: AAAAAAAA field ref 12873 */ 12874.LOP_SGET_JUMBO_resolve: 12875 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12876 EXPORT_PC() @ resolve() could throw, so export now 12877 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12878 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12879 cmp r0, #0 @ success? 12880 bne .LOP_SGET_JUMBO_finish @ yes, finish 12881 b common_exceptionThrown @ no, handle exception 12882 12883/* continuation for OP_SGET_WIDE_JUMBO */ 12884 12885 /* 12886 * Continuation if the field has not yet been resolved. 12887 * r1: BBBB field ref 12888 * 12889 * Returns StaticField pointer in r0. 12890 */ 12891.LOP_SGET_WIDE_JUMBO_resolve: 12892 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12893 EXPORT_PC() @ resolve() could throw, so export now 12894 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12895 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12896 cmp r0, #0 @ success? 12897 bne .LOP_SGET_WIDE_JUMBO_finish @ yes, finish 12898 b common_exceptionThrown @ no, handle exception 12899 12900/* continuation for OP_SGET_OBJECT_JUMBO */ 12901 12902 /* 12903 * Continuation if the field has not yet been resolved. 12904 * r1: AAAAAAAA field ref 12905 */ 12906.LOP_SGET_OBJECT_JUMBO_resolve: 12907 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12908 EXPORT_PC() @ resolve() could throw, so export now 12909 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12910 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12911 cmp r0, #0 @ success? 12912 bne .LOP_SGET_OBJECT_JUMBO_finish @ yes, finish 12913 b common_exceptionThrown @ no, handle exception 12914 12915/* continuation for OP_SGET_BOOLEAN_JUMBO */ 12916 12917 /* 12918 * Continuation if the field has not yet been resolved. 12919 * r1: AAAAAAAA field ref 12920 */ 12921.LOP_SGET_BOOLEAN_JUMBO_resolve: 12922 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12923 EXPORT_PC() @ resolve() could throw, so export now 12924 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12925 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12926 cmp r0, #0 @ success? 12927 bne .LOP_SGET_BOOLEAN_JUMBO_finish @ yes, finish 12928 b common_exceptionThrown @ no, handle exception 12929 12930/* continuation for OP_SGET_BYTE_JUMBO */ 12931 12932 /* 12933 * Continuation if the field has not yet been resolved. 12934 * r1: AAAAAAAA field ref 12935 */ 12936.LOP_SGET_BYTE_JUMBO_resolve: 12937 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12938 EXPORT_PC() @ resolve() could throw, so export now 12939 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12940 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12941 cmp r0, #0 @ success? 12942 bne .LOP_SGET_BYTE_JUMBO_finish @ yes, finish 12943 b common_exceptionThrown @ no, handle exception 12944 12945/* continuation for OP_SGET_CHAR_JUMBO */ 12946 12947 /* 12948 * Continuation if the field has not yet been resolved. 12949 * r1: AAAAAAAA field ref 12950 */ 12951.LOP_SGET_CHAR_JUMBO_resolve: 12952 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12953 EXPORT_PC() @ resolve() could throw, so export now 12954 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12955 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12956 cmp r0, #0 @ success? 12957 bne .LOP_SGET_CHAR_JUMBO_finish @ yes, finish 12958 b common_exceptionThrown @ no, handle exception 12959 12960/* continuation for OP_SGET_SHORT_JUMBO */ 12961 12962 /* 12963 * Continuation if the field has not yet been resolved. 12964 * r1: AAAAAAAA field ref 12965 */ 12966.LOP_SGET_SHORT_JUMBO_resolve: 12967 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12968 EXPORT_PC() @ resolve() could throw, so export now 12969 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12970 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12971 cmp r0, #0 @ success? 12972 bne .LOP_SGET_SHORT_JUMBO_finish @ yes, finish 12973 b common_exceptionThrown @ no, handle exception 12974 12975/* continuation for OP_SPUT_JUMBO */ 12976 12977 /* 12978 * Continuation if the field has not yet been resolved. 12979 * r1: AAAAAAAA field ref 12980 */ 12981.LOP_SPUT_JUMBO_resolve: 12982 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12983 EXPORT_PC() @ resolve() could throw, so export now 12984 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12985 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12986 cmp r0, #0 @ success? 12987 bne .LOP_SPUT_JUMBO_finish @ yes, finish 12988 b common_exceptionThrown @ no, handle exception 12989 12990/* continuation for OP_SPUT_WIDE_JUMBO */ 12991 12992 /* 12993 * Continuation if the field has not yet been resolved. 12994 * r1: BBBB field ref 12995 * r9: &fp[AA] 12996 * 12997 * Returns StaticField pointer in r2. 12998 */ 12999.LOP_SPUT_WIDE_JUMBO_resolve: 13000 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13001 EXPORT_PC() @ resolve() could throw, so export now 13002 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13003 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13004 cmp r0, #0 @ success? 13005 mov r2, r0 @ copy to r2 13006 bne .LOP_SPUT_WIDE_JUMBO_finish @ yes, finish 13007 b common_exceptionThrown @ no, handle exception 13008 13009/* continuation for OP_SPUT_OBJECT_JUMBO */ 13010 13011.LOP_SPUT_OBJECT_JUMBO_finish: @ field ptr in r0 13012 FETCH(r2, 3) @ r2<- BBBB 13013 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 13014 GET_VREG(r1, r2) @ r1<- fp[BBBB] 13015 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 13016 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 13017 GET_INST_OPCODE(ip) @ extract opcode from rINST 13018 @ no-op @ releasing store 13019 str r1, [r0, #offStaticField_value] @ field<- vBBBB 13020 cmp r1, #0 @ stored a null object? 13021 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 13022 GOTO_OPCODE(ip) @ jump to next instruction 13023 13024/* continuation for OP_SPUT_BOOLEAN_JUMBO */ 13025 13026 /* 13027 * Continuation if the field has not yet been resolved. 13028 * r1: AAAAAAAA field ref 13029 */ 13030.LOP_SPUT_BOOLEAN_JUMBO_resolve: 13031 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13032 EXPORT_PC() @ resolve() could throw, so export now 13033 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13034 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13035 cmp r0, #0 @ success? 13036 bne .LOP_SPUT_BOOLEAN_JUMBO_finish @ yes, finish 13037 b common_exceptionThrown @ no, handle exception 13038 13039/* continuation for OP_SPUT_BYTE_JUMBO */ 13040 13041 /* 13042 * Continuation if the field has not yet been resolved. 13043 * r1: AAAAAAAA field ref 13044 */ 13045.LOP_SPUT_BYTE_JUMBO_resolve: 13046 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13047 EXPORT_PC() @ resolve() could throw, so export now 13048 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13049 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13050 cmp r0, #0 @ success? 13051 bne .LOP_SPUT_BYTE_JUMBO_finish @ yes, finish 13052 b common_exceptionThrown @ no, handle exception 13053 13054/* continuation for OP_SPUT_CHAR_JUMBO */ 13055 13056 /* 13057 * Continuation if the field has not yet been resolved. 13058 * r1: AAAAAAAA field ref 13059 */ 13060.LOP_SPUT_CHAR_JUMBO_resolve: 13061 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13062 EXPORT_PC() @ resolve() could throw, so export now 13063 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13064 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13065 cmp r0, #0 @ success? 13066 bne .LOP_SPUT_CHAR_JUMBO_finish @ yes, finish 13067 b common_exceptionThrown @ no, handle exception 13068 13069/* continuation for OP_SPUT_SHORT_JUMBO */ 13070 13071 /* 13072 * Continuation if the field has not yet been resolved. 13073 * r1: AAAAAAAA field ref 13074 */ 13075.LOP_SPUT_SHORT_JUMBO_resolve: 13076 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13077 EXPORT_PC() @ resolve() could throw, so export now 13078 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13079 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13080 cmp r0, #0 @ success? 13081 bne .LOP_SPUT_SHORT_JUMBO_finish @ yes, finish 13082 b common_exceptionThrown @ no, handle exception 13083 13084/* continuation for OP_INVOKE_VIRTUAL_JUMBO */ 13085 13086 /* 13087 * At this point: 13088 * r0 = resolved base method 13089 */ 13090.LOP_INVOKE_VIRTUAL_JUMBO_continue: 13091 FETCH(r10, 4) @ r10<- CCCC 13092 GET_VREG(r1, r10) @ r1<- "this" ptr 13093 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 13094 cmp r1, #0 @ is "this" null? 13095 beq common_errNullObject @ null "this", throw exception 13096 ldr r3, [r1, #offObject_clazz] @ r1<- thisPtr->clazz 13097 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 13098 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 13099 bl common_invokeMethodJumbo @ continue on 13100 13101/* continuation for OP_INVOKE_SUPER_JUMBO */ 13102 13103 /* 13104 * At this point: 13105 * r0 = resolved base method 13106 * r9 = method->clazz 13107 */ 13108.LOP_INVOKE_SUPER_JUMBO_continue: 13109 ldr r1, [r9, #offClassObject_super] @ r1<- method->clazz->super 13110 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 13111 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 13112 EXPORT_PC() @ must export for invoke 13113 cmp r2, r3 @ compare (methodIndex, vtableCount) 13114 bcs .LOP_INVOKE_SUPER_JUMBO_nsm @ method not present in superclass 13115 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 13116 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 13117 bl common_invokeMethodJumbo @ continue on 13118 13119.LOP_INVOKE_SUPER_JUMBO_resolve: 13120 mov r0, r9 @ r0<- method->clazz 13121 mov r2, #METHOD_VIRTUAL @ resolver method type 13122 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 13123 cmp r0, #0 @ got null? 13124 bne .LOP_INVOKE_SUPER_JUMBO_continue @ no, continue 13125 b common_exceptionThrown @ yes, handle exception 13126 13127 /* 13128 * Throw a NoSuchMethodError with the method name as the message. 13129 * r0 = resolved base method 13130 */ 13131.LOP_INVOKE_SUPER_JUMBO_nsm: 13132 ldr r1, [r0, #offMethod_name] @ r1<- method name 13133 b common_errNoSuchMethod 13134 13135/* continuation for OP_INVOKE_DIRECT_JUMBO */ 13136 13137 /* 13138 * On entry: 13139 * r1 = reference (CCCC) 13140 * r10 = "this" register 13141 */ 13142.LOP_INVOKE_DIRECT_JUMBO_resolve: 13143 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 13144 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 13145 mov r2, #METHOD_DIRECT @ resolver method type 13146 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 13147 cmp r0, #0 @ got null? 13148 GET_VREG(r2, r10) @ r2<- "this" ptr (reload) 13149 bne .LOP_INVOKE_DIRECT_JUMBO_finish @ no, continue 13150 b common_exceptionThrown @ yes, handle exception 13151 13152 .size dvmAsmSisterStart, .-dvmAsmSisterStart 13153 .global dvmAsmSisterEnd 13154dvmAsmSisterEnd: 13155 13156/* File: armv5te/footer.S */ 13157 13158/* 13159 * =========================================================================== 13160 * Common subroutines and data 13161 * =========================================================================== 13162 */ 13163 13164 13165 13166 .text 13167 .align 2 13168 13169#if defined(WITH_JIT) 13170#if defined(WITH_SELF_VERIFICATION) 13171 .global dvmJitToInterpPunt 13172dvmJitToInterpPunt: 13173 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13174 mov r2,#kSVSPunt @ r2<- interpreter entry point 13175 mov r3, #0 13176 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13177 b jitSVShadowRunEnd @ doesn't return 13178 13179 .global dvmJitToInterpSingleStep 13180dvmJitToInterpSingleStep: 13181 str lr,[rGLUE,#offGlue_jitResumeNPC] 13182 str r1,[rGLUE,#offGlue_jitResumeDPC] 13183 mov r2,#kSVSSingleStep @ r2<- interpreter entry point 13184 b jitSVShadowRunEnd @ doesn't return 13185 13186 .global dvmJitToInterpNoChainNoProfile 13187dvmJitToInterpNoChainNoProfile: 13188 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13189 mov r0,rPC @ pass our target PC 13190 mov r2,#kSVSNoProfile @ r2<- interpreter entry point 13191 mov r3, #0 @ 0 means !inJitCodeCache 13192 str r3, [r10, #offThread_inJitCodeCache] @ back to the interp land 13193 b jitSVShadowRunEnd @ doesn't return 13194 13195 .global dvmJitToInterpTraceSelectNoChain 13196dvmJitToInterpTraceSelectNoChain: 13197 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13198 mov r0,rPC @ pass our target PC 13199 mov r2,#kSVSTraceSelect @ r2<- interpreter entry point 13200 mov r3, #0 @ 0 means !inJitCodeCache 13201 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13202 b jitSVShadowRunEnd @ doesn't return 13203 13204 .global dvmJitToInterpTraceSelect 13205dvmJitToInterpTraceSelect: 13206 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13207 ldr r0,[lr, #-1] @ pass our target PC 13208 mov r2,#kSVSTraceSelect @ r2<- interpreter entry point 13209 mov r3, #0 @ 0 means !inJitCodeCache 13210 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13211 b jitSVShadowRunEnd @ doesn't return 13212 13213 .global dvmJitToInterpBackwardBranch 13214dvmJitToInterpBackwardBranch: 13215 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13216 ldr r0,[lr, #-1] @ pass our target PC 13217 mov r2,#kSVSBackwardBranch @ r2<- interpreter entry point 13218 mov r3, #0 @ 0 means !inJitCodeCache 13219 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13220 b jitSVShadowRunEnd @ doesn't return 13221 13222 .global dvmJitToInterpNormal 13223dvmJitToInterpNormal: 13224 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13225 ldr r0,[lr, #-1] @ pass our target PC 13226 mov r2,#kSVSNormal @ r2<- interpreter entry point 13227 mov r3, #0 @ 0 means !inJitCodeCache 13228 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13229 b jitSVShadowRunEnd @ doesn't return 13230 13231 .global dvmJitToInterpNoChain 13232dvmJitToInterpNoChain: 13233 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13234 mov r0,rPC @ pass our target PC 13235 mov r2,#kSVSNoChain @ r2<- interpreter entry point 13236 mov r3, #0 @ 0 means !inJitCodeCache 13237 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13238 b jitSVShadowRunEnd @ doesn't return 13239#else 13240/* 13241 * Return from the translation cache to the interpreter when the compiler is 13242 * having issues translating/executing a Dalvik instruction. We have to skip 13243 * the code cache lookup otherwise it is possible to indefinitely bouce 13244 * between the interpreter and the code cache if the instruction that fails 13245 * to be compiled happens to be at a trace start. 13246 */ 13247 .global dvmJitToInterpPunt 13248dvmJitToInterpPunt: 13249 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13250 mov rPC, r0 13251#if defined(WITH_JIT_TUNING) 13252 mov r0,lr 13253 bl dvmBumpPunt; 13254#endif 13255 EXPORT_PC() 13256 mov r0, #0 13257 str r0, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13258 adrl rIBASE, dvmAsmInstructionStart 13259 FETCH_INST() 13260 GET_INST_OPCODE(ip) 13261 GOTO_OPCODE(ip) 13262 13263/* 13264 * Return to the interpreter to handle a single instruction. 13265 * On entry: 13266 * r0 <= PC 13267 * r1 <= PC of resume instruction 13268 * lr <= resume point in translation 13269 */ 13270 .global dvmJitToInterpSingleStep 13271dvmJitToInterpSingleStep: 13272 str lr,[rGLUE,#offGlue_jitResumeNPC] 13273 str r1,[rGLUE,#offGlue_jitResumeDPC] 13274 mov r1,#kInterpEntryInstr 13275 @ enum is 4 byte in aapcs-EABI 13276 str r1, [rGLUE, #offGlue_entryPoint] 13277 mov rPC,r0 13278 EXPORT_PC() 13279 13280 adrl rIBASE, dvmAsmInstructionStart 13281 mov r2,#kJitSingleStep @ Ask for single step and then revert 13282 str r2,[rGLUE,#offGlue_jitState] 13283 mov r1,#1 @ set changeInterp to bail to debug interp 13284 b common_gotoBail 13285 13286/* 13287 * Return from the translation cache and immediately request 13288 * a translation for the exit target. Commonly used for callees. 13289 */ 13290 .global dvmJitToInterpTraceSelectNoChain 13291dvmJitToInterpTraceSelectNoChain: 13292#if defined(WITH_JIT_TUNING) 13293 bl dvmBumpNoChain 13294#endif 13295 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13296 mov r0,rPC 13297 bl dvmJitGetTraceAddr @ Is there a translation? 13298 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13299 mov r1, rPC @ arg1 of translation may need this 13300 mov lr, #0 @ in case target is HANDLER_INTERPRET 13301 cmp r0,#0 @ !0 means translation exists 13302 bxne r0 @ continue native execution if so 13303 b 2f @ branch over to use the interpreter 13304 13305/* 13306 * Return from the translation cache and immediately request 13307 * a translation for the exit target. Commonly used following 13308 * invokes. 13309 */ 13310 .global dvmJitToInterpTraceSelect 13311dvmJitToInterpTraceSelect: 13312 ldr rPC,[lr, #-1] @ get our target PC 13313 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13314 add rINST,lr,#-5 @ save start of chain branch 13315 add rINST, #-4 @ .. which is 9 bytes back 13316 mov r0,rPC 13317 bl dvmJitGetTraceAddr @ Is there a translation? 13318 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13319 cmp r0,#0 13320 beq 2f 13321 mov r1,rINST 13322 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 13323 mov r1, rPC @ arg1 of translation may need this 13324 mov lr, #0 @ in case target is HANDLER_INTERPRET 13325 cmp r0,#0 @ successful chain? 13326 bxne r0 @ continue native execution 13327 b toInterpreter @ didn't chain - resume with interpreter 13328 13329/* No translation, so request one if profiling isn't disabled*/ 133302: 13331 adrl rIBASE, dvmAsmInstructionStart 13332 GET_JIT_PROF_TABLE(r0) 13333 FETCH_INST() 13334 cmp r0, #0 13335 movne r2,#kJitTSelectRequestHot @ ask for trace selection 13336 bne common_selectTrace 13337 GET_INST_OPCODE(ip) 13338 GOTO_OPCODE(ip) 13339 13340/* 13341 * Return from the translation cache to the interpreter. 13342 * The return was done with a BLX from thumb mode, and 13343 * the following 32-bit word contains the target rPC value. 13344 * Note that lr (r14) will have its low-order bit set to denote 13345 * its thumb-mode origin. 13346 * 13347 * We'll need to stash our lr origin away, recover the new 13348 * target and then check to see if there is a translation available 13349 * for our new target. If so, we do a translation chain and 13350 * go back to native execution. Otherwise, it's back to the 13351 * interpreter (after treating this entry as a potential 13352 * trace start). 13353 */ 13354 .global dvmJitToInterpNormal 13355dvmJitToInterpNormal: 13356 ldr rPC,[lr, #-1] @ get our target PC 13357 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13358 add rINST,lr,#-5 @ save start of chain branch 13359 add rINST,#-4 @ .. which is 9 bytes back 13360#if defined(WITH_JIT_TUNING) 13361 bl dvmBumpNormal 13362#endif 13363 mov r0,rPC 13364 bl dvmJitGetTraceAddr @ Is there a translation? 13365 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13366 cmp r0,#0 13367 beq toInterpreter @ go if not, otherwise do chain 13368 mov r1,rINST 13369 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 13370 mov r1, rPC @ arg1 of translation may need this 13371 mov lr, #0 @ in case target is HANDLER_INTERPRET 13372 cmp r0,#0 @ successful chain? 13373 bxne r0 @ continue native execution 13374 b toInterpreter @ didn't chain - resume with interpreter 13375 13376/* 13377 * Return from the translation cache to the interpreter to do method invocation. 13378 * Check if translation exists for the callee, but don't chain to it. 13379 */ 13380 .global dvmJitToInterpNoChainNoProfile 13381dvmJitToInterpNoChainNoProfile: 13382#if defined(WITH_JIT_TUNING) 13383 bl dvmBumpNoChain 13384#endif 13385 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13386 mov r0,rPC 13387 bl dvmJitGetTraceAddr @ Is there a translation? 13388 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13389 mov r1, rPC @ arg1 of translation may need this 13390 mov lr, #0 @ in case target is HANDLER_INTERPRET 13391 cmp r0,#0 13392 bxne r0 @ continue native execution if so 13393 EXPORT_PC() 13394 adrl rIBASE, dvmAsmInstructionStart 13395 FETCH_INST() 13396 GET_INST_OPCODE(ip) @ extract opcode from rINST 13397 GOTO_OPCODE(ip) @ jump to next instruction 13398 13399/* 13400 * Return from the translation cache to the interpreter to do method invocation. 13401 * Check if translation exists for the callee, but don't chain to it. 13402 */ 13403 .global dvmJitToInterpNoChain 13404dvmJitToInterpNoChain: 13405#if defined(WITH_JIT_TUNING) 13406 bl dvmBumpNoChain 13407#endif 13408 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13409 mov r0,rPC 13410 bl dvmJitGetTraceAddr @ Is there a translation? 13411 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13412 mov r1, rPC @ arg1 of translation may need this 13413 mov lr, #0 @ in case target is HANDLER_INTERPRET 13414 cmp r0,#0 13415 bxne r0 @ continue native execution if so 13416#endif 13417 13418/* 13419 * No translation, restore interpreter regs and start interpreting. 13420 * rGLUE & rFP were preserved in the translated code, and rPC has 13421 * already been restored by the time we get here. We'll need to set 13422 * up rIBASE & rINST, and load the address of the JitTable into r0. 13423 */ 13424toInterpreter: 13425 EXPORT_PC() 13426 adrl rIBASE, dvmAsmInstructionStart 13427 FETCH_INST() 13428 GET_JIT_PROF_TABLE(r0) 13429 @ NOTE: intended fallthrough 13430 13431/* 13432 * Common code to update potential trace start counter, and initiate 13433 * a trace-build if appropriate. On entry, rPC should point to the 13434 * next instruction to execute, and rINST should be already loaded with 13435 * the next opcode word, and r0 holds a pointer to the jit profile 13436 * table (pJitProfTable). 13437 */ 13438common_testUpdateProfile: 13439 cmp r0,#0 13440 GET_INST_OPCODE(ip) 13441 GOTO_OPCODE_IFEQ(ip) @ if not profiling, fallthrough otherwise */ 13442 13443common_updateProfile: 13444 eor r3,rPC,rPC,lsr #12 @ cheap, but fast hash function 13445 lsl r3,r3,#(32 - JIT_PROF_SIZE_LOG_2) @ shift out excess bits 13446 ldrb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter 13447 GET_INST_OPCODE(ip) 13448 subs r1,r1,#1 @ decrement counter 13449 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it 13450 GOTO_OPCODE_IFNE(ip) @ if not threshold, fallthrough otherwise */ 13451 13452/* 13453 * Here, we switch to the debug interpreter to request 13454 * trace selection. First, though, check to see if there 13455 * is already a native translation in place (and, if so, 13456 * jump to it now). 13457 */ 13458 GET_JIT_THRESHOLD(r1) 13459 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13460 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter 13461 EXPORT_PC() 13462 mov r0,rPC 13463 bl dvmJitGetTraceAddr @ r0<- dvmJitGetTraceAddr(rPC) 13464 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13465 mov r1, rPC @ arg1 of translation may need this 13466 mov lr, #0 @ in case target is HANDLER_INTERPRET 13467 cmp r0,#0 13468#if !defined(WITH_SELF_VERIFICATION) 13469 bxne r0 @ jump to the translation 13470 mov r2,#kJitTSelectRequest @ ask for trace selection 13471 @ fall-through to common_selectTrace 13472#else 13473 moveq r2,#kJitTSelectRequest @ ask for trace selection 13474 beq common_selectTrace 13475 /* 13476 * At this point, we have a target translation. However, if 13477 * that translation is actually the interpret-only pseudo-translation 13478 * we want to treat it the same as no translation. 13479 */ 13480 mov r10, r0 @ save target 13481 bl dvmCompilerGetInterpretTemplate 13482 cmp r0, r10 @ special case? 13483 bne jitSVShadowRunStart @ set up self verification shadow space 13484 @ Need to clear the inJitCodeCache flag 13485 ldr r10, [rGLUE, #offGlue_self] @ r10 <- glue->self 13486 mov r3, #0 @ 0 means not in the JIT code cache 13487 str r3, [r10, #offThread_inJitCodeCache] @ back to the interp land 13488 GET_INST_OPCODE(ip) 13489 GOTO_OPCODE(ip) 13490 /* no return */ 13491#endif 13492 13493/* 13494 * On entry: 13495 * r2 is jit state, e.g. kJitTSelectRequest or kJitTSelectRequestHot 13496 */ 13497common_selectTrace: 13498 str r2,[rGLUE,#offGlue_jitState] 13499 mov r2,#kInterpEntryInstr @ normal entry reason 13500 str r2,[rGLUE,#offGlue_entryPoint] 13501 mov r1,#1 @ set changeInterp 13502 b common_gotoBail 13503 13504#if defined(WITH_SELF_VERIFICATION) 13505/* 13506 * Save PC and registers to shadow memory for self verification mode 13507 * before jumping to native translation. 13508 * On entry: 13509 * rPC, rFP, rGLUE: the values that they should contain 13510 * r10: the address of the target translation. 13511 */ 13512jitSVShadowRunStart: 13513 mov r0,rPC @ r0<- program counter 13514 mov r1,rFP @ r1<- frame pointer 13515 mov r2,rGLUE @ r2<- InterpState pointer 13516 mov r3,r10 @ r3<- target translation 13517 bl dvmSelfVerificationSaveState @ save registers to shadow space 13518 ldr rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space 13519 add rGLUE,r0,#offShadowSpace_interpState @ rGLUE<- rGLUE in shadow space 13520 bx r10 @ jump to the translation 13521 13522/* 13523 * Restore PC, registers, and interpState to original values 13524 * before jumping back to the interpreter. 13525 */ 13526jitSVShadowRunEnd: 13527 mov r1,rFP @ pass ending fp 13528 bl dvmSelfVerificationRestoreState @ restore pc and fp values 13529 ldr rPC,[r0,#offShadowSpace_startPC] @ restore PC 13530 ldr rFP,[r0,#offShadowSpace_fp] @ restore FP 13531 ldr rGLUE,[r0,#offShadowSpace_glue] @ restore InterpState 13532 ldr r1,[r0,#offShadowSpace_svState] @ get self verification state 13533 cmp r1,#0 @ check for punt condition 13534 beq 1f 13535 mov r2,#kJitSelfVerification @ ask for self verification 13536 str r2,[rGLUE,#offGlue_jitState] 13537 mov r2,#kInterpEntryInstr @ normal entry reason 13538 str r2,[rGLUE,#offGlue_entryPoint] 13539 mov r1,#1 @ set changeInterp 13540 b common_gotoBail 13541 135421: @ exit to interpreter without check 13543 EXPORT_PC() 13544 adrl rIBASE, dvmAsmInstructionStart 13545 FETCH_INST() 13546 GET_INST_OPCODE(ip) 13547 GOTO_OPCODE(ip) 13548#endif 13549 13550#endif 13551 13552/* 13553 * Common code when a backward branch is taken. 13554 * 13555 * TODO: we could avoid a branch by just setting r0 and falling through 13556 * into the common_periodicChecks code, and having a test on r0 at the 13557 * end determine if we should return to the caller or update & branch to 13558 * the next instr. 13559 * 13560 * On entry: 13561 * r9 is PC adjustment *in bytes* 13562 */ 13563common_backwardBranch: 13564 mov r0, #kInterpEntryInstr 13565 bl common_periodicChecks 13566#if defined(WITH_JIT) 13567 GET_JIT_PROF_TABLE(r0) 13568 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 13569 cmp r0,#0 13570 bne common_updateProfile 13571 GET_INST_OPCODE(ip) 13572 GOTO_OPCODE(ip) 13573#else 13574 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 13575 GET_INST_OPCODE(ip) @ extract opcode from rINST 13576 GOTO_OPCODE(ip) @ jump to next instruction 13577#endif 13578 13579 13580/* 13581 * Need to see if the thread needs to be suspended or debugger/profiler 13582 * activity has begun. If so, we suspend the thread or side-exit to 13583 * the debug interpreter as appropriate. 13584 * 13585 * The common case is no activity on any of these, so we want to figure 13586 * that out quickly. If something is up, we can then sort out what. 13587 * 13588 * We want to be fast if the VM was built without debugger or profiler 13589 * support, but we also need to recognize that the system is usually 13590 * shipped with both of these enabled. 13591 * 13592 * TODO: reduce this so we're just checking a single location. 13593 * 13594 * On entry: 13595 * r0 is reentry type, e.g. kInterpEntryInstr (for debugger/profiling) 13596 * r9 is trampoline PC adjustment *in bytes* 13597 */ 13598common_periodicChecks: 13599 ldr r1, [rGLUE, #offGlue_pInterpBreak] @ r3<- &interpBreak 13600 /* speculatively load address of thread-specific suspend count */ 13601 ldr r3, [rGLUE, #offGlue_pSelfSuspendCount] @ r3<- &suspendCount 13602 ldr r1, [r1] @ r1<- interpBreak 13603 /* speculatively load thread-specific suspend count */ 13604 ldr ip, [r3] @ ip<- suspendCount (int) 13605 cmp r1, #0 @ anything unusual? 13606 bxeq lr @ return if not 13607 /* 13608 * One or more interesting events have happened. Figure out what. 13609 * 13610 * r0 still holds the reentry type. 13611 */ 13612 cmp ip, #0 @ want suspend? 13613 beq 3f @ no, must be something else 13614 13615 stmfd sp!, {r0, lr} @ preserve r0 and lr 13616#if defined(WITH_JIT) 13617 /* 13618 * Refresh the Jit's cached copy of profile table pointer. This pointer 13619 * doubles as the Jit's on/off switch. 13620 */ 13621 ldr r3, [rGLUE, #offGlue_ppJitProfTable] @ r3<-&gDvmJit.pJitProfTable 13622 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 13623 ldr r3, [r3] @ r3 <- pJitProfTable 13624 EXPORT_PC() @ need for precise GC 13625 str r3, [rGLUE, #offGlue_pJitProfTable] @ refresh Jit's on/off switch 13626#else 13627 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 13628 EXPORT_PC() @ need for precise GC 13629#endif 13630 bl dvmCheckSuspendPending @ do full check, suspend if necessary 13631 ldmfd sp!, {r0, lr} @ restore r0 and lr 13632 13633 /* 13634 * Reload the interpBreak flags - they may have changed while we 13635 * were suspended. 13636 */ 13637 ldr r1, [rGLUE, #offGlue_pInterpBreak] @ r1<- &interpBreak 13638 ldr r1, [r1] @ r1<- interpBreak 136393: 13640 /* 13641 * TODO: this code is too fragile. Need a general mechanism 13642 * to identify what actions to take by submode. Some profiling modes 13643 * (instruction count) need to single-step, while method tracing 13644 * may not. Debugging with breakpoints can run unfettered, but 13645 * source-level single-stepping requires Dalvik singlestepping. 13646 * GC may require a one-shot action and then full-speed resumption. 13647 */ 13648 ands r1, #(kSubModeDebuggerActive | kSubModeEmulatorTrace | kSubModeInstCounting) 13649 bxeq lr @ nothing to do, return 13650 13651 @ debugger/profiler enabled, bail out; glue->entryPoint was set above 13652 str r0, [rGLUE, #offGlue_entryPoint] @ store r0, need for debug/prof 13653 add rPC, rPC, r9 @ update rPC 13654 mov r1, #1 @ "want switch" = true 13655 b common_gotoBail @ side exit 13656 13657 13658/* 13659 * The equivalent of "goto bail", this calls through the "bail handler". 13660 * 13661 * State registers will be saved to the "glue" area before bailing. 13662 * 13663 * On entry: 13664 * r1 is "bool changeInterp", indicating if we want to switch to the 13665 * other interpreter or just bail all the way out 13666 */ 13667common_gotoBail: 13668 SAVE_PC_FP_TO_GLUE() @ export state to "glue" 13669 mov r0, rGLUE @ r0<- glue ptr 13670 b dvmMterpStdBail @ call(glue, changeInterp) 13671 13672 @add r1, r1, #1 @ using (boolean+1) 13673 @add r0, rGLUE, #offGlue_jmpBuf @ r0<- &glue->jmpBuf 13674 @bl _longjmp @ does not return 13675 @bl common_abort 13676 13677 13678/* 13679 * Common code for jumbo method invocation. 13680 * NOTE: this adjusts rPC to account for the difference in instruction width. 13681 * As a result, the savedPc in the stack frame will not be wholly accurate. So 13682 * long as that is only used for source file line number calculations, we're 13683 * okay. 13684 * 13685 * On entry: 13686 * r0 is "Method* methodToCall", the method we're trying to call 13687 */ 13688common_invokeMethodJumbo: 13689.LinvokeNewJumbo: 13690 @ prepare to copy args to "outs" area of current frame 13691 add rPC, rPC, #4 @ adjust pc to make return consistent 13692 FETCH(r2, 1) @ r2<- BBBB (arg count) 13693 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 13694 cmp r2, #0 @ no args? 13695 beq .LinvokeArgsDone @ if no args, skip the rest 13696 FETCH(r1, 2) @ r1<- CCCC 13697 b .LinvokeRangeArgs @ handle args like invoke range 13698 13699/* 13700 * Common code for method invocation with range. 13701 * 13702 * On entry: 13703 * r0 is "Method* methodToCall", the method we're trying to call 13704 */ 13705common_invokeMethodRange: 13706.LinvokeNewRange: 13707 @ prepare to copy args to "outs" area of current frame 13708 movs r2, rINST, lsr #8 @ r2<- AA (arg count) -- test for zero 13709 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 13710 beq .LinvokeArgsDone @ if no args, skip the rest 13711 FETCH(r1, 2) @ r1<- CCCC 13712 13713.LinvokeRangeArgs: 13714 @ r0=methodToCall, r1=CCCC, r2=count, r10=outs 13715 @ (very few methods have > 10 args; could unroll for common cases) 13716 add r3, rFP, r1, lsl #2 @ r3<- &fp[CCCC] 13717 sub r10, r10, r2, lsl #2 @ r10<- "outs" area, for call args 137181: ldr r1, [r3], #4 @ val = *fp++ 13719 subs r2, r2, #1 @ count-- 13720 str r1, [r10], #4 @ *outs++ = val 13721 bne 1b @ ...while count != 0 13722 b .LinvokeArgsDone 13723 13724/* 13725 * Common code for method invocation without range. 13726 * 13727 * On entry: 13728 * r0 is "Method* methodToCall", the method we're trying to call 13729 */ 13730common_invokeMethodNoRange: 13731.LinvokeNewNoRange: 13732 @ prepare to copy args to "outs" area of current frame 13733 movs r2, rINST, lsr #12 @ r2<- B (arg count) -- test for zero 13734 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 13735 FETCH(r1, 2) @ r1<- GFED (load here to hide latency) 13736 beq .LinvokeArgsDone 13737 13738 @ r0=methodToCall, r1=GFED, r2=count, r10=outs 13739.LinvokeNonRange: 13740 rsb r2, r2, #5 @ r2<- 5-r2 13741 add pc, pc, r2, lsl #4 @ computed goto, 4 instrs each 13742 bl common_abort @ (skipped due to ARM prefetch) 137435: and ip, rINST, #0x0f00 @ isolate A 13744 ldr r2, [rFP, ip, lsr #6] @ r2<- vA (shift right 8, left 2) 13745 mov r0, r0 @ nop 13746 str r2, [r10, #-4]! @ *--outs = vA 137474: and ip, r1, #0xf000 @ isolate G 13748 ldr r2, [rFP, ip, lsr #10] @ r2<- vG (shift right 12, left 2) 13749 mov r0, r0 @ nop 13750 str r2, [r10, #-4]! @ *--outs = vG 137513: and ip, r1, #0x0f00 @ isolate F 13752 ldr r2, [rFP, ip, lsr #6] @ r2<- vF 13753 mov r0, r0 @ nop 13754 str r2, [r10, #-4]! @ *--outs = vF 137552: and ip, r1, #0x00f0 @ isolate E 13756 ldr r2, [rFP, ip, lsr #2] @ r2<- vE 13757 mov r0, r0 @ nop 13758 str r2, [r10, #-4]! @ *--outs = vE 137591: and ip, r1, #0x000f @ isolate D 13760 ldr r2, [rFP, ip, lsl #2] @ r2<- vD 13761 mov r0, r0 @ nop 13762 str r2, [r10, #-4]! @ *--outs = vD 137630: @ fall through to .LinvokeArgsDone 13764 13765.LinvokeArgsDone: @ r0=methodToCall 13766 ldrh r9, [r0, #offMethod_registersSize] @ r9<- methodToCall->regsSize 13767 ldrh r3, [r0, #offMethod_outsSize] @ r3<- methodToCall->outsSize 13768 ldr r2, [r0, #offMethod_insns] @ r2<- method->insns 13769 ldr rINST, [r0, #offMethod_clazz] @ rINST<- method->clazz 13770 @ find space for the new stack frame, check for overflow 13771 SAVEAREA_FROM_FP(r1, rFP) @ r1<- stack save area 13772 sub r1, r1, r9, lsl #2 @ r1<- newFp (old savearea - regsSize) 13773 SAVEAREA_FROM_FP(r10, r1) @ r10<- newSaveArea 13774@ bl common_dumpRegs 13775 ldr r9, [rGLUE, #offGlue_interpStackEnd] @ r9<- interpStackEnd 13776 sub r3, r10, r3, lsl #2 @ r3<- bottom (newsave - outsSize) 13777 cmp r3, r9 @ bottom < interpStackEnd? 13778 ldr lr, [rGLUE, #offGlue_pInterpBreak] 13779 ldr r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags 13780 blo .LstackOverflow @ yes, this frame will overflow stack 13781 13782 @ set up newSaveArea 13783 ldr lr, [lr] @ lr<- active submodes 13784#ifdef EASY_GDB 13785 SAVEAREA_FROM_FP(ip, rFP) @ ip<- stack save area 13786 str ip, [r10, #offStackSaveArea_prevSave] 13787#endif 13788 str rFP, [r10, #offStackSaveArea_prevFrame] 13789 str rPC, [r10, #offStackSaveArea_savedPc] 13790#if defined(WITH_JIT) 13791 mov r9, #0 13792 str r9, [r10, #offStackSaveArea_returnAddr] 13793#endif 13794 ands lr, #kSubModeMethodTrace @ method tracing? 13795 beq 1f @ skip if not 13796 stmfd sp!, {r0-r3} @ preserve r0-r3 13797 mov r1, r6 13798 @ r0=methodToCall, r1=rGlue 13799 bl dvmFastMethodTraceEnter 13800 ldmfd sp!, {r0-r3} @ restore r0-r3 138011: 13802 str r0, [r10, #offStackSaveArea_method] 13803 tst r3, #ACC_NATIVE 13804 bne .LinvokeNative 13805 13806 /* 13807 stmfd sp!, {r0-r3} 13808 bl common_printNewline 13809 mov r0, rFP 13810 mov r1, #0 13811 bl dvmDumpFp 13812 ldmfd sp!, {r0-r3} 13813 stmfd sp!, {r0-r3} 13814 mov r0, r1 13815 mov r1, r10 13816 bl dvmDumpFp 13817 bl common_printNewline 13818 ldmfd sp!, {r0-r3} 13819 */ 13820 13821 ldrh r9, [r2] @ r9 <- load INST from new PC 13822 ldr r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex 13823 mov rPC, r2 @ publish new rPC 13824 ldr r2, [rGLUE, #offGlue_self] @ r2<- glue->self 13825 13826 @ Update "glue" values for the new method 13827 @ r0=methodToCall, r1=newFp, r2=self, r3=newMethodClass, r9=newINST 13828 str r0, [rGLUE, #offGlue_method] @ glue->method = methodToCall 13829 str r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ... 13830#if defined(WITH_JIT) 13831 GET_JIT_PROF_TABLE(r0) 13832 mov rFP, r1 @ fp = newFp 13833 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 13834 mov rINST, r9 @ publish new rINST 13835 str r1, [r2, #offThread_curFrame] @ self->curFrame = newFp 13836 cmp r0,#0 13837 bne common_updateProfile 13838 GOTO_OPCODE(ip) @ jump to next instruction 13839#else 13840 mov rFP, r1 @ fp = newFp 13841 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 13842 mov rINST, r9 @ publish new rINST 13843 str r1, [r2, #offThread_curFrame] @ self->curFrame = newFp 13844 GOTO_OPCODE(ip) @ jump to next instruction 13845#endif 13846 13847.LinvokeNative: 13848 @ Prep for the native call 13849 @ r0=methodToCall, r1=newFp, r10=newSaveArea 13850 ldr r3, [rGLUE, #offGlue_self] @ r3<- glue->self 13851 ldr lr, [rGLUE, #offGlue_pInterpBreak] 13852 ldr r9, [r3, #offThread_jniLocal_topCookie] @ r9<- thread->localRef->... 13853 str r1, [r3, #offThread_curFrame] @ self->curFrame = newFp 13854 str r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top 13855 ldr lr, [lr] @ lr<- active submodes 13856 mov r9, r3 @ r9<- glue->self (preserve) 13857 13858 mov r2, r0 @ r2<- methodToCall 13859 mov r0, r1 @ r0<- newFp (points to args) 13860 add r1, rGLUE, #offGlue_retval @ r1<- &retval 13861 13862#ifdef ASSIST_DEBUGGER 13863 /* insert fake function header to help gdb find the stack frame */ 13864 b .Lskip 13865 .type dalvik_mterp, %function 13866dalvik_mterp: 13867 .fnstart 13868 MTERP_ENTRY1 13869 MTERP_ENTRY2 13870.Lskip: 13871#endif 13872 13873 ands lr, #kSubModeMethodTrace @ method tracing? 13874 beq 110f @ hop if not 13875 @ r2=JNIMethod, r6=rGLUE 13876 stmfd sp!, {r2,r6} 13877 13878 mov lr, pc @ set return addr 13879 ldr pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 13880 13881 @ r0=JNIMethod, r1=rGLUE 13882 ldmfd sp!, {r0-r1} 13883 bl dvmFastNativeMethodTraceExit 13884 @ r2=JNIMethod, r6=rGLUE 13885 stmfd sp!, {r2,r6} 13886 b 220f 13887110: 13888 mov lr, pc @ set return addr 13889 ldr pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 13890220: 13891#if defined(WITH_JIT) 13892 ldr r3, [rGLUE, #offGlue_ppJitProfTable] @ Refresh Jit's on/off status 13893#endif 13894 13895 @ native return; r9=self, r10=newSaveArea 13896 @ equivalent to dvmPopJniLocals 13897 ldr r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top 13898 ldr r1, [r9, #offThread_exception] @ check for exception 13899#if defined(WITH_JIT) 13900 ldr r3, [r3] @ r3 <- gDvmJit.pProfTable 13901#endif 13902 str rFP, [r9, #offThread_curFrame] @ self->curFrame = fp 13903 cmp r1, #0 @ null? 13904 str r0, [r9, #offThread_jniLocal_topCookie] @ new top <- old top 13905#if defined(WITH_JIT) 13906 str r3, [rGLUE, #offGlue_pJitProfTable] @ refresh cached on/off switch 13907#endif 13908 bne common_exceptionThrown @ no, handle exception 13909 13910 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 13911 GET_INST_OPCODE(ip) @ extract opcode from rINST 13912 GOTO_OPCODE(ip) @ jump to next instruction 13913 13914.LstackOverflow: @ r0=methodToCall 13915 mov r1, r0 @ r1<- methodToCall 13916 ldr r0, [rGLUE, #offGlue_self] @ r0<- self 13917 bl dvmHandleStackOverflow 13918 b common_exceptionThrown 13919#ifdef ASSIST_DEBUGGER 13920 .fnend 13921#endif 13922 13923 13924 /* 13925 * Common code for method invocation, calling through "glue code". 13926 * 13927 * TODO: now that we have range and non-range invoke handlers, this 13928 * needs to be split into two. Maybe just create entry points 13929 * that set r9 and jump here? 13930 * 13931 * On entry: 13932 * r0 is "Method* methodToCall", the method we're trying to call 13933 * r9 is "bool methodCallRange", indicating if this is a /range variant 13934 */ 13935 .if 0 13936.LinvokeOld: 13937 sub sp, sp, #8 @ space for args + pad 13938 FETCH(ip, 2) @ ip<- FEDC or CCCC 13939 mov r2, r0 @ A2<- methodToCall 13940 mov r0, rGLUE @ A0<- glue 13941 SAVE_PC_FP_TO_GLUE() @ export state to "glue" 13942 mov r1, r9 @ A1<- methodCallRange 13943 mov r3, rINST, lsr #8 @ A3<- AA 13944 str ip, [sp, #0] @ A4<- ip 13945 bl dvmMterp_invokeMethod @ call the C invokeMethod 13946 add sp, sp, #8 @ remove arg area 13947 b common_resumeAfterGlueCall @ continue to next instruction 13948 .endif 13949 13950 13951 13952/* 13953 * Common code for handling a return instruction. 13954 * 13955 * This does not return. 13956 */ 13957common_returnFromMethod: 13958.LreturnNew: 13959 mov r0, #kInterpEntryReturn 13960 mov r9, #0 13961 bl common_periodicChecks 13962 13963 ldr lr, [rGLUE, #offGlue_pInterpBreak] 13964 SAVEAREA_FROM_FP(r0, rFP) 13965 ldr lr, [lr] @ lr<- active submodes 13966 ldr r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc 13967 ands lr, #kSubModeMethodTrace @ method tracing? 13968 beq 333f 13969 stmfd sp!, {r0-r3} @ preserve r0-r3 13970 mov r0, r6 13971 @ r0=rGlue 13972 bl dvmFastJavaMethodTraceExit 13973 ldmfd sp!, {r0-r3} @ restore r0-r3 13974333: 13975 ldr rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame 13976 ldr r3, [rGLUE, #offGlue_self] @ r3<- glue->self 13977 ldr r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)] 13978 @ r2<- method we're returning to 13979 cmp r2, #0 @ is this a break frame? 13980#if defined(WORKAROUND_CORTEX_A9_745320) 13981 /* Don't use conditional loads if the HW defect exists */ 13982 beq 101f 13983 ldr r10, [r2, #offMethod_clazz] @ r10<- method->clazz 13984101: 13985#else 13986 ldrne r10, [r2, #offMethod_clazz] @ r10<- method->clazz 13987#endif 13988 mov r1, #0 @ "want switch" = false 13989 beq common_gotoBail @ break frame, bail out completely 13990 13991 PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST 13992 str r2, [rGLUE, #offGlue_method]@ glue->method = newSave->method 13993 ldr r1, [r10, #offClassObject_pDvmDex] @ r1<- method->clazz->pDvmDex 13994 str rFP, [r3, #offThread_curFrame] @ self->curFrame = fp 13995#if defined(WITH_JIT) 13996 ldr r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr 13997 mov rPC, r9 @ publish new rPC 13998 str r1, [rGLUE, #offGlue_methodClassDex] 13999 str r10, [r3, #offThread_inJitCodeCache] @ may return to JIT'ed land 14000 cmp r10, #0 @ caller is compiled code 14001 blxne r10 14002 GET_INST_OPCODE(ip) @ extract opcode from rINST 14003 GOTO_OPCODE(ip) @ jump to next instruction 14004#else 14005 GET_INST_OPCODE(ip) @ extract opcode from rINST 14006 mov rPC, r9 @ publish new rPC 14007 str r1, [rGLUE, #offGlue_methodClassDex] 14008 GOTO_OPCODE(ip) @ jump to next instruction 14009#endif 14010 14011 /* 14012 * Return handling, calls through "glue code". 14013 */ 14014 .if 0 14015.LreturnOld: 14016 SAVE_PC_FP_TO_GLUE() @ export state 14017 mov r0, rGLUE @ arg to function 14018 bl dvmMterp_returnFromMethod 14019 b common_resumeAfterGlueCall 14020 .endif 14021 14022 14023/* 14024 * Somebody has thrown an exception. Handle it. 14025 * 14026 * If the exception processing code returns to us (instead of falling 14027 * out of the interpreter), continue with whatever the next instruction 14028 * now happens to be. 14029 * 14030 * This does not return. 14031 */ 14032 .global dvmMterpCommonExceptionThrown 14033dvmMterpCommonExceptionThrown: 14034common_exceptionThrown: 14035.LexceptionNew: 14036 mov r0, #kInterpEntryThrow 14037 mov r9, #0 14038 bl common_periodicChecks 14039 14040 ldr r10, [rGLUE, #offGlue_self] @ r10<- glue->self 14041 ldr r9, [r10, #offThread_exception] @ r9<- self->exception 14042 mov r1, r10 @ r1<- self 14043 mov r0, r9 @ r0<- exception 14044 bl dvmAddTrackedAlloc @ don't let the exception be GCed 14045 mov r3, #0 @ r3<- NULL 14046 str r3, [r10, #offThread_exception] @ self->exception = NULL 14047 14048 /* set up args and a local for "&fp" */ 14049 /* (str sp, [sp, #-4]! would be perfect here, but is discouraged) */ 14050 str rFP, [sp, #-4]! @ *--sp = fp 14051 mov ip, sp @ ip<- &fp 14052 mov r3, #0 @ r3<- false 14053 str ip, [sp, #-4]! @ *--sp = &fp 14054 ldr r1, [rGLUE, #offGlue_method] @ r1<- glue->method 14055 mov r0, r10 @ r0<- self 14056 ldr r1, [r1, #offMethod_insns] @ r1<- method->insns 14057 mov r2, r9 @ r2<- exception 14058 sub r1, rPC, r1 @ r1<- pc - method->insns 14059 mov r1, r1, asr #1 @ r1<- offset in code units 14060 14061 /* call, r0 gets catchRelPc (a code-unit offset) */ 14062 bl dvmFindCatchBlock @ call(self, relPc, exc, scan?, &fp) 14063 14064 /* fix earlier stack overflow if necessary; may trash rFP */ 14065 ldrb r1, [r10, #offThread_stackOverflowed] 14066 cmp r1, #0 @ did we overflow earlier? 14067 beq 1f @ no, skip ahead 14068 mov rFP, r0 @ save relPc result in rFP 14069 mov r0, r10 @ r0<- self 14070 mov r1, r9 @ r1<- exception 14071 bl dvmCleanupStackOverflow @ call(self) 14072 mov r0, rFP @ restore result 140731: 14074 14075 /* update frame pointer and check result from dvmFindCatchBlock */ 14076 ldr rFP, [sp, #4] @ retrieve the updated rFP 14077 cmp r0, #0 @ is catchRelPc < 0? 14078 add sp, sp, #8 @ restore stack 14079 bmi .LnotCaughtLocally 14080 14081 /* adjust locals to match self->curFrame and updated PC */ 14082 SAVEAREA_FROM_FP(r1, rFP) @ r1<- new save area 14083 ldr r1, [r1, #offStackSaveArea_method] @ r1<- new method 14084 str r1, [rGLUE, #offGlue_method] @ glue->method = new method 14085 ldr r2, [r1, #offMethod_clazz] @ r2<- method->clazz 14086 ldr r3, [r1, #offMethod_insns] @ r3<- method->insns 14087 ldr r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex 14088 add rPC, r3, r0, asl #1 @ rPC<- method->insns + catchRelPc 14089 str r2, [rGLUE, #offGlue_methodClassDex] @ glue->pDvmDex = meth... 14090 14091 /* release the tracked alloc on the exception */ 14092 mov r0, r9 @ r0<- exception 14093 mov r1, r10 @ r1<- self 14094 bl dvmReleaseTrackedAlloc @ release the exception 14095 14096 /* restore the exception if the handler wants it */ 14097 FETCH_INST() @ load rINST from rPC 14098 GET_INST_OPCODE(ip) @ extract opcode from rINST 14099 cmp ip, #OP_MOVE_EXCEPTION @ is it "move-exception"? 14100 streq r9, [r10, #offThread_exception] @ yes, restore the exception 14101 GOTO_OPCODE(ip) @ jump to next instruction 14102 14103.LnotCaughtLocally: @ r9=exception, r10=self 14104 /* fix stack overflow if necessary */ 14105 ldrb r1, [r10, #offThread_stackOverflowed] 14106 cmp r1, #0 @ did we overflow earlier? 14107 movne r0, r10 @ if yes: r0<- self 14108 movne r1, r9 @ if yes: r1<- exception 14109 blne dvmCleanupStackOverflow @ if yes: call(self) 14110 14111 @ may want to show "not caught locally" debug messages here 14112#if DVM_SHOW_EXCEPTION >= 2 14113 /* call __android_log_print(prio, tag, format, ...) */ 14114 /* "Exception %s from %s:%d not caught locally" */ 14115 @ dvmLineNumFromPC(method, pc - method->insns) 14116 ldr r0, [rGLUE, #offGlue_method] 14117 ldr r1, [r0, #offMethod_insns] 14118 sub r1, rPC, r1 14119 asr r1, r1, #1 14120 bl dvmLineNumFromPC 14121 str r0, [sp, #-4]! 14122 @ dvmGetMethodSourceFile(method) 14123 ldr r0, [rGLUE, #offGlue_method] 14124 bl dvmGetMethodSourceFile 14125 str r0, [sp, #-4]! 14126 @ exception->clazz->descriptor 14127 ldr r3, [r9, #offObject_clazz] 14128 ldr r3, [r3, #offClassObject_descriptor] 14129 @ 14130 ldr r2, strExceptionNotCaughtLocally 14131 ldr r1, strLogTag 14132 mov r0, #3 @ LOG_DEBUG 14133 bl __android_log_print 14134#endif 14135 str r9, [r10, #offThread_exception] @ restore exception 14136 mov r0, r9 @ r0<- exception 14137 mov r1, r10 @ r1<- self 14138 bl dvmReleaseTrackedAlloc @ release the exception 14139 mov r1, #0 @ "want switch" = false 14140 b common_gotoBail @ bail out 14141 14142 14143 /* 14144 * Exception handling, calls through "glue code". 14145 */ 14146 .if 0 14147.LexceptionOld: 14148 SAVE_PC_FP_TO_GLUE() @ export state 14149 mov r0, rGLUE @ arg to function 14150 bl dvmMterp_exceptionThrown 14151 b common_resumeAfterGlueCall 14152 .endif 14153 14154 14155/* 14156 * After returning from a "glued" function, pull out the updated 14157 * values and start executing at the next instruction. 14158 */ 14159common_resumeAfterGlueCall: 14160 LOAD_PC_FP_FROM_GLUE() @ pull rPC and rFP out of glue 14161 FETCH_INST() @ load rINST from rPC 14162 GET_INST_OPCODE(ip) @ extract opcode from rINST 14163 GOTO_OPCODE(ip) @ jump to next instruction 14164 14165/* 14166 * Invalid array index. Note that our calling convention is strange; we use r1 14167 * and r3 because those just happen to be the registers all our callers are 14168 * using. We shuffle them here before calling the C function. 14169 * r1: index 14170 * r3: size 14171 */ 14172common_errArrayIndex: 14173 EXPORT_PC() 14174 mov r0, r1 14175 mov r1, r3 14176 bl dvmThrowAIOOBE 14177 b common_exceptionThrown 14178 14179/* 14180 * Integer divide or mod by zero. 14181 */ 14182common_errDivideByZero: 14183 EXPORT_PC() 14184 ldr r0, strArithmeticException 14185 ldr r1, strDivideByZero 14186 bl dvmThrowException 14187 b common_exceptionThrown 14188 14189/* 14190 * Attempt to allocate an array with a negative size. 14191 */ 14192common_errNegativeArraySize: 14193 EXPORT_PC() 14194 ldr r0, strNegativeArraySizeException 14195 mov r1, #0 14196 bl dvmThrowException 14197 b common_exceptionThrown 14198 14199/* 14200 * Invocation of a non-existent method. 14201 */ 14202common_errNoSuchMethod: 14203 EXPORT_PC() 14204 ldr r0, strNoSuchMethodError 14205 mov r1, #0 14206 bl dvmThrowException 14207 b common_exceptionThrown 14208 14209/* 14210 * We encountered a null object when we weren't expecting one. We 14211 * export the PC, throw a NullPointerException, and goto the exception 14212 * processing code. 14213 */ 14214common_errNullObject: 14215 EXPORT_PC() 14216 ldr r0, strNullPointerException 14217 mov r1, #0 14218 bl dvmThrowException 14219 b common_exceptionThrown 14220 14221/* 14222 * For debugging, cause an immediate fault. The source address will 14223 * be in lr (use a bl instruction to jump here). 14224 */ 14225common_abort: 14226 ldr pc, .LdeadFood 14227.LdeadFood: 14228 .word 0xdeadf00d 14229 14230/* 14231 * Spit out a "we were here", preserving all registers. (The attempt 14232 * to save ip won't work, but we need to save an even number of 14233 * registers for EABI 64-bit stack alignment.) 14234 */ 14235 .macro SQUEAK num 14236common_squeak\num: 14237 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14238 ldr r0, strSqueak 14239 mov r1, #\num 14240 bl printf 14241 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14242 bx lr 14243 .endm 14244 14245 SQUEAK 0 14246 SQUEAK 1 14247 SQUEAK 2 14248 SQUEAK 3 14249 SQUEAK 4 14250 SQUEAK 5 14251 14252/* 14253 * Spit out the number in r0, preserving registers. 14254 */ 14255common_printNum: 14256 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14257 mov r1, r0 14258 ldr r0, strSqueak 14259 bl printf 14260 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14261 bx lr 14262 14263/* 14264 * Print a newline, preserving registers. 14265 */ 14266common_printNewline: 14267 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14268 ldr r0, strNewline 14269 bl printf 14270 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14271 bx lr 14272 14273 /* 14274 * Print the 32-bit quantity in r0 as a hex value, preserving registers. 14275 */ 14276common_printHex: 14277 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14278 mov r1, r0 14279 ldr r0, strPrintHex 14280 bl printf 14281 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14282 bx lr 14283 14284/* 14285 * Print the 64-bit quantity in r0-r1, preserving registers. 14286 */ 14287common_printLong: 14288 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14289 mov r3, r1 14290 mov r2, r0 14291 ldr r0, strPrintLong 14292 bl printf 14293 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14294 bx lr 14295 14296/* 14297 * Print full method info. Pass the Method* in r0. Preserves regs. 14298 */ 14299common_printMethod: 14300 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14301 bl dvmMterpPrintMethod 14302 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14303 bx lr 14304 14305/* 14306 * Call a C helper function that dumps regs and possibly some 14307 * additional info. Requires the C function to be compiled in. 14308 */ 14309 .if 0 14310common_dumpRegs: 14311 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14312 bl dvmMterpDumpArmRegs 14313 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14314 bx lr 14315 .endif 14316 14317#if 0 14318/* 14319 * Experiment on VFP mode. 14320 * 14321 * uint32_t setFPSCR(uint32_t val, uint32_t mask) 14322 * 14323 * Updates the bits specified by "mask", setting them to the values in "val". 14324 */ 14325setFPSCR: 14326 and r0, r0, r1 @ make sure no stray bits are set 14327 fmrx r2, fpscr @ get VFP reg 14328 mvn r1, r1 @ bit-invert mask 14329 and r2, r2, r1 @ clear masked bits 14330 orr r2, r2, r0 @ set specified bits 14331 fmxr fpscr, r2 @ set VFP reg 14332 mov r0, r2 @ return new value 14333 bx lr 14334 14335 .align 2 14336 .global dvmConfigureFP 14337 .type dvmConfigureFP, %function 14338dvmConfigureFP: 14339 stmfd sp!, {ip, lr} 14340 /* 0x03000000 sets DN/FZ */ 14341 /* 0x00009f00 clears the six exception enable flags */ 14342 bl common_squeak0 14343 mov r0, #0x03000000 @ r0<- 0x03000000 14344 add r1, r0, #0x9f00 @ r1<- 0x03009f00 14345 bl setFPSCR 14346 ldmfd sp!, {ip, pc} 14347#endif 14348 14349 14350/* 14351 * String references, must be close to the code that uses them. 14352 */ 14353 .align 2 14354strArithmeticException: 14355 .word .LstrArithmeticException 14356strDivideByZero: 14357 .word .LstrDivideByZero 14358strNegativeArraySizeException: 14359 .word .LstrNegativeArraySizeException 14360strNoSuchMethodError: 14361 .word .LstrNoSuchMethodError 14362strNullPointerException: 14363 .word .LstrNullPointerException 14364 14365strLogTag: 14366 .word .LstrLogTag 14367strExceptionNotCaughtLocally: 14368 .word .LstrExceptionNotCaughtLocally 14369 14370strNewline: 14371 .word .LstrNewline 14372strSqueak: 14373 .word .LstrSqueak 14374strPrintHex: 14375 .word .LstrPrintHex 14376strPrintLong: 14377 .word .LstrPrintLong 14378 14379/* 14380 * Zero-terminated ASCII string data. 14381 * 14382 * On ARM we have two choices: do like gcc does, and LDR from a .word 14383 * with the address, or use an ADR pseudo-op to get the address 14384 * directly. ADR saves 4 bytes and an indirection, but it's using a 14385 * PC-relative addressing mode and hence has a limited range, which 14386 * makes it not work well with mergeable string sections. 14387 */ 14388 .section .rodata.str1.4,"aMS",%progbits,1 14389 14390.LstrBadEntryPoint: 14391 .asciz "Bad entry point %d\n" 14392.LstrArithmeticException: 14393 .asciz "Ljava/lang/ArithmeticException;" 14394.LstrDivideByZero: 14395 .asciz "divide by zero" 14396.LstrFilledNewArrayNotImpl: 14397 .asciz "filled-new-array only implemented for objects and 'int'" 14398.LstrInternalError: 14399 .asciz "Ljava/lang/InternalError;" 14400.LstrInstantiationError: 14401 .asciz "Ljava/lang/InstantiationError;" 14402.LstrNegativeArraySizeException: 14403 .asciz "Ljava/lang/NegativeArraySizeException;" 14404.LstrNoSuchMethodError: 14405 .asciz "Ljava/lang/NoSuchMethodError;" 14406.LstrNullPointerException: 14407 .asciz "Ljava/lang/NullPointerException;" 14408 14409.LstrLogTag: 14410 .asciz "mterp" 14411.LstrExceptionNotCaughtLocally: 14412 .asciz "Exception %s from %s:%d not caught locally\n" 14413 14414.LstrNewline: 14415 .asciz "\n" 14416.LstrSqueak: 14417 .asciz "<%d>" 14418.LstrPrintHex: 14419 .asciz "<0x%x>" 14420.LstrPrintLong: 14421 .asciz "<%lld>" 14422 14423