InterpAsm-armv5te.S revision d3a92b577f11c6357c76dc850c6cbf352ef4c760
1/* 2 * This file was generated automatically by gen-mterp.py for 'armv5te'. 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 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 GET_INST_OPCODE(ip) @ extract opcode from rINST 857 GOTO_OPCODE(ip) @ jump to next instruction 858 859/* ------------------------------ */ 860 .balign 64 861.L_OP_MONITOR_EXIT: /* 0x1e */ 862/* File: armv5te/OP_MONITOR_EXIT.S */ 863 /* 864 * Unlock an object. 865 * 866 * Exceptions that occur when unlocking a monitor need to appear as 867 * if they happened at the following instruction. See the Dalvik 868 * instruction spec. 869 */ 870 /* monitor-exit vAA */ 871 mov r2, rINST, lsr #8 @ r2<- AA 872 EXPORT_PC() @ before fetch: export the PC 873 GET_VREG(r1, r2) @ r1<- vAA (object) 874 cmp r1, #0 @ null object? 875 beq 1f @ yes 876 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 877 bl dvmUnlockObject @ r0<- success for unlock(self, obj) 878 cmp r0, #0 @ failed? 879 FETCH_ADVANCE_INST(1) @ before throw: advance rPC, load rINST 880 beq common_exceptionThrown @ yes, exception is pending 881 GET_INST_OPCODE(ip) @ extract opcode from rINST 882 GOTO_OPCODE(ip) @ jump to next instruction 8831: 884 FETCH_ADVANCE_INST(1) @ advance before throw 885 b common_errNullObject 886 887/* ------------------------------ */ 888 .balign 64 889.L_OP_CHECK_CAST: /* 0x1f */ 890/* File: armv5te/OP_CHECK_CAST.S */ 891 /* 892 * Check to see if a cast from one class to another is allowed. 893 */ 894 /* check-cast vAA, class@BBBB */ 895 mov r3, rINST, lsr #8 @ r3<- AA 896 FETCH(r2, 1) @ r2<- BBBB 897 GET_VREG(r9, r3) @ r9<- object 898 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- pDvmDex 899 cmp r9, #0 @ is object null? 900 ldr r0, [r0, #offDvmDex_pResClasses] @ r0<- pDvmDex->pResClasses 901 beq .LOP_CHECK_CAST_okay @ null obj, cast always succeeds 902 ldr r1, [r0, r2, lsl #2] @ r1<- resolved class 903 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 904 cmp r1, #0 @ have we resolved this before? 905 beq .LOP_CHECK_CAST_resolve @ not resolved, do it now 906.LOP_CHECK_CAST_resolved: 907 cmp r0, r1 @ same class (trivial success)? 908 bne .LOP_CHECK_CAST_fullcheck @ no, do full check 909.LOP_CHECK_CAST_okay: 910 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 911 GET_INST_OPCODE(ip) @ extract opcode from rINST 912 GOTO_OPCODE(ip) @ jump to next instruction 913 914/* ------------------------------ */ 915 .balign 64 916.L_OP_INSTANCE_OF: /* 0x20 */ 917/* File: armv5te/OP_INSTANCE_OF.S */ 918 /* 919 * Check to see if an object reference is an instance of a class. 920 * 921 * Most common situation is a non-null object, being compared against 922 * an already-resolved class. 923 */ 924 /* instance-of vA, vB, class@CCCC */ 925 mov r3, rINST, lsr #12 @ r3<- B 926 mov r9, rINST, lsr #8 @ r9<- A+ 927 GET_VREG(r0, r3) @ r0<- vB (object) 928 and r9, r9, #15 @ r9<- A 929 cmp r0, #0 @ is object null? 930 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- pDvmDex 931 beq .LOP_INSTANCE_OF_store @ null obj, not an instance, store r0 932 FETCH(r3, 1) @ r3<- CCCC 933 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- pDvmDex->pResClasses 934 ldr r1, [r2, r3, lsl #2] @ r1<- resolved class 935 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 936 cmp r1, #0 @ have we resolved this before? 937 beq .LOP_INSTANCE_OF_resolve @ not resolved, do it now 938.LOP_INSTANCE_OF_resolved: @ r0=obj->clazz, r1=resolved class 939 cmp r0, r1 @ same class (trivial success)? 940 beq .LOP_INSTANCE_OF_trivial @ yes, trivial finish 941 b .LOP_INSTANCE_OF_fullcheck @ no, do full check 942 943/* ------------------------------ */ 944 .balign 64 945.L_OP_ARRAY_LENGTH: /* 0x21 */ 946/* File: armv5te/OP_ARRAY_LENGTH.S */ 947 /* 948 * Return the length of an array. 949 */ 950 mov r1, rINST, lsr #12 @ r1<- B 951 mov r2, rINST, lsr #8 @ r2<- A+ 952 GET_VREG(r0, r1) @ r0<- vB (object ref) 953 and r2, r2, #15 @ r2<- A 954 cmp r0, #0 @ is object null? 955 beq common_errNullObject @ yup, fail 956 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 957 ldr r3, [r0, #offArrayObject_length] @ r3<- array length 958 GET_INST_OPCODE(ip) @ extract opcode from rINST 959 SET_VREG(r3, r2) @ vB<- length 960 GOTO_OPCODE(ip) @ jump to next instruction 961 962/* ------------------------------ */ 963 .balign 64 964.L_OP_NEW_INSTANCE: /* 0x22 */ 965/* File: armv5te/OP_NEW_INSTANCE.S */ 966 /* 967 * Create a new instance of a class. 968 */ 969 /* new-instance vAA, class@BBBB */ 970 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 971 FETCH(r1, 1) @ r1<- BBBB 972 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 973 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 974 EXPORT_PC() @ req'd for init, resolve, alloc 975 cmp r0, #0 @ already resolved? 976 beq .LOP_NEW_INSTANCE_resolve @ no, resolve it now 977.LOP_NEW_INSTANCE_resolved: @ r0=class 978 ldrb r1, [r0, #offClassObject_status] @ r1<- ClassStatus enum 979 cmp r1, #CLASS_INITIALIZED @ has class been initialized? 980 bne .LOP_NEW_INSTANCE_needinit @ no, init class now 981.LOP_NEW_INSTANCE_initialized: @ r0=class 982 mov r1, #ALLOC_DONT_TRACK @ flags for alloc call 983 bl dvmAllocObject @ r0<- new object 984 b .LOP_NEW_INSTANCE_finish @ continue 985 986/* ------------------------------ */ 987 .balign 64 988.L_OP_NEW_ARRAY: /* 0x23 */ 989/* File: armv5te/OP_NEW_ARRAY.S */ 990 /* 991 * Allocate an array of objects, specified with the array class 992 * and a count. 993 * 994 * The verifier guarantees that this is an array class, so we don't 995 * check for it here. 996 */ 997 /* new-array vA, vB, class@CCCC */ 998 mov r0, rINST, lsr #12 @ r0<- B 999 FETCH(r2, 1) @ r2<- CCCC 1000 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 1001 GET_VREG(r1, r0) @ r1<- vB (array length) 1002 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1003 cmp r1, #0 @ check length 1004 ldr r0, [r3, r2, lsl #2] @ r0<- resolved class 1005 bmi common_errNegativeArraySize @ negative length, bail 1006 cmp r0, #0 @ already resolved? 1007 EXPORT_PC() @ req'd for resolve, alloc 1008 bne .LOP_NEW_ARRAY_finish @ resolved, continue 1009 b .LOP_NEW_ARRAY_resolve @ do resolve now 1010 1011/* ------------------------------ */ 1012 .balign 64 1013.L_OP_FILLED_NEW_ARRAY: /* 0x24 */ 1014/* File: armv5te/OP_FILLED_NEW_ARRAY.S */ 1015 /* 1016 * Create a new array with elements filled from registers. 1017 * 1018 * for: filled-new-array, filled-new-array/range 1019 */ 1020 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1021 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1022 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 1023 FETCH(r1, 1) @ r1<- BBBB 1024 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1025 EXPORT_PC() @ need for resolve and alloc 1026 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 1027 mov r10, rINST, lsr #8 @ r10<- AA or BA 1028 cmp r0, #0 @ already resolved? 1029 bne .LOP_FILLED_NEW_ARRAY_continue @ yes, continue on 10308: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 1031 mov r2, #0 @ r2<- false 1032 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 1033 bl dvmResolveClass @ r0<- call(clazz, ref) 1034 cmp r0, #0 @ got null? 1035 beq common_exceptionThrown @ yes, handle exception 1036 b .LOP_FILLED_NEW_ARRAY_continue 1037 1038/* ------------------------------ */ 1039 .balign 64 1040.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */ 1041/* File: armv5te/OP_FILLED_NEW_ARRAY_RANGE.S */ 1042/* File: armv5te/OP_FILLED_NEW_ARRAY.S */ 1043 /* 1044 * Create a new array with elements filled from registers. 1045 * 1046 * for: filled-new-array, filled-new-array/range 1047 */ 1048 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1049 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1050 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 1051 FETCH(r1, 1) @ r1<- BBBB 1052 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1053 EXPORT_PC() @ need for resolve and alloc 1054 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 1055 mov r10, rINST, lsr #8 @ r10<- AA or BA 1056 cmp r0, #0 @ already resolved? 1057 bne .LOP_FILLED_NEW_ARRAY_RANGE_continue @ yes, continue on 10588: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 1059 mov r2, #0 @ r2<- false 1060 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 1061 bl dvmResolveClass @ r0<- call(clazz, ref) 1062 cmp r0, #0 @ got null? 1063 beq common_exceptionThrown @ yes, handle exception 1064 b .LOP_FILLED_NEW_ARRAY_RANGE_continue 1065 1066 1067/* ------------------------------ */ 1068 .balign 64 1069.L_OP_FILL_ARRAY_DATA: /* 0x26 */ 1070/* File: armv5te/OP_FILL_ARRAY_DATA.S */ 1071 /* fill-array-data vAA, +BBBBBBBB */ 1072 FETCH(r0, 1) @ r0<- bbbb (lo) 1073 FETCH(r1, 2) @ r1<- BBBB (hi) 1074 mov r3, rINST, lsr #8 @ r3<- AA 1075 orr r1, r0, r1, lsl #16 @ r1<- BBBBbbbb 1076 GET_VREG(r0, r3) @ r0<- vAA (array object) 1077 add r1, rPC, r1, lsl #1 @ r1<- PC + BBBBbbbb*2 (array data off.) 1078 EXPORT_PC(); 1079 bl dvmInterpHandleFillArrayData@ fill the array with predefined data 1080 cmp r0, #0 @ 0 means an exception is thrown 1081 beq common_exceptionThrown @ has exception 1082 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 1083 GET_INST_OPCODE(ip) @ extract opcode from rINST 1084 GOTO_OPCODE(ip) @ jump to next instruction 1085 1086/* ------------------------------ */ 1087 .balign 64 1088.L_OP_THROW: /* 0x27 */ 1089/* File: armv5te/OP_THROW.S */ 1090 /* 1091 * Throw an exception object in the current thread. 1092 */ 1093 /* throw vAA */ 1094 mov r2, rINST, lsr #8 @ r2<- AA 1095 GET_VREG(r1, r2) @ r1<- vAA (exception object) 1096 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 1097 EXPORT_PC() @ exception handler can throw 1098 cmp r1, #0 @ null object? 1099 beq common_errNullObject @ yes, throw an NPE instead 1100 @ bypass dvmSetException, just store it 1101 str r1, [r0, #offThread_exception] @ thread->exception<- obj 1102 b common_exceptionThrown 1103 1104/* ------------------------------ */ 1105 .balign 64 1106.L_OP_GOTO: /* 0x28 */ 1107/* File: armv5te/OP_GOTO.S */ 1108 /* 1109 * Unconditional branch, 8-bit offset. 1110 * 1111 * The branch distance is a signed code-unit offset, which we need to 1112 * double to get a byte offset. 1113 */ 1114 /* goto +AA */ 1115 mov r0, rINST, lsl #16 @ r0<- AAxx0000 1116 movs r9, r0, asr #24 @ r9<- ssssssAA (sign-extended) 1117 mov r9, r9, lsl #1 @ r9<- byte offset 1118 bmi common_backwardBranch @ backward branch, do periodic checks 1119#if defined(WITH_JIT) 1120 GET_JIT_PROF_TABLE(r0) 1121 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1122 cmp r0,#0 1123 bne common_updateProfile 1124 GET_INST_OPCODE(ip) @ extract opcode from rINST 1125 GOTO_OPCODE(ip) @ jump to next instruction 1126#else 1127 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1128 GET_INST_OPCODE(ip) @ extract opcode from rINST 1129 GOTO_OPCODE(ip) @ jump to next instruction 1130#endif 1131 1132/* ------------------------------ */ 1133 .balign 64 1134.L_OP_GOTO_16: /* 0x29 */ 1135/* File: armv5te/OP_GOTO_16.S */ 1136 /* 1137 * Unconditional branch, 16-bit offset. 1138 * 1139 * The branch distance is a signed code-unit offset, which we need to 1140 * double to get a byte offset. 1141 */ 1142 /* goto/16 +AAAA */ 1143 FETCH_S(r0, 1) @ r0<- ssssAAAA (sign-extended) 1144 movs r9, r0, asl #1 @ r9<- byte offset, check sign 1145 bmi common_backwardBranch @ backward branch, do periodic checks 1146#if defined(WITH_JIT) 1147 GET_JIT_PROF_TABLE(r0) 1148 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1149 cmp r0,#0 1150 bne common_updateProfile 1151 GET_INST_OPCODE(ip) @ extract opcode from rINST 1152 GOTO_OPCODE(ip) @ jump to next instruction 1153#else 1154 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1155 GET_INST_OPCODE(ip) @ extract opcode from rINST 1156 GOTO_OPCODE(ip) @ jump to next instruction 1157#endif 1158 1159/* ------------------------------ */ 1160 .balign 64 1161.L_OP_GOTO_32: /* 0x2a */ 1162/* File: armv5te/OP_GOTO_32.S */ 1163 /* 1164 * Unconditional branch, 32-bit offset. 1165 * 1166 * The branch distance is a signed code-unit offset, which we need to 1167 * double to get a byte offset. 1168 * 1169 * Unlike most opcodes, this one is allowed to branch to itself, so 1170 * our "backward branch" test must be "<=0" instead of "<0". The ORRS 1171 * instruction doesn't affect the V flag, so we need to clear it 1172 * explicitly. 1173 */ 1174 /* goto/32 +AAAAAAAA */ 1175 FETCH(r0, 1) @ r0<- aaaa (lo) 1176 FETCH(r1, 2) @ r1<- AAAA (hi) 1177 cmp ip, ip @ (clear V flag during stall) 1178 orrs r0, r0, r1, lsl #16 @ r0<- AAAAaaaa, check sign 1179 mov r9, r0, asl #1 @ r9<- byte offset 1180 ble common_backwardBranch @ backward branch, do periodic checks 1181#if defined(WITH_JIT) 1182 GET_JIT_PROF_TABLE(r0) 1183 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1184 cmp r0,#0 1185 bne common_updateProfile 1186 GET_INST_OPCODE(ip) @ extract opcode from rINST 1187 GOTO_OPCODE(ip) @ jump to next instruction 1188#else 1189 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1190 GET_INST_OPCODE(ip) @ extract opcode from rINST 1191 GOTO_OPCODE(ip) @ jump to next instruction 1192#endif 1193 1194/* ------------------------------ */ 1195 .balign 64 1196.L_OP_PACKED_SWITCH: /* 0x2b */ 1197/* File: armv5te/OP_PACKED_SWITCH.S */ 1198 /* 1199 * Handle a packed-switch or sparse-switch instruction. In both cases 1200 * we decode it and hand it off to a helper function. 1201 * 1202 * We don't really expect backward branches in a switch statement, but 1203 * they're perfectly legal, so we check for them here. 1204 * 1205 * for: packed-switch, sparse-switch 1206 */ 1207 /* op vAA, +BBBB */ 1208 FETCH(r0, 1) @ r0<- bbbb (lo) 1209 FETCH(r1, 2) @ r1<- BBBB (hi) 1210 mov r3, rINST, lsr #8 @ r3<- AA 1211 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 1212 GET_VREG(r1, r3) @ r1<- vAA 1213 add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 1214 bl dvmInterpHandlePackedSwitch @ r0<- code-unit branch offset 1215 movs r9, r0, asl #1 @ r9<- branch byte offset, check sign 1216 bmi common_backwardBranch @ backward branch, do periodic checks 1217 beq common_backwardBranch @ (want to use BLE but V is unknown) 1218#if defined(WITH_JIT) 1219 GET_JIT_PROF_TABLE(r0) 1220 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1221 cmp r0,#0 1222 bne common_updateProfile 1223 GET_INST_OPCODE(ip) @ extract opcode from rINST 1224 GOTO_OPCODE(ip) @ jump to next instruction 1225#else 1226 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1227 GET_INST_OPCODE(ip) @ extract opcode from rINST 1228 GOTO_OPCODE(ip) @ jump to next instruction 1229#endif 1230 1231/* ------------------------------ */ 1232 .balign 64 1233.L_OP_SPARSE_SWITCH: /* 0x2c */ 1234/* File: armv5te/OP_SPARSE_SWITCH.S */ 1235/* File: armv5te/OP_PACKED_SWITCH.S */ 1236 /* 1237 * Handle a packed-switch or sparse-switch instruction. In both cases 1238 * we decode it and hand it off to a helper function. 1239 * 1240 * We don't really expect backward branches in a switch statement, but 1241 * they're perfectly legal, so we check for them here. 1242 * 1243 * for: packed-switch, sparse-switch 1244 */ 1245 /* op vAA, +BBBB */ 1246 FETCH(r0, 1) @ r0<- bbbb (lo) 1247 FETCH(r1, 2) @ r1<- BBBB (hi) 1248 mov r3, rINST, lsr #8 @ r3<- AA 1249 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 1250 GET_VREG(r1, r3) @ r1<- vAA 1251 add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 1252 bl dvmInterpHandleSparseSwitch @ r0<- code-unit branch offset 1253 movs r9, r0, asl #1 @ r9<- branch byte offset, check sign 1254 bmi common_backwardBranch @ backward branch, do periodic checks 1255 beq common_backwardBranch @ (want to use BLE but V is unknown) 1256#if defined(WITH_JIT) 1257 GET_JIT_PROF_TABLE(r0) 1258 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1259 cmp r0,#0 1260 bne common_updateProfile 1261 GET_INST_OPCODE(ip) @ extract opcode from rINST 1262 GOTO_OPCODE(ip) @ jump to next instruction 1263#else 1264 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1265 GET_INST_OPCODE(ip) @ extract opcode from rINST 1266 GOTO_OPCODE(ip) @ jump to next instruction 1267#endif 1268 1269 1270/* ------------------------------ */ 1271 .balign 64 1272.L_OP_CMPL_FLOAT: /* 0x2d */ 1273/* File: armv5te/OP_CMPL_FLOAT.S */ 1274 /* 1275 * Compare two floating-point values. Puts 0, 1, or -1 into the 1276 * destination register based on the results of the comparison. 1277 * 1278 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending 1279 * on what value we'd like to return when one of the operands is NaN. 1280 * 1281 * The operation we're implementing is: 1282 * if (x == y) 1283 * return 0; 1284 * else if (x < y) 1285 * return -1; 1286 * else if (x > y) 1287 * return 1; 1288 * else 1289 * return {-1,1}; // one or both operands was NaN 1290 * 1291 * The straightforward implementation requires 3 calls to functions 1292 * that return a result in r0. We can do it with two calls if our 1293 * EABI library supports __aeabi_cfcmple (only one if we want to check 1294 * for NaN directly): 1295 * check x <= y 1296 * if <, return -1 1297 * if ==, return 0 1298 * check y <= x 1299 * if <, return 1 1300 * return {-1,1} 1301 * 1302 * for: cmpl-float, cmpg-float 1303 */ 1304 /* op vAA, vBB, vCC */ 1305 FETCH(r0, 1) @ r0<- CCBB 1306 and r2, r0, #255 @ r2<- BB 1307 mov r3, r0, lsr #8 @ r3<- CC 1308 GET_VREG(r9, r2) @ r9<- vBB 1309 GET_VREG(r10, r3) @ r10<- vCC 1310 mov r0, r9 @ copy to arg registers 1311 mov r1, r10 1312 bl __aeabi_cfcmple @ cmp <=: C clear if <, Z set if eq 1313 bhi .LOP_CMPL_FLOAT_gt_or_nan @ C set and Z clear, disambiguate 1314 mvncc r1, #0 @ (less than) r1<- -1 1315 moveq r1, #0 @ (equal) r1<- 0, trumps less than 1316.LOP_CMPL_FLOAT_finish: 1317 mov r3, rINST, lsr #8 @ r3<- AA 1318 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1319 SET_VREG(r1, r3) @ vAA<- r1 1320 GET_INST_OPCODE(ip) @ extract opcode from rINST 1321 GOTO_OPCODE(ip) @ jump to next instruction 1322 1323/* ------------------------------ */ 1324 .balign 64 1325.L_OP_CMPG_FLOAT: /* 0x2e */ 1326/* File: armv5te/OP_CMPG_FLOAT.S */ 1327/* File: armv5te/OP_CMPL_FLOAT.S */ 1328 /* 1329 * Compare two floating-point values. Puts 0, 1, or -1 into the 1330 * destination register based on the results of the comparison. 1331 * 1332 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending 1333 * on what value we'd like to return when one of the operands is NaN. 1334 * 1335 * The operation we're implementing is: 1336 * if (x == y) 1337 * return 0; 1338 * else if (x < y) 1339 * return -1; 1340 * else if (x > y) 1341 * return 1; 1342 * else 1343 * return {-1,1}; // one or both operands was NaN 1344 * 1345 * The straightforward implementation requires 3 calls to functions 1346 * that return a result in r0. We can do it with two calls if our 1347 * EABI library supports __aeabi_cfcmple (only one if we want to check 1348 * for NaN directly): 1349 * check x <= y 1350 * if <, return -1 1351 * if ==, return 0 1352 * check y <= x 1353 * if <, return 1 1354 * return {-1,1} 1355 * 1356 * for: cmpl-float, cmpg-float 1357 */ 1358 /* op vAA, vBB, vCC */ 1359 FETCH(r0, 1) @ r0<- CCBB 1360 and r2, r0, #255 @ r2<- BB 1361 mov r3, r0, lsr #8 @ r3<- CC 1362 GET_VREG(r9, r2) @ r9<- vBB 1363 GET_VREG(r10, r3) @ r10<- vCC 1364 mov r0, r9 @ copy to arg registers 1365 mov r1, r10 1366 bl __aeabi_cfcmple @ cmp <=: C clear if <, Z set if eq 1367 bhi .LOP_CMPG_FLOAT_gt_or_nan @ C set and Z clear, disambiguate 1368 mvncc r1, #0 @ (less than) r1<- -1 1369 moveq r1, #0 @ (equal) r1<- 0, trumps less than 1370.LOP_CMPG_FLOAT_finish: 1371 mov r3, rINST, lsr #8 @ r3<- AA 1372 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1373 SET_VREG(r1, r3) @ vAA<- r1 1374 GET_INST_OPCODE(ip) @ extract opcode from rINST 1375 GOTO_OPCODE(ip) @ jump to next instruction 1376 1377 1378/* ------------------------------ */ 1379 .balign 64 1380.L_OP_CMPL_DOUBLE: /* 0x2f */ 1381/* File: armv5te/OP_CMPL_DOUBLE.S */ 1382 /* 1383 * Compare two floating-point values. Puts 0, 1, or -1 into the 1384 * destination register based on the results of the comparison. 1385 * 1386 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending 1387 * on what value we'd like to return when one of the operands is NaN. 1388 * 1389 * See OP_CMPL_FLOAT for an explanation. 1390 * 1391 * For: cmpl-double, cmpg-double 1392 */ 1393 /* op vAA, vBB, vCC */ 1394 FETCH(r0, 1) @ r0<- CCBB 1395 and r9, r0, #255 @ r9<- BB 1396 mov r10, r0, lsr #8 @ r10<- CC 1397 add r9, rFP, r9, lsl #2 @ r9<- &fp[BB] 1398 add r10, rFP, r10, lsl #2 @ r10<- &fp[CC] 1399 ldmia r9, {r0-r1} @ r0/r1<- vBB/vBB+1 1400 ldmia r10, {r2-r3} @ r2/r3<- vCC/vCC+1 1401 bl __aeabi_cdcmple @ cmp <=: C clear if <, Z set if eq 1402 bhi .LOP_CMPL_DOUBLE_gt_or_nan @ C set and Z clear, disambiguate 1403 mvncc r1, #0 @ (less than) r1<- -1 1404 moveq r1, #0 @ (equal) r1<- 0, trumps less than 1405.LOP_CMPL_DOUBLE_finish: 1406 mov r3, rINST, lsr #8 @ r3<- AA 1407 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1408 SET_VREG(r1, r3) @ vAA<- r1 1409 GET_INST_OPCODE(ip) @ extract opcode from rINST 1410 GOTO_OPCODE(ip) @ jump to next instruction 1411 1412/* ------------------------------ */ 1413 .balign 64 1414.L_OP_CMPG_DOUBLE: /* 0x30 */ 1415/* File: armv5te/OP_CMPG_DOUBLE.S */ 1416/* File: armv5te/OP_CMPL_DOUBLE.S */ 1417 /* 1418 * Compare two floating-point values. Puts 0, 1, or -1 into the 1419 * destination register based on the results of the comparison. 1420 * 1421 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending 1422 * on what value we'd like to return when one of the operands is NaN. 1423 * 1424 * See OP_CMPL_FLOAT for an explanation. 1425 * 1426 * For: cmpl-double, cmpg-double 1427 */ 1428 /* op vAA, vBB, vCC */ 1429 FETCH(r0, 1) @ r0<- CCBB 1430 and r9, r0, #255 @ r9<- BB 1431 mov r10, r0, lsr #8 @ r10<- CC 1432 add r9, rFP, r9, lsl #2 @ r9<- &fp[BB] 1433 add r10, rFP, r10, lsl #2 @ r10<- &fp[CC] 1434 ldmia r9, {r0-r1} @ r0/r1<- vBB/vBB+1 1435 ldmia r10, {r2-r3} @ r2/r3<- vCC/vCC+1 1436 bl __aeabi_cdcmple @ cmp <=: C clear if <, Z set if eq 1437 bhi .LOP_CMPG_DOUBLE_gt_or_nan @ C set and Z clear, disambiguate 1438 mvncc r1, #0 @ (less than) r1<- -1 1439 moveq r1, #0 @ (equal) r1<- 0, trumps less than 1440.LOP_CMPG_DOUBLE_finish: 1441 mov r3, rINST, lsr #8 @ r3<- AA 1442 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1443 SET_VREG(r1, r3) @ vAA<- r1 1444 GET_INST_OPCODE(ip) @ extract opcode from rINST 1445 GOTO_OPCODE(ip) @ jump to next instruction 1446 1447 1448/* ------------------------------ */ 1449 .balign 64 1450.L_OP_CMP_LONG: /* 0x31 */ 1451/* File: armv5te/OP_CMP_LONG.S */ 1452 /* 1453 * Compare two 64-bit values. Puts 0, 1, or -1 into the destination 1454 * register based on the results of the comparison. 1455 * 1456 * We load the full values with LDM, but in practice many values could 1457 * be resolved by only looking at the high word. This could be made 1458 * faster or slower by splitting the LDM into a pair of LDRs. 1459 * 1460 * If we just wanted to set condition flags, we could do this: 1461 * subs ip, r0, r2 1462 * sbcs ip, r1, r3 1463 * subeqs ip, r0, r2 1464 * Leaving { <0, 0, >0 } in ip. However, we have to set it to a specific 1465 * integer value, which we can do with 2 conditional mov/mvn instructions 1466 * (set 1, set -1; if they're equal we already have 0 in ip), giving 1467 * us a constant 5-cycle path plus a branch at the end to the 1468 * instruction epilogue code. The multi-compare approach below needs 1469 * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch 1470 * in the worst case (the 64-bit values are equal). 1471 */ 1472 /* cmp-long vAA, vBB, vCC */ 1473 FETCH(r0, 1) @ r0<- CCBB 1474 mov r9, rINST, lsr #8 @ r9<- AA 1475 and r2, r0, #255 @ r2<- BB 1476 mov r3, r0, lsr #8 @ r3<- CC 1477 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 1478 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 1479 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 1480 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 1481 cmp r1, r3 @ compare (vBB+1, vCC+1) 1482 blt .LOP_CMP_LONG_less @ signed compare on high part 1483 bgt .LOP_CMP_LONG_greater 1484 subs r1, r0, r2 @ r1<- r0 - r2 1485 bhi .LOP_CMP_LONG_greater @ unsigned compare on low part 1486 bne .LOP_CMP_LONG_less 1487 b .LOP_CMP_LONG_finish @ equal; r1 already holds 0 1488 1489/* ------------------------------ */ 1490 .balign 64 1491.L_OP_IF_EQ: /* 0x32 */ 1492/* File: armv5te/OP_IF_EQ.S */ 1493/* File: armv5te/bincmp.S */ 1494 /* 1495 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1496 * fragment that specifies the *reverse* comparison to perform, e.g. 1497 * for "if-le" you would use "gt". 1498 * 1499 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1500 */ 1501 /* if-cmp vA, vB, +CCCC */ 1502 mov r0, rINST, lsr #8 @ r0<- A+ 1503 mov r1, rINST, lsr #12 @ r1<- B 1504 and r0, r0, #15 1505 GET_VREG(r3, r1) @ r3<- vB 1506 GET_VREG(r2, r0) @ r2<- vA 1507 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1508 cmp r2, r3 @ compare (vA, vB) 1509 bne 1f @ branch to 1 if comparison failed 1510 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1511 movs r9, r9, asl #1 @ convert to bytes, check sign 1512 bmi common_backwardBranch @ yes, do periodic checks 15131: 1514#if defined(WITH_JIT) 1515 GET_JIT_PROF_TABLE(r0) 1516 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1517 b common_testUpdateProfile 1518#else 1519 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1520 GET_INST_OPCODE(ip) @ extract opcode from rINST 1521 GOTO_OPCODE(ip) @ jump to next instruction 1522#endif 1523 1524 1525/* ------------------------------ */ 1526 .balign 64 1527.L_OP_IF_NE: /* 0x33 */ 1528/* File: armv5te/OP_IF_NE.S */ 1529/* File: armv5te/bincmp.S */ 1530 /* 1531 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1532 * fragment that specifies the *reverse* comparison to perform, e.g. 1533 * for "if-le" you would use "gt". 1534 * 1535 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1536 */ 1537 /* if-cmp vA, vB, +CCCC */ 1538 mov r0, rINST, lsr #8 @ r0<- A+ 1539 mov r1, rINST, lsr #12 @ r1<- B 1540 and r0, r0, #15 1541 GET_VREG(r3, r1) @ r3<- vB 1542 GET_VREG(r2, r0) @ r2<- vA 1543 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1544 cmp r2, r3 @ compare (vA, vB) 1545 beq 1f @ branch to 1 if comparison failed 1546 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1547 movs r9, r9, asl #1 @ convert to bytes, check sign 1548 bmi common_backwardBranch @ yes, do periodic checks 15491: 1550#if defined(WITH_JIT) 1551 GET_JIT_PROF_TABLE(r0) 1552 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1553 b common_testUpdateProfile 1554#else 1555 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1556 GET_INST_OPCODE(ip) @ extract opcode from rINST 1557 GOTO_OPCODE(ip) @ jump to next instruction 1558#endif 1559 1560 1561/* ------------------------------ */ 1562 .balign 64 1563.L_OP_IF_LT: /* 0x34 */ 1564/* File: armv5te/OP_IF_LT.S */ 1565/* File: armv5te/bincmp.S */ 1566 /* 1567 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1568 * fragment that specifies the *reverse* comparison to perform, e.g. 1569 * for "if-le" you would use "gt". 1570 * 1571 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1572 */ 1573 /* if-cmp vA, vB, +CCCC */ 1574 mov r0, rINST, lsr #8 @ r0<- A+ 1575 mov r1, rINST, lsr #12 @ r1<- B 1576 and r0, r0, #15 1577 GET_VREG(r3, r1) @ r3<- vB 1578 GET_VREG(r2, r0) @ r2<- vA 1579 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1580 cmp r2, r3 @ compare (vA, vB) 1581 bge 1f @ branch to 1 if comparison failed 1582 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1583 movs r9, r9, asl #1 @ convert to bytes, check sign 1584 bmi common_backwardBranch @ yes, do periodic checks 15851: 1586#if defined(WITH_JIT) 1587 GET_JIT_PROF_TABLE(r0) 1588 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1589 b common_testUpdateProfile 1590#else 1591 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1592 GET_INST_OPCODE(ip) @ extract opcode from rINST 1593 GOTO_OPCODE(ip) @ jump to next instruction 1594#endif 1595 1596 1597/* ------------------------------ */ 1598 .balign 64 1599.L_OP_IF_GE: /* 0x35 */ 1600/* File: armv5te/OP_IF_GE.S */ 1601/* File: armv5te/bincmp.S */ 1602 /* 1603 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1604 * fragment that specifies the *reverse* comparison to perform, e.g. 1605 * for "if-le" you would use "gt". 1606 * 1607 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1608 */ 1609 /* if-cmp vA, vB, +CCCC */ 1610 mov r0, rINST, lsr #8 @ r0<- A+ 1611 mov r1, rINST, lsr #12 @ r1<- B 1612 and r0, r0, #15 1613 GET_VREG(r3, r1) @ r3<- vB 1614 GET_VREG(r2, r0) @ r2<- vA 1615 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1616 cmp r2, r3 @ compare (vA, vB) 1617 blt 1f @ branch to 1 if comparison failed 1618 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1619 movs r9, r9, asl #1 @ convert to bytes, check sign 1620 bmi common_backwardBranch @ yes, do periodic checks 16211: 1622#if defined(WITH_JIT) 1623 GET_JIT_PROF_TABLE(r0) 1624 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1625 b common_testUpdateProfile 1626#else 1627 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1628 GET_INST_OPCODE(ip) @ extract opcode from rINST 1629 GOTO_OPCODE(ip) @ jump to next instruction 1630#endif 1631 1632 1633/* ------------------------------ */ 1634 .balign 64 1635.L_OP_IF_GT: /* 0x36 */ 1636/* File: armv5te/OP_IF_GT.S */ 1637/* File: armv5te/bincmp.S */ 1638 /* 1639 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1640 * fragment that specifies the *reverse* comparison to perform, e.g. 1641 * for "if-le" you would use "gt". 1642 * 1643 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1644 */ 1645 /* if-cmp vA, vB, +CCCC */ 1646 mov r0, rINST, lsr #8 @ r0<- A+ 1647 mov r1, rINST, lsr #12 @ r1<- B 1648 and r0, r0, #15 1649 GET_VREG(r3, r1) @ r3<- vB 1650 GET_VREG(r2, r0) @ r2<- vA 1651 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1652 cmp r2, r3 @ compare (vA, vB) 1653 ble 1f @ branch to 1 if comparison failed 1654 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1655 movs r9, r9, asl #1 @ convert to bytes, check sign 1656 bmi common_backwardBranch @ yes, do periodic checks 16571: 1658#if defined(WITH_JIT) 1659 GET_JIT_PROF_TABLE(r0) 1660 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1661 b common_testUpdateProfile 1662#else 1663 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1664 GET_INST_OPCODE(ip) @ extract opcode from rINST 1665 GOTO_OPCODE(ip) @ jump to next instruction 1666#endif 1667 1668 1669/* ------------------------------ */ 1670 .balign 64 1671.L_OP_IF_LE: /* 0x37 */ 1672/* File: armv5te/OP_IF_LE.S */ 1673/* File: armv5te/bincmp.S */ 1674 /* 1675 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1676 * fragment that specifies the *reverse* comparison to perform, e.g. 1677 * for "if-le" you would use "gt". 1678 * 1679 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1680 */ 1681 /* if-cmp vA, vB, +CCCC */ 1682 mov r0, rINST, lsr #8 @ r0<- A+ 1683 mov r1, rINST, lsr #12 @ r1<- B 1684 and r0, r0, #15 1685 GET_VREG(r3, r1) @ r3<- vB 1686 GET_VREG(r2, r0) @ r2<- vA 1687 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1688 cmp r2, r3 @ compare (vA, vB) 1689 bgt 1f @ branch to 1 if comparison failed 1690 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1691 movs r9, r9, asl #1 @ convert to bytes, check sign 1692 bmi common_backwardBranch @ yes, do periodic checks 16931: 1694#if defined(WITH_JIT) 1695 GET_JIT_PROF_TABLE(r0) 1696 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1697 b common_testUpdateProfile 1698#else 1699 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1700 GET_INST_OPCODE(ip) @ extract opcode from rINST 1701 GOTO_OPCODE(ip) @ jump to next instruction 1702#endif 1703 1704 1705/* ------------------------------ */ 1706 .balign 64 1707.L_OP_IF_EQZ: /* 0x38 */ 1708/* File: armv5te/OP_IF_EQZ.S */ 1709/* File: armv5te/zcmp.S */ 1710 /* 1711 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1712 * fragment that specifies the *reverse* comparison to perform, e.g. 1713 * for "if-le" you would use "gt". 1714 * 1715 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1716 */ 1717 /* if-cmp vAA, +BBBB */ 1718 mov r0, rINST, lsr #8 @ r0<- AA 1719 GET_VREG(r2, r0) @ r2<- vAA 1720 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1721 cmp r2, #0 @ compare (vA, 0) 1722 bne 1f @ branch to 1 if comparison failed 1723 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1724 movs r9, r9, asl #1 @ convert to bytes, check sign 1725 bmi common_backwardBranch @ backward branch, do periodic checks 17261: 1727#if defined(WITH_JIT) 1728 GET_JIT_PROF_TABLE(r0) 1729 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1730 cmp r0,#0 1731 bne common_updateProfile 1732 GET_INST_OPCODE(ip) @ extract opcode from rINST 1733 GOTO_OPCODE(ip) @ jump to next instruction 1734#else 1735 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1736 GET_INST_OPCODE(ip) @ extract opcode from rINST 1737 GOTO_OPCODE(ip) @ jump to next instruction 1738#endif 1739 1740 1741/* ------------------------------ */ 1742 .balign 64 1743.L_OP_IF_NEZ: /* 0x39 */ 1744/* File: armv5te/OP_IF_NEZ.S */ 1745/* File: armv5te/zcmp.S */ 1746 /* 1747 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1748 * fragment that specifies the *reverse* comparison to perform, e.g. 1749 * for "if-le" you would use "gt". 1750 * 1751 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1752 */ 1753 /* if-cmp vAA, +BBBB */ 1754 mov r0, rINST, lsr #8 @ r0<- AA 1755 GET_VREG(r2, r0) @ r2<- vAA 1756 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1757 cmp r2, #0 @ compare (vA, 0) 1758 beq 1f @ branch to 1 if comparison failed 1759 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1760 movs r9, r9, asl #1 @ convert to bytes, check sign 1761 bmi common_backwardBranch @ backward branch, do periodic checks 17621: 1763#if defined(WITH_JIT) 1764 GET_JIT_PROF_TABLE(r0) 1765 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1766 cmp r0,#0 1767 bne common_updateProfile 1768 GET_INST_OPCODE(ip) @ extract opcode from rINST 1769 GOTO_OPCODE(ip) @ jump to next instruction 1770#else 1771 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1772 GET_INST_OPCODE(ip) @ extract opcode from rINST 1773 GOTO_OPCODE(ip) @ jump to next instruction 1774#endif 1775 1776 1777/* ------------------------------ */ 1778 .balign 64 1779.L_OP_IF_LTZ: /* 0x3a */ 1780/* File: armv5te/OP_IF_LTZ.S */ 1781/* File: armv5te/zcmp.S */ 1782 /* 1783 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1784 * fragment that specifies the *reverse* comparison to perform, e.g. 1785 * for "if-le" you would use "gt". 1786 * 1787 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1788 */ 1789 /* if-cmp vAA, +BBBB */ 1790 mov r0, rINST, lsr #8 @ r0<- AA 1791 GET_VREG(r2, r0) @ r2<- vAA 1792 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1793 cmp r2, #0 @ compare (vA, 0) 1794 bge 1f @ branch to 1 if comparison failed 1795 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1796 movs r9, r9, asl #1 @ convert to bytes, check sign 1797 bmi common_backwardBranch @ backward branch, do periodic checks 17981: 1799#if defined(WITH_JIT) 1800 GET_JIT_PROF_TABLE(r0) 1801 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1802 cmp r0,#0 1803 bne common_updateProfile 1804 GET_INST_OPCODE(ip) @ extract opcode from rINST 1805 GOTO_OPCODE(ip) @ jump to next instruction 1806#else 1807 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1808 GET_INST_OPCODE(ip) @ extract opcode from rINST 1809 GOTO_OPCODE(ip) @ jump to next instruction 1810#endif 1811 1812 1813/* ------------------------------ */ 1814 .balign 64 1815.L_OP_IF_GEZ: /* 0x3b */ 1816/* File: armv5te/OP_IF_GEZ.S */ 1817/* File: armv5te/zcmp.S */ 1818 /* 1819 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1820 * fragment that specifies the *reverse* comparison to perform, e.g. 1821 * for "if-le" you would use "gt". 1822 * 1823 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1824 */ 1825 /* if-cmp vAA, +BBBB */ 1826 mov r0, rINST, lsr #8 @ r0<- AA 1827 GET_VREG(r2, r0) @ r2<- vAA 1828 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1829 cmp r2, #0 @ compare (vA, 0) 1830 blt 1f @ branch to 1 if comparison failed 1831 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1832 movs r9, r9, asl #1 @ convert to bytes, check sign 1833 bmi common_backwardBranch @ backward branch, do periodic checks 18341: 1835#if defined(WITH_JIT) 1836 GET_JIT_PROF_TABLE(r0) 1837 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1838 cmp r0,#0 1839 bne common_updateProfile 1840 GET_INST_OPCODE(ip) @ extract opcode from rINST 1841 GOTO_OPCODE(ip) @ jump to next instruction 1842#else 1843 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1844 GET_INST_OPCODE(ip) @ extract opcode from rINST 1845 GOTO_OPCODE(ip) @ jump to next instruction 1846#endif 1847 1848 1849/* ------------------------------ */ 1850 .balign 64 1851.L_OP_IF_GTZ: /* 0x3c */ 1852/* File: armv5te/OP_IF_GTZ.S */ 1853/* File: armv5te/zcmp.S */ 1854 /* 1855 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1856 * fragment that specifies the *reverse* comparison to perform, e.g. 1857 * for "if-le" you would use "gt". 1858 * 1859 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1860 */ 1861 /* if-cmp vAA, +BBBB */ 1862 mov r0, rINST, lsr #8 @ r0<- AA 1863 GET_VREG(r2, r0) @ r2<- vAA 1864 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1865 cmp r2, #0 @ compare (vA, 0) 1866 ble 1f @ branch to 1 if comparison failed 1867 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1868 movs r9, r9, asl #1 @ convert to bytes, check sign 1869 bmi common_backwardBranch @ backward branch, do periodic checks 18701: 1871#if defined(WITH_JIT) 1872 GET_JIT_PROF_TABLE(r0) 1873 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1874 cmp r0,#0 1875 bne common_updateProfile 1876 GET_INST_OPCODE(ip) @ extract opcode from rINST 1877 GOTO_OPCODE(ip) @ jump to next instruction 1878#else 1879 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1880 GET_INST_OPCODE(ip) @ extract opcode from rINST 1881 GOTO_OPCODE(ip) @ jump to next instruction 1882#endif 1883 1884 1885/* ------------------------------ */ 1886 .balign 64 1887.L_OP_IF_LEZ: /* 0x3d */ 1888/* File: armv5te/OP_IF_LEZ.S */ 1889/* File: armv5te/zcmp.S */ 1890 /* 1891 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1892 * fragment that specifies the *reverse* comparison to perform, e.g. 1893 * for "if-le" you would use "gt". 1894 * 1895 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1896 */ 1897 /* if-cmp vAA, +BBBB */ 1898 mov r0, rINST, lsr #8 @ r0<- AA 1899 GET_VREG(r2, r0) @ r2<- vAA 1900 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1901 cmp r2, #0 @ compare (vA, 0) 1902 bgt 1f @ branch to 1 if comparison failed 1903 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1904 movs r9, r9, asl #1 @ convert to bytes, check sign 1905 bmi common_backwardBranch @ backward branch, do periodic checks 19061: 1907#if defined(WITH_JIT) 1908 GET_JIT_PROF_TABLE(r0) 1909 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1910 cmp r0,#0 1911 bne common_updateProfile 1912 GET_INST_OPCODE(ip) @ extract opcode from rINST 1913 GOTO_OPCODE(ip) @ jump to next instruction 1914#else 1915 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1916 GET_INST_OPCODE(ip) @ extract opcode from rINST 1917 GOTO_OPCODE(ip) @ jump to next instruction 1918#endif 1919 1920 1921/* ------------------------------ */ 1922 .balign 64 1923.L_OP_UNUSED_3E: /* 0x3e */ 1924/* File: armv5te/OP_UNUSED_3E.S */ 1925/* File: armv5te/unused.S */ 1926 bl common_abort 1927 1928 1929/* ------------------------------ */ 1930 .balign 64 1931.L_OP_UNUSED_3F: /* 0x3f */ 1932/* File: armv5te/OP_UNUSED_3F.S */ 1933/* File: armv5te/unused.S */ 1934 bl common_abort 1935 1936 1937/* ------------------------------ */ 1938 .balign 64 1939.L_OP_UNUSED_40: /* 0x40 */ 1940/* File: armv5te/OP_UNUSED_40.S */ 1941/* File: armv5te/unused.S */ 1942 bl common_abort 1943 1944 1945/* ------------------------------ */ 1946 .balign 64 1947.L_OP_UNUSED_41: /* 0x41 */ 1948/* File: armv5te/OP_UNUSED_41.S */ 1949/* File: armv5te/unused.S */ 1950 bl common_abort 1951 1952 1953/* ------------------------------ */ 1954 .balign 64 1955.L_OP_UNUSED_42: /* 0x42 */ 1956/* File: armv5te/OP_UNUSED_42.S */ 1957/* File: armv5te/unused.S */ 1958 bl common_abort 1959 1960 1961/* ------------------------------ */ 1962 .balign 64 1963.L_OP_UNUSED_43: /* 0x43 */ 1964/* File: armv5te/OP_UNUSED_43.S */ 1965/* File: armv5te/unused.S */ 1966 bl common_abort 1967 1968 1969/* ------------------------------ */ 1970 .balign 64 1971.L_OP_AGET: /* 0x44 */ 1972/* File: armv5te/OP_AGET.S */ 1973 /* 1974 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1975 * 1976 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1977 * instructions. We use a pair of FETCH_Bs instead. 1978 * 1979 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1980 */ 1981 /* op vAA, vBB, vCC */ 1982 FETCH_B(r2, 1, 0) @ r2<- BB 1983 mov r9, rINST, lsr #8 @ r9<- AA 1984 FETCH_B(r3, 1, 1) @ r3<- CC 1985 GET_VREG(r0, r2) @ r0<- vBB (array object) 1986 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1987 cmp r0, #0 @ null array object? 1988 beq common_errNullObject @ yes, bail 1989 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1990 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 1991 cmp r1, r3 @ compare unsigned index, length 1992 bcs common_errArrayIndex @ index >= length, bail 1993 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1994 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 1995 GET_INST_OPCODE(ip) @ extract opcode from rINST 1996 SET_VREG(r2, r9) @ vAA<- r2 1997 GOTO_OPCODE(ip) @ jump to next instruction 1998 1999/* ------------------------------ */ 2000 .balign 64 2001.L_OP_AGET_WIDE: /* 0x45 */ 2002/* File: armv5te/OP_AGET_WIDE.S */ 2003 /* 2004 * Array get, 64 bits. vAA <- vBB[vCC]. 2005 * 2006 * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD. 2007 */ 2008 /* aget-wide vAA, vBB, vCC */ 2009 FETCH(r0, 1) @ r0<- CCBB 2010 mov r9, rINST, lsr #8 @ r9<- AA 2011 and r2, r0, #255 @ r2<- BB 2012 mov r3, r0, lsr #8 @ r3<- CC 2013 GET_VREG(r0, r2) @ r0<- vBB (array object) 2014 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2015 cmp r0, #0 @ null array object? 2016 beq common_errNullObject @ yes, bail 2017 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2018 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 2019 cmp r1, r3 @ compare unsigned index, length 2020 bcc .LOP_AGET_WIDE_finish @ okay, continue below 2021 b common_errArrayIndex @ index >= length, bail 2022 @ May want to swap the order of these two branches depending on how the 2023 @ branch prediction (if any) handles conditional forward branches vs. 2024 @ unconditional forward branches. 2025 2026/* ------------------------------ */ 2027 .balign 64 2028.L_OP_AGET_OBJECT: /* 0x46 */ 2029/* File: armv5te/OP_AGET_OBJECT.S */ 2030/* File: armv5te/OP_AGET.S */ 2031 /* 2032 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2033 * 2034 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2035 * instructions. We use a pair of FETCH_Bs instead. 2036 * 2037 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2038 */ 2039 /* op vAA, vBB, vCC */ 2040 FETCH_B(r2, 1, 0) @ r2<- BB 2041 mov r9, rINST, lsr #8 @ r9<- AA 2042 FETCH_B(r3, 1, 1) @ r3<- CC 2043 GET_VREG(r0, r2) @ r0<- vBB (array object) 2044 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2045 cmp r0, #0 @ null array object? 2046 beq common_errNullObject @ yes, bail 2047 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2048 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 2049 cmp r1, r3 @ compare unsigned index, length 2050 bcs common_errArrayIndex @ index >= length, bail 2051 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2052 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2053 GET_INST_OPCODE(ip) @ extract opcode from rINST 2054 SET_VREG(r2, r9) @ vAA<- r2 2055 GOTO_OPCODE(ip) @ jump to next instruction 2056 2057 2058/* ------------------------------ */ 2059 .balign 64 2060.L_OP_AGET_BOOLEAN: /* 0x47 */ 2061/* File: armv5te/OP_AGET_BOOLEAN.S */ 2062/* File: armv5te/OP_AGET.S */ 2063 /* 2064 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2065 * 2066 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2067 * instructions. We use a pair of FETCH_Bs instead. 2068 * 2069 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2070 */ 2071 /* op vAA, vBB, vCC */ 2072 FETCH_B(r2, 1, 0) @ r2<- BB 2073 mov r9, rINST, lsr #8 @ r9<- AA 2074 FETCH_B(r3, 1, 1) @ r3<- CC 2075 GET_VREG(r0, r2) @ r0<- vBB (array object) 2076 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2077 cmp r0, #0 @ null array object? 2078 beq common_errNullObject @ yes, bail 2079 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2080 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2081 cmp r1, r3 @ compare unsigned index, length 2082 bcs common_errArrayIndex @ index >= length, bail 2083 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2084 ldrb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2085 GET_INST_OPCODE(ip) @ extract opcode from rINST 2086 SET_VREG(r2, r9) @ vAA<- r2 2087 GOTO_OPCODE(ip) @ jump to next instruction 2088 2089 2090/* ------------------------------ */ 2091 .balign 64 2092.L_OP_AGET_BYTE: /* 0x48 */ 2093/* File: armv5te/OP_AGET_BYTE.S */ 2094/* File: armv5te/OP_AGET.S */ 2095 /* 2096 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2097 * 2098 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2099 * instructions. We use a pair of FETCH_Bs instead. 2100 * 2101 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2102 */ 2103 /* op vAA, vBB, vCC */ 2104 FETCH_B(r2, 1, 0) @ r2<- BB 2105 mov r9, rINST, lsr #8 @ r9<- AA 2106 FETCH_B(r3, 1, 1) @ r3<- CC 2107 GET_VREG(r0, r2) @ r0<- vBB (array object) 2108 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2109 cmp r0, #0 @ null array object? 2110 beq common_errNullObject @ yes, bail 2111 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2112 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2113 cmp r1, r3 @ compare unsigned index, length 2114 bcs common_errArrayIndex @ index >= length, bail 2115 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2116 ldrsb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2117 GET_INST_OPCODE(ip) @ extract opcode from rINST 2118 SET_VREG(r2, r9) @ vAA<- r2 2119 GOTO_OPCODE(ip) @ jump to next instruction 2120 2121 2122/* ------------------------------ */ 2123 .balign 64 2124.L_OP_AGET_CHAR: /* 0x49 */ 2125/* File: armv5te/OP_AGET_CHAR.S */ 2126/* File: armv5te/OP_AGET.S */ 2127 /* 2128 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2129 * 2130 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2131 * instructions. We use a pair of FETCH_Bs instead. 2132 * 2133 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2134 */ 2135 /* op vAA, vBB, vCC */ 2136 FETCH_B(r2, 1, 0) @ r2<- BB 2137 mov r9, rINST, lsr #8 @ r9<- AA 2138 FETCH_B(r3, 1, 1) @ r3<- CC 2139 GET_VREG(r0, r2) @ r0<- vBB (array object) 2140 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2141 cmp r0, #0 @ null array object? 2142 beq common_errNullObject @ yes, bail 2143 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2144 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2145 cmp r1, r3 @ compare unsigned index, length 2146 bcs common_errArrayIndex @ index >= length, bail 2147 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2148 ldrh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2149 GET_INST_OPCODE(ip) @ extract opcode from rINST 2150 SET_VREG(r2, r9) @ vAA<- r2 2151 GOTO_OPCODE(ip) @ jump to next instruction 2152 2153 2154/* ------------------------------ */ 2155 .balign 64 2156.L_OP_AGET_SHORT: /* 0x4a */ 2157/* File: armv5te/OP_AGET_SHORT.S */ 2158/* File: armv5te/OP_AGET.S */ 2159 /* 2160 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2161 * 2162 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2163 * instructions. We use a pair of FETCH_Bs instead. 2164 * 2165 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2166 */ 2167 /* op vAA, vBB, vCC */ 2168 FETCH_B(r2, 1, 0) @ r2<- BB 2169 mov r9, rINST, lsr #8 @ r9<- AA 2170 FETCH_B(r3, 1, 1) @ r3<- CC 2171 GET_VREG(r0, r2) @ r0<- vBB (array object) 2172 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2173 cmp r0, #0 @ null array object? 2174 beq common_errNullObject @ yes, bail 2175 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2176 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2177 cmp r1, r3 @ compare unsigned index, length 2178 bcs common_errArrayIndex @ index >= length, bail 2179 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2180 ldrsh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2181 GET_INST_OPCODE(ip) @ extract opcode from rINST 2182 SET_VREG(r2, r9) @ vAA<- r2 2183 GOTO_OPCODE(ip) @ jump to next instruction 2184 2185 2186/* ------------------------------ */ 2187 .balign 64 2188.L_OP_APUT: /* 0x4b */ 2189/* File: armv5te/OP_APUT.S */ 2190 /* 2191 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2192 * 2193 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2194 * instructions. We use a pair of FETCH_Bs instead. 2195 * 2196 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2197 */ 2198 /* op vAA, vBB, vCC */ 2199 FETCH_B(r2, 1, 0) @ r2<- BB 2200 mov r9, rINST, lsr #8 @ r9<- AA 2201 FETCH_B(r3, 1, 1) @ r3<- CC 2202 GET_VREG(r0, r2) @ r0<- vBB (array object) 2203 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2204 cmp r0, #0 @ null array object? 2205 beq common_errNullObject @ yes, bail 2206 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2207 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 2208 cmp r1, r3 @ compare unsigned index, length 2209 bcs common_errArrayIndex @ index >= length, bail 2210 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2211 GET_VREG(r2, r9) @ r2<- vAA 2212 GET_INST_OPCODE(ip) @ extract opcode from rINST 2213 str r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2214 GOTO_OPCODE(ip) @ jump to next instruction 2215 2216/* ------------------------------ */ 2217 .balign 64 2218.L_OP_APUT_WIDE: /* 0x4c */ 2219/* File: armv5te/OP_APUT_WIDE.S */ 2220 /* 2221 * Array put, 64 bits. vBB[vCC] <- vAA. 2222 * 2223 * Arrays of long/double are 64-bit aligned, so it's okay to use STRD. 2224 */ 2225 /* aput-wide vAA, vBB, vCC */ 2226 FETCH(r0, 1) @ r0<- CCBB 2227 mov r9, rINST, lsr #8 @ r9<- AA 2228 and r2, r0, #255 @ r2<- BB 2229 mov r3, r0, lsr #8 @ r3<- CC 2230 GET_VREG(r0, r2) @ r0<- vBB (array object) 2231 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2232 cmp r0, #0 @ null array object? 2233 beq common_errNullObject @ yes, bail 2234 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2235 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 2236 cmp r1, r3 @ compare unsigned index, length 2237 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2238 bcc .LOP_APUT_WIDE_finish @ okay, continue below 2239 b common_errArrayIndex @ index >= length, bail 2240 @ May want to swap the order of these two branches depending on how the 2241 @ branch prediction (if any) handles conditional forward branches vs. 2242 @ unconditional forward branches. 2243 2244/* ------------------------------ */ 2245 .balign 64 2246.L_OP_APUT_OBJECT: /* 0x4d */ 2247/* File: armv5te/OP_APUT_OBJECT.S */ 2248 /* 2249 * Store an object into an array. vBB[vCC] <- vAA. 2250 */ 2251 /* op vAA, vBB, vCC */ 2252 FETCH(r0, 1) @ r0<- CCBB 2253 mov r9, rINST, lsr #8 @ r9<- AA 2254 and r2, r0, #255 @ r2<- BB 2255 mov r3, r0, lsr #8 @ r3<- CC 2256 GET_VREG(rINST, r2) @ rINST<- vBB (array object) 2257 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2258 cmp rINST, #0 @ null array object? 2259 GET_VREG(r9, r9) @ r9<- vAA 2260 beq common_errNullObject @ yes, bail 2261 ldr r3, [rINST, #offArrayObject_length] @ r3<- arrayObj->length 2262 add r10, rINST, r1, lsl #2 @ r10<- arrayObj + index*width 2263 cmp r1, r3 @ compare unsigned index, length 2264 bcc .LOP_APUT_OBJECT_finish @ we're okay, continue on 2265 b common_errArrayIndex @ index >= length, bail 2266 2267 2268/* ------------------------------ */ 2269 .balign 64 2270.L_OP_APUT_BOOLEAN: /* 0x4e */ 2271/* File: armv5te/OP_APUT_BOOLEAN.S */ 2272/* File: armv5te/OP_APUT.S */ 2273 /* 2274 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2275 * 2276 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2277 * instructions. We use a pair of FETCH_Bs instead. 2278 * 2279 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2280 */ 2281 /* op vAA, vBB, vCC */ 2282 FETCH_B(r2, 1, 0) @ r2<- BB 2283 mov r9, rINST, lsr #8 @ r9<- AA 2284 FETCH_B(r3, 1, 1) @ r3<- CC 2285 GET_VREG(r0, r2) @ r0<- vBB (array object) 2286 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2287 cmp r0, #0 @ null array object? 2288 beq common_errNullObject @ yes, bail 2289 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2290 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2291 cmp r1, r3 @ compare unsigned index, length 2292 bcs common_errArrayIndex @ index >= length, bail 2293 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2294 GET_VREG(r2, r9) @ r2<- vAA 2295 GET_INST_OPCODE(ip) @ extract opcode from rINST 2296 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2297 GOTO_OPCODE(ip) @ jump to next instruction 2298 2299 2300/* ------------------------------ */ 2301 .balign 64 2302.L_OP_APUT_BYTE: /* 0x4f */ 2303/* File: armv5te/OP_APUT_BYTE.S */ 2304/* File: armv5te/OP_APUT.S */ 2305 /* 2306 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2307 * 2308 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2309 * instructions. We use a pair of FETCH_Bs instead. 2310 * 2311 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2312 */ 2313 /* op vAA, vBB, vCC */ 2314 FETCH_B(r2, 1, 0) @ r2<- BB 2315 mov r9, rINST, lsr #8 @ r9<- AA 2316 FETCH_B(r3, 1, 1) @ r3<- CC 2317 GET_VREG(r0, r2) @ r0<- vBB (array object) 2318 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2319 cmp r0, #0 @ null array object? 2320 beq common_errNullObject @ yes, bail 2321 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2322 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2323 cmp r1, r3 @ compare unsigned index, length 2324 bcs common_errArrayIndex @ index >= length, bail 2325 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2326 GET_VREG(r2, r9) @ r2<- vAA 2327 GET_INST_OPCODE(ip) @ extract opcode from rINST 2328 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2329 GOTO_OPCODE(ip) @ jump to next instruction 2330 2331 2332/* ------------------------------ */ 2333 .balign 64 2334.L_OP_APUT_CHAR: /* 0x50 */ 2335/* File: armv5te/OP_APUT_CHAR.S */ 2336/* File: armv5te/OP_APUT.S */ 2337 /* 2338 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2339 * 2340 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2341 * instructions. We use a pair of FETCH_Bs instead. 2342 * 2343 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2344 */ 2345 /* op vAA, vBB, vCC */ 2346 FETCH_B(r2, 1, 0) @ r2<- BB 2347 mov r9, rINST, lsr #8 @ r9<- AA 2348 FETCH_B(r3, 1, 1) @ r3<- CC 2349 GET_VREG(r0, r2) @ r0<- vBB (array object) 2350 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2351 cmp r0, #0 @ null array object? 2352 beq common_errNullObject @ yes, bail 2353 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2354 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2355 cmp r1, r3 @ compare unsigned index, length 2356 bcs common_errArrayIndex @ index >= length, bail 2357 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2358 GET_VREG(r2, r9) @ r2<- vAA 2359 GET_INST_OPCODE(ip) @ extract opcode from rINST 2360 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2361 GOTO_OPCODE(ip) @ jump to next instruction 2362 2363 2364/* ------------------------------ */ 2365 .balign 64 2366.L_OP_APUT_SHORT: /* 0x51 */ 2367/* File: armv5te/OP_APUT_SHORT.S */ 2368/* File: armv5te/OP_APUT.S */ 2369 /* 2370 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2371 * 2372 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2373 * instructions. We use a pair of FETCH_Bs instead. 2374 * 2375 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2376 */ 2377 /* op vAA, vBB, vCC */ 2378 FETCH_B(r2, 1, 0) @ r2<- BB 2379 mov r9, rINST, lsr #8 @ r9<- AA 2380 FETCH_B(r3, 1, 1) @ r3<- CC 2381 GET_VREG(r0, r2) @ r0<- vBB (array object) 2382 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2383 cmp r0, #0 @ null array object? 2384 beq common_errNullObject @ yes, bail 2385 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2386 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2387 cmp r1, r3 @ compare unsigned index, length 2388 bcs common_errArrayIndex @ index >= length, bail 2389 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2390 GET_VREG(r2, r9) @ r2<- vAA 2391 GET_INST_OPCODE(ip) @ extract opcode from rINST 2392 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2393 GOTO_OPCODE(ip) @ jump to next instruction 2394 2395 2396/* ------------------------------ */ 2397 .balign 64 2398.L_OP_IGET: /* 0x52 */ 2399/* File: armv5te/OP_IGET.S */ 2400 /* 2401 * General 32-bit instance field get. 2402 * 2403 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2404 */ 2405 /* op vA, vB, field@CCCC */ 2406 mov r0, rINST, lsr #12 @ r0<- B 2407 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2408 FETCH(r1, 1) @ r1<- field ref CCCC 2409 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2410 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2411 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2412 cmp r0, #0 @ is resolved entry null? 2413 bne .LOP_IGET_finish @ no, already resolved 24148: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2415 EXPORT_PC() @ resolve() could throw 2416 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2417 bl dvmResolveInstField @ r0<- resolved InstField ptr 2418 cmp r0, #0 2419 bne .LOP_IGET_finish 2420 b common_exceptionThrown 2421 2422/* ------------------------------ */ 2423 .balign 64 2424.L_OP_IGET_WIDE: /* 0x53 */ 2425/* File: armv5te/OP_IGET_WIDE.S */ 2426 /* 2427 * Wide 32-bit instance field get. 2428 */ 2429 /* iget-wide vA, vB, field@CCCC */ 2430 mov r0, rINST, lsr #12 @ r0<- B 2431 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2432 FETCH(r1, 1) @ r1<- field ref CCCC 2433 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2434 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2435 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2436 cmp r0, #0 @ is resolved entry null? 2437 bne .LOP_IGET_WIDE_finish @ no, already resolved 24388: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2439 EXPORT_PC() @ resolve() could throw 2440 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2441 bl dvmResolveInstField @ r0<- resolved InstField ptr 2442 cmp r0, #0 2443 bne .LOP_IGET_WIDE_finish 2444 b common_exceptionThrown 2445 2446/* ------------------------------ */ 2447 .balign 64 2448.L_OP_IGET_OBJECT: /* 0x54 */ 2449/* File: armv5te/OP_IGET_OBJECT.S */ 2450/* File: armv5te/OP_IGET.S */ 2451 /* 2452 * General 32-bit instance field get. 2453 * 2454 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2455 */ 2456 /* op vA, vB, field@CCCC */ 2457 mov r0, rINST, lsr #12 @ r0<- B 2458 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2459 FETCH(r1, 1) @ r1<- field ref CCCC 2460 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2461 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2462 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2463 cmp r0, #0 @ is resolved entry null? 2464 bne .LOP_IGET_OBJECT_finish @ no, already resolved 24658: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2466 EXPORT_PC() @ resolve() could throw 2467 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2468 bl dvmResolveInstField @ r0<- resolved InstField ptr 2469 cmp r0, #0 2470 bne .LOP_IGET_OBJECT_finish 2471 b common_exceptionThrown 2472 2473 2474/* ------------------------------ */ 2475 .balign 64 2476.L_OP_IGET_BOOLEAN: /* 0x55 */ 2477/* File: armv5te/OP_IGET_BOOLEAN.S */ 2478@include "armv5te/OP_IGET.S" { "load":"ldrb", "sqnum":"1" } 2479/* File: armv5te/OP_IGET.S */ 2480 /* 2481 * General 32-bit instance field get. 2482 * 2483 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2484 */ 2485 /* op vA, vB, field@CCCC */ 2486 mov r0, rINST, lsr #12 @ r0<- B 2487 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2488 FETCH(r1, 1) @ r1<- field ref CCCC 2489 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2490 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2491 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2492 cmp r0, #0 @ is resolved entry null? 2493 bne .LOP_IGET_BOOLEAN_finish @ no, already resolved 24948: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2495 EXPORT_PC() @ resolve() could throw 2496 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2497 bl dvmResolveInstField @ r0<- resolved InstField ptr 2498 cmp r0, #0 2499 bne .LOP_IGET_BOOLEAN_finish 2500 b common_exceptionThrown 2501 2502 2503/* ------------------------------ */ 2504 .balign 64 2505.L_OP_IGET_BYTE: /* 0x56 */ 2506/* File: armv5te/OP_IGET_BYTE.S */ 2507@include "armv5te/OP_IGET.S" { "load":"ldrsb", "sqnum":"2" } 2508/* File: armv5te/OP_IGET.S */ 2509 /* 2510 * General 32-bit instance field get. 2511 * 2512 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2513 */ 2514 /* op vA, vB, field@CCCC */ 2515 mov r0, rINST, lsr #12 @ r0<- B 2516 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2517 FETCH(r1, 1) @ r1<- field ref CCCC 2518 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2519 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2520 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2521 cmp r0, #0 @ is resolved entry null? 2522 bne .LOP_IGET_BYTE_finish @ no, already resolved 25238: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2524 EXPORT_PC() @ resolve() could throw 2525 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2526 bl dvmResolveInstField @ r0<- resolved InstField ptr 2527 cmp r0, #0 2528 bne .LOP_IGET_BYTE_finish 2529 b common_exceptionThrown 2530 2531 2532/* ------------------------------ */ 2533 .balign 64 2534.L_OP_IGET_CHAR: /* 0x57 */ 2535/* File: armv5te/OP_IGET_CHAR.S */ 2536@include "armv5te/OP_IGET.S" { "load":"ldrh", "sqnum":"3" } 2537/* File: armv5te/OP_IGET.S */ 2538 /* 2539 * General 32-bit instance field get. 2540 * 2541 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2542 */ 2543 /* op vA, vB, field@CCCC */ 2544 mov r0, rINST, lsr #12 @ r0<- B 2545 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2546 FETCH(r1, 1) @ r1<- field ref CCCC 2547 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2548 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2549 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2550 cmp r0, #0 @ is resolved entry null? 2551 bne .LOP_IGET_CHAR_finish @ no, already resolved 25528: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2553 EXPORT_PC() @ resolve() could throw 2554 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2555 bl dvmResolveInstField @ r0<- resolved InstField ptr 2556 cmp r0, #0 2557 bne .LOP_IGET_CHAR_finish 2558 b common_exceptionThrown 2559 2560 2561/* ------------------------------ */ 2562 .balign 64 2563.L_OP_IGET_SHORT: /* 0x58 */ 2564/* File: armv5te/OP_IGET_SHORT.S */ 2565@include "armv5te/OP_IGET.S" { "load":"ldrsh", "sqnum":"4" } 2566/* File: armv5te/OP_IGET.S */ 2567 /* 2568 * General 32-bit instance field get. 2569 * 2570 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2571 */ 2572 /* op vA, vB, field@CCCC */ 2573 mov r0, rINST, lsr #12 @ r0<- B 2574 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2575 FETCH(r1, 1) @ r1<- field ref CCCC 2576 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2577 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2578 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2579 cmp r0, #0 @ is resolved entry null? 2580 bne .LOP_IGET_SHORT_finish @ no, already resolved 25818: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2582 EXPORT_PC() @ resolve() could throw 2583 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2584 bl dvmResolveInstField @ r0<- resolved InstField ptr 2585 cmp r0, #0 2586 bne .LOP_IGET_SHORT_finish 2587 b common_exceptionThrown 2588 2589 2590/* ------------------------------ */ 2591 .balign 64 2592.L_OP_IPUT: /* 0x59 */ 2593/* File: armv5te/OP_IPUT.S */ 2594 /* 2595 * General 32-bit instance field put. 2596 * 2597 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2598 */ 2599 /* op vA, vB, field@CCCC */ 2600 mov r0, rINST, lsr #12 @ r0<- B 2601 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2602 FETCH(r1, 1) @ r1<- field ref CCCC 2603 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2604 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2605 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2606 cmp r0, #0 @ is resolved entry null? 2607 bne .LOP_IPUT_finish @ no, already resolved 26088: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2609 EXPORT_PC() @ resolve() could throw 2610 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2611 bl dvmResolveInstField @ r0<- resolved InstField ptr 2612 cmp r0, #0 @ success? 2613 bne .LOP_IPUT_finish @ yes, finish up 2614 b common_exceptionThrown 2615 2616/* ------------------------------ */ 2617 .balign 64 2618.L_OP_IPUT_WIDE: /* 0x5a */ 2619/* File: armv5te/OP_IPUT_WIDE.S */ 2620 /* iput-wide vA, vB, field@CCCC */ 2621 mov r0, rINST, lsr #12 @ r0<- B 2622 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2623 FETCH(r1, 1) @ r1<- field ref CCCC 2624 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2625 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2626 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2627 cmp r0, #0 @ is resolved entry null? 2628 bne .LOP_IPUT_WIDE_finish @ no, already resolved 26298: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2630 EXPORT_PC() @ resolve() could throw 2631 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2632 bl dvmResolveInstField @ r0<- resolved InstField ptr 2633 cmp r0, #0 @ success? 2634 bne .LOP_IPUT_WIDE_finish @ yes, finish up 2635 b common_exceptionThrown 2636 2637/* ------------------------------ */ 2638 .balign 64 2639.L_OP_IPUT_OBJECT: /* 0x5b */ 2640/* File: armv5te/OP_IPUT_OBJECT.S */ 2641 /* 2642 * 32-bit instance field put. 2643 * 2644 * for: iput-object, iput-object-volatile 2645 */ 2646 /* op vA, vB, field@CCCC */ 2647 mov r0, rINST, lsr #12 @ r0<- B 2648 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2649 FETCH(r1, 1) @ r1<- field ref CCCC 2650 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2651 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2652 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2653 cmp r0, #0 @ is resolved entry null? 2654 bne .LOP_IPUT_OBJECT_finish @ no, already resolved 26558: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2656 EXPORT_PC() @ resolve() could throw 2657 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2658 bl dvmResolveInstField @ r0<- resolved InstField ptr 2659 cmp r0, #0 @ success? 2660 bne .LOP_IPUT_OBJECT_finish @ yes, finish up 2661 b common_exceptionThrown 2662 2663/* ------------------------------ */ 2664 .balign 64 2665.L_OP_IPUT_BOOLEAN: /* 0x5c */ 2666/* File: armv5te/OP_IPUT_BOOLEAN.S */ 2667@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"1" } 2668/* File: armv5te/OP_IPUT.S */ 2669 /* 2670 * General 32-bit instance field put. 2671 * 2672 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2673 */ 2674 /* op vA, vB, field@CCCC */ 2675 mov r0, rINST, lsr #12 @ r0<- B 2676 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2677 FETCH(r1, 1) @ r1<- field ref CCCC 2678 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2679 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2680 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2681 cmp r0, #0 @ is resolved entry null? 2682 bne .LOP_IPUT_BOOLEAN_finish @ no, already resolved 26838: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2684 EXPORT_PC() @ resolve() could throw 2685 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2686 bl dvmResolveInstField @ r0<- resolved InstField ptr 2687 cmp r0, #0 @ success? 2688 bne .LOP_IPUT_BOOLEAN_finish @ yes, finish up 2689 b common_exceptionThrown 2690 2691 2692/* ------------------------------ */ 2693 .balign 64 2694.L_OP_IPUT_BYTE: /* 0x5d */ 2695/* File: armv5te/OP_IPUT_BYTE.S */ 2696@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"2" } 2697/* File: armv5te/OP_IPUT.S */ 2698 /* 2699 * General 32-bit instance field put. 2700 * 2701 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2702 */ 2703 /* op vA, vB, field@CCCC */ 2704 mov r0, rINST, lsr #12 @ r0<- B 2705 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2706 FETCH(r1, 1) @ r1<- field ref CCCC 2707 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2708 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2709 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2710 cmp r0, #0 @ is resolved entry null? 2711 bne .LOP_IPUT_BYTE_finish @ no, already resolved 27128: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2713 EXPORT_PC() @ resolve() could throw 2714 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2715 bl dvmResolveInstField @ r0<- resolved InstField ptr 2716 cmp r0, #0 @ success? 2717 bne .LOP_IPUT_BYTE_finish @ yes, finish up 2718 b common_exceptionThrown 2719 2720 2721/* ------------------------------ */ 2722 .balign 64 2723.L_OP_IPUT_CHAR: /* 0x5e */ 2724/* File: armv5te/OP_IPUT_CHAR.S */ 2725@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"3" } 2726/* File: armv5te/OP_IPUT.S */ 2727 /* 2728 * General 32-bit instance field put. 2729 * 2730 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2731 */ 2732 /* op vA, vB, field@CCCC */ 2733 mov r0, rINST, lsr #12 @ r0<- B 2734 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2735 FETCH(r1, 1) @ r1<- field ref CCCC 2736 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2737 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2738 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2739 cmp r0, #0 @ is resolved entry null? 2740 bne .LOP_IPUT_CHAR_finish @ no, already resolved 27418: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2742 EXPORT_PC() @ resolve() could throw 2743 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2744 bl dvmResolveInstField @ r0<- resolved InstField ptr 2745 cmp r0, #0 @ success? 2746 bne .LOP_IPUT_CHAR_finish @ yes, finish up 2747 b common_exceptionThrown 2748 2749 2750/* ------------------------------ */ 2751 .balign 64 2752.L_OP_IPUT_SHORT: /* 0x5f */ 2753/* File: armv5te/OP_IPUT_SHORT.S */ 2754@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"4" } 2755/* File: armv5te/OP_IPUT.S */ 2756 /* 2757 * General 32-bit instance field put. 2758 * 2759 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2760 */ 2761 /* op vA, vB, field@CCCC */ 2762 mov r0, rINST, lsr #12 @ r0<- B 2763 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2764 FETCH(r1, 1) @ r1<- field ref CCCC 2765 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2766 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2767 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2768 cmp r0, #0 @ is resolved entry null? 2769 bne .LOP_IPUT_SHORT_finish @ no, already resolved 27708: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2771 EXPORT_PC() @ resolve() could throw 2772 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2773 bl dvmResolveInstField @ r0<- resolved InstField ptr 2774 cmp r0, #0 @ success? 2775 bne .LOP_IPUT_SHORT_finish @ yes, finish up 2776 b common_exceptionThrown 2777 2778 2779/* ------------------------------ */ 2780 .balign 64 2781.L_OP_SGET: /* 0x60 */ 2782/* File: armv5te/OP_SGET.S */ 2783 /* 2784 * General 32-bit SGET handler. 2785 * 2786 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2787 */ 2788 /* op vAA, field@BBBB */ 2789 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2790 FETCH(r1, 1) @ r1<- field ref BBBB 2791 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2792 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2793 cmp r0, #0 @ is resolved entry null? 2794 beq .LOP_SGET_resolve @ yes, do resolve 2795.LOP_SGET_finish: @ field ptr in r0 2796 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2797 @ no-op @ acquiring load 2798 mov r2, rINST, lsr #8 @ r2<- AA 2799 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2800 SET_VREG(r1, r2) @ fp[AA]<- r1 2801 GET_INST_OPCODE(ip) @ extract opcode from rINST 2802 GOTO_OPCODE(ip) @ jump to next instruction 2803 2804/* ------------------------------ */ 2805 .balign 64 2806.L_OP_SGET_WIDE: /* 0x61 */ 2807/* File: armv5te/OP_SGET_WIDE.S */ 2808 /* 2809 * 64-bit SGET handler. 2810 */ 2811 /* sget-wide vAA, field@BBBB */ 2812 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2813 FETCH(r1, 1) @ r1<- field ref BBBB 2814 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2815 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2816 cmp r0, #0 @ is resolved entry null? 2817 beq .LOP_SGET_WIDE_resolve @ yes, do resolve 2818.LOP_SGET_WIDE_finish: 2819 mov r9, rINST, lsr #8 @ r9<- AA 2820 .if 0 2821 add r0, r0, #offStaticField_value @ r0<- pointer to data 2822 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 2823 .else 2824 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 2825 .endif 2826 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2827 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2828 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 2829 GET_INST_OPCODE(ip) @ extract opcode from rINST 2830 GOTO_OPCODE(ip) @ jump to next instruction 2831 2832/* ------------------------------ */ 2833 .balign 64 2834.L_OP_SGET_OBJECT: /* 0x62 */ 2835/* File: armv5te/OP_SGET_OBJECT.S */ 2836/* File: armv5te/OP_SGET.S */ 2837 /* 2838 * General 32-bit SGET handler. 2839 * 2840 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2841 */ 2842 /* op vAA, field@BBBB */ 2843 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2844 FETCH(r1, 1) @ r1<- field ref BBBB 2845 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2846 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2847 cmp r0, #0 @ is resolved entry null? 2848 beq .LOP_SGET_OBJECT_resolve @ yes, do resolve 2849.LOP_SGET_OBJECT_finish: @ field ptr in r0 2850 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2851 @ no-op @ acquiring load 2852 mov r2, rINST, lsr #8 @ r2<- AA 2853 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2854 SET_VREG(r1, r2) @ fp[AA]<- r1 2855 GET_INST_OPCODE(ip) @ extract opcode from rINST 2856 GOTO_OPCODE(ip) @ jump to next instruction 2857 2858 2859/* ------------------------------ */ 2860 .balign 64 2861.L_OP_SGET_BOOLEAN: /* 0x63 */ 2862/* File: armv5te/OP_SGET_BOOLEAN.S */ 2863/* File: armv5te/OP_SGET.S */ 2864 /* 2865 * General 32-bit SGET handler. 2866 * 2867 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2868 */ 2869 /* op vAA, field@BBBB */ 2870 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2871 FETCH(r1, 1) @ r1<- field ref BBBB 2872 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2873 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2874 cmp r0, #0 @ is resolved entry null? 2875 beq .LOP_SGET_BOOLEAN_resolve @ yes, do resolve 2876.LOP_SGET_BOOLEAN_finish: @ field ptr in r0 2877 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2878 @ no-op @ acquiring load 2879 mov r2, rINST, lsr #8 @ r2<- AA 2880 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2881 SET_VREG(r1, r2) @ fp[AA]<- r1 2882 GET_INST_OPCODE(ip) @ extract opcode from rINST 2883 GOTO_OPCODE(ip) @ jump to next instruction 2884 2885 2886/* ------------------------------ */ 2887 .balign 64 2888.L_OP_SGET_BYTE: /* 0x64 */ 2889/* File: armv5te/OP_SGET_BYTE.S */ 2890/* File: armv5te/OP_SGET.S */ 2891 /* 2892 * General 32-bit SGET handler. 2893 * 2894 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2895 */ 2896 /* op vAA, field@BBBB */ 2897 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2898 FETCH(r1, 1) @ r1<- field ref BBBB 2899 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2900 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2901 cmp r0, #0 @ is resolved entry null? 2902 beq .LOP_SGET_BYTE_resolve @ yes, do resolve 2903.LOP_SGET_BYTE_finish: @ field ptr in r0 2904 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2905 @ no-op @ acquiring load 2906 mov r2, rINST, lsr #8 @ r2<- AA 2907 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2908 SET_VREG(r1, r2) @ fp[AA]<- r1 2909 GET_INST_OPCODE(ip) @ extract opcode from rINST 2910 GOTO_OPCODE(ip) @ jump to next instruction 2911 2912 2913/* ------------------------------ */ 2914 .balign 64 2915.L_OP_SGET_CHAR: /* 0x65 */ 2916/* File: armv5te/OP_SGET_CHAR.S */ 2917/* File: armv5te/OP_SGET.S */ 2918 /* 2919 * General 32-bit SGET handler. 2920 * 2921 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2922 */ 2923 /* op vAA, field@BBBB */ 2924 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2925 FETCH(r1, 1) @ r1<- field ref BBBB 2926 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2927 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2928 cmp r0, #0 @ is resolved entry null? 2929 beq .LOP_SGET_CHAR_resolve @ yes, do resolve 2930.LOP_SGET_CHAR_finish: @ field ptr in r0 2931 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2932 @ no-op @ acquiring load 2933 mov r2, rINST, lsr #8 @ r2<- AA 2934 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2935 SET_VREG(r1, r2) @ fp[AA]<- r1 2936 GET_INST_OPCODE(ip) @ extract opcode from rINST 2937 GOTO_OPCODE(ip) @ jump to next instruction 2938 2939 2940/* ------------------------------ */ 2941 .balign 64 2942.L_OP_SGET_SHORT: /* 0x66 */ 2943/* File: armv5te/OP_SGET_SHORT.S */ 2944/* File: armv5te/OP_SGET.S */ 2945 /* 2946 * General 32-bit SGET handler. 2947 * 2948 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2949 */ 2950 /* op vAA, field@BBBB */ 2951 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2952 FETCH(r1, 1) @ r1<- field ref BBBB 2953 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2954 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2955 cmp r0, #0 @ is resolved entry null? 2956 beq .LOP_SGET_SHORT_resolve @ yes, do resolve 2957.LOP_SGET_SHORT_finish: @ field ptr in r0 2958 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2959 @ no-op @ acquiring load 2960 mov r2, rINST, lsr #8 @ r2<- AA 2961 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2962 SET_VREG(r1, r2) @ fp[AA]<- r1 2963 GET_INST_OPCODE(ip) @ extract opcode from rINST 2964 GOTO_OPCODE(ip) @ jump to next instruction 2965 2966 2967/* ------------------------------ */ 2968 .balign 64 2969.L_OP_SPUT: /* 0x67 */ 2970/* File: armv5te/OP_SPUT.S */ 2971 /* 2972 * General 32-bit SPUT handler. 2973 * 2974 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2975 */ 2976 /* op vAA, field@BBBB */ 2977 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2978 FETCH(r1, 1) @ r1<- field ref BBBB 2979 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2980 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2981 cmp r0, #0 @ is resolved entry null? 2982 beq .LOP_SPUT_resolve @ yes, do resolve 2983.LOP_SPUT_finish: @ field ptr in r0 2984 mov r2, rINST, lsr #8 @ r2<- AA 2985 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2986 GET_VREG(r1, r2) @ r1<- fp[AA] 2987 GET_INST_OPCODE(ip) @ extract opcode from rINST 2988 @ no-op @ releasing store 2989 str r1, [r0, #offStaticField_value] @ field<- vAA 2990 GOTO_OPCODE(ip) @ jump to next instruction 2991 2992/* ------------------------------ */ 2993 .balign 64 2994.L_OP_SPUT_WIDE: /* 0x68 */ 2995/* File: armv5te/OP_SPUT_WIDE.S */ 2996 /* 2997 * 64-bit SPUT handler. 2998 */ 2999 /* sput-wide vAA, field@BBBB */ 3000 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- DvmDex 3001 FETCH(r1, 1) @ r1<- field ref BBBB 3002 ldr r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields 3003 mov r9, rINST, lsr #8 @ r9<- AA 3004 ldr r2, [r0, r1, lsl #2] @ r2<- resolved StaticField ptr 3005 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 3006 cmp r2, #0 @ is resolved entry null? 3007 beq .LOP_SPUT_WIDE_resolve @ yes, do resolve 3008.LOP_SPUT_WIDE_finish: @ field ptr in r2, AA in r9 3009 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3010 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 3011 GET_INST_OPCODE(r10) @ extract opcode from rINST 3012 .if 0 3013 add r2, r2, #offStaticField_value @ r2<- pointer to data 3014 bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2 3015 .else 3016 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 3017 .endif 3018 GOTO_OPCODE(r10) @ jump to next instruction 3019 3020/* ------------------------------ */ 3021 .balign 64 3022.L_OP_SPUT_OBJECT: /* 0x69 */ 3023/* File: armv5te/OP_SPUT_OBJECT.S */ 3024 /* 3025 * 32-bit SPUT handler for objects 3026 * 3027 * for: sput-object, sput-object-volatile 3028 */ 3029 /* op vAA, field@BBBB */ 3030 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3031 FETCH(r1, 1) @ r1<- field ref BBBB 3032 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3033 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3034 cmp r0, #0 @ is resolved entry null? 3035 bne .LOP_SPUT_OBJECT_finish @ no, continue 3036 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 3037 EXPORT_PC() @ resolve() could throw, so export now 3038 ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz 3039 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 3040 cmp r0, #0 @ success? 3041 bne .LOP_SPUT_OBJECT_finish @ yes, finish 3042 b common_exceptionThrown @ no, handle exception 3043 3044 3045/* ------------------------------ */ 3046 .balign 64 3047.L_OP_SPUT_BOOLEAN: /* 0x6a */ 3048/* File: armv5te/OP_SPUT_BOOLEAN.S */ 3049/* File: armv5te/OP_SPUT.S */ 3050 /* 3051 * General 32-bit SPUT handler. 3052 * 3053 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3054 */ 3055 /* op vAA, field@BBBB */ 3056 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3057 FETCH(r1, 1) @ r1<- field ref BBBB 3058 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3059 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3060 cmp r0, #0 @ is resolved entry null? 3061 beq .LOP_SPUT_BOOLEAN_resolve @ yes, do resolve 3062.LOP_SPUT_BOOLEAN_finish: @ field ptr in r0 3063 mov r2, rINST, lsr #8 @ r2<- AA 3064 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3065 GET_VREG(r1, r2) @ r1<- fp[AA] 3066 GET_INST_OPCODE(ip) @ extract opcode from rINST 3067 @ no-op @ releasing store 3068 str r1, [r0, #offStaticField_value] @ field<- vAA 3069 GOTO_OPCODE(ip) @ jump to next instruction 3070 3071 3072/* ------------------------------ */ 3073 .balign 64 3074.L_OP_SPUT_BYTE: /* 0x6b */ 3075/* File: armv5te/OP_SPUT_BYTE.S */ 3076/* File: armv5te/OP_SPUT.S */ 3077 /* 3078 * General 32-bit SPUT handler. 3079 * 3080 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3081 */ 3082 /* op vAA, field@BBBB */ 3083 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3084 FETCH(r1, 1) @ r1<- field ref BBBB 3085 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3086 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3087 cmp r0, #0 @ is resolved entry null? 3088 beq .LOP_SPUT_BYTE_resolve @ yes, do resolve 3089.LOP_SPUT_BYTE_finish: @ field ptr in r0 3090 mov r2, rINST, lsr #8 @ r2<- AA 3091 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3092 GET_VREG(r1, r2) @ r1<- fp[AA] 3093 GET_INST_OPCODE(ip) @ extract opcode from rINST 3094 @ no-op @ releasing store 3095 str r1, [r0, #offStaticField_value] @ field<- vAA 3096 GOTO_OPCODE(ip) @ jump to next instruction 3097 3098 3099/* ------------------------------ */ 3100 .balign 64 3101.L_OP_SPUT_CHAR: /* 0x6c */ 3102/* File: armv5te/OP_SPUT_CHAR.S */ 3103/* File: armv5te/OP_SPUT.S */ 3104 /* 3105 * General 32-bit SPUT handler. 3106 * 3107 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3108 */ 3109 /* op vAA, field@BBBB */ 3110 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3111 FETCH(r1, 1) @ r1<- field ref BBBB 3112 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3113 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3114 cmp r0, #0 @ is resolved entry null? 3115 beq .LOP_SPUT_CHAR_resolve @ yes, do resolve 3116.LOP_SPUT_CHAR_finish: @ field ptr in r0 3117 mov r2, rINST, lsr #8 @ r2<- AA 3118 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3119 GET_VREG(r1, r2) @ r1<- fp[AA] 3120 GET_INST_OPCODE(ip) @ extract opcode from rINST 3121 @ no-op @ releasing store 3122 str r1, [r0, #offStaticField_value] @ field<- vAA 3123 GOTO_OPCODE(ip) @ jump to next instruction 3124 3125 3126/* ------------------------------ */ 3127 .balign 64 3128.L_OP_SPUT_SHORT: /* 0x6d */ 3129/* File: armv5te/OP_SPUT_SHORT.S */ 3130/* File: armv5te/OP_SPUT.S */ 3131 /* 3132 * General 32-bit SPUT handler. 3133 * 3134 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3135 */ 3136 /* op vAA, field@BBBB */ 3137 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3138 FETCH(r1, 1) @ r1<- field ref BBBB 3139 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3140 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3141 cmp r0, #0 @ is resolved entry null? 3142 beq .LOP_SPUT_SHORT_resolve @ yes, do resolve 3143.LOP_SPUT_SHORT_finish: @ field ptr in r0 3144 mov r2, rINST, lsr #8 @ r2<- AA 3145 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3146 GET_VREG(r1, r2) @ r1<- fp[AA] 3147 GET_INST_OPCODE(ip) @ extract opcode from rINST 3148 @ no-op @ releasing store 3149 str r1, [r0, #offStaticField_value] @ field<- vAA 3150 GOTO_OPCODE(ip) @ jump to next instruction 3151 3152 3153/* ------------------------------ */ 3154 .balign 64 3155.L_OP_INVOKE_VIRTUAL: /* 0x6e */ 3156/* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3157 /* 3158 * Handle a virtual method call. 3159 * 3160 * for: invoke-virtual, invoke-virtual/range 3161 */ 3162 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3163 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3164 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3165 FETCH(r1, 1) @ r1<- BBBB 3166 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3167 FETCH(r10, 2) @ r10<- GFED or CCCC 3168 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3169 .if (!0) 3170 and r10, r10, #15 @ r10<- D (or stays CCCC) 3171 .endif 3172 cmp r0, #0 @ already resolved? 3173 EXPORT_PC() @ must export for invoke 3174 bne .LOP_INVOKE_VIRTUAL_continue @ yes, continue on 3175 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 3176 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3177 mov r2, #METHOD_VIRTUAL @ resolver method type 3178 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3179 cmp r0, #0 @ got null? 3180 bne .LOP_INVOKE_VIRTUAL_continue @ no, continue 3181 b common_exceptionThrown @ yes, handle exception 3182 3183/* ------------------------------ */ 3184 .balign 64 3185.L_OP_INVOKE_SUPER: /* 0x6f */ 3186/* File: armv5te/OP_INVOKE_SUPER.S */ 3187 /* 3188 * Handle a "super" method call. 3189 * 3190 * for: invoke-super, invoke-super/range 3191 */ 3192 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3193 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3194 FETCH(r10, 2) @ r10<- GFED or CCCC 3195 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3196 .if (!0) 3197 and r10, r10, #15 @ r10<- D (or stays CCCC) 3198 .endif 3199 FETCH(r1, 1) @ r1<- BBBB 3200 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3201 GET_VREG(r2, r10) @ r2<- "this" ptr 3202 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3203 cmp r2, #0 @ null "this"? 3204 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 3205 beq common_errNullObject @ null "this", throw exception 3206 cmp r0, #0 @ already resolved? 3207 ldr r9, [r9, #offMethod_clazz] @ r9<- method->clazz 3208 EXPORT_PC() @ must export for invoke 3209 bne .LOP_INVOKE_SUPER_continue @ resolved, continue on 3210 b .LOP_INVOKE_SUPER_resolve @ do resolve now 3211 3212/* ------------------------------ */ 3213 .balign 64 3214.L_OP_INVOKE_DIRECT: /* 0x70 */ 3215/* File: armv5te/OP_INVOKE_DIRECT.S */ 3216 /* 3217 * Handle a direct method call. 3218 * 3219 * (We could defer the "is 'this' pointer null" test to the common 3220 * method invocation code, and use a flag to indicate that static 3221 * calls don't count. If we do this as part of copying the arguments 3222 * out we could avoiding loading the first arg twice.) 3223 * 3224 * for: invoke-direct, invoke-direct/range 3225 */ 3226 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3227 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3228 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3229 FETCH(r1, 1) @ r1<- BBBB 3230 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3231 FETCH(r10, 2) @ r10<- GFED or CCCC 3232 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3233 .if (!0) 3234 and r10, r10, #15 @ r10<- D (or stays CCCC) 3235 .endif 3236 cmp r0, #0 @ already resolved? 3237 EXPORT_PC() @ must export for invoke 3238 GET_VREG(r2, r10) @ r2<- "this" ptr 3239 beq .LOP_INVOKE_DIRECT_resolve @ not resolved, do it now 3240.LOP_INVOKE_DIRECT_finish: 3241 cmp r2, #0 @ null "this" ref? 3242 bne common_invokeMethodNoRange @ no, continue on 3243 b common_errNullObject @ yes, throw exception 3244 3245/* ------------------------------ */ 3246 .balign 64 3247.L_OP_INVOKE_STATIC: /* 0x71 */ 3248/* File: armv5te/OP_INVOKE_STATIC.S */ 3249 /* 3250 * Handle a static method call. 3251 * 3252 * for: invoke-static, invoke-static/range 3253 */ 3254 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3255 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3256 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3257 FETCH(r1, 1) @ r1<- BBBB 3258 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3259 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3260 cmp r0, #0 @ already resolved? 3261 EXPORT_PC() @ must export for invoke 3262 bne common_invokeMethodNoRange @ yes, continue on 32630: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 3264 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3265 mov r2, #METHOD_STATIC @ resolver method type 3266 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3267 cmp r0, #0 @ got null? 3268 bne common_invokeMethodNoRange @ no, continue 3269 b common_exceptionThrown @ yes, handle exception 3270 3271/* ------------------------------ */ 3272 .balign 64 3273.L_OP_INVOKE_INTERFACE: /* 0x72 */ 3274/* File: armv5te/OP_INVOKE_INTERFACE.S */ 3275 /* 3276 * Handle an interface method call. 3277 * 3278 * for: invoke-interface, invoke-interface/range 3279 */ 3280 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3281 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3282 FETCH(r2, 2) @ r2<- FEDC or CCCC 3283 FETCH(r1, 1) @ r1<- BBBB 3284 .if (!0) 3285 and r2, r2, #15 @ r2<- C (or stays CCCC) 3286 .endif 3287 EXPORT_PC() @ must export for invoke 3288 GET_VREG(r0, r2) @ r0<- first arg ("this") 3289 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- methodClassDex 3290 cmp r0, #0 @ null obj? 3291 ldr r2, [rGLUE, #offGlue_method] @ r2<- method 3292 beq common_errNullObject @ yes, fail 3293 ldr r0, [r0, #offObject_clazz] @ r0<- thisPtr->clazz 3294 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3295 cmp r0, #0 @ failed? 3296 beq common_exceptionThrown @ yes, handle exception 3297 b common_invokeMethodNoRange @ jump to common handler 3298 3299/* ------------------------------ */ 3300 .balign 64 3301.L_OP_UNUSED_73: /* 0x73 */ 3302/* File: armv5te/OP_UNUSED_73.S */ 3303/* File: armv5te/unused.S */ 3304 bl common_abort 3305 3306 3307/* ------------------------------ */ 3308 .balign 64 3309.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */ 3310/* File: armv5te/OP_INVOKE_VIRTUAL_RANGE.S */ 3311/* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3312 /* 3313 * Handle a virtual method call. 3314 * 3315 * for: invoke-virtual, invoke-virtual/range 3316 */ 3317 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3318 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3319 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3320 FETCH(r1, 1) @ r1<- BBBB 3321 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3322 FETCH(r10, 2) @ r10<- GFED or CCCC 3323 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3324 .if (!1) 3325 and r10, r10, #15 @ r10<- D (or stays CCCC) 3326 .endif 3327 cmp r0, #0 @ already resolved? 3328 EXPORT_PC() @ must export for invoke 3329 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ yes, continue on 3330 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 3331 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3332 mov r2, #METHOD_VIRTUAL @ resolver method type 3333 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3334 cmp r0, #0 @ got null? 3335 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ no, continue 3336 b common_exceptionThrown @ yes, handle exception 3337 3338 3339/* ------------------------------ */ 3340 .balign 64 3341.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */ 3342/* File: armv5te/OP_INVOKE_SUPER_RANGE.S */ 3343/* File: armv5te/OP_INVOKE_SUPER.S */ 3344 /* 3345 * Handle a "super" method call. 3346 * 3347 * for: invoke-super, invoke-super/range 3348 */ 3349 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3350 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3351 FETCH(r10, 2) @ r10<- GFED or CCCC 3352 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3353 .if (!1) 3354 and r10, r10, #15 @ r10<- D (or stays CCCC) 3355 .endif 3356 FETCH(r1, 1) @ r1<- BBBB 3357 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3358 GET_VREG(r2, r10) @ r2<- "this" ptr 3359 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3360 cmp r2, #0 @ null "this"? 3361 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 3362 beq common_errNullObject @ null "this", throw exception 3363 cmp r0, #0 @ already resolved? 3364 ldr r9, [r9, #offMethod_clazz] @ r9<- method->clazz 3365 EXPORT_PC() @ must export for invoke 3366 bne .LOP_INVOKE_SUPER_RANGE_continue @ resolved, continue on 3367 b .LOP_INVOKE_SUPER_RANGE_resolve @ do resolve now 3368 3369 3370/* ------------------------------ */ 3371 .balign 64 3372.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */ 3373/* File: armv5te/OP_INVOKE_DIRECT_RANGE.S */ 3374/* File: armv5te/OP_INVOKE_DIRECT.S */ 3375 /* 3376 * Handle a direct method call. 3377 * 3378 * (We could defer the "is 'this' pointer null" test to the common 3379 * method invocation code, and use a flag to indicate that static 3380 * calls don't count. If we do this as part of copying the arguments 3381 * out we could avoiding loading the first arg twice.) 3382 * 3383 * for: invoke-direct, invoke-direct/range 3384 */ 3385 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3386 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3387 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3388 FETCH(r1, 1) @ r1<- BBBB 3389 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3390 FETCH(r10, 2) @ r10<- GFED or CCCC 3391 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3392 .if (!1) 3393 and r10, r10, #15 @ r10<- D (or stays CCCC) 3394 .endif 3395 cmp r0, #0 @ already resolved? 3396 EXPORT_PC() @ must export for invoke 3397 GET_VREG(r2, r10) @ r2<- "this" ptr 3398 beq .LOP_INVOKE_DIRECT_RANGE_resolve @ not resolved, do it now 3399.LOP_INVOKE_DIRECT_RANGE_finish: 3400 cmp r2, #0 @ null "this" ref? 3401 bne common_invokeMethodRange @ no, continue on 3402 b common_errNullObject @ yes, throw exception 3403 3404 3405/* ------------------------------ */ 3406 .balign 64 3407.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */ 3408/* File: armv5te/OP_INVOKE_STATIC_RANGE.S */ 3409/* File: armv5te/OP_INVOKE_STATIC.S */ 3410 /* 3411 * Handle a static method call. 3412 * 3413 * for: invoke-static, invoke-static/range 3414 */ 3415 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3416 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3417 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3418 FETCH(r1, 1) @ r1<- BBBB 3419 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3420 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3421 cmp r0, #0 @ already resolved? 3422 EXPORT_PC() @ must export for invoke 3423 bne common_invokeMethodRange @ yes, continue on 34240: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 3425 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3426 mov r2, #METHOD_STATIC @ resolver method type 3427 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3428 cmp r0, #0 @ got null? 3429 bne common_invokeMethodRange @ no, continue 3430 b common_exceptionThrown @ yes, handle exception 3431 3432 3433/* ------------------------------ */ 3434 .balign 64 3435.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */ 3436/* File: armv5te/OP_INVOKE_INTERFACE_RANGE.S */ 3437/* File: armv5te/OP_INVOKE_INTERFACE.S */ 3438 /* 3439 * Handle an interface method call. 3440 * 3441 * for: invoke-interface, invoke-interface/range 3442 */ 3443 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3444 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3445 FETCH(r2, 2) @ r2<- FEDC or CCCC 3446 FETCH(r1, 1) @ r1<- BBBB 3447 .if (!1) 3448 and r2, r2, #15 @ r2<- C (or stays CCCC) 3449 .endif 3450 EXPORT_PC() @ must export for invoke 3451 GET_VREG(r0, r2) @ r0<- first arg ("this") 3452 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- methodClassDex 3453 cmp r0, #0 @ null obj? 3454 ldr r2, [rGLUE, #offGlue_method] @ r2<- method 3455 beq common_errNullObject @ yes, fail 3456 ldr r0, [r0, #offObject_clazz] @ r0<- thisPtr->clazz 3457 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3458 cmp r0, #0 @ failed? 3459 beq common_exceptionThrown @ yes, handle exception 3460 b common_invokeMethodRange @ jump to common handler 3461 3462 3463/* ------------------------------ */ 3464 .balign 64 3465.L_OP_UNUSED_79: /* 0x79 */ 3466/* File: armv5te/OP_UNUSED_79.S */ 3467/* File: armv5te/unused.S */ 3468 bl common_abort 3469 3470 3471/* ------------------------------ */ 3472 .balign 64 3473.L_OP_UNUSED_7A: /* 0x7a */ 3474/* File: armv5te/OP_UNUSED_7A.S */ 3475/* File: armv5te/unused.S */ 3476 bl common_abort 3477 3478 3479/* ------------------------------ */ 3480 .balign 64 3481.L_OP_NEG_INT: /* 0x7b */ 3482/* File: armv5te/OP_NEG_INT.S */ 3483/* File: armv5te/unop.S */ 3484 /* 3485 * Generic 32-bit unary operation. Provide an "instr" line that 3486 * specifies an instruction that performs "result = op r0". 3487 * This could be an ARM instruction or a function call. 3488 * 3489 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3490 * int-to-byte, int-to-char, int-to-short 3491 */ 3492 /* unop vA, vB */ 3493 mov r3, rINST, lsr #12 @ r3<- B 3494 mov r9, rINST, lsr #8 @ r9<- A+ 3495 GET_VREG(r0, r3) @ r0<- vB 3496 and r9, r9, #15 3497 @ optional op; may set condition codes 3498 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3499 rsb r0, r0, #0 @ r0<- op, r0-r3 changed 3500 GET_INST_OPCODE(ip) @ extract opcode from rINST 3501 SET_VREG(r0, r9) @ vAA<- r0 3502 GOTO_OPCODE(ip) @ jump to next instruction 3503 /* 9-10 instructions */ 3504 3505 3506/* ------------------------------ */ 3507 .balign 64 3508.L_OP_NOT_INT: /* 0x7c */ 3509/* File: armv5te/OP_NOT_INT.S */ 3510/* File: armv5te/unop.S */ 3511 /* 3512 * Generic 32-bit unary operation. Provide an "instr" line that 3513 * specifies an instruction that performs "result = op r0". 3514 * This could be an ARM instruction or a function call. 3515 * 3516 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3517 * int-to-byte, int-to-char, int-to-short 3518 */ 3519 /* unop vA, vB */ 3520 mov r3, rINST, lsr #12 @ r3<- B 3521 mov r9, rINST, lsr #8 @ r9<- A+ 3522 GET_VREG(r0, r3) @ r0<- vB 3523 and r9, r9, #15 3524 @ optional op; may set condition codes 3525 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3526 mvn r0, r0 @ r0<- op, r0-r3 changed 3527 GET_INST_OPCODE(ip) @ extract opcode from rINST 3528 SET_VREG(r0, r9) @ vAA<- r0 3529 GOTO_OPCODE(ip) @ jump to next instruction 3530 /* 9-10 instructions */ 3531 3532 3533/* ------------------------------ */ 3534 .balign 64 3535.L_OP_NEG_LONG: /* 0x7d */ 3536/* File: armv5te/OP_NEG_LONG.S */ 3537/* File: armv5te/unopWide.S */ 3538 /* 3539 * Generic 64-bit unary operation. Provide an "instr" line that 3540 * specifies an instruction that performs "result = op r0/r1". 3541 * This could be an ARM instruction or a function call. 3542 * 3543 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3544 */ 3545 /* unop vA, vB */ 3546 mov r9, rINST, lsr #8 @ r9<- A+ 3547 mov r3, rINST, lsr #12 @ r3<- B 3548 and r9, r9, #15 3549 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3550 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3551 ldmia r3, {r0-r1} @ r0/r1<- vAA 3552 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3553 rsbs r0, r0, #0 @ optional op; may set condition codes 3554 rsc r1, r1, #0 @ r0/r1<- op, r2-r3 changed 3555 GET_INST_OPCODE(ip) @ extract opcode from rINST 3556 stmia r9, {r0-r1} @ vAA<- r0/r1 3557 GOTO_OPCODE(ip) @ jump to next instruction 3558 /* 12-13 instructions */ 3559 3560 3561/* ------------------------------ */ 3562 .balign 64 3563.L_OP_NOT_LONG: /* 0x7e */ 3564/* File: armv5te/OP_NOT_LONG.S */ 3565/* File: armv5te/unopWide.S */ 3566 /* 3567 * Generic 64-bit unary operation. Provide an "instr" line that 3568 * specifies an instruction that performs "result = op r0/r1". 3569 * This could be an ARM instruction or a function call. 3570 * 3571 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3572 */ 3573 /* unop vA, vB */ 3574 mov r9, rINST, lsr #8 @ r9<- A+ 3575 mov r3, rINST, lsr #12 @ r3<- B 3576 and r9, r9, #15 3577 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3578 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3579 ldmia r3, {r0-r1} @ r0/r1<- vAA 3580 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3581 mvn r0, r0 @ optional op; may set condition codes 3582 mvn r1, r1 @ r0/r1<- op, r2-r3 changed 3583 GET_INST_OPCODE(ip) @ extract opcode from rINST 3584 stmia r9, {r0-r1} @ vAA<- r0/r1 3585 GOTO_OPCODE(ip) @ jump to next instruction 3586 /* 12-13 instructions */ 3587 3588 3589/* ------------------------------ */ 3590 .balign 64 3591.L_OP_NEG_FLOAT: /* 0x7f */ 3592/* File: armv5te/OP_NEG_FLOAT.S */ 3593/* File: armv5te/unop.S */ 3594 /* 3595 * Generic 32-bit unary operation. Provide an "instr" line that 3596 * specifies an instruction that performs "result = op r0". 3597 * This could be an ARM instruction or a function call. 3598 * 3599 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3600 * int-to-byte, int-to-char, int-to-short 3601 */ 3602 /* unop vA, vB */ 3603 mov r3, rINST, lsr #12 @ r3<- B 3604 mov r9, rINST, lsr #8 @ r9<- A+ 3605 GET_VREG(r0, r3) @ r0<- vB 3606 and r9, r9, #15 3607 @ optional op; may set condition codes 3608 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3609 add r0, r0, #0x80000000 @ r0<- op, r0-r3 changed 3610 GET_INST_OPCODE(ip) @ extract opcode from rINST 3611 SET_VREG(r0, r9) @ vAA<- r0 3612 GOTO_OPCODE(ip) @ jump to next instruction 3613 /* 9-10 instructions */ 3614 3615 3616/* ------------------------------ */ 3617 .balign 64 3618.L_OP_NEG_DOUBLE: /* 0x80 */ 3619/* File: armv5te/OP_NEG_DOUBLE.S */ 3620/* File: armv5te/unopWide.S */ 3621 /* 3622 * Generic 64-bit unary operation. Provide an "instr" line that 3623 * specifies an instruction that performs "result = op r0/r1". 3624 * This could be an ARM instruction or a function call. 3625 * 3626 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3627 */ 3628 /* unop vA, vB */ 3629 mov r9, rINST, lsr #8 @ r9<- A+ 3630 mov r3, rINST, lsr #12 @ r3<- B 3631 and r9, r9, #15 3632 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3633 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3634 ldmia r3, {r0-r1} @ r0/r1<- vAA 3635 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3636 @ optional op; may set condition codes 3637 add r1, r1, #0x80000000 @ r0/r1<- op, r2-r3 changed 3638 GET_INST_OPCODE(ip) @ extract opcode from rINST 3639 stmia r9, {r0-r1} @ vAA<- r0/r1 3640 GOTO_OPCODE(ip) @ jump to next instruction 3641 /* 12-13 instructions */ 3642 3643 3644/* ------------------------------ */ 3645 .balign 64 3646.L_OP_INT_TO_LONG: /* 0x81 */ 3647/* File: armv5te/OP_INT_TO_LONG.S */ 3648/* File: armv5te/unopWider.S */ 3649 /* 3650 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3651 * that specifies an instruction that performs "result = op r0", where 3652 * "result" is a 64-bit quantity in r0/r1. 3653 * 3654 * For: int-to-long, int-to-double, float-to-long, float-to-double 3655 */ 3656 /* unop vA, vB */ 3657 mov r9, rINST, lsr #8 @ r9<- A+ 3658 mov r3, rINST, lsr #12 @ r3<- B 3659 and r9, r9, #15 3660 GET_VREG(r0, r3) @ r0<- vB 3661 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3662 @ optional op; may set condition codes 3663 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3664 mov r1, r0, asr #31 @ r0<- op, r0-r3 changed 3665 GET_INST_OPCODE(ip) @ extract opcode from rINST 3666 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3667 GOTO_OPCODE(ip) @ jump to next instruction 3668 /* 10-11 instructions */ 3669 3670 3671/* ------------------------------ */ 3672 .balign 64 3673.L_OP_INT_TO_FLOAT: /* 0x82 */ 3674/* File: armv5te/OP_INT_TO_FLOAT.S */ 3675/* File: armv5te/unop.S */ 3676 /* 3677 * Generic 32-bit unary operation. Provide an "instr" line that 3678 * specifies an instruction that performs "result = op r0". 3679 * This could be an ARM instruction or a function call. 3680 * 3681 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3682 * int-to-byte, int-to-char, int-to-short 3683 */ 3684 /* unop vA, vB */ 3685 mov r3, rINST, lsr #12 @ r3<- B 3686 mov r9, rINST, lsr #8 @ r9<- A+ 3687 GET_VREG(r0, r3) @ r0<- vB 3688 and r9, r9, #15 3689 @ optional op; may set condition codes 3690 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3691 bl __aeabi_i2f @ r0<- op, r0-r3 changed 3692 GET_INST_OPCODE(ip) @ extract opcode from rINST 3693 SET_VREG(r0, r9) @ vAA<- r0 3694 GOTO_OPCODE(ip) @ jump to next instruction 3695 /* 9-10 instructions */ 3696 3697 3698/* ------------------------------ */ 3699 .balign 64 3700.L_OP_INT_TO_DOUBLE: /* 0x83 */ 3701/* File: armv5te/OP_INT_TO_DOUBLE.S */ 3702/* File: armv5te/unopWider.S */ 3703 /* 3704 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3705 * that specifies an instruction that performs "result = op r0", where 3706 * "result" is a 64-bit quantity in r0/r1. 3707 * 3708 * For: int-to-long, int-to-double, float-to-long, float-to-double 3709 */ 3710 /* unop vA, vB */ 3711 mov r9, rINST, lsr #8 @ r9<- A+ 3712 mov r3, rINST, lsr #12 @ r3<- B 3713 and r9, r9, #15 3714 GET_VREG(r0, r3) @ r0<- vB 3715 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3716 @ optional op; may set condition codes 3717 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3718 bl __aeabi_i2d @ r0<- op, r0-r3 changed 3719 GET_INST_OPCODE(ip) @ extract opcode from rINST 3720 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3721 GOTO_OPCODE(ip) @ jump to next instruction 3722 /* 10-11 instructions */ 3723 3724 3725/* ------------------------------ */ 3726 .balign 64 3727.L_OP_LONG_TO_INT: /* 0x84 */ 3728/* File: armv5te/OP_LONG_TO_INT.S */ 3729/* we ignore the high word, making this equivalent to a 32-bit reg move */ 3730/* File: armv5te/OP_MOVE.S */ 3731 /* for move, move-object, long-to-int */ 3732 /* op vA, vB */ 3733 mov r1, rINST, lsr #12 @ r1<- B from 15:12 3734 mov r0, rINST, lsr #8 @ r0<- A from 11:8 3735 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3736 GET_VREG(r2, r1) @ r2<- fp[B] 3737 and r0, r0, #15 3738 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 3739 SET_VREG(r2, r0) @ fp[A]<- r2 3740 GOTO_OPCODE(ip) @ execute next instruction 3741 3742 3743/* ------------------------------ */ 3744 .balign 64 3745.L_OP_LONG_TO_FLOAT: /* 0x85 */ 3746/* File: armv5te/OP_LONG_TO_FLOAT.S */ 3747/* File: armv5te/unopNarrower.S */ 3748 /* 3749 * Generic 64bit-to-32bit unary operation. Provide an "instr" line 3750 * that specifies an instruction that performs "result = op r0/r1", where 3751 * "result" is a 32-bit quantity in r0. 3752 * 3753 * For: long-to-float, double-to-int, double-to-float 3754 * 3755 * (This would work for long-to-int, but that instruction is actually 3756 * an exact match for OP_MOVE.) 3757 */ 3758 /* unop vA, vB */ 3759 mov r3, rINST, lsr #12 @ r3<- B 3760 mov r9, rINST, lsr #8 @ r9<- A+ 3761 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3762 and r9, r9, #15 3763 ldmia r3, {r0-r1} @ r0/r1<- vB/vB+1 3764 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3765 @ optional op; may set condition codes 3766 bl __aeabi_l2f @ r0<- op, r0-r3 changed 3767 GET_INST_OPCODE(ip) @ extract opcode from rINST 3768 SET_VREG(r0, r9) @ vA<- r0 3769 GOTO_OPCODE(ip) @ jump to next instruction 3770 /* 10-11 instructions */ 3771 3772 3773/* ------------------------------ */ 3774 .balign 64 3775.L_OP_LONG_TO_DOUBLE: /* 0x86 */ 3776/* File: armv5te/OP_LONG_TO_DOUBLE.S */ 3777/* File: armv5te/unopWide.S */ 3778 /* 3779 * Generic 64-bit unary operation. Provide an "instr" line that 3780 * specifies an instruction that performs "result = op r0/r1". 3781 * This could be an ARM instruction or a function call. 3782 * 3783 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3784 */ 3785 /* unop vA, vB */ 3786 mov r9, rINST, lsr #8 @ r9<- A+ 3787 mov r3, rINST, lsr #12 @ r3<- B 3788 and r9, r9, #15 3789 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3790 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3791 ldmia r3, {r0-r1} @ r0/r1<- vAA 3792 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3793 @ optional op; may set condition codes 3794 bl __aeabi_l2d @ r0/r1<- op, r2-r3 changed 3795 GET_INST_OPCODE(ip) @ extract opcode from rINST 3796 stmia r9, {r0-r1} @ vAA<- r0/r1 3797 GOTO_OPCODE(ip) @ jump to next instruction 3798 /* 12-13 instructions */ 3799 3800 3801/* ------------------------------ */ 3802 .balign 64 3803.L_OP_FLOAT_TO_INT: /* 0x87 */ 3804/* File: armv5te/OP_FLOAT_TO_INT.S */ 3805/* EABI appears to have Java-style conversions of +inf/-inf/NaN */ 3806/* File: armv5te/unop.S */ 3807 /* 3808 * Generic 32-bit unary operation. Provide an "instr" line that 3809 * specifies an instruction that performs "result = op r0". 3810 * This could be an ARM instruction or a function call. 3811 * 3812 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3813 * int-to-byte, int-to-char, int-to-short 3814 */ 3815 /* unop vA, vB */ 3816 mov r3, rINST, lsr #12 @ r3<- B 3817 mov r9, rINST, lsr #8 @ r9<- A+ 3818 GET_VREG(r0, r3) @ r0<- vB 3819 and r9, r9, #15 3820 @ optional op; may set condition codes 3821 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3822 bl __aeabi_f2iz @ r0<- op, r0-r3 changed 3823 GET_INST_OPCODE(ip) @ extract opcode from rINST 3824 SET_VREG(r0, r9) @ vAA<- r0 3825 GOTO_OPCODE(ip) @ jump to next instruction 3826 /* 9-10 instructions */ 3827 3828 3829#if 0 3830@include "armv5te/unop.S" {"instr":"bl f2i_doconv"} 3831@break 3832/* 3833 * Convert the float in r0 to an int in r0. 3834 * 3835 * We have to clip values to int min/max per the specification. The 3836 * expected common case is a "reasonable" value that converts directly 3837 * to modest integer. The EABI convert function isn't doing this for us. 3838 */ 3839f2i_doconv: 3840 stmfd sp!, {r4, lr} 3841 mov r1, #0x4f000000 @ (float)maxint 3842 mov r4, r0 3843 bl __aeabi_fcmpge @ is arg >= maxint? 3844 cmp r0, #0 @ nonzero == yes 3845 mvnne r0, #0x80000000 @ return maxint (7fffffff) 3846 ldmnefd sp!, {r4, pc} 3847 3848 mov r0, r4 @ recover arg 3849 mov r1, #0xcf000000 @ (float)minint 3850 bl __aeabi_fcmple @ is arg <= minint? 3851 cmp r0, #0 @ nonzero == yes 3852 movne r0, #0x80000000 @ return minint (80000000) 3853 ldmnefd sp!, {r4, pc} 3854 3855 mov r0, r4 @ recover arg 3856 mov r1, r4 3857 bl __aeabi_fcmpeq @ is arg == self? 3858 cmp r0, #0 @ zero == no 3859 ldmeqfd sp!, {r4, pc} @ return zero for NaN 3860 3861 mov r0, r4 @ recover arg 3862 bl __aeabi_f2iz @ convert float to int 3863 ldmfd sp!, {r4, pc} 3864#endif 3865 3866/* ------------------------------ */ 3867 .balign 64 3868.L_OP_FLOAT_TO_LONG: /* 0x88 */ 3869/* File: armv5te/OP_FLOAT_TO_LONG.S */ 3870@include "armv5te/unopWider.S" {"instr":"bl __aeabi_f2lz"} 3871/* File: armv5te/unopWider.S */ 3872 /* 3873 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3874 * that specifies an instruction that performs "result = op r0", where 3875 * "result" is a 64-bit quantity in r0/r1. 3876 * 3877 * For: int-to-long, int-to-double, float-to-long, float-to-double 3878 */ 3879 /* unop vA, vB */ 3880 mov r9, rINST, lsr #8 @ r9<- A+ 3881 mov r3, rINST, lsr #12 @ r3<- B 3882 and r9, r9, #15 3883 GET_VREG(r0, r3) @ r0<- vB 3884 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3885 @ optional op; may set condition codes 3886 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3887 bl f2l_doconv @ r0<- op, r0-r3 changed 3888 GET_INST_OPCODE(ip) @ extract opcode from rINST 3889 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3890 GOTO_OPCODE(ip) @ jump to next instruction 3891 /* 10-11 instructions */ 3892 3893 3894 3895/* ------------------------------ */ 3896 .balign 64 3897.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */ 3898/* File: armv5te/OP_FLOAT_TO_DOUBLE.S */ 3899/* File: armv5te/unopWider.S */ 3900 /* 3901 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3902 * that specifies an instruction that performs "result = op r0", where 3903 * "result" is a 64-bit quantity in r0/r1. 3904 * 3905 * For: int-to-long, int-to-double, float-to-long, float-to-double 3906 */ 3907 /* unop vA, vB */ 3908 mov r9, rINST, lsr #8 @ r9<- A+ 3909 mov r3, rINST, lsr #12 @ r3<- B 3910 and r9, r9, #15 3911 GET_VREG(r0, r3) @ r0<- vB 3912 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3913 @ optional op; may set condition codes 3914 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3915 bl __aeabi_f2d @ r0<- op, r0-r3 changed 3916 GET_INST_OPCODE(ip) @ extract opcode from rINST 3917 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3918 GOTO_OPCODE(ip) @ jump to next instruction 3919 /* 10-11 instructions */ 3920 3921 3922/* ------------------------------ */ 3923 .balign 64 3924.L_OP_DOUBLE_TO_INT: /* 0x8a */ 3925/* File: armv5te/OP_DOUBLE_TO_INT.S */ 3926/* EABI appears to have Java-style conversions of +inf/-inf/NaN */ 3927/* File: armv5te/unopNarrower.S */ 3928 /* 3929 * Generic 64bit-to-32bit unary operation. Provide an "instr" line 3930 * that specifies an instruction that performs "result = op r0/r1", where 3931 * "result" is a 32-bit quantity in r0. 3932 * 3933 * For: long-to-float, double-to-int, double-to-float 3934 * 3935 * (This would work for long-to-int, but that instruction is actually 3936 * an exact match for OP_MOVE.) 3937 */ 3938 /* unop vA, vB */ 3939 mov r3, rINST, lsr #12 @ r3<- B 3940 mov r9, rINST, lsr #8 @ r9<- A+ 3941 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3942 and r9, r9, #15 3943 ldmia r3, {r0-r1} @ r0/r1<- vB/vB+1 3944 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3945 @ optional op; may set condition codes 3946 bl __aeabi_d2iz @ r0<- op, r0-r3 changed 3947 GET_INST_OPCODE(ip) @ extract opcode from rINST 3948 SET_VREG(r0, r9) @ vA<- r0 3949 GOTO_OPCODE(ip) @ jump to next instruction 3950 /* 10-11 instructions */ 3951 3952 3953#if 0 3954@include "armv5te/unopNarrower.S" {"instr":"bl d2i_doconv"} 3955@break 3956/* 3957 * Convert the double in r0/r1 to an int in r0. 3958 * 3959 * We have to clip values to int min/max per the specification. The 3960 * expected common case is a "reasonable" value that converts directly 3961 * to modest integer. The EABI convert function isn't doing this for us. 3962 */ 3963d2i_doconv: 3964 stmfd sp!, {r4, r5, lr} @ save regs 3965 mov r2, #0x80000000 @ maxint, as a double (low word) 3966 mov r2, r2, asr #9 @ 0xffc00000 3967 sub sp, sp, #4 @ align for EABI 3968 mvn r3, #0xbe000000 @ maxint, as a double (high word) 3969 sub r3, r3, #0x00200000 @ 0x41dfffff 3970 mov r4, r0 @ save a copy of r0 3971 mov r5, r1 @ and r1 3972 bl __aeabi_dcmpge @ is arg >= maxint? 3973 cmp r0, #0 @ nonzero == yes 3974 mvnne r0, #0x80000000 @ return maxint (0x7fffffff) 3975 bne 1f 3976 3977 mov r0, r4 @ recover arg 3978 mov r1, r5 3979 mov r3, #0xc1000000 @ minint, as a double (high word) 3980 add r3, r3, #0x00e00000 @ 0xc1e00000 3981 mov r2, #0 @ minint, as a double (low word) 3982 bl __aeabi_dcmple @ is arg <= minint? 3983 cmp r0, #0 @ nonzero == yes 3984 movne r0, #0x80000000 @ return minint (80000000) 3985 bne 1f 3986 3987 mov r0, r4 @ recover arg 3988 mov r1, r5 3989 mov r2, r4 @ compare against self 3990 mov r3, r5 3991 bl __aeabi_dcmpeq @ is arg == self? 3992 cmp r0, #0 @ zero == no 3993 beq 1f @ return zero for NaN 3994 3995 mov r0, r4 @ recover arg 3996 mov r1, r5 3997 bl __aeabi_d2iz @ convert double to int 3998 39991: 4000 add sp, sp, #4 4001 ldmfd sp!, {r4, r5, pc} 4002#endif 4003 4004/* ------------------------------ */ 4005 .balign 64 4006.L_OP_DOUBLE_TO_LONG: /* 0x8b */ 4007/* File: armv5te/OP_DOUBLE_TO_LONG.S */ 4008@include "armv5te/unopWide.S" {"instr":"bl __aeabi_d2lz"} 4009/* File: armv5te/unopWide.S */ 4010 /* 4011 * Generic 64-bit unary operation. Provide an "instr" line that 4012 * specifies an instruction that performs "result = op r0/r1". 4013 * This could be an ARM instruction or a function call. 4014 * 4015 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 4016 */ 4017 /* unop vA, vB */ 4018 mov r9, rINST, lsr #8 @ r9<- A+ 4019 mov r3, rINST, lsr #12 @ r3<- B 4020 and r9, r9, #15 4021 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 4022 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 4023 ldmia r3, {r0-r1} @ r0/r1<- vAA 4024 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 4025 @ optional op; may set condition codes 4026 bl d2l_doconv @ r0/r1<- op, r2-r3 changed 4027 GET_INST_OPCODE(ip) @ extract opcode from rINST 4028 stmia r9, {r0-r1} @ vAA<- r0/r1 4029 GOTO_OPCODE(ip) @ jump to next instruction 4030 /* 12-13 instructions */ 4031 4032 4033 4034/* ------------------------------ */ 4035 .balign 64 4036.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */ 4037/* File: armv5te/OP_DOUBLE_TO_FLOAT.S */ 4038/* File: armv5te/unopNarrower.S */ 4039 /* 4040 * Generic 64bit-to-32bit unary operation. Provide an "instr" line 4041 * that specifies an instruction that performs "result = op r0/r1", where 4042 * "result" is a 32-bit quantity in r0. 4043 * 4044 * For: long-to-float, double-to-int, double-to-float 4045 * 4046 * (This would work for long-to-int, but that instruction is actually 4047 * an exact match for OP_MOVE.) 4048 */ 4049 /* unop vA, vB */ 4050 mov r3, rINST, lsr #12 @ r3<- B 4051 mov r9, rINST, lsr #8 @ r9<- A+ 4052 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 4053 and r9, r9, #15 4054 ldmia r3, {r0-r1} @ r0/r1<- vB/vB+1 4055 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 4056 @ optional op; may set condition codes 4057 bl __aeabi_d2f @ r0<- op, r0-r3 changed 4058 GET_INST_OPCODE(ip) @ extract opcode from rINST 4059 SET_VREG(r0, r9) @ vA<- r0 4060 GOTO_OPCODE(ip) @ jump to next instruction 4061 /* 10-11 instructions */ 4062 4063 4064/* ------------------------------ */ 4065 .balign 64 4066.L_OP_INT_TO_BYTE: /* 0x8d */ 4067/* File: armv5te/OP_INT_TO_BYTE.S */ 4068/* File: armv5te/unop.S */ 4069 /* 4070 * Generic 32-bit unary operation. Provide an "instr" line that 4071 * specifies an instruction that performs "result = op r0". 4072 * This could be an ARM instruction or a function call. 4073 * 4074 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 4075 * int-to-byte, int-to-char, int-to-short 4076 */ 4077 /* unop vA, vB */ 4078 mov r3, rINST, lsr #12 @ r3<- B 4079 mov r9, rINST, lsr #8 @ r9<- A+ 4080 GET_VREG(r0, r3) @ r0<- vB 4081 and r9, r9, #15 4082 mov r0, r0, asl #24 @ optional op; may set condition codes 4083 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 4084 mov r0, r0, asr #24 @ r0<- op, r0-r3 changed 4085 GET_INST_OPCODE(ip) @ extract opcode from rINST 4086 SET_VREG(r0, r9) @ vAA<- r0 4087 GOTO_OPCODE(ip) @ jump to next instruction 4088 /* 9-10 instructions */ 4089 4090 4091/* ------------------------------ */ 4092 .balign 64 4093.L_OP_INT_TO_CHAR: /* 0x8e */ 4094/* File: armv5te/OP_INT_TO_CHAR.S */ 4095/* File: armv5te/unop.S */ 4096 /* 4097 * Generic 32-bit unary operation. Provide an "instr" line that 4098 * specifies an instruction that performs "result = op r0". 4099 * This could be an ARM instruction or a function call. 4100 * 4101 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 4102 * int-to-byte, int-to-char, int-to-short 4103 */ 4104 /* unop vA, vB */ 4105 mov r3, rINST, lsr #12 @ r3<- B 4106 mov r9, rINST, lsr #8 @ r9<- A+ 4107 GET_VREG(r0, r3) @ r0<- vB 4108 and r9, r9, #15 4109 mov r0, r0, asl #16 @ optional op; may set condition codes 4110 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 4111 mov r0, r0, lsr #16 @ r0<- op, r0-r3 changed 4112 GET_INST_OPCODE(ip) @ extract opcode from rINST 4113 SET_VREG(r0, r9) @ vAA<- r0 4114 GOTO_OPCODE(ip) @ jump to next instruction 4115 /* 9-10 instructions */ 4116 4117 4118/* ------------------------------ */ 4119 .balign 64 4120.L_OP_INT_TO_SHORT: /* 0x8f */ 4121/* File: armv5te/OP_INT_TO_SHORT.S */ 4122/* File: armv5te/unop.S */ 4123 /* 4124 * Generic 32-bit unary operation. Provide an "instr" line that 4125 * specifies an instruction that performs "result = op r0". 4126 * This could be an ARM instruction or a function call. 4127 * 4128 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 4129 * int-to-byte, int-to-char, int-to-short 4130 */ 4131 /* unop vA, vB */ 4132 mov r3, rINST, lsr #12 @ r3<- B 4133 mov r9, rINST, lsr #8 @ r9<- A+ 4134 GET_VREG(r0, r3) @ r0<- vB 4135 and r9, r9, #15 4136 mov r0, r0, asl #16 @ optional op; may set condition codes 4137 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 4138 mov r0, r0, asr #16 @ 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 /* 9-10 instructions */ 4143 4144 4145/* ------------------------------ */ 4146 .balign 64 4147.L_OP_ADD_INT: /* 0x90 */ 4148/* File: armv5te/OP_ADD_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 0 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 add r0, r0, r1 @ 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_SUB_INT: /* 0x91 */ 4189/* File: armv5te/OP_SUB_INT.S */ 4190/* File: armv5te/binop.S */ 4191 /* 4192 * Generic 32-bit binary operation. Provide an "instr" line that 4193 * specifies an instruction that performs "result = r0 op r1". 4194 * This could be an ARM instruction or a function call. (If the result 4195 * comes back in a register other than r0, you can override "result".) 4196 * 4197 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4198 * vCC (r1). Useful for integer division and modulus. Note that we 4199 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4200 * handles it correctly. 4201 * 4202 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4203 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4204 * mul-float, div-float, rem-float 4205 */ 4206 /* binop vAA, vBB, vCC */ 4207 FETCH(r0, 1) @ r0<- CCBB 4208 mov r9, rINST, lsr #8 @ r9<- AA 4209 mov r3, r0, lsr #8 @ r3<- CC 4210 and r2, r0, #255 @ r2<- BB 4211 GET_VREG(r1, r3) @ r1<- vCC 4212 GET_VREG(r0, r2) @ r0<- vBB 4213 .if 0 4214 cmp r1, #0 @ is second operand zero? 4215 beq common_errDivideByZero 4216 .endif 4217 4218 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4219 @ optional op; may set condition codes 4220 sub r0, r0, r1 @ r0<- op, r0-r3 changed 4221 GET_INST_OPCODE(ip) @ extract opcode from rINST 4222 SET_VREG(r0, r9) @ vAA<- r0 4223 GOTO_OPCODE(ip) @ jump to next instruction 4224 /* 11-14 instructions */ 4225 4226 4227/* ------------------------------ */ 4228 .balign 64 4229.L_OP_MUL_INT: /* 0x92 */ 4230/* File: armv5te/OP_MUL_INT.S */ 4231/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 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 mul r0, r1, r0 @ 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_DIV_INT: /* 0x93 */ 4272/* File: armv5te/OP_DIV_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 1 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 bl __aeabi_idiv @ 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_REM_INT: /* 0x94 */ 4313/* File: armv5te/OP_REM_INT.S */ 4314/* idivmod returns quotient in r0 and remainder in r1 */ 4315/* File: armv5te/binop.S */ 4316 /* 4317 * Generic 32-bit binary operation. Provide an "instr" line that 4318 * specifies an instruction that performs "result = r0 op r1". 4319 * This could be an ARM instruction or a function call. (If the result 4320 * comes back in a register other than r0, you can override "result".) 4321 * 4322 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4323 * vCC (r1). Useful for integer division and modulus. Note that we 4324 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4325 * handles it correctly. 4326 * 4327 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4328 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4329 * mul-float, div-float, rem-float 4330 */ 4331 /* binop vAA, vBB, vCC */ 4332 FETCH(r0, 1) @ r0<- CCBB 4333 mov r9, rINST, lsr #8 @ r9<- AA 4334 mov r3, r0, lsr #8 @ r3<- CC 4335 and r2, r0, #255 @ r2<- BB 4336 GET_VREG(r1, r3) @ r1<- vCC 4337 GET_VREG(r0, r2) @ r0<- vBB 4338 .if 1 4339 cmp r1, #0 @ is second operand zero? 4340 beq common_errDivideByZero 4341 .endif 4342 4343 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4344 @ optional op; may set condition codes 4345 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 4346 GET_INST_OPCODE(ip) @ extract opcode from rINST 4347 SET_VREG(r1, r9) @ vAA<- r1 4348 GOTO_OPCODE(ip) @ jump to next instruction 4349 /* 11-14 instructions */ 4350 4351 4352/* ------------------------------ */ 4353 .balign 64 4354.L_OP_AND_INT: /* 0x95 */ 4355/* File: armv5te/OP_AND_INT.S */ 4356/* File: armv5te/binop.S */ 4357 /* 4358 * Generic 32-bit binary operation. Provide an "instr" line that 4359 * specifies an instruction that performs "result = r0 op r1". 4360 * This could be an ARM instruction or a function call. (If the result 4361 * comes back in a register other than r0, you can override "result".) 4362 * 4363 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4364 * vCC (r1). Useful for integer division and modulus. Note that we 4365 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4366 * handles it correctly. 4367 * 4368 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4369 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4370 * mul-float, div-float, rem-float 4371 */ 4372 /* binop vAA, vBB, vCC */ 4373 FETCH(r0, 1) @ r0<- CCBB 4374 mov r9, rINST, lsr #8 @ r9<- AA 4375 mov r3, r0, lsr #8 @ r3<- CC 4376 and r2, r0, #255 @ r2<- BB 4377 GET_VREG(r1, r3) @ r1<- vCC 4378 GET_VREG(r0, r2) @ r0<- vBB 4379 .if 0 4380 cmp r1, #0 @ is second operand zero? 4381 beq common_errDivideByZero 4382 .endif 4383 4384 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4385 @ optional op; may set condition codes 4386 and r0, r0, r1 @ r0<- op, r0-r3 changed 4387 GET_INST_OPCODE(ip) @ extract opcode from rINST 4388 SET_VREG(r0, r9) @ vAA<- r0 4389 GOTO_OPCODE(ip) @ jump to next instruction 4390 /* 11-14 instructions */ 4391 4392 4393/* ------------------------------ */ 4394 .balign 64 4395.L_OP_OR_INT: /* 0x96 */ 4396/* File: armv5te/OP_OR_INT.S */ 4397/* File: armv5te/binop.S */ 4398 /* 4399 * Generic 32-bit binary operation. Provide an "instr" line that 4400 * specifies an instruction that performs "result = r0 op r1". 4401 * This could be an ARM instruction or a function call. (If the result 4402 * comes back in a register other than r0, you can override "result".) 4403 * 4404 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4405 * vCC (r1). Useful for integer division and modulus. Note that we 4406 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4407 * handles it correctly. 4408 * 4409 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4410 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4411 * mul-float, div-float, rem-float 4412 */ 4413 /* binop vAA, vBB, vCC */ 4414 FETCH(r0, 1) @ r0<- CCBB 4415 mov r9, rINST, lsr #8 @ r9<- AA 4416 mov r3, r0, lsr #8 @ r3<- CC 4417 and r2, r0, #255 @ r2<- BB 4418 GET_VREG(r1, r3) @ r1<- vCC 4419 GET_VREG(r0, r2) @ r0<- vBB 4420 .if 0 4421 cmp r1, #0 @ is second operand zero? 4422 beq common_errDivideByZero 4423 .endif 4424 4425 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4426 @ optional op; may set condition codes 4427 orr r0, r0, r1 @ r0<- op, r0-r3 changed 4428 GET_INST_OPCODE(ip) @ extract opcode from rINST 4429 SET_VREG(r0, r9) @ vAA<- r0 4430 GOTO_OPCODE(ip) @ jump to next instruction 4431 /* 11-14 instructions */ 4432 4433 4434/* ------------------------------ */ 4435 .balign 64 4436.L_OP_XOR_INT: /* 0x97 */ 4437/* File: armv5te/OP_XOR_INT.S */ 4438/* File: armv5te/binop.S */ 4439 /* 4440 * Generic 32-bit binary operation. Provide an "instr" line that 4441 * specifies an instruction that performs "result = r0 op r1". 4442 * This could be an ARM instruction or a function call. (If the result 4443 * comes back in a register other than r0, you can override "result".) 4444 * 4445 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4446 * vCC (r1). Useful for integer division and modulus. Note that we 4447 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4448 * handles it correctly. 4449 * 4450 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4451 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4452 * mul-float, div-float, rem-float 4453 */ 4454 /* binop vAA, vBB, vCC */ 4455 FETCH(r0, 1) @ r0<- CCBB 4456 mov r9, rINST, lsr #8 @ r9<- AA 4457 mov r3, r0, lsr #8 @ r3<- CC 4458 and r2, r0, #255 @ r2<- BB 4459 GET_VREG(r1, r3) @ r1<- vCC 4460 GET_VREG(r0, r2) @ r0<- vBB 4461 .if 0 4462 cmp r1, #0 @ is second operand zero? 4463 beq common_errDivideByZero 4464 .endif 4465 4466 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4467 @ optional op; may set condition codes 4468 eor r0, r0, r1 @ r0<- op, r0-r3 changed 4469 GET_INST_OPCODE(ip) @ extract opcode from rINST 4470 SET_VREG(r0, r9) @ vAA<- r0 4471 GOTO_OPCODE(ip) @ jump to next instruction 4472 /* 11-14 instructions */ 4473 4474 4475/* ------------------------------ */ 4476 .balign 64 4477.L_OP_SHL_INT: /* 0x98 */ 4478/* File: armv5te/OP_SHL_INT.S */ 4479/* File: armv5te/binop.S */ 4480 /* 4481 * Generic 32-bit binary operation. Provide an "instr" line that 4482 * specifies an instruction that performs "result = r0 op r1". 4483 * This could be an ARM instruction or a function call. (If the result 4484 * comes back in a register other than r0, you can override "result".) 4485 * 4486 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4487 * vCC (r1). Useful for integer division and modulus. Note that we 4488 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4489 * handles it correctly. 4490 * 4491 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4492 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4493 * mul-float, div-float, rem-float 4494 */ 4495 /* binop vAA, vBB, vCC */ 4496 FETCH(r0, 1) @ r0<- CCBB 4497 mov r9, rINST, lsr #8 @ r9<- AA 4498 mov r3, r0, lsr #8 @ r3<- CC 4499 and r2, r0, #255 @ r2<- BB 4500 GET_VREG(r1, r3) @ r1<- vCC 4501 GET_VREG(r0, r2) @ r0<- vBB 4502 .if 0 4503 cmp r1, #0 @ is second operand zero? 4504 beq common_errDivideByZero 4505 .endif 4506 4507 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4508 and r1, r1, #31 @ optional op; may set condition codes 4509 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 4510 GET_INST_OPCODE(ip) @ extract opcode from rINST 4511 SET_VREG(r0, r9) @ vAA<- r0 4512 GOTO_OPCODE(ip) @ jump to next instruction 4513 /* 11-14 instructions */ 4514 4515 4516/* ------------------------------ */ 4517 .balign 64 4518.L_OP_SHR_INT: /* 0x99 */ 4519/* File: armv5te/OP_SHR_INT.S */ 4520/* File: armv5te/binop.S */ 4521 /* 4522 * Generic 32-bit binary operation. Provide an "instr" line that 4523 * specifies an instruction that performs "result = r0 op r1". 4524 * This could be an ARM instruction or a function call. (If the result 4525 * comes back in a register other than r0, you can override "result".) 4526 * 4527 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4528 * vCC (r1). Useful for integer division and modulus. Note that we 4529 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4530 * handles it correctly. 4531 * 4532 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4533 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4534 * mul-float, div-float, rem-float 4535 */ 4536 /* binop vAA, vBB, vCC */ 4537 FETCH(r0, 1) @ r0<- CCBB 4538 mov r9, rINST, lsr #8 @ r9<- AA 4539 mov r3, r0, lsr #8 @ r3<- CC 4540 and r2, r0, #255 @ r2<- BB 4541 GET_VREG(r1, r3) @ r1<- vCC 4542 GET_VREG(r0, r2) @ r0<- vBB 4543 .if 0 4544 cmp r1, #0 @ is second operand zero? 4545 beq common_errDivideByZero 4546 .endif 4547 4548 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4549 and r1, r1, #31 @ optional op; may set condition codes 4550 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 4551 GET_INST_OPCODE(ip) @ extract opcode from rINST 4552 SET_VREG(r0, r9) @ vAA<- r0 4553 GOTO_OPCODE(ip) @ jump to next instruction 4554 /* 11-14 instructions */ 4555 4556 4557/* ------------------------------ */ 4558 .balign 64 4559.L_OP_USHR_INT: /* 0x9a */ 4560/* File: armv5te/OP_USHR_INT.S */ 4561/* File: armv5te/binop.S */ 4562 /* 4563 * Generic 32-bit binary operation. Provide an "instr" line that 4564 * specifies an instruction that performs "result = r0 op r1". 4565 * This could be an ARM instruction or a function call. (If the result 4566 * comes back in a register other than r0, you can override "result".) 4567 * 4568 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4569 * vCC (r1). Useful for integer division and modulus. Note that we 4570 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4571 * handles it correctly. 4572 * 4573 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4574 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4575 * mul-float, div-float, rem-float 4576 */ 4577 /* binop vAA, vBB, vCC */ 4578 FETCH(r0, 1) @ r0<- CCBB 4579 mov r9, rINST, lsr #8 @ r9<- AA 4580 mov r3, r0, lsr #8 @ r3<- CC 4581 and r2, r0, #255 @ r2<- BB 4582 GET_VREG(r1, r3) @ r1<- vCC 4583 GET_VREG(r0, r2) @ r0<- vBB 4584 .if 0 4585 cmp r1, #0 @ is second operand zero? 4586 beq common_errDivideByZero 4587 .endif 4588 4589 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4590 and r1, r1, #31 @ optional op; may set condition codes 4591 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 4592 GET_INST_OPCODE(ip) @ extract opcode from rINST 4593 SET_VREG(r0, r9) @ vAA<- r0 4594 GOTO_OPCODE(ip) @ jump to next instruction 4595 /* 11-14 instructions */ 4596 4597 4598/* ------------------------------ */ 4599 .balign 64 4600.L_OP_ADD_LONG: /* 0x9b */ 4601/* File: armv5te/OP_ADD_LONG.S */ 4602/* File: armv5te/binopWide.S */ 4603 /* 4604 * Generic 64-bit binary operation. Provide an "instr" line that 4605 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4606 * This could be an ARM instruction or a function call. (If the result 4607 * comes back in a register other than r0, you can override "result".) 4608 * 4609 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4610 * vCC (r1). Useful for integer division and modulus. 4611 * 4612 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4613 * xor-long, add-double, sub-double, mul-double, div-double, 4614 * rem-double 4615 * 4616 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4617 */ 4618 /* binop vAA, vBB, vCC */ 4619 FETCH(r0, 1) @ r0<- CCBB 4620 mov r9, rINST, lsr #8 @ r9<- AA 4621 and r2, r0, #255 @ r2<- BB 4622 mov r3, r0, lsr #8 @ r3<- CC 4623 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4624 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4625 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4626 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4627 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4628 .if 0 4629 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4630 beq common_errDivideByZero 4631 .endif 4632 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4633 4634 adds r0, r0, r2 @ optional op; may set condition codes 4635 adc r1, r1, r3 @ result<- op, r0-r3 changed 4636 GET_INST_OPCODE(ip) @ extract opcode from rINST 4637 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4638 GOTO_OPCODE(ip) @ jump to next instruction 4639 /* 14-17 instructions */ 4640 4641 4642/* ------------------------------ */ 4643 .balign 64 4644.L_OP_SUB_LONG: /* 0x9c */ 4645/* File: armv5te/OP_SUB_LONG.S */ 4646/* File: armv5te/binopWide.S */ 4647 /* 4648 * Generic 64-bit binary operation. Provide an "instr" line that 4649 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4650 * This could be an ARM instruction or a function call. (If the result 4651 * comes back in a register other than r0, you can override "result".) 4652 * 4653 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4654 * vCC (r1). Useful for integer division and modulus. 4655 * 4656 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4657 * xor-long, add-double, sub-double, mul-double, div-double, 4658 * rem-double 4659 * 4660 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4661 */ 4662 /* binop vAA, vBB, vCC */ 4663 FETCH(r0, 1) @ r0<- CCBB 4664 mov r9, rINST, lsr #8 @ r9<- AA 4665 and r2, r0, #255 @ r2<- BB 4666 mov r3, r0, lsr #8 @ r3<- CC 4667 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4668 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4669 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4670 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4671 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4672 .if 0 4673 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4674 beq common_errDivideByZero 4675 .endif 4676 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4677 4678 subs r0, r0, r2 @ optional op; may set condition codes 4679 sbc r1, r1, r3 @ result<- op, r0-r3 changed 4680 GET_INST_OPCODE(ip) @ extract opcode from rINST 4681 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4682 GOTO_OPCODE(ip) @ jump to next instruction 4683 /* 14-17 instructions */ 4684 4685 4686/* ------------------------------ */ 4687 .balign 64 4688.L_OP_MUL_LONG: /* 0x9d */ 4689/* File: armv5te/OP_MUL_LONG.S */ 4690 /* 4691 * Signed 64-bit integer multiply. 4692 * 4693 * Consider WXxYZ (r1r0 x r3r2) with a long multiply: 4694 * WX 4695 * x YZ 4696 * -------- 4697 * ZW ZX 4698 * YW YX 4699 * 4700 * The low word of the result holds ZX, the high word holds 4701 * (ZW+YX) + (the high overflow from ZX). YW doesn't matter because 4702 * it doesn't fit in the low 64 bits. 4703 * 4704 * Unlike most ARM math operations, multiply instructions have 4705 * restrictions on using the same register more than once (Rd and Rm 4706 * cannot be the same). 4707 */ 4708 /* mul-long vAA, vBB, vCC */ 4709 FETCH(r0, 1) @ r0<- CCBB 4710 and r2, r0, #255 @ r2<- BB 4711 mov r3, r0, lsr #8 @ r3<- CC 4712 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4713 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4714 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4715 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4716 mul ip, r2, r1 @ ip<- ZxW 4717 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 4718 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 4719 mov r0, rINST, lsr #8 @ r0<- AA 4720 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 4721 add r0, rFP, r0, lsl #2 @ r0<- &fp[AA] 4722 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4723 b .LOP_MUL_LONG_finish 4724 4725/* ------------------------------ */ 4726 .balign 64 4727.L_OP_DIV_LONG: /* 0x9e */ 4728/* File: armv5te/OP_DIV_LONG.S */ 4729/* File: armv5te/binopWide.S */ 4730 /* 4731 * Generic 64-bit binary operation. Provide an "instr" line that 4732 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4733 * This could be an ARM instruction or a function call. (If the result 4734 * comes back in a register other than r0, you can override "result".) 4735 * 4736 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4737 * vCC (r1). Useful for integer division and modulus. 4738 * 4739 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4740 * xor-long, add-double, sub-double, mul-double, div-double, 4741 * rem-double 4742 * 4743 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4744 */ 4745 /* binop vAA, vBB, vCC */ 4746 FETCH(r0, 1) @ r0<- CCBB 4747 mov r9, rINST, lsr #8 @ r9<- AA 4748 and r2, r0, #255 @ r2<- BB 4749 mov r3, r0, lsr #8 @ r3<- CC 4750 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4751 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4752 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4753 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4754 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4755 .if 1 4756 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4757 beq common_errDivideByZero 4758 .endif 4759 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4760 4761 @ optional op; may set condition codes 4762 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4763 GET_INST_OPCODE(ip) @ extract opcode from rINST 4764 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4765 GOTO_OPCODE(ip) @ jump to next instruction 4766 /* 14-17 instructions */ 4767 4768 4769/* ------------------------------ */ 4770 .balign 64 4771.L_OP_REM_LONG: /* 0x9f */ 4772/* File: armv5te/OP_REM_LONG.S */ 4773/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 4774/* File: armv5te/binopWide.S */ 4775 /* 4776 * Generic 64-bit binary operation. Provide an "instr" line that 4777 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4778 * This could be an ARM instruction or a function call. (If the result 4779 * comes back in a register other than r0, you can override "result".) 4780 * 4781 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4782 * vCC (r1). Useful for integer division and modulus. 4783 * 4784 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4785 * xor-long, add-double, sub-double, mul-double, div-double, 4786 * rem-double 4787 * 4788 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4789 */ 4790 /* binop vAA, vBB, vCC */ 4791 FETCH(r0, 1) @ r0<- CCBB 4792 mov r9, rINST, lsr #8 @ r9<- AA 4793 and r2, r0, #255 @ r2<- BB 4794 mov r3, r0, lsr #8 @ r3<- CC 4795 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4796 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4797 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4798 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4799 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4800 .if 1 4801 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4802 beq common_errDivideByZero 4803 .endif 4804 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4805 4806 @ optional op; may set condition codes 4807 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4808 GET_INST_OPCODE(ip) @ extract opcode from rINST 4809 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 4810 GOTO_OPCODE(ip) @ jump to next instruction 4811 /* 14-17 instructions */ 4812 4813 4814/* ------------------------------ */ 4815 .balign 64 4816.L_OP_AND_LONG: /* 0xa0 */ 4817/* File: armv5te/OP_AND_LONG.S */ 4818/* File: armv5te/binopWide.S */ 4819 /* 4820 * Generic 64-bit binary operation. Provide an "instr" line that 4821 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4822 * This could be an ARM instruction or a function call. (If the result 4823 * comes back in a register other than r0, you can override "result".) 4824 * 4825 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4826 * vCC (r1). Useful for integer division and modulus. 4827 * 4828 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4829 * xor-long, add-double, sub-double, mul-double, div-double, 4830 * rem-double 4831 * 4832 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4833 */ 4834 /* binop vAA, vBB, vCC */ 4835 FETCH(r0, 1) @ r0<- CCBB 4836 mov r9, rINST, lsr #8 @ r9<- AA 4837 and r2, r0, #255 @ r2<- BB 4838 mov r3, r0, lsr #8 @ r3<- CC 4839 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4840 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4841 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4842 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4843 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4844 .if 0 4845 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4846 beq common_errDivideByZero 4847 .endif 4848 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4849 4850 and r0, r0, r2 @ optional op; may set condition codes 4851 and r1, r1, r3 @ result<- op, r0-r3 changed 4852 GET_INST_OPCODE(ip) @ extract opcode from rINST 4853 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4854 GOTO_OPCODE(ip) @ jump to next instruction 4855 /* 14-17 instructions */ 4856 4857 4858/* ------------------------------ */ 4859 .balign 64 4860.L_OP_OR_LONG: /* 0xa1 */ 4861/* File: armv5te/OP_OR_LONG.S */ 4862/* File: armv5te/binopWide.S */ 4863 /* 4864 * Generic 64-bit binary operation. Provide an "instr" line that 4865 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4866 * This could be an ARM instruction or a function call. (If the result 4867 * comes back in a register other than r0, you can override "result".) 4868 * 4869 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4870 * vCC (r1). Useful for integer division and modulus. 4871 * 4872 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4873 * xor-long, add-double, sub-double, mul-double, div-double, 4874 * rem-double 4875 * 4876 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4877 */ 4878 /* binop vAA, vBB, vCC */ 4879 FETCH(r0, 1) @ r0<- CCBB 4880 mov r9, rINST, lsr #8 @ r9<- AA 4881 and r2, r0, #255 @ r2<- BB 4882 mov r3, r0, lsr #8 @ r3<- CC 4883 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4884 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4885 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4886 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4887 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4888 .if 0 4889 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4890 beq common_errDivideByZero 4891 .endif 4892 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4893 4894 orr r0, r0, r2 @ optional op; may set condition codes 4895 orr r1, r1, r3 @ result<- op, r0-r3 changed 4896 GET_INST_OPCODE(ip) @ extract opcode from rINST 4897 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4898 GOTO_OPCODE(ip) @ jump to next instruction 4899 /* 14-17 instructions */ 4900 4901 4902/* ------------------------------ */ 4903 .balign 64 4904.L_OP_XOR_LONG: /* 0xa2 */ 4905/* File: armv5te/OP_XOR_LONG.S */ 4906/* File: armv5te/binopWide.S */ 4907 /* 4908 * Generic 64-bit binary operation. Provide an "instr" line that 4909 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4910 * This could be an ARM instruction or a function call. (If the result 4911 * comes back in a register other than r0, you can override "result".) 4912 * 4913 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4914 * vCC (r1). Useful for integer division and modulus. 4915 * 4916 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4917 * xor-long, add-double, sub-double, mul-double, div-double, 4918 * rem-double 4919 * 4920 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4921 */ 4922 /* binop vAA, vBB, vCC */ 4923 FETCH(r0, 1) @ r0<- CCBB 4924 mov r9, rINST, lsr #8 @ r9<- AA 4925 and r2, r0, #255 @ r2<- BB 4926 mov r3, r0, lsr #8 @ r3<- CC 4927 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4928 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4929 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4930 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4931 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4932 .if 0 4933 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4934 beq common_errDivideByZero 4935 .endif 4936 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4937 4938 eor r0, r0, r2 @ optional op; may set condition codes 4939 eor r1, r1, r3 @ result<- op, r0-r3 changed 4940 GET_INST_OPCODE(ip) @ extract opcode from rINST 4941 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4942 GOTO_OPCODE(ip) @ jump to next instruction 4943 /* 14-17 instructions */ 4944 4945 4946/* ------------------------------ */ 4947 .balign 64 4948.L_OP_SHL_LONG: /* 0xa3 */ 4949/* File: armv5te/OP_SHL_LONG.S */ 4950 /* 4951 * Long integer shift. This is different from the generic 32/64-bit 4952 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4953 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4954 * 6 bits of the shift distance. 4955 */ 4956 /* shl-long vAA, vBB, vCC */ 4957 FETCH(r0, 1) @ r0<- CCBB 4958 mov r9, rINST, lsr #8 @ r9<- AA 4959 and r3, r0, #255 @ r3<- BB 4960 mov r0, r0, lsr #8 @ r0<- CC 4961 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4962 GET_VREG(r2, r0) @ r2<- vCC 4963 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4964 and r2, r2, #63 @ r2<- r2 & 0x3f 4965 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4966 4967 mov r1, r1, asl r2 @ r1<- r1 << r2 4968 rsb r3, r2, #32 @ r3<- 32 - r2 4969 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 4970 subs ip, r2, #32 @ ip<- r2 - 32 4971 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 4972 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4973 b .LOP_SHL_LONG_finish 4974 4975/* ------------------------------ */ 4976 .balign 64 4977.L_OP_SHR_LONG: /* 0xa4 */ 4978/* File: armv5te/OP_SHR_LONG.S */ 4979 /* 4980 * Long integer shift. This is different from the generic 32/64-bit 4981 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4982 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4983 * 6 bits of the shift distance. 4984 */ 4985 /* shr-long vAA, vBB, vCC */ 4986 FETCH(r0, 1) @ r0<- CCBB 4987 mov r9, rINST, lsr #8 @ r9<- AA 4988 and r3, r0, #255 @ r3<- BB 4989 mov r0, r0, lsr #8 @ r0<- CC 4990 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4991 GET_VREG(r2, r0) @ r2<- vCC 4992 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4993 and r2, r2, #63 @ r0<- r0 & 0x3f 4994 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4995 4996 mov r0, r0, lsr r2 @ r0<- r2 >> r2 4997 rsb r3, r2, #32 @ r3<- 32 - r2 4998 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 4999 subs ip, r2, #32 @ ip<- r2 - 32 5000 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 5001 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5002 b .LOP_SHR_LONG_finish 5003 5004/* ------------------------------ */ 5005 .balign 64 5006.L_OP_USHR_LONG: /* 0xa5 */ 5007/* File: armv5te/OP_USHR_LONG.S */ 5008 /* 5009 * Long integer shift. This is different from the generic 32/64-bit 5010 * binary operations because vAA/vBB are 64-bit but vCC (the shift 5011 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 5012 * 6 bits of the shift distance. 5013 */ 5014 /* ushr-long vAA, vBB, vCC */ 5015 FETCH(r0, 1) @ r0<- CCBB 5016 mov r9, rINST, lsr #8 @ r9<- AA 5017 and r3, r0, #255 @ r3<- BB 5018 mov r0, r0, lsr #8 @ r0<- CC 5019 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 5020 GET_VREG(r2, r0) @ r2<- vCC 5021 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 5022 and r2, r2, #63 @ r0<- r0 & 0x3f 5023 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 5024 5025 mov r0, r0, lsr r2 @ r0<- r2 >> r2 5026 rsb r3, r2, #32 @ r3<- 32 - r2 5027 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 5028 subs ip, r2, #32 @ ip<- r2 - 32 5029 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 5030 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5031 b .LOP_USHR_LONG_finish 5032 5033/* ------------------------------ */ 5034 .balign 64 5035.L_OP_ADD_FLOAT: /* 0xa6 */ 5036/* File: armv5te/OP_ADD_FLOAT.S */ 5037/* File: armv5te/binop.S */ 5038 /* 5039 * Generic 32-bit binary operation. Provide an "instr" line that 5040 * specifies an instruction that performs "result = r0 op r1". 5041 * This could be an ARM instruction or a function call. (If the result 5042 * comes back in a register other than r0, you can override "result".) 5043 * 5044 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5045 * vCC (r1). Useful for integer division and modulus. Note that we 5046 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 5047 * handles it correctly. 5048 * 5049 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 5050 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 5051 * mul-float, div-float, rem-float 5052 */ 5053 /* binop vAA, vBB, vCC */ 5054 FETCH(r0, 1) @ r0<- CCBB 5055 mov r9, rINST, lsr #8 @ r9<- AA 5056 mov r3, r0, lsr #8 @ r3<- CC 5057 and r2, r0, #255 @ r2<- BB 5058 GET_VREG(r1, r3) @ r1<- vCC 5059 GET_VREG(r0, r2) @ r0<- vBB 5060 .if 0 5061 cmp r1, #0 @ is second operand zero? 5062 beq common_errDivideByZero 5063 .endif 5064 5065 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5066 @ optional op; may set condition codes 5067 bl __aeabi_fadd @ r0<- op, r0-r3 changed 5068 GET_INST_OPCODE(ip) @ extract opcode from rINST 5069 SET_VREG(r0, r9) @ vAA<- r0 5070 GOTO_OPCODE(ip) @ jump to next instruction 5071 /* 11-14 instructions */ 5072 5073 5074/* ------------------------------ */ 5075 .balign 64 5076.L_OP_SUB_FLOAT: /* 0xa7 */ 5077/* File: armv5te/OP_SUB_FLOAT.S */ 5078/* File: armv5te/binop.S */ 5079 /* 5080 * Generic 32-bit binary operation. Provide an "instr" line that 5081 * specifies an instruction that performs "result = r0 op r1". 5082 * This could be an ARM instruction or a function call. (If the result 5083 * comes back in a register other than r0, you can override "result".) 5084 * 5085 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5086 * vCC (r1). Useful for integer division and modulus. Note that we 5087 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 5088 * handles it correctly. 5089 * 5090 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 5091 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 5092 * mul-float, div-float, rem-float 5093 */ 5094 /* binop vAA, vBB, vCC */ 5095 FETCH(r0, 1) @ r0<- CCBB 5096 mov r9, rINST, lsr #8 @ r9<- AA 5097 mov r3, r0, lsr #8 @ r3<- CC 5098 and r2, r0, #255 @ r2<- BB 5099 GET_VREG(r1, r3) @ r1<- vCC 5100 GET_VREG(r0, r2) @ r0<- vBB 5101 .if 0 5102 cmp r1, #0 @ is second operand zero? 5103 beq common_errDivideByZero 5104 .endif 5105 5106 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5107 @ optional op; may set condition codes 5108 bl __aeabi_fsub @ r0<- op, r0-r3 changed 5109 GET_INST_OPCODE(ip) @ extract opcode from rINST 5110 SET_VREG(r0, r9) @ vAA<- r0 5111 GOTO_OPCODE(ip) @ jump to next instruction 5112 /* 11-14 instructions */ 5113 5114 5115/* ------------------------------ */ 5116 .balign 64 5117.L_OP_MUL_FLOAT: /* 0xa8 */ 5118/* File: armv5te/OP_MUL_FLOAT.S */ 5119/* File: armv5te/binop.S */ 5120 /* 5121 * Generic 32-bit binary operation. Provide an "instr" line that 5122 * specifies an instruction that performs "result = r0 op r1". 5123 * This could be an ARM instruction or a function call. (If the result 5124 * comes back in a register other than r0, you can override "result".) 5125 * 5126 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5127 * vCC (r1). Useful for integer division and modulus. Note that we 5128 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 5129 * handles it correctly. 5130 * 5131 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 5132 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 5133 * mul-float, div-float, rem-float 5134 */ 5135 /* binop vAA, vBB, vCC */ 5136 FETCH(r0, 1) @ r0<- CCBB 5137 mov r9, rINST, lsr #8 @ r9<- AA 5138 mov r3, r0, lsr #8 @ r3<- CC 5139 and r2, r0, #255 @ r2<- BB 5140 GET_VREG(r1, r3) @ r1<- vCC 5141 GET_VREG(r0, r2) @ r0<- vBB 5142 .if 0 5143 cmp r1, #0 @ is second operand zero? 5144 beq common_errDivideByZero 5145 .endif 5146 5147 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5148 @ optional op; may set condition codes 5149 bl __aeabi_fmul @ r0<- op, r0-r3 changed 5150 GET_INST_OPCODE(ip) @ extract opcode from rINST 5151 SET_VREG(r0, r9) @ vAA<- r0 5152 GOTO_OPCODE(ip) @ jump to next instruction 5153 /* 11-14 instructions */ 5154 5155 5156/* ------------------------------ */ 5157 .balign 64 5158.L_OP_DIV_FLOAT: /* 0xa9 */ 5159/* File: armv5te/OP_DIV_FLOAT.S */ 5160/* File: armv5te/binop.S */ 5161 /* 5162 * Generic 32-bit binary operation. Provide an "instr" line that 5163 * specifies an instruction that performs "result = r0 op r1". 5164 * This could be an ARM instruction or a function call. (If the result 5165 * comes back in a register other than r0, you can override "result".) 5166 * 5167 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5168 * vCC (r1). Useful for integer division and modulus. Note that we 5169 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 5170 * handles it correctly. 5171 * 5172 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 5173 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 5174 * mul-float, div-float, rem-float 5175 */ 5176 /* binop vAA, vBB, vCC */ 5177 FETCH(r0, 1) @ r0<- CCBB 5178 mov r9, rINST, lsr #8 @ r9<- AA 5179 mov r3, r0, lsr #8 @ r3<- CC 5180 and r2, r0, #255 @ r2<- BB 5181 GET_VREG(r1, r3) @ r1<- vCC 5182 GET_VREG(r0, r2) @ r0<- vBB 5183 .if 0 5184 cmp r1, #0 @ is second operand zero? 5185 beq common_errDivideByZero 5186 .endif 5187 5188 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5189 @ optional op; may set condition codes 5190 bl __aeabi_fdiv @ r0<- op, r0-r3 changed 5191 GET_INST_OPCODE(ip) @ extract opcode from rINST 5192 SET_VREG(r0, r9) @ vAA<- r0 5193 GOTO_OPCODE(ip) @ jump to next instruction 5194 /* 11-14 instructions */ 5195 5196 5197/* ------------------------------ */ 5198 .balign 64 5199.L_OP_REM_FLOAT: /* 0xaa */ 5200/* File: armv5te/OP_REM_FLOAT.S */ 5201/* EABI doesn't define a float remainder function, but libm does */ 5202/* File: armv5te/binop.S */ 5203 /* 5204 * Generic 32-bit binary operation. Provide an "instr" line that 5205 * specifies an instruction that performs "result = r0 op r1". 5206 * This could be an ARM instruction or a function call. (If the result 5207 * comes back in a register other than r0, you can override "result".) 5208 * 5209 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5210 * vCC (r1). Useful for integer division and modulus. Note that we 5211 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 5212 * handles it correctly. 5213 * 5214 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 5215 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 5216 * mul-float, div-float, rem-float 5217 */ 5218 /* binop vAA, vBB, vCC */ 5219 FETCH(r0, 1) @ r0<- CCBB 5220 mov r9, rINST, lsr #8 @ r9<- AA 5221 mov r3, r0, lsr #8 @ r3<- CC 5222 and r2, r0, #255 @ r2<- BB 5223 GET_VREG(r1, r3) @ r1<- vCC 5224 GET_VREG(r0, r2) @ r0<- vBB 5225 .if 0 5226 cmp r1, #0 @ is second operand zero? 5227 beq common_errDivideByZero 5228 .endif 5229 5230 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5231 @ optional op; may set condition codes 5232 bl fmodf @ r0<- op, r0-r3 changed 5233 GET_INST_OPCODE(ip) @ extract opcode from rINST 5234 SET_VREG(r0, r9) @ vAA<- r0 5235 GOTO_OPCODE(ip) @ jump to next instruction 5236 /* 11-14 instructions */ 5237 5238 5239/* ------------------------------ */ 5240 .balign 64 5241.L_OP_ADD_DOUBLE: /* 0xab */ 5242/* File: armv5te/OP_ADD_DOUBLE.S */ 5243/* File: armv5te/binopWide.S */ 5244 /* 5245 * Generic 64-bit binary operation. Provide an "instr" line that 5246 * specifies an instruction that performs "result = r0-r1 op r2-r3". 5247 * This could be an ARM instruction or a function call. (If the result 5248 * comes back in a register other than r0, you can override "result".) 5249 * 5250 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5251 * vCC (r1). Useful for integer division and modulus. 5252 * 5253 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 5254 * xor-long, add-double, sub-double, mul-double, div-double, 5255 * rem-double 5256 * 5257 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 5258 */ 5259 /* binop vAA, vBB, vCC */ 5260 FETCH(r0, 1) @ r0<- CCBB 5261 mov r9, rINST, lsr #8 @ r9<- AA 5262 and r2, r0, #255 @ r2<- BB 5263 mov r3, r0, lsr #8 @ r3<- CC 5264 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 5265 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 5266 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 5267 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 5268 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 5269 .if 0 5270 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5271 beq common_errDivideByZero 5272 .endif 5273 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5274 5275 @ optional op; may set condition codes 5276 bl __aeabi_dadd @ result<- op, r0-r3 changed 5277 GET_INST_OPCODE(ip) @ extract opcode from rINST 5278 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5279 GOTO_OPCODE(ip) @ jump to next instruction 5280 /* 14-17 instructions */ 5281 5282 5283/* ------------------------------ */ 5284 .balign 64 5285.L_OP_SUB_DOUBLE: /* 0xac */ 5286/* File: armv5te/OP_SUB_DOUBLE.S */ 5287/* File: armv5te/binopWide.S */ 5288 /* 5289 * Generic 64-bit binary operation. Provide an "instr" line that 5290 * specifies an instruction that performs "result = r0-r1 op r2-r3". 5291 * This could be an ARM instruction or a function call. (If the result 5292 * comes back in a register other than r0, you can override "result".) 5293 * 5294 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5295 * vCC (r1). Useful for integer division and modulus. 5296 * 5297 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 5298 * xor-long, add-double, sub-double, mul-double, div-double, 5299 * rem-double 5300 * 5301 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 5302 */ 5303 /* binop vAA, vBB, vCC */ 5304 FETCH(r0, 1) @ r0<- CCBB 5305 mov r9, rINST, lsr #8 @ r9<- AA 5306 and r2, r0, #255 @ r2<- BB 5307 mov r3, r0, lsr #8 @ r3<- CC 5308 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 5309 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 5310 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 5311 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 5312 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 5313 .if 0 5314 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5315 beq common_errDivideByZero 5316 .endif 5317 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5318 5319 @ optional op; may set condition codes 5320 bl __aeabi_dsub @ result<- op, r0-r3 changed 5321 GET_INST_OPCODE(ip) @ extract opcode from rINST 5322 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5323 GOTO_OPCODE(ip) @ jump to next instruction 5324 /* 14-17 instructions */ 5325 5326 5327/* ------------------------------ */ 5328 .balign 64 5329.L_OP_MUL_DOUBLE: /* 0xad */ 5330/* File: armv5te/OP_MUL_DOUBLE.S */ 5331/* File: armv5te/binopWide.S */ 5332 /* 5333 * Generic 64-bit binary operation. Provide an "instr" line that 5334 * specifies an instruction that performs "result = r0-r1 op r2-r3". 5335 * This could be an ARM instruction or a function call. (If the result 5336 * comes back in a register other than r0, you can override "result".) 5337 * 5338 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5339 * vCC (r1). Useful for integer division and modulus. 5340 * 5341 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 5342 * xor-long, add-double, sub-double, mul-double, div-double, 5343 * rem-double 5344 * 5345 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 5346 */ 5347 /* binop vAA, vBB, vCC */ 5348 FETCH(r0, 1) @ r0<- CCBB 5349 mov r9, rINST, lsr #8 @ r9<- AA 5350 and r2, r0, #255 @ r2<- BB 5351 mov r3, r0, lsr #8 @ r3<- CC 5352 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 5353 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 5354 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 5355 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 5356 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 5357 .if 0 5358 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5359 beq common_errDivideByZero 5360 .endif 5361 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5362 5363 @ optional op; may set condition codes 5364 bl __aeabi_dmul @ result<- op, r0-r3 changed 5365 GET_INST_OPCODE(ip) @ extract opcode from rINST 5366 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5367 GOTO_OPCODE(ip) @ jump to next instruction 5368 /* 14-17 instructions */ 5369 5370 5371/* ------------------------------ */ 5372 .balign 64 5373.L_OP_DIV_DOUBLE: /* 0xae */ 5374/* File: armv5te/OP_DIV_DOUBLE.S */ 5375/* File: armv5te/binopWide.S */ 5376 /* 5377 * Generic 64-bit binary operation. Provide an "instr" line that 5378 * specifies an instruction that performs "result = r0-r1 op r2-r3". 5379 * This could be an ARM instruction or a function call. (If the result 5380 * comes back in a register other than r0, you can override "result".) 5381 * 5382 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5383 * vCC (r1). Useful for integer division and modulus. 5384 * 5385 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 5386 * xor-long, add-double, sub-double, mul-double, div-double, 5387 * rem-double 5388 * 5389 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 5390 */ 5391 /* binop vAA, vBB, vCC */ 5392 FETCH(r0, 1) @ r0<- CCBB 5393 mov r9, rINST, lsr #8 @ r9<- AA 5394 and r2, r0, #255 @ r2<- BB 5395 mov r3, r0, lsr #8 @ r3<- CC 5396 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 5397 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 5398 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 5399 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 5400 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 5401 .if 0 5402 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5403 beq common_errDivideByZero 5404 .endif 5405 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5406 5407 @ optional op; may set condition codes 5408 bl __aeabi_ddiv @ result<- op, r0-r3 changed 5409 GET_INST_OPCODE(ip) @ extract opcode from rINST 5410 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5411 GOTO_OPCODE(ip) @ jump to next instruction 5412 /* 14-17 instructions */ 5413 5414 5415/* ------------------------------ */ 5416 .balign 64 5417.L_OP_REM_DOUBLE: /* 0xaf */ 5418/* File: armv5te/OP_REM_DOUBLE.S */ 5419/* EABI doesn't define a double remainder function, but libm does */ 5420/* File: armv5te/binopWide.S */ 5421 /* 5422 * Generic 64-bit binary operation. Provide an "instr" line that 5423 * specifies an instruction that performs "result = r0-r1 op r2-r3". 5424 * This could be an ARM instruction or a function call. (If the result 5425 * comes back in a register other than r0, you can override "result".) 5426 * 5427 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5428 * vCC (r1). Useful for integer division and modulus. 5429 * 5430 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 5431 * xor-long, add-double, sub-double, mul-double, div-double, 5432 * rem-double 5433 * 5434 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 5435 */ 5436 /* binop vAA, vBB, vCC */ 5437 FETCH(r0, 1) @ r0<- CCBB 5438 mov r9, rINST, lsr #8 @ r9<- AA 5439 and r2, r0, #255 @ r2<- BB 5440 mov r3, r0, lsr #8 @ r3<- CC 5441 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 5442 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 5443 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 5444 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 5445 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 5446 .if 0 5447 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5448 beq common_errDivideByZero 5449 .endif 5450 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5451 5452 @ optional op; may set condition codes 5453 bl fmod @ result<- op, r0-r3 changed 5454 GET_INST_OPCODE(ip) @ extract opcode from rINST 5455 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5456 GOTO_OPCODE(ip) @ jump to next instruction 5457 /* 14-17 instructions */ 5458 5459 5460/* ------------------------------ */ 5461 .balign 64 5462.L_OP_ADD_INT_2ADDR: /* 0xb0 */ 5463/* File: armv5te/OP_ADD_INT_2ADDR.S */ 5464/* File: armv5te/binop2addr.S */ 5465 /* 5466 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5467 * that specifies an instruction that performs "result = r0 op r1". 5468 * This could be an ARM instruction or a function call. (If the result 5469 * comes back in a register other than r0, you can override "result".) 5470 * 5471 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5472 * vCC (r1). Useful for integer division and modulus. 5473 * 5474 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5475 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5476 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5477 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5478 */ 5479 /* binop/2addr vA, vB */ 5480 mov r9, rINST, lsr #8 @ r9<- A+ 5481 mov r3, rINST, lsr #12 @ r3<- B 5482 and r9, r9, #15 5483 GET_VREG(r1, r3) @ r1<- vB 5484 GET_VREG(r0, r9) @ r0<- vA 5485 .if 0 5486 cmp r1, #0 @ is second operand zero? 5487 beq common_errDivideByZero 5488 .endif 5489 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5490 5491 @ optional op; may set condition codes 5492 add r0, r0, r1 @ r0<- op, r0-r3 changed 5493 GET_INST_OPCODE(ip) @ extract opcode from rINST 5494 SET_VREG(r0, r9) @ vAA<- r0 5495 GOTO_OPCODE(ip) @ jump to next instruction 5496 /* 10-13 instructions */ 5497 5498 5499/* ------------------------------ */ 5500 .balign 64 5501.L_OP_SUB_INT_2ADDR: /* 0xb1 */ 5502/* File: armv5te/OP_SUB_INT_2ADDR.S */ 5503/* File: armv5te/binop2addr.S */ 5504 /* 5505 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5506 * that specifies an instruction that performs "result = r0 op r1". 5507 * This could be an ARM instruction or a function call. (If the result 5508 * comes back in a register other than r0, you can override "result".) 5509 * 5510 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5511 * vCC (r1). Useful for integer division and modulus. 5512 * 5513 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5514 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5515 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5516 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5517 */ 5518 /* binop/2addr vA, vB */ 5519 mov r9, rINST, lsr #8 @ r9<- A+ 5520 mov r3, rINST, lsr #12 @ r3<- B 5521 and r9, r9, #15 5522 GET_VREG(r1, r3) @ r1<- vB 5523 GET_VREG(r0, r9) @ r0<- vA 5524 .if 0 5525 cmp r1, #0 @ is second operand zero? 5526 beq common_errDivideByZero 5527 .endif 5528 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5529 5530 @ optional op; may set condition codes 5531 sub r0, r0, r1 @ r0<- op, r0-r3 changed 5532 GET_INST_OPCODE(ip) @ extract opcode from rINST 5533 SET_VREG(r0, r9) @ vAA<- r0 5534 GOTO_OPCODE(ip) @ jump to next instruction 5535 /* 10-13 instructions */ 5536 5537 5538/* ------------------------------ */ 5539 .balign 64 5540.L_OP_MUL_INT_2ADDR: /* 0xb2 */ 5541/* File: armv5te/OP_MUL_INT_2ADDR.S */ 5542/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 5543/* File: armv5te/binop2addr.S */ 5544 /* 5545 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5546 * that specifies an instruction that performs "result = r0 op r1". 5547 * This could be an ARM instruction or a function call. (If the result 5548 * comes back in a register other than r0, you can override "result".) 5549 * 5550 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5551 * vCC (r1). Useful for integer division and modulus. 5552 * 5553 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5554 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5555 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5556 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5557 */ 5558 /* binop/2addr vA, vB */ 5559 mov r9, rINST, lsr #8 @ r9<- A+ 5560 mov r3, rINST, lsr #12 @ r3<- B 5561 and r9, r9, #15 5562 GET_VREG(r1, r3) @ r1<- vB 5563 GET_VREG(r0, r9) @ r0<- vA 5564 .if 0 5565 cmp r1, #0 @ is second operand zero? 5566 beq common_errDivideByZero 5567 .endif 5568 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5569 5570 @ optional op; may set condition codes 5571 mul r0, r1, r0 @ r0<- op, r0-r3 changed 5572 GET_INST_OPCODE(ip) @ extract opcode from rINST 5573 SET_VREG(r0, r9) @ vAA<- r0 5574 GOTO_OPCODE(ip) @ jump to next instruction 5575 /* 10-13 instructions */ 5576 5577 5578/* ------------------------------ */ 5579 .balign 64 5580.L_OP_DIV_INT_2ADDR: /* 0xb3 */ 5581/* File: armv5te/OP_DIV_INT_2ADDR.S */ 5582/* File: armv5te/binop2addr.S */ 5583 /* 5584 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5585 * that specifies an instruction that performs "result = r0 op r1". 5586 * This could be an ARM instruction or a function call. (If the result 5587 * comes back in a register other than r0, you can override "result".) 5588 * 5589 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5590 * vCC (r1). Useful for integer division and modulus. 5591 * 5592 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5593 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5594 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5595 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5596 */ 5597 /* binop/2addr vA, vB */ 5598 mov r9, rINST, lsr #8 @ r9<- A+ 5599 mov r3, rINST, lsr #12 @ r3<- B 5600 and r9, r9, #15 5601 GET_VREG(r1, r3) @ r1<- vB 5602 GET_VREG(r0, r9) @ r0<- vA 5603 .if 1 5604 cmp r1, #0 @ is second operand zero? 5605 beq common_errDivideByZero 5606 .endif 5607 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5608 5609 @ optional op; may set condition codes 5610 bl __aeabi_idiv @ r0<- op, r0-r3 changed 5611 GET_INST_OPCODE(ip) @ extract opcode from rINST 5612 SET_VREG(r0, r9) @ vAA<- r0 5613 GOTO_OPCODE(ip) @ jump to next instruction 5614 /* 10-13 instructions */ 5615 5616 5617/* ------------------------------ */ 5618 .balign 64 5619.L_OP_REM_INT_2ADDR: /* 0xb4 */ 5620/* File: armv5te/OP_REM_INT_2ADDR.S */ 5621/* idivmod returns quotient in r0 and remainder in r1 */ 5622/* File: armv5te/binop2addr.S */ 5623 /* 5624 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5625 * that specifies an instruction that performs "result = r0 op r1". 5626 * This could be an ARM instruction or a function call. (If the result 5627 * comes back in a register other than r0, you can override "result".) 5628 * 5629 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5630 * vCC (r1). Useful for integer division and modulus. 5631 * 5632 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5633 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5634 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5635 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5636 */ 5637 /* binop/2addr vA, vB */ 5638 mov r9, rINST, lsr #8 @ r9<- A+ 5639 mov r3, rINST, lsr #12 @ r3<- B 5640 and r9, r9, #15 5641 GET_VREG(r1, r3) @ r1<- vB 5642 GET_VREG(r0, r9) @ r0<- vA 5643 .if 1 5644 cmp r1, #0 @ is second operand zero? 5645 beq common_errDivideByZero 5646 .endif 5647 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5648 5649 @ optional op; may set condition codes 5650 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 5651 GET_INST_OPCODE(ip) @ extract opcode from rINST 5652 SET_VREG(r1, r9) @ vAA<- r1 5653 GOTO_OPCODE(ip) @ jump to next instruction 5654 /* 10-13 instructions */ 5655 5656 5657/* ------------------------------ */ 5658 .balign 64 5659.L_OP_AND_INT_2ADDR: /* 0xb5 */ 5660/* File: armv5te/OP_AND_INT_2ADDR.S */ 5661/* File: armv5te/binop2addr.S */ 5662 /* 5663 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5664 * that specifies an instruction that performs "result = r0 op r1". 5665 * This could be an ARM instruction or a function call. (If the result 5666 * comes back in a register other than r0, you can override "result".) 5667 * 5668 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5669 * vCC (r1). Useful for integer division and modulus. 5670 * 5671 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5672 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5673 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5674 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5675 */ 5676 /* binop/2addr vA, vB */ 5677 mov r9, rINST, lsr #8 @ r9<- A+ 5678 mov r3, rINST, lsr #12 @ r3<- B 5679 and r9, r9, #15 5680 GET_VREG(r1, r3) @ r1<- vB 5681 GET_VREG(r0, r9) @ r0<- vA 5682 .if 0 5683 cmp r1, #0 @ is second operand zero? 5684 beq common_errDivideByZero 5685 .endif 5686 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5687 5688 @ optional op; may set condition codes 5689 and r0, r0, r1 @ r0<- op, r0-r3 changed 5690 GET_INST_OPCODE(ip) @ extract opcode from rINST 5691 SET_VREG(r0, r9) @ vAA<- r0 5692 GOTO_OPCODE(ip) @ jump to next instruction 5693 /* 10-13 instructions */ 5694 5695 5696/* ------------------------------ */ 5697 .balign 64 5698.L_OP_OR_INT_2ADDR: /* 0xb6 */ 5699/* File: armv5te/OP_OR_INT_2ADDR.S */ 5700/* File: armv5te/binop2addr.S */ 5701 /* 5702 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5703 * that specifies an instruction that performs "result = r0 op r1". 5704 * This could be an ARM instruction or a function call. (If the result 5705 * comes back in a register other than r0, you can override "result".) 5706 * 5707 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5708 * vCC (r1). Useful for integer division and modulus. 5709 * 5710 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5711 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5712 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5713 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5714 */ 5715 /* binop/2addr vA, vB */ 5716 mov r9, rINST, lsr #8 @ r9<- A+ 5717 mov r3, rINST, lsr #12 @ r3<- B 5718 and r9, r9, #15 5719 GET_VREG(r1, r3) @ r1<- vB 5720 GET_VREG(r0, r9) @ r0<- vA 5721 .if 0 5722 cmp r1, #0 @ is second operand zero? 5723 beq common_errDivideByZero 5724 .endif 5725 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5726 5727 @ optional op; may set condition codes 5728 orr r0, r0, r1 @ r0<- op, r0-r3 changed 5729 GET_INST_OPCODE(ip) @ extract opcode from rINST 5730 SET_VREG(r0, r9) @ vAA<- r0 5731 GOTO_OPCODE(ip) @ jump to next instruction 5732 /* 10-13 instructions */ 5733 5734 5735/* ------------------------------ */ 5736 .balign 64 5737.L_OP_XOR_INT_2ADDR: /* 0xb7 */ 5738/* File: armv5te/OP_XOR_INT_2ADDR.S */ 5739/* File: armv5te/binop2addr.S */ 5740 /* 5741 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5742 * that specifies an instruction that performs "result = r0 op r1". 5743 * This could be an ARM instruction or a function call. (If the result 5744 * comes back in a register other than r0, you can override "result".) 5745 * 5746 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5747 * vCC (r1). Useful for integer division and modulus. 5748 * 5749 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5750 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5751 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5752 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5753 */ 5754 /* binop/2addr vA, vB */ 5755 mov r9, rINST, lsr #8 @ r9<- A+ 5756 mov r3, rINST, lsr #12 @ r3<- B 5757 and r9, r9, #15 5758 GET_VREG(r1, r3) @ r1<- vB 5759 GET_VREG(r0, r9) @ r0<- vA 5760 .if 0 5761 cmp r1, #0 @ is second operand zero? 5762 beq common_errDivideByZero 5763 .endif 5764 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5765 5766 @ optional op; may set condition codes 5767 eor r0, r0, r1 @ r0<- op, r0-r3 changed 5768 GET_INST_OPCODE(ip) @ extract opcode from rINST 5769 SET_VREG(r0, r9) @ vAA<- r0 5770 GOTO_OPCODE(ip) @ jump to next instruction 5771 /* 10-13 instructions */ 5772 5773 5774/* ------------------------------ */ 5775 .balign 64 5776.L_OP_SHL_INT_2ADDR: /* 0xb8 */ 5777/* File: armv5te/OP_SHL_INT_2ADDR.S */ 5778/* File: armv5te/binop2addr.S */ 5779 /* 5780 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5781 * that specifies an instruction that performs "result = r0 op r1". 5782 * This could be an ARM instruction or a function call. (If the result 5783 * comes back in a register other than r0, you can override "result".) 5784 * 5785 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5786 * vCC (r1). Useful for integer division and modulus. 5787 * 5788 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5789 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5790 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5791 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5792 */ 5793 /* binop/2addr vA, vB */ 5794 mov r9, rINST, lsr #8 @ r9<- A+ 5795 mov r3, rINST, lsr #12 @ r3<- B 5796 and r9, r9, #15 5797 GET_VREG(r1, r3) @ r1<- vB 5798 GET_VREG(r0, r9) @ r0<- vA 5799 .if 0 5800 cmp r1, #0 @ is second operand zero? 5801 beq common_errDivideByZero 5802 .endif 5803 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5804 5805 and r1, r1, #31 @ optional op; may set condition codes 5806 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 5807 GET_INST_OPCODE(ip) @ extract opcode from rINST 5808 SET_VREG(r0, r9) @ vAA<- r0 5809 GOTO_OPCODE(ip) @ jump to next instruction 5810 /* 10-13 instructions */ 5811 5812 5813/* ------------------------------ */ 5814 .balign 64 5815.L_OP_SHR_INT_2ADDR: /* 0xb9 */ 5816/* File: armv5te/OP_SHR_INT_2ADDR.S */ 5817/* File: armv5te/binop2addr.S */ 5818 /* 5819 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5820 * that specifies an instruction that performs "result = r0 op r1". 5821 * This could be an ARM instruction or a function call. (If the result 5822 * comes back in a register other than r0, you can override "result".) 5823 * 5824 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5825 * vCC (r1). Useful for integer division and modulus. 5826 * 5827 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5828 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5829 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5830 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5831 */ 5832 /* binop/2addr vA, vB */ 5833 mov r9, rINST, lsr #8 @ r9<- A+ 5834 mov r3, rINST, lsr #12 @ r3<- B 5835 and r9, r9, #15 5836 GET_VREG(r1, r3) @ r1<- vB 5837 GET_VREG(r0, r9) @ r0<- vA 5838 .if 0 5839 cmp r1, #0 @ is second operand zero? 5840 beq common_errDivideByZero 5841 .endif 5842 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5843 5844 and r1, r1, #31 @ optional op; may set condition codes 5845 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 5846 GET_INST_OPCODE(ip) @ extract opcode from rINST 5847 SET_VREG(r0, r9) @ vAA<- r0 5848 GOTO_OPCODE(ip) @ jump to next instruction 5849 /* 10-13 instructions */ 5850 5851 5852/* ------------------------------ */ 5853 .balign 64 5854.L_OP_USHR_INT_2ADDR: /* 0xba */ 5855/* File: armv5te/OP_USHR_INT_2ADDR.S */ 5856/* File: armv5te/binop2addr.S */ 5857 /* 5858 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5859 * that specifies an instruction that performs "result = r0 op r1". 5860 * This could be an ARM instruction or a function call. (If the result 5861 * comes back in a register other than r0, you can override "result".) 5862 * 5863 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5864 * vCC (r1). Useful for integer division and modulus. 5865 * 5866 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5867 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5868 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5869 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5870 */ 5871 /* binop/2addr vA, vB */ 5872 mov r9, rINST, lsr #8 @ r9<- A+ 5873 mov r3, rINST, lsr #12 @ r3<- B 5874 and r9, r9, #15 5875 GET_VREG(r1, r3) @ r1<- vB 5876 GET_VREG(r0, r9) @ r0<- vA 5877 .if 0 5878 cmp r1, #0 @ is second operand zero? 5879 beq common_errDivideByZero 5880 .endif 5881 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5882 5883 and r1, r1, #31 @ optional op; may set condition codes 5884 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 5885 GET_INST_OPCODE(ip) @ extract opcode from rINST 5886 SET_VREG(r0, r9) @ vAA<- r0 5887 GOTO_OPCODE(ip) @ jump to next instruction 5888 /* 10-13 instructions */ 5889 5890 5891/* ------------------------------ */ 5892 .balign 64 5893.L_OP_ADD_LONG_2ADDR: /* 0xbb */ 5894/* File: armv5te/OP_ADD_LONG_2ADDR.S */ 5895/* File: armv5te/binopWide2addr.S */ 5896 /* 5897 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5898 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5899 * This could be an ARM instruction or a function call. (If the result 5900 * comes back in a register other than r0, you can override "result".) 5901 * 5902 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5903 * vCC (r1). Useful for integer division and modulus. 5904 * 5905 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5906 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5907 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5908 * rem-double/2addr 5909 */ 5910 /* binop/2addr vA, vB */ 5911 mov r9, rINST, lsr #8 @ r9<- A+ 5912 mov r1, rINST, lsr #12 @ r1<- B 5913 and r9, r9, #15 5914 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5915 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5916 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5917 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5918 .if 0 5919 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5920 beq common_errDivideByZero 5921 .endif 5922 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5923 5924 adds r0, r0, r2 @ optional op; may set condition codes 5925 adc r1, r1, r3 @ result<- op, r0-r3 changed 5926 GET_INST_OPCODE(ip) @ extract opcode from rINST 5927 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5928 GOTO_OPCODE(ip) @ jump to next instruction 5929 /* 12-15 instructions */ 5930 5931 5932/* ------------------------------ */ 5933 .balign 64 5934.L_OP_SUB_LONG_2ADDR: /* 0xbc */ 5935/* File: armv5te/OP_SUB_LONG_2ADDR.S */ 5936/* File: armv5te/binopWide2addr.S */ 5937 /* 5938 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5939 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5940 * This could be an ARM instruction or a function call. (If the result 5941 * comes back in a register other than r0, you can override "result".) 5942 * 5943 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5944 * vCC (r1). Useful for integer division and modulus. 5945 * 5946 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5947 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5948 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5949 * rem-double/2addr 5950 */ 5951 /* binop/2addr vA, vB */ 5952 mov r9, rINST, lsr #8 @ r9<- A+ 5953 mov r1, rINST, lsr #12 @ r1<- B 5954 and r9, r9, #15 5955 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5956 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5957 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5958 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5959 .if 0 5960 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5961 beq common_errDivideByZero 5962 .endif 5963 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5964 5965 subs r0, r0, r2 @ optional op; may set condition codes 5966 sbc r1, r1, r3 @ result<- op, r0-r3 changed 5967 GET_INST_OPCODE(ip) @ extract opcode from rINST 5968 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5969 GOTO_OPCODE(ip) @ jump to next instruction 5970 /* 12-15 instructions */ 5971 5972 5973/* ------------------------------ */ 5974 .balign 64 5975.L_OP_MUL_LONG_2ADDR: /* 0xbd */ 5976/* File: armv5te/OP_MUL_LONG_2ADDR.S */ 5977 /* 5978 * Signed 64-bit integer multiply, "/2addr" version. 5979 * 5980 * See OP_MUL_LONG for an explanation. 5981 * 5982 * We get a little tight on registers, so to avoid looking up &fp[A] 5983 * again we stuff it into rINST. 5984 */ 5985 /* mul-long/2addr vA, vB */ 5986 mov r9, rINST, lsr #8 @ r9<- A+ 5987 mov r1, rINST, lsr #12 @ r1<- B 5988 and r9, r9, #15 5989 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5990 add rINST, rFP, r9, lsl #2 @ rINST<- &fp[A] 5991 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5992 ldmia rINST, {r0-r1} @ r0/r1<- vAA/vAA+1 5993 mul ip, r2, r1 @ ip<- ZxW 5994 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 5995 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 5996 mov r0, rINST @ r0<- &fp[A] (free up rINST) 5997 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5998 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 5999 GET_INST_OPCODE(ip) @ extract opcode from rINST 6000 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 6001 GOTO_OPCODE(ip) @ jump to next instruction 6002 6003/* ------------------------------ */ 6004 .balign 64 6005.L_OP_DIV_LONG_2ADDR: /* 0xbe */ 6006/* File: armv5te/OP_DIV_LONG_2ADDR.S */ 6007/* File: armv5te/binopWide2addr.S */ 6008 /* 6009 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6010 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6011 * This could be an ARM instruction or a function call. (If the result 6012 * comes back in a register other than r0, you can override "result".) 6013 * 6014 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6015 * vCC (r1). Useful for integer division and modulus. 6016 * 6017 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6018 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6019 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6020 * rem-double/2addr 6021 */ 6022 /* binop/2addr vA, vB */ 6023 mov r9, rINST, lsr #8 @ r9<- A+ 6024 mov r1, rINST, lsr #12 @ r1<- B 6025 and r9, r9, #15 6026 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6027 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6028 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6029 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6030 .if 1 6031 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6032 beq common_errDivideByZero 6033 .endif 6034 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6035 6036 @ optional op; may set condition codes 6037 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 6038 GET_INST_OPCODE(ip) @ extract opcode from rINST 6039 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6040 GOTO_OPCODE(ip) @ jump to next instruction 6041 /* 12-15 instructions */ 6042 6043 6044/* ------------------------------ */ 6045 .balign 64 6046.L_OP_REM_LONG_2ADDR: /* 0xbf */ 6047/* File: armv5te/OP_REM_LONG_2ADDR.S */ 6048/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 6049/* File: armv5te/binopWide2addr.S */ 6050 /* 6051 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6052 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6053 * This could be an ARM instruction or a function call. (If the result 6054 * comes back in a register other than r0, you can override "result".) 6055 * 6056 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6057 * vCC (r1). Useful for integer division and modulus. 6058 * 6059 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6060 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6061 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6062 * rem-double/2addr 6063 */ 6064 /* binop/2addr vA, vB */ 6065 mov r9, rINST, lsr #8 @ r9<- A+ 6066 mov r1, rINST, lsr #12 @ r1<- B 6067 and r9, r9, #15 6068 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6069 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6070 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6071 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6072 .if 1 6073 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6074 beq common_errDivideByZero 6075 .endif 6076 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6077 6078 @ optional op; may set condition codes 6079 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 6080 GET_INST_OPCODE(ip) @ extract opcode from rINST 6081 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 6082 GOTO_OPCODE(ip) @ jump to next instruction 6083 /* 12-15 instructions */ 6084 6085 6086/* ------------------------------ */ 6087 .balign 64 6088.L_OP_AND_LONG_2ADDR: /* 0xc0 */ 6089/* File: armv5te/OP_AND_LONG_2ADDR.S */ 6090/* File: armv5te/binopWide2addr.S */ 6091 /* 6092 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6093 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6094 * This could be an ARM instruction or a function call. (If the result 6095 * comes back in a register other than r0, you can override "result".) 6096 * 6097 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6098 * vCC (r1). Useful for integer division and modulus. 6099 * 6100 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6101 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6102 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6103 * rem-double/2addr 6104 */ 6105 /* binop/2addr vA, vB */ 6106 mov r9, rINST, lsr #8 @ r9<- A+ 6107 mov r1, rINST, lsr #12 @ r1<- B 6108 and r9, r9, #15 6109 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6110 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6111 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6112 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6113 .if 0 6114 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6115 beq common_errDivideByZero 6116 .endif 6117 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6118 6119 and r0, r0, r2 @ optional op; may set condition codes 6120 and r1, r1, r3 @ result<- op, r0-r3 changed 6121 GET_INST_OPCODE(ip) @ extract opcode from rINST 6122 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6123 GOTO_OPCODE(ip) @ jump to next instruction 6124 /* 12-15 instructions */ 6125 6126 6127/* ------------------------------ */ 6128 .balign 64 6129.L_OP_OR_LONG_2ADDR: /* 0xc1 */ 6130/* File: armv5te/OP_OR_LONG_2ADDR.S */ 6131/* File: armv5te/binopWide2addr.S */ 6132 /* 6133 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6134 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6135 * This could be an ARM instruction or a function call. (If the result 6136 * comes back in a register other than r0, you can override "result".) 6137 * 6138 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6139 * vCC (r1). Useful for integer division and modulus. 6140 * 6141 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6142 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6143 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6144 * rem-double/2addr 6145 */ 6146 /* binop/2addr vA, vB */ 6147 mov r9, rINST, lsr #8 @ r9<- A+ 6148 mov r1, rINST, lsr #12 @ r1<- B 6149 and r9, r9, #15 6150 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6151 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6152 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6153 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6154 .if 0 6155 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6156 beq common_errDivideByZero 6157 .endif 6158 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6159 6160 orr r0, r0, r2 @ optional op; may set condition codes 6161 orr r1, r1, r3 @ result<- op, r0-r3 changed 6162 GET_INST_OPCODE(ip) @ extract opcode from rINST 6163 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6164 GOTO_OPCODE(ip) @ jump to next instruction 6165 /* 12-15 instructions */ 6166 6167 6168/* ------------------------------ */ 6169 .balign 64 6170.L_OP_XOR_LONG_2ADDR: /* 0xc2 */ 6171/* File: armv5te/OP_XOR_LONG_2ADDR.S */ 6172/* File: armv5te/binopWide2addr.S */ 6173 /* 6174 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6175 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6176 * This could be an ARM instruction or a function call. (If the result 6177 * comes back in a register other than r0, you can override "result".) 6178 * 6179 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6180 * vCC (r1). Useful for integer division and modulus. 6181 * 6182 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6183 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6184 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6185 * rem-double/2addr 6186 */ 6187 /* binop/2addr vA, vB */ 6188 mov r9, rINST, lsr #8 @ r9<- A+ 6189 mov r1, rINST, lsr #12 @ r1<- B 6190 and r9, r9, #15 6191 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6192 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6193 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6194 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6195 .if 0 6196 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6197 beq common_errDivideByZero 6198 .endif 6199 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6200 6201 eor r0, r0, r2 @ optional op; may set condition codes 6202 eor r1, r1, r3 @ result<- op, r0-r3 changed 6203 GET_INST_OPCODE(ip) @ extract opcode from rINST 6204 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6205 GOTO_OPCODE(ip) @ jump to next instruction 6206 /* 12-15 instructions */ 6207 6208 6209/* ------------------------------ */ 6210 .balign 64 6211.L_OP_SHL_LONG_2ADDR: /* 0xc3 */ 6212/* File: armv5te/OP_SHL_LONG_2ADDR.S */ 6213 /* 6214 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 6215 * 32-bit shift distance. 6216 */ 6217 /* shl-long/2addr vA, vB */ 6218 mov r9, rINST, lsr #8 @ r9<- A+ 6219 mov r3, rINST, lsr #12 @ r3<- B 6220 and r9, r9, #15 6221 GET_VREG(r2, r3) @ r2<- vB 6222 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6223 and r2, r2, #63 @ r2<- r2 & 0x3f 6224 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6225 6226 mov r1, r1, asl r2 @ r1<- r1 << r2 6227 rsb r3, r2, #32 @ r3<- 32 - r2 6228 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 6229 subs ip, r2, #32 @ ip<- r2 - 32 6230 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6231 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 6232 mov r0, r0, asl r2 @ r0<- r0 << r2 6233 b .LOP_SHL_LONG_2ADDR_finish 6234 6235/* ------------------------------ */ 6236 .balign 64 6237.L_OP_SHR_LONG_2ADDR: /* 0xc4 */ 6238/* File: armv5te/OP_SHR_LONG_2ADDR.S */ 6239 /* 6240 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 6241 * 32-bit shift distance. 6242 */ 6243 /* shr-long/2addr vA, vB */ 6244 mov r9, rINST, lsr #8 @ r9<- A+ 6245 mov r3, rINST, lsr #12 @ r3<- B 6246 and r9, r9, #15 6247 GET_VREG(r2, r3) @ r2<- vB 6248 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6249 and r2, r2, #63 @ r2<- r2 & 0x3f 6250 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6251 6252 mov r0, r0, lsr r2 @ r0<- r2 >> r2 6253 rsb r3, r2, #32 @ r3<- 32 - r2 6254 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 6255 subs ip, r2, #32 @ ip<- r2 - 32 6256 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6257 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 6258 mov r1, r1, asr r2 @ r1<- r1 >> r2 6259 b .LOP_SHR_LONG_2ADDR_finish 6260 6261/* ------------------------------ */ 6262 .balign 64 6263.L_OP_USHR_LONG_2ADDR: /* 0xc5 */ 6264/* File: armv5te/OP_USHR_LONG_2ADDR.S */ 6265 /* 6266 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 6267 * 32-bit shift distance. 6268 */ 6269 /* ushr-long/2addr vA, vB */ 6270 mov r9, rINST, lsr #8 @ r9<- A+ 6271 mov r3, rINST, lsr #12 @ r3<- B 6272 and r9, r9, #15 6273 GET_VREG(r2, r3) @ r2<- vB 6274 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6275 and r2, r2, #63 @ r2<- r2 & 0x3f 6276 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6277 6278 mov r0, r0, lsr r2 @ r0<- r2 >> r2 6279 rsb r3, r2, #32 @ r3<- 32 - r2 6280 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 6281 subs ip, r2, #32 @ ip<- r2 - 32 6282 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6283 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 6284 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 6285 b .LOP_USHR_LONG_2ADDR_finish 6286 6287/* ------------------------------ */ 6288 .balign 64 6289.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */ 6290/* File: armv5te/OP_ADD_FLOAT_2ADDR.S */ 6291/* File: armv5te/binop2addr.S */ 6292 /* 6293 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6294 * that specifies an instruction that performs "result = r0 op r1". 6295 * This could be an ARM instruction or a function call. (If the result 6296 * comes back in a register other than r0, you can override "result".) 6297 * 6298 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6299 * vCC (r1). Useful for integer division and modulus. 6300 * 6301 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6302 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6303 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6304 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6305 */ 6306 /* binop/2addr vA, vB */ 6307 mov r9, rINST, lsr #8 @ r9<- A+ 6308 mov r3, rINST, lsr #12 @ r3<- B 6309 and r9, r9, #15 6310 GET_VREG(r1, r3) @ r1<- vB 6311 GET_VREG(r0, r9) @ r0<- vA 6312 .if 0 6313 cmp r1, #0 @ is second operand zero? 6314 beq common_errDivideByZero 6315 .endif 6316 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6317 6318 @ optional op; may set condition codes 6319 bl __aeabi_fadd @ r0<- op, r0-r3 changed 6320 GET_INST_OPCODE(ip) @ extract opcode from rINST 6321 SET_VREG(r0, r9) @ vAA<- r0 6322 GOTO_OPCODE(ip) @ jump to next instruction 6323 /* 10-13 instructions */ 6324 6325 6326/* ------------------------------ */ 6327 .balign 64 6328.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */ 6329/* File: armv5te/OP_SUB_FLOAT_2ADDR.S */ 6330/* File: armv5te/binop2addr.S */ 6331 /* 6332 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6333 * that specifies an instruction that performs "result = r0 op r1". 6334 * This could be an ARM instruction or a function call. (If the result 6335 * comes back in a register other than r0, you can override "result".) 6336 * 6337 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6338 * vCC (r1). Useful for integer division and modulus. 6339 * 6340 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6341 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6342 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6343 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6344 */ 6345 /* binop/2addr vA, vB */ 6346 mov r9, rINST, lsr #8 @ r9<- A+ 6347 mov r3, rINST, lsr #12 @ r3<- B 6348 and r9, r9, #15 6349 GET_VREG(r1, r3) @ r1<- vB 6350 GET_VREG(r0, r9) @ r0<- vA 6351 .if 0 6352 cmp r1, #0 @ is second operand zero? 6353 beq common_errDivideByZero 6354 .endif 6355 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6356 6357 @ optional op; may set condition codes 6358 bl __aeabi_fsub @ r0<- op, r0-r3 changed 6359 GET_INST_OPCODE(ip) @ extract opcode from rINST 6360 SET_VREG(r0, r9) @ vAA<- r0 6361 GOTO_OPCODE(ip) @ jump to next instruction 6362 /* 10-13 instructions */ 6363 6364 6365/* ------------------------------ */ 6366 .balign 64 6367.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */ 6368/* File: armv5te/OP_MUL_FLOAT_2ADDR.S */ 6369/* File: armv5te/binop2addr.S */ 6370 /* 6371 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6372 * that specifies an instruction that performs "result = r0 op r1". 6373 * This could be an ARM instruction or a function call. (If the result 6374 * comes back in a register other than r0, you can override "result".) 6375 * 6376 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6377 * vCC (r1). Useful for integer division and modulus. 6378 * 6379 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6380 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6381 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6382 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6383 */ 6384 /* binop/2addr vA, vB */ 6385 mov r9, rINST, lsr #8 @ r9<- A+ 6386 mov r3, rINST, lsr #12 @ r3<- B 6387 and r9, r9, #15 6388 GET_VREG(r1, r3) @ r1<- vB 6389 GET_VREG(r0, r9) @ r0<- vA 6390 .if 0 6391 cmp r1, #0 @ is second operand zero? 6392 beq common_errDivideByZero 6393 .endif 6394 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6395 6396 @ optional op; may set condition codes 6397 bl __aeabi_fmul @ r0<- op, r0-r3 changed 6398 GET_INST_OPCODE(ip) @ extract opcode from rINST 6399 SET_VREG(r0, r9) @ vAA<- r0 6400 GOTO_OPCODE(ip) @ jump to next instruction 6401 /* 10-13 instructions */ 6402 6403 6404/* ------------------------------ */ 6405 .balign 64 6406.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */ 6407/* File: armv5te/OP_DIV_FLOAT_2ADDR.S */ 6408/* File: armv5te/binop2addr.S */ 6409 /* 6410 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6411 * that specifies an instruction that performs "result = r0 op r1". 6412 * This could be an ARM instruction or a function call. (If the result 6413 * comes back in a register other than r0, you can override "result".) 6414 * 6415 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6416 * vCC (r1). Useful for integer division and modulus. 6417 * 6418 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6419 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6420 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6421 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6422 */ 6423 /* binop/2addr vA, vB */ 6424 mov r9, rINST, lsr #8 @ r9<- A+ 6425 mov r3, rINST, lsr #12 @ r3<- B 6426 and r9, r9, #15 6427 GET_VREG(r1, r3) @ r1<- vB 6428 GET_VREG(r0, r9) @ r0<- vA 6429 .if 0 6430 cmp r1, #0 @ is second operand zero? 6431 beq common_errDivideByZero 6432 .endif 6433 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6434 6435 @ optional op; may set condition codes 6436 bl __aeabi_fdiv @ r0<- op, r0-r3 changed 6437 GET_INST_OPCODE(ip) @ extract opcode from rINST 6438 SET_VREG(r0, r9) @ vAA<- r0 6439 GOTO_OPCODE(ip) @ jump to next instruction 6440 /* 10-13 instructions */ 6441 6442 6443/* ------------------------------ */ 6444 .balign 64 6445.L_OP_REM_FLOAT_2ADDR: /* 0xca */ 6446/* File: armv5te/OP_REM_FLOAT_2ADDR.S */ 6447/* EABI doesn't define a float remainder function, but libm does */ 6448/* File: armv5te/binop2addr.S */ 6449 /* 6450 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6451 * that specifies an instruction that performs "result = r0 op r1". 6452 * This could be an ARM instruction or a function call. (If the result 6453 * comes back in a register other than r0, you can override "result".) 6454 * 6455 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6456 * vCC (r1). Useful for integer division and modulus. 6457 * 6458 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6459 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6460 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6461 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6462 */ 6463 /* binop/2addr vA, vB */ 6464 mov r9, rINST, lsr #8 @ r9<- A+ 6465 mov r3, rINST, lsr #12 @ r3<- B 6466 and r9, r9, #15 6467 GET_VREG(r1, r3) @ r1<- vB 6468 GET_VREG(r0, r9) @ r0<- vA 6469 .if 0 6470 cmp r1, #0 @ is second operand zero? 6471 beq common_errDivideByZero 6472 .endif 6473 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6474 6475 @ optional op; may set condition codes 6476 bl fmodf @ 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_ADD_DOUBLE_2ADDR: /* 0xcb */ 6486/* File: armv5te/OP_ADD_DOUBLE_2ADDR.S */ 6487/* File: armv5te/binopWide2addr.S */ 6488 /* 6489 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6490 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 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-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6498 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6499 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6500 * rem-double/2addr 6501 */ 6502 /* binop/2addr vA, vB */ 6503 mov r9, rINST, lsr #8 @ r9<- A+ 6504 mov r1, rINST, lsr #12 @ r1<- B 6505 and r9, r9, #15 6506 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6507 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6508 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6509 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6510 .if 0 6511 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6512 beq common_errDivideByZero 6513 .endif 6514 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6515 6516 @ optional op; may set condition codes 6517 bl __aeabi_dadd @ result<- op, r0-r3 changed 6518 GET_INST_OPCODE(ip) @ extract opcode from rINST 6519 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6520 GOTO_OPCODE(ip) @ jump to next instruction 6521 /* 12-15 instructions */ 6522 6523 6524/* ------------------------------ */ 6525 .balign 64 6526.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */ 6527/* File: armv5te/OP_SUB_DOUBLE_2ADDR.S */ 6528/* File: armv5te/binopWide2addr.S */ 6529 /* 6530 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6531 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6532 * This could be an ARM instruction or a function call. (If the result 6533 * comes back in a register other than r0, you can override "result".) 6534 * 6535 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6536 * vCC (r1). Useful for integer division and modulus. 6537 * 6538 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6539 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6540 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6541 * rem-double/2addr 6542 */ 6543 /* binop/2addr vA, vB */ 6544 mov r9, rINST, lsr #8 @ r9<- A+ 6545 mov r1, rINST, lsr #12 @ r1<- B 6546 and r9, r9, #15 6547 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6548 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6549 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6550 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6551 .if 0 6552 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6553 beq common_errDivideByZero 6554 .endif 6555 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6556 6557 @ optional op; may set condition codes 6558 bl __aeabi_dsub @ result<- op, r0-r3 changed 6559 GET_INST_OPCODE(ip) @ extract opcode from rINST 6560 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6561 GOTO_OPCODE(ip) @ jump to next instruction 6562 /* 12-15 instructions */ 6563 6564 6565/* ------------------------------ */ 6566 .balign 64 6567.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */ 6568/* File: armv5te/OP_MUL_DOUBLE_2ADDR.S */ 6569/* File: armv5te/binopWide2addr.S */ 6570 /* 6571 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6572 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6573 * This could be an ARM instruction or a function call. (If the result 6574 * comes back in a register other than r0, you can override "result".) 6575 * 6576 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6577 * vCC (r1). Useful for integer division and modulus. 6578 * 6579 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6580 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6581 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6582 * rem-double/2addr 6583 */ 6584 /* binop/2addr vA, vB */ 6585 mov r9, rINST, lsr #8 @ r9<- A+ 6586 mov r1, rINST, lsr #12 @ r1<- B 6587 and r9, r9, #15 6588 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6589 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6590 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6591 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6592 .if 0 6593 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6594 beq common_errDivideByZero 6595 .endif 6596 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6597 6598 @ optional op; may set condition codes 6599 bl __aeabi_dmul @ result<- op, r0-r3 changed 6600 GET_INST_OPCODE(ip) @ extract opcode from rINST 6601 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6602 GOTO_OPCODE(ip) @ jump to next instruction 6603 /* 12-15 instructions */ 6604 6605 6606/* ------------------------------ */ 6607 .balign 64 6608.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */ 6609/* File: armv5te/OP_DIV_DOUBLE_2ADDR.S */ 6610/* File: armv5te/binopWide2addr.S */ 6611 /* 6612 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6613 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6614 * This could be an ARM instruction or a function call. (If the result 6615 * comes back in a register other than r0, you can override "result".) 6616 * 6617 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6618 * vCC (r1). Useful for integer division and modulus. 6619 * 6620 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6621 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6622 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6623 * rem-double/2addr 6624 */ 6625 /* binop/2addr vA, vB */ 6626 mov r9, rINST, lsr #8 @ r9<- A+ 6627 mov r1, rINST, lsr #12 @ r1<- B 6628 and r9, r9, #15 6629 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6630 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6631 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6632 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6633 .if 0 6634 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6635 beq common_errDivideByZero 6636 .endif 6637 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6638 6639 @ optional op; may set condition codes 6640 bl __aeabi_ddiv @ result<- op, r0-r3 changed 6641 GET_INST_OPCODE(ip) @ extract opcode from rINST 6642 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6643 GOTO_OPCODE(ip) @ jump to next instruction 6644 /* 12-15 instructions */ 6645 6646 6647/* ------------------------------ */ 6648 .balign 64 6649.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */ 6650/* File: armv5te/OP_REM_DOUBLE_2ADDR.S */ 6651/* EABI doesn't define a double remainder function, but libm does */ 6652/* File: armv5te/binopWide2addr.S */ 6653 /* 6654 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6655 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6656 * This could be an ARM instruction or a function call. (If the result 6657 * comes back in a register other than r0, you can override "result".) 6658 * 6659 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6660 * vCC (r1). Useful for integer division and modulus. 6661 * 6662 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6663 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6664 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6665 * rem-double/2addr 6666 */ 6667 /* binop/2addr vA, vB */ 6668 mov r9, rINST, lsr #8 @ r9<- A+ 6669 mov r1, rINST, lsr #12 @ r1<- B 6670 and r9, r9, #15 6671 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6672 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6673 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6674 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6675 .if 0 6676 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6677 beq common_errDivideByZero 6678 .endif 6679 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6680 6681 @ optional op; may set condition codes 6682 bl fmod @ result<- op, r0-r3 changed 6683 GET_INST_OPCODE(ip) @ extract opcode from rINST 6684 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6685 GOTO_OPCODE(ip) @ jump to next instruction 6686 /* 12-15 instructions */ 6687 6688 6689/* ------------------------------ */ 6690 .balign 64 6691.L_OP_ADD_INT_LIT16: /* 0xd0 */ 6692/* File: armv5te/OP_ADD_INT_LIT16.S */ 6693/* File: armv5te/binopLit16.S */ 6694 /* 6695 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6696 * that specifies an instruction that performs "result = r0 op r1". 6697 * This could be an ARM instruction or a function call. (If the result 6698 * comes back in a register other than r0, you can override "result".) 6699 * 6700 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6701 * vCC (r1). Useful for integer division and modulus. 6702 * 6703 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6704 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6705 */ 6706 /* binop/lit16 vA, vB, #+CCCC */ 6707 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6708 mov r2, rINST, lsr #12 @ r2<- B 6709 mov r9, rINST, lsr #8 @ r9<- A+ 6710 GET_VREG(r0, r2) @ r0<- vB 6711 and r9, r9, #15 6712 .if 0 6713 cmp r1, #0 @ is second operand zero? 6714 beq common_errDivideByZero 6715 .endif 6716 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6717 6718 add r0, r0, r1 @ r0<- op, r0-r3 changed 6719 GET_INST_OPCODE(ip) @ extract opcode from rINST 6720 SET_VREG(r0, r9) @ vAA<- r0 6721 GOTO_OPCODE(ip) @ jump to next instruction 6722 /* 10-13 instructions */ 6723 6724 6725/* ------------------------------ */ 6726 .balign 64 6727.L_OP_RSUB_INT: /* 0xd1 */ 6728/* File: armv5te/OP_RSUB_INT.S */ 6729/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */ 6730/* File: armv5te/binopLit16.S */ 6731 /* 6732 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6733 * that specifies an instruction that performs "result = r0 op r1". 6734 * This could be an ARM instruction or a function call. (If the result 6735 * comes back in a register other than r0, you can override "result".) 6736 * 6737 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6738 * vCC (r1). Useful for integer division and modulus. 6739 * 6740 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6741 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6742 */ 6743 /* binop/lit16 vA, vB, #+CCCC */ 6744 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6745 mov r2, rINST, lsr #12 @ r2<- B 6746 mov r9, rINST, lsr #8 @ r9<- A+ 6747 GET_VREG(r0, r2) @ r0<- vB 6748 and r9, r9, #15 6749 .if 0 6750 cmp r1, #0 @ is second operand zero? 6751 beq common_errDivideByZero 6752 .endif 6753 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6754 6755 rsb r0, r0, r1 @ r0<- op, r0-r3 changed 6756 GET_INST_OPCODE(ip) @ extract opcode from rINST 6757 SET_VREG(r0, r9) @ vAA<- r0 6758 GOTO_OPCODE(ip) @ jump to next instruction 6759 /* 10-13 instructions */ 6760 6761 6762/* ------------------------------ */ 6763 .balign 64 6764.L_OP_MUL_INT_LIT16: /* 0xd2 */ 6765/* File: armv5te/OP_MUL_INT_LIT16.S */ 6766/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 6767/* File: armv5te/binopLit16.S */ 6768 /* 6769 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6770 * that specifies an instruction that performs "result = r0 op r1". 6771 * This could be an ARM instruction or a function call. (If the result 6772 * comes back in a register other than r0, you can override "result".) 6773 * 6774 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6775 * vCC (r1). Useful for integer division and modulus. 6776 * 6777 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6778 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6779 */ 6780 /* binop/lit16 vA, vB, #+CCCC */ 6781 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6782 mov r2, rINST, lsr #12 @ r2<- B 6783 mov r9, rINST, lsr #8 @ r9<- A+ 6784 GET_VREG(r0, r2) @ r0<- vB 6785 and r9, r9, #15 6786 .if 0 6787 cmp r1, #0 @ is second operand zero? 6788 beq common_errDivideByZero 6789 .endif 6790 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6791 6792 mul r0, r1, r0 @ r0<- op, r0-r3 changed 6793 GET_INST_OPCODE(ip) @ extract opcode from rINST 6794 SET_VREG(r0, r9) @ vAA<- r0 6795 GOTO_OPCODE(ip) @ jump to next instruction 6796 /* 10-13 instructions */ 6797 6798 6799/* ------------------------------ */ 6800 .balign 64 6801.L_OP_DIV_INT_LIT16: /* 0xd3 */ 6802/* File: armv5te/OP_DIV_INT_LIT16.S */ 6803/* File: armv5te/binopLit16.S */ 6804 /* 6805 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6806 * that specifies an instruction that performs "result = r0 op r1". 6807 * This could be an ARM instruction or a function call. (If the result 6808 * comes back in a register other than r0, you can override "result".) 6809 * 6810 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6811 * vCC (r1). Useful for integer division and modulus. 6812 * 6813 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6814 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6815 */ 6816 /* binop/lit16 vA, vB, #+CCCC */ 6817 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6818 mov r2, rINST, lsr #12 @ r2<- B 6819 mov r9, rINST, lsr #8 @ r9<- A+ 6820 GET_VREG(r0, r2) @ r0<- vB 6821 and r9, r9, #15 6822 .if 1 6823 cmp r1, #0 @ is second operand zero? 6824 beq common_errDivideByZero 6825 .endif 6826 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6827 6828 bl __aeabi_idiv @ r0<- op, r0-r3 changed 6829 GET_INST_OPCODE(ip) @ extract opcode from rINST 6830 SET_VREG(r0, r9) @ vAA<- r0 6831 GOTO_OPCODE(ip) @ jump to next instruction 6832 /* 10-13 instructions */ 6833 6834 6835/* ------------------------------ */ 6836 .balign 64 6837.L_OP_REM_INT_LIT16: /* 0xd4 */ 6838/* File: armv5te/OP_REM_INT_LIT16.S */ 6839/* idivmod returns quotient in r0 and remainder in r1 */ 6840/* File: armv5te/binopLit16.S */ 6841 /* 6842 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6843 * that specifies an instruction that performs "result = r0 op r1". 6844 * This could be an ARM instruction or a function call. (If the result 6845 * comes back in a register other than r0, you can override "result".) 6846 * 6847 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6848 * vCC (r1). Useful for integer division and modulus. 6849 * 6850 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6851 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6852 */ 6853 /* binop/lit16 vA, vB, #+CCCC */ 6854 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6855 mov r2, rINST, lsr #12 @ r2<- B 6856 mov r9, rINST, lsr #8 @ r9<- A+ 6857 GET_VREG(r0, r2) @ r0<- vB 6858 and r9, r9, #15 6859 .if 1 6860 cmp r1, #0 @ is second operand zero? 6861 beq common_errDivideByZero 6862 .endif 6863 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6864 6865 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 6866 GET_INST_OPCODE(ip) @ extract opcode from rINST 6867 SET_VREG(r1, r9) @ vAA<- r1 6868 GOTO_OPCODE(ip) @ jump to next instruction 6869 /* 10-13 instructions */ 6870 6871 6872/* ------------------------------ */ 6873 .balign 64 6874.L_OP_AND_INT_LIT16: /* 0xd5 */ 6875/* File: armv5te/OP_AND_INT_LIT16.S */ 6876/* File: armv5te/binopLit16.S */ 6877 /* 6878 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6879 * that specifies an instruction that performs "result = r0 op r1". 6880 * This could be an ARM instruction or a function call. (If the result 6881 * comes back in a register other than r0, you can override "result".) 6882 * 6883 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6884 * vCC (r1). Useful for integer division and modulus. 6885 * 6886 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6887 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6888 */ 6889 /* binop/lit16 vA, vB, #+CCCC */ 6890 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6891 mov r2, rINST, lsr #12 @ r2<- B 6892 mov r9, rINST, lsr #8 @ r9<- A+ 6893 GET_VREG(r0, r2) @ r0<- vB 6894 and r9, r9, #15 6895 .if 0 6896 cmp r1, #0 @ is second operand zero? 6897 beq common_errDivideByZero 6898 .endif 6899 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6900 6901 and r0, r0, r1 @ r0<- op, r0-r3 changed 6902 GET_INST_OPCODE(ip) @ extract opcode from rINST 6903 SET_VREG(r0, r9) @ vAA<- r0 6904 GOTO_OPCODE(ip) @ jump to next instruction 6905 /* 10-13 instructions */ 6906 6907 6908/* ------------------------------ */ 6909 .balign 64 6910.L_OP_OR_INT_LIT16: /* 0xd6 */ 6911/* File: armv5te/OP_OR_INT_LIT16.S */ 6912/* File: armv5te/binopLit16.S */ 6913 /* 6914 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6915 * that specifies an instruction that performs "result = r0 op r1". 6916 * This could be an ARM instruction or a function call. (If the result 6917 * comes back in a register other than r0, you can override "result".) 6918 * 6919 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6920 * vCC (r1). Useful for integer division and modulus. 6921 * 6922 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6923 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6924 */ 6925 /* binop/lit16 vA, vB, #+CCCC */ 6926 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6927 mov r2, rINST, lsr #12 @ r2<- B 6928 mov r9, rINST, lsr #8 @ r9<- A+ 6929 GET_VREG(r0, r2) @ r0<- vB 6930 and r9, r9, #15 6931 .if 0 6932 cmp r1, #0 @ is second operand zero? 6933 beq common_errDivideByZero 6934 .endif 6935 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6936 6937 orr r0, r0, r1 @ r0<- op, r0-r3 changed 6938 GET_INST_OPCODE(ip) @ extract opcode from rINST 6939 SET_VREG(r0, r9) @ vAA<- r0 6940 GOTO_OPCODE(ip) @ jump to next instruction 6941 /* 10-13 instructions */ 6942 6943 6944/* ------------------------------ */ 6945 .balign 64 6946.L_OP_XOR_INT_LIT16: /* 0xd7 */ 6947/* File: armv5te/OP_XOR_INT_LIT16.S */ 6948/* File: armv5te/binopLit16.S */ 6949 /* 6950 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6951 * that specifies an instruction that performs "result = r0 op r1". 6952 * This could be an ARM instruction or a function call. (If the result 6953 * comes back in a register other than r0, you can override "result".) 6954 * 6955 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6956 * vCC (r1). Useful for integer division and modulus. 6957 * 6958 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6959 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6960 */ 6961 /* binop/lit16 vA, vB, #+CCCC */ 6962 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6963 mov r2, rINST, lsr #12 @ r2<- B 6964 mov r9, rINST, lsr #8 @ r9<- A+ 6965 GET_VREG(r0, r2) @ r0<- vB 6966 and r9, r9, #15 6967 .if 0 6968 cmp r1, #0 @ is second operand zero? 6969 beq common_errDivideByZero 6970 .endif 6971 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6972 6973 eor r0, r0, r1 @ r0<- op, r0-r3 changed 6974 GET_INST_OPCODE(ip) @ extract opcode from rINST 6975 SET_VREG(r0, r9) @ vAA<- r0 6976 GOTO_OPCODE(ip) @ jump to next instruction 6977 /* 10-13 instructions */ 6978 6979 6980/* ------------------------------ */ 6981 .balign 64 6982.L_OP_ADD_INT_LIT8: /* 0xd8 */ 6983/* File: armv5te/OP_ADD_INT_LIT8.S */ 6984/* File: armv5te/binopLit8.S */ 6985 /* 6986 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6987 * that specifies an instruction that performs "result = r0 op r1". 6988 * This could be an ARM instruction or a function call. (If the result 6989 * comes back in a register other than r0, you can override "result".) 6990 * 6991 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6992 * vCC (r1). Useful for integer division and modulus. 6993 * 6994 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6995 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6996 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6997 */ 6998 /* binop/lit8 vAA, vBB, #+CC */ 6999 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7000 mov r9, rINST, lsr #8 @ r9<- AA 7001 and r2, r3, #255 @ r2<- BB 7002 GET_VREG(r0, r2) @ r0<- vBB 7003 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7004 .if 0 7005 @cmp r1, #0 @ is second operand zero? 7006 beq common_errDivideByZero 7007 .endif 7008 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7009 7010 @ optional op; may set condition codes 7011 add r0, r0, r1 @ r0<- op, r0-r3 changed 7012 GET_INST_OPCODE(ip) @ extract opcode from rINST 7013 SET_VREG(r0, r9) @ vAA<- r0 7014 GOTO_OPCODE(ip) @ jump to next instruction 7015 /* 10-12 instructions */ 7016 7017 7018/* ------------------------------ */ 7019 .balign 64 7020.L_OP_RSUB_INT_LIT8: /* 0xd9 */ 7021/* File: armv5te/OP_RSUB_INT_LIT8.S */ 7022/* File: armv5te/binopLit8.S */ 7023 /* 7024 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7025 * that specifies an instruction that performs "result = r0 op r1". 7026 * This could be an ARM instruction or a function call. (If the result 7027 * comes back in a register other than r0, you can override "result".) 7028 * 7029 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7030 * vCC (r1). Useful for integer division and modulus. 7031 * 7032 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7033 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7034 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7035 */ 7036 /* binop/lit8 vAA, vBB, #+CC */ 7037 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7038 mov r9, rINST, lsr #8 @ r9<- AA 7039 and r2, r3, #255 @ r2<- BB 7040 GET_VREG(r0, r2) @ r0<- vBB 7041 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7042 .if 0 7043 @cmp r1, #0 @ is second operand zero? 7044 beq common_errDivideByZero 7045 .endif 7046 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7047 7048 @ optional op; may set condition codes 7049 rsb r0, r0, r1 @ r0<- op, r0-r3 changed 7050 GET_INST_OPCODE(ip) @ extract opcode from rINST 7051 SET_VREG(r0, r9) @ vAA<- r0 7052 GOTO_OPCODE(ip) @ jump to next instruction 7053 /* 10-12 instructions */ 7054 7055 7056/* ------------------------------ */ 7057 .balign 64 7058.L_OP_MUL_INT_LIT8: /* 0xda */ 7059/* File: armv5te/OP_MUL_INT_LIT8.S */ 7060/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 7061/* File: armv5te/binopLit8.S */ 7062 /* 7063 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7064 * that specifies an instruction that performs "result = r0 op r1". 7065 * This could be an ARM instruction or a function call. (If the result 7066 * comes back in a register other than r0, you can override "result".) 7067 * 7068 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7069 * vCC (r1). Useful for integer division and modulus. 7070 * 7071 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7072 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7073 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7074 */ 7075 /* binop/lit8 vAA, vBB, #+CC */ 7076 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7077 mov r9, rINST, lsr #8 @ r9<- AA 7078 and r2, r3, #255 @ r2<- BB 7079 GET_VREG(r0, r2) @ r0<- vBB 7080 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7081 .if 0 7082 @cmp r1, #0 @ is second operand zero? 7083 beq common_errDivideByZero 7084 .endif 7085 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7086 7087 @ optional op; may set condition codes 7088 mul r0, r1, r0 @ r0<- op, r0-r3 changed 7089 GET_INST_OPCODE(ip) @ extract opcode from rINST 7090 SET_VREG(r0, r9) @ vAA<- r0 7091 GOTO_OPCODE(ip) @ jump to next instruction 7092 /* 10-12 instructions */ 7093 7094 7095/* ------------------------------ */ 7096 .balign 64 7097.L_OP_DIV_INT_LIT8: /* 0xdb */ 7098/* File: armv5te/OP_DIV_INT_LIT8.S */ 7099/* File: armv5te/binopLit8.S */ 7100 /* 7101 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7102 * that specifies an instruction that performs "result = r0 op r1". 7103 * This could be an ARM instruction or a function call. (If the result 7104 * comes back in a register other than r0, you can override "result".) 7105 * 7106 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7107 * vCC (r1). Useful for integer division and modulus. 7108 * 7109 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7110 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7111 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7112 */ 7113 /* binop/lit8 vAA, vBB, #+CC */ 7114 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7115 mov r9, rINST, lsr #8 @ r9<- AA 7116 and r2, r3, #255 @ r2<- BB 7117 GET_VREG(r0, r2) @ r0<- vBB 7118 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7119 .if 1 7120 @cmp r1, #0 @ is second operand zero? 7121 beq common_errDivideByZero 7122 .endif 7123 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7124 7125 @ optional op; may set condition codes 7126 bl __aeabi_idiv @ r0<- op, r0-r3 changed 7127 GET_INST_OPCODE(ip) @ extract opcode from rINST 7128 SET_VREG(r0, r9) @ vAA<- r0 7129 GOTO_OPCODE(ip) @ jump to next instruction 7130 /* 10-12 instructions */ 7131 7132 7133/* ------------------------------ */ 7134 .balign 64 7135.L_OP_REM_INT_LIT8: /* 0xdc */ 7136/* File: armv5te/OP_REM_INT_LIT8.S */ 7137/* idivmod returns quotient in r0 and remainder in r1 */ 7138/* File: armv5te/binopLit8.S */ 7139 /* 7140 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7141 * that specifies an instruction that performs "result = r0 op r1". 7142 * This could be an ARM instruction or a function call. (If the result 7143 * comes back in a register other than r0, you can override "result".) 7144 * 7145 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7146 * vCC (r1). Useful for integer division and modulus. 7147 * 7148 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7149 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7150 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7151 */ 7152 /* binop/lit8 vAA, vBB, #+CC */ 7153 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7154 mov r9, rINST, lsr #8 @ r9<- AA 7155 and r2, r3, #255 @ r2<- BB 7156 GET_VREG(r0, r2) @ r0<- vBB 7157 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7158 .if 1 7159 @cmp r1, #0 @ is second operand zero? 7160 beq common_errDivideByZero 7161 .endif 7162 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7163 7164 @ optional op; may set condition codes 7165 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 7166 GET_INST_OPCODE(ip) @ extract opcode from rINST 7167 SET_VREG(r1, r9) @ vAA<- r1 7168 GOTO_OPCODE(ip) @ jump to next instruction 7169 /* 10-12 instructions */ 7170 7171 7172/* ------------------------------ */ 7173 .balign 64 7174.L_OP_AND_INT_LIT8: /* 0xdd */ 7175/* File: armv5te/OP_AND_INT_LIT8.S */ 7176/* File: armv5te/binopLit8.S */ 7177 /* 7178 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7179 * that specifies an instruction that performs "result = r0 op r1". 7180 * This could be an ARM instruction or a function call. (If the result 7181 * comes back in a register other than r0, you can override "result".) 7182 * 7183 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7184 * vCC (r1). Useful for integer division and modulus. 7185 * 7186 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7187 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7188 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7189 */ 7190 /* binop/lit8 vAA, vBB, #+CC */ 7191 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7192 mov r9, rINST, lsr #8 @ r9<- AA 7193 and r2, r3, #255 @ r2<- BB 7194 GET_VREG(r0, r2) @ r0<- vBB 7195 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7196 .if 0 7197 @cmp r1, #0 @ is second operand zero? 7198 beq common_errDivideByZero 7199 .endif 7200 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7201 7202 @ optional op; may set condition codes 7203 and r0, r0, r1 @ r0<- op, r0-r3 changed 7204 GET_INST_OPCODE(ip) @ extract opcode from rINST 7205 SET_VREG(r0, r9) @ vAA<- r0 7206 GOTO_OPCODE(ip) @ jump to next instruction 7207 /* 10-12 instructions */ 7208 7209 7210/* ------------------------------ */ 7211 .balign 64 7212.L_OP_OR_INT_LIT8: /* 0xde */ 7213/* File: armv5te/OP_OR_INT_LIT8.S */ 7214/* File: armv5te/binopLit8.S */ 7215 /* 7216 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7217 * that specifies an instruction that performs "result = r0 op r1". 7218 * This could be an ARM instruction or a function call. (If the result 7219 * comes back in a register other than r0, you can override "result".) 7220 * 7221 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7222 * vCC (r1). Useful for integer division and modulus. 7223 * 7224 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7225 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7226 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7227 */ 7228 /* binop/lit8 vAA, vBB, #+CC */ 7229 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7230 mov r9, rINST, lsr #8 @ r9<- AA 7231 and r2, r3, #255 @ r2<- BB 7232 GET_VREG(r0, r2) @ r0<- vBB 7233 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7234 .if 0 7235 @cmp r1, #0 @ is second operand zero? 7236 beq common_errDivideByZero 7237 .endif 7238 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7239 7240 @ optional op; may set condition codes 7241 orr r0, r0, r1 @ r0<- op, r0-r3 changed 7242 GET_INST_OPCODE(ip) @ extract opcode from rINST 7243 SET_VREG(r0, r9) @ vAA<- r0 7244 GOTO_OPCODE(ip) @ jump to next instruction 7245 /* 10-12 instructions */ 7246 7247 7248/* ------------------------------ */ 7249 .balign 64 7250.L_OP_XOR_INT_LIT8: /* 0xdf */ 7251/* File: armv5te/OP_XOR_INT_LIT8.S */ 7252/* File: armv5te/binopLit8.S */ 7253 /* 7254 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7255 * that specifies an instruction that performs "result = r0 op r1". 7256 * This could be an ARM instruction or a function call. (If the result 7257 * comes back in a register other than r0, you can override "result".) 7258 * 7259 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7260 * vCC (r1). Useful for integer division and modulus. 7261 * 7262 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7263 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7264 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7265 */ 7266 /* binop/lit8 vAA, vBB, #+CC */ 7267 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7268 mov r9, rINST, lsr #8 @ r9<- AA 7269 and r2, r3, #255 @ r2<- BB 7270 GET_VREG(r0, r2) @ r0<- vBB 7271 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7272 .if 0 7273 @cmp r1, #0 @ is second operand zero? 7274 beq common_errDivideByZero 7275 .endif 7276 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7277 7278 @ optional op; may set condition codes 7279 eor r0, r0, r1 @ r0<- op, r0-r3 changed 7280 GET_INST_OPCODE(ip) @ extract opcode from rINST 7281 SET_VREG(r0, r9) @ vAA<- r0 7282 GOTO_OPCODE(ip) @ jump to next instruction 7283 /* 10-12 instructions */ 7284 7285 7286/* ------------------------------ */ 7287 .balign 64 7288.L_OP_SHL_INT_LIT8: /* 0xe0 */ 7289/* File: armv5te/OP_SHL_INT_LIT8.S */ 7290/* File: armv5te/binopLit8.S */ 7291 /* 7292 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7293 * that specifies an instruction that performs "result = r0 op r1". 7294 * This could be an ARM instruction or a function call. (If the result 7295 * comes back in a register other than r0, you can override "result".) 7296 * 7297 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7298 * vCC (r1). Useful for integer division and modulus. 7299 * 7300 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7301 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7302 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7303 */ 7304 /* binop/lit8 vAA, vBB, #+CC */ 7305 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7306 mov r9, rINST, lsr #8 @ r9<- AA 7307 and r2, r3, #255 @ r2<- BB 7308 GET_VREG(r0, r2) @ r0<- vBB 7309 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7310 .if 0 7311 @cmp r1, #0 @ is second operand zero? 7312 beq common_errDivideByZero 7313 .endif 7314 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7315 7316 and r1, r1, #31 @ optional op; may set condition codes 7317 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 7318 GET_INST_OPCODE(ip) @ extract opcode from rINST 7319 SET_VREG(r0, r9) @ vAA<- r0 7320 GOTO_OPCODE(ip) @ jump to next instruction 7321 /* 10-12 instructions */ 7322 7323 7324/* ------------------------------ */ 7325 .balign 64 7326.L_OP_SHR_INT_LIT8: /* 0xe1 */ 7327/* File: armv5te/OP_SHR_INT_LIT8.S */ 7328/* File: armv5te/binopLit8.S */ 7329 /* 7330 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7331 * that specifies an instruction that performs "result = r0 op r1". 7332 * This could be an ARM instruction or a function call. (If the result 7333 * comes back in a register other than r0, you can override "result".) 7334 * 7335 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7336 * vCC (r1). Useful for integer division and modulus. 7337 * 7338 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7339 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7340 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7341 */ 7342 /* binop/lit8 vAA, vBB, #+CC */ 7343 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7344 mov r9, rINST, lsr #8 @ r9<- AA 7345 and r2, r3, #255 @ r2<- BB 7346 GET_VREG(r0, r2) @ r0<- vBB 7347 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7348 .if 0 7349 @cmp r1, #0 @ is second operand zero? 7350 beq common_errDivideByZero 7351 .endif 7352 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7353 7354 and r1, r1, #31 @ optional op; may set condition codes 7355 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 7356 GET_INST_OPCODE(ip) @ extract opcode from rINST 7357 SET_VREG(r0, r9) @ vAA<- r0 7358 GOTO_OPCODE(ip) @ jump to next instruction 7359 /* 10-12 instructions */ 7360 7361 7362/* ------------------------------ */ 7363 .balign 64 7364.L_OP_USHR_INT_LIT8: /* 0xe2 */ 7365/* File: armv5te/OP_USHR_INT_LIT8.S */ 7366/* File: armv5te/binopLit8.S */ 7367 /* 7368 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7369 * that specifies an instruction that performs "result = r0 op r1". 7370 * This could be an ARM instruction or a function call. (If the result 7371 * comes back in a register other than r0, you can override "result".) 7372 * 7373 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7374 * vCC (r1). Useful for integer division and modulus. 7375 * 7376 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7377 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7378 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7379 */ 7380 /* binop/lit8 vAA, vBB, #+CC */ 7381 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7382 mov r9, rINST, lsr #8 @ r9<- AA 7383 and r2, r3, #255 @ r2<- BB 7384 GET_VREG(r0, r2) @ r0<- vBB 7385 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7386 .if 0 7387 @cmp r1, #0 @ is second operand zero? 7388 beq common_errDivideByZero 7389 .endif 7390 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7391 7392 and r1, r1, #31 @ optional op; may set condition codes 7393 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 7394 GET_INST_OPCODE(ip) @ extract opcode from rINST 7395 SET_VREG(r0, r9) @ vAA<- r0 7396 GOTO_OPCODE(ip) @ jump to next instruction 7397 /* 10-12 instructions */ 7398 7399 7400/* ------------------------------ */ 7401 .balign 64 7402.L_OP_IGET_VOLATILE: /* 0xe3 */ 7403/* File: armv5te/OP_IGET_VOLATILE.S */ 7404/* File: armv5te/OP_IGET.S */ 7405 /* 7406 * General 32-bit instance field get. 7407 * 7408 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7409 */ 7410 /* op vA, vB, field@CCCC */ 7411 mov r0, rINST, lsr #12 @ r0<- B 7412 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7413 FETCH(r1, 1) @ r1<- field ref CCCC 7414 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7415 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7416 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7417 cmp r0, #0 @ is resolved entry null? 7418 bne .LOP_IGET_VOLATILE_finish @ no, already resolved 74198: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7420 EXPORT_PC() @ resolve() could throw 7421 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7422 bl dvmResolveInstField @ r0<- resolved InstField ptr 7423 cmp r0, #0 7424 bne .LOP_IGET_VOLATILE_finish 7425 b common_exceptionThrown 7426 7427 7428/* ------------------------------ */ 7429 .balign 64 7430.L_OP_IPUT_VOLATILE: /* 0xe4 */ 7431/* File: armv5te/OP_IPUT_VOLATILE.S */ 7432/* File: armv5te/OP_IPUT.S */ 7433 /* 7434 * General 32-bit instance field put. 7435 * 7436 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 7437 */ 7438 /* op vA, vB, field@CCCC */ 7439 mov r0, rINST, lsr #12 @ r0<- B 7440 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7441 FETCH(r1, 1) @ r1<- field ref CCCC 7442 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7443 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7444 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7445 cmp r0, #0 @ is resolved entry null? 7446 bne .LOP_IPUT_VOLATILE_finish @ no, already resolved 74478: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7448 EXPORT_PC() @ resolve() could throw 7449 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7450 bl dvmResolveInstField @ r0<- resolved InstField ptr 7451 cmp r0, #0 @ success? 7452 bne .LOP_IPUT_VOLATILE_finish @ yes, finish up 7453 b common_exceptionThrown 7454 7455 7456/* ------------------------------ */ 7457 .balign 64 7458.L_OP_SGET_VOLATILE: /* 0xe5 */ 7459/* File: armv5te/OP_SGET_VOLATILE.S */ 7460/* File: armv5te/OP_SGET.S */ 7461 /* 7462 * General 32-bit SGET handler. 7463 * 7464 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7465 */ 7466 /* op vAA, field@BBBB */ 7467 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 7468 FETCH(r1, 1) @ r1<- field ref BBBB 7469 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7470 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7471 cmp r0, #0 @ is resolved entry null? 7472 beq .LOP_SGET_VOLATILE_resolve @ yes, do resolve 7473.LOP_SGET_VOLATILE_finish: @ field ptr in r0 7474 ldr r1, [r0, #offStaticField_value] @ r1<- field value 7475 SMP_DMB @ acquiring load 7476 mov r2, rINST, lsr #8 @ r2<- AA 7477 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7478 SET_VREG(r1, r2) @ fp[AA]<- r1 7479 GET_INST_OPCODE(ip) @ extract opcode from rINST 7480 GOTO_OPCODE(ip) @ jump to next instruction 7481 7482 7483/* ------------------------------ */ 7484 .balign 64 7485.L_OP_SPUT_VOLATILE: /* 0xe6 */ 7486/* File: armv5te/OP_SPUT_VOLATILE.S */ 7487/* File: armv5te/OP_SPUT.S */ 7488 /* 7489 * General 32-bit SPUT handler. 7490 * 7491 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 7492 */ 7493 /* op vAA, field@BBBB */ 7494 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 7495 FETCH(r1, 1) @ r1<- field ref BBBB 7496 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7497 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7498 cmp r0, #0 @ is resolved entry null? 7499 beq .LOP_SPUT_VOLATILE_resolve @ yes, do resolve 7500.LOP_SPUT_VOLATILE_finish: @ field ptr in r0 7501 mov r2, rINST, lsr #8 @ r2<- AA 7502 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7503 GET_VREG(r1, r2) @ r1<- fp[AA] 7504 GET_INST_OPCODE(ip) @ extract opcode from rINST 7505 SMP_DMB @ releasing store 7506 str r1, [r0, #offStaticField_value] @ field<- vAA 7507 GOTO_OPCODE(ip) @ jump to next instruction 7508 7509 7510/* ------------------------------ */ 7511 .balign 64 7512.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */ 7513/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */ 7514/* File: armv5te/OP_IGET.S */ 7515 /* 7516 * General 32-bit instance field get. 7517 * 7518 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7519 */ 7520 /* op vA, vB, field@CCCC */ 7521 mov r0, rINST, lsr #12 @ r0<- B 7522 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7523 FETCH(r1, 1) @ r1<- field ref CCCC 7524 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7525 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7526 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7527 cmp r0, #0 @ is resolved entry null? 7528 bne .LOP_IGET_OBJECT_VOLATILE_finish @ no, already resolved 75298: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7530 EXPORT_PC() @ resolve() could throw 7531 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7532 bl dvmResolveInstField @ r0<- resolved InstField ptr 7533 cmp r0, #0 7534 bne .LOP_IGET_OBJECT_VOLATILE_finish 7535 b common_exceptionThrown 7536 7537 7538/* ------------------------------ */ 7539 .balign 64 7540.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */ 7541/* File: armv5te/OP_IGET_WIDE_VOLATILE.S */ 7542/* File: armv5te/OP_IGET_WIDE.S */ 7543 /* 7544 * Wide 32-bit instance field get. 7545 */ 7546 /* iget-wide vA, vB, field@CCCC */ 7547 mov r0, rINST, lsr #12 @ r0<- B 7548 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7549 FETCH(r1, 1) @ r1<- field ref CCCC 7550 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7551 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7552 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7553 cmp r0, #0 @ is resolved entry null? 7554 bne .LOP_IGET_WIDE_VOLATILE_finish @ no, already resolved 75558: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7556 EXPORT_PC() @ resolve() could throw 7557 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7558 bl dvmResolveInstField @ r0<- resolved InstField ptr 7559 cmp r0, #0 7560 bne .LOP_IGET_WIDE_VOLATILE_finish 7561 b common_exceptionThrown 7562 7563 7564/* ------------------------------ */ 7565 .balign 64 7566.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */ 7567/* File: armv5te/OP_IPUT_WIDE_VOLATILE.S */ 7568/* File: armv5te/OP_IPUT_WIDE.S */ 7569 /* iput-wide vA, vB, field@CCCC */ 7570 mov r0, rINST, lsr #12 @ r0<- B 7571 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7572 FETCH(r1, 1) @ r1<- field ref CCCC 7573 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7574 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7575 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7576 cmp r0, #0 @ is resolved entry null? 7577 bne .LOP_IPUT_WIDE_VOLATILE_finish @ no, already resolved 75788: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7579 EXPORT_PC() @ resolve() could throw 7580 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7581 bl dvmResolveInstField @ r0<- resolved InstField ptr 7582 cmp r0, #0 @ success? 7583 bne .LOP_IPUT_WIDE_VOLATILE_finish @ yes, finish up 7584 b common_exceptionThrown 7585 7586 7587/* ------------------------------ */ 7588 .balign 64 7589.L_OP_SGET_WIDE_VOLATILE: /* 0xea */ 7590/* File: armv5te/OP_SGET_WIDE_VOLATILE.S */ 7591/* File: armv5te/OP_SGET_WIDE.S */ 7592 /* 7593 * 64-bit SGET handler. 7594 */ 7595 /* sget-wide vAA, field@BBBB */ 7596 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 7597 FETCH(r1, 1) @ r1<- field ref BBBB 7598 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7599 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7600 cmp r0, #0 @ is resolved entry null? 7601 beq .LOP_SGET_WIDE_VOLATILE_resolve @ yes, do resolve 7602.LOP_SGET_WIDE_VOLATILE_finish: 7603 mov r9, rINST, lsr #8 @ r9<- AA 7604 .if 1 7605 add r0, r0, #offStaticField_value @ r0<- pointer to data 7606 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 7607 .else 7608 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 7609 .endif 7610 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7611 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7612 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 7613 GET_INST_OPCODE(ip) @ extract opcode from rINST 7614 GOTO_OPCODE(ip) @ jump to next instruction 7615 7616 7617/* ------------------------------ */ 7618 .balign 64 7619.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */ 7620/* File: armv5te/OP_SPUT_WIDE_VOLATILE.S */ 7621/* File: armv5te/OP_SPUT_WIDE.S */ 7622 /* 7623 * 64-bit SPUT handler. 7624 */ 7625 /* sput-wide vAA, field@BBBB */ 7626 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- DvmDex 7627 FETCH(r1, 1) @ r1<- field ref BBBB 7628 ldr r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields 7629 mov r9, rINST, lsr #8 @ r9<- AA 7630 ldr r2, [r0, r1, lsl #2] @ r2<- resolved StaticField ptr 7631 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7632 cmp r2, #0 @ is resolved entry null? 7633 beq .LOP_SPUT_WIDE_VOLATILE_resolve @ yes, do resolve 7634.LOP_SPUT_WIDE_VOLATILE_finish: @ field ptr in r2, AA in r9 7635 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7636 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 7637 GET_INST_OPCODE(r10) @ extract opcode from rINST 7638 .if 1 7639 add r2, r2, #offStaticField_value @ r2<- pointer to data 7640 bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2 7641 .else 7642 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 7643 .endif 7644 GOTO_OPCODE(r10) @ jump to next instruction 7645 7646 7647/* ------------------------------ */ 7648 .balign 64 7649.L_OP_BREAKPOINT: /* 0xec */ 7650/* File: armv5te/OP_BREAKPOINT.S */ 7651/* File: armv5te/unused.S */ 7652 bl common_abort 7653 7654 7655/* ------------------------------ */ 7656 .balign 64 7657.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */ 7658/* File: armv5te/OP_THROW_VERIFICATION_ERROR.S */ 7659 /* 7660 * Handle a throw-verification-error instruction. This throws an 7661 * exception for an error discovered during verification. The 7662 * exception is indicated by AA, with some detail provided by BBBB. 7663 */ 7664 /* op AA, ref@BBBB */ 7665 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 7666 FETCH(r2, 1) @ r2<- BBBB 7667 EXPORT_PC() @ export the PC 7668 mov r1, rINST, lsr #8 @ r1<- AA 7669 bl dvmThrowVerificationError @ always throws 7670 b common_exceptionThrown @ handle exception 7671 7672/* ------------------------------ */ 7673 .balign 64 7674.L_OP_EXECUTE_INLINE: /* 0xee */ 7675/* File: armv5te/OP_EXECUTE_INLINE.S */ 7676 /* 7677 * Execute a "native inline" instruction. 7678 * 7679 * We need to call an InlineOp4Func: 7680 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7681 * 7682 * The first four args are in r0-r3, pointer to return value storage 7683 * is on the stack. The function's return value is a flag that tells 7684 * us if an exception was thrown. 7685 */ 7686 /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */ 7687 FETCH(r10, 1) @ r10<- BBBB 7688 add r1, rGLUE, #offGlue_retval @ r1<- &glue->retval 7689 EXPORT_PC() @ can throw 7690 sub sp, sp, #8 @ make room for arg, +64 bit align 7691 mov r0, rINST, lsr #12 @ r0<- B 7692 str r1, [sp] @ push &glue->retval 7693 bl .LOP_EXECUTE_INLINE_continue @ make call; will return after 7694 add sp, sp, #8 @ pop stack 7695 cmp r0, #0 @ test boolean result of inline 7696 beq common_exceptionThrown @ returned false, handle exception 7697 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7698 GET_INST_OPCODE(ip) @ extract opcode from rINST 7699 GOTO_OPCODE(ip) @ jump to next instruction 7700 7701/* ------------------------------ */ 7702 .balign 64 7703.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */ 7704/* File: armv5te/OP_EXECUTE_INLINE_RANGE.S */ 7705 /* 7706 * Execute a "native inline" instruction, using "/range" semantics. 7707 * Same idea as execute-inline, but we get the args differently. 7708 * 7709 * We need to call an InlineOp4Func: 7710 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7711 * 7712 * The first four args are in r0-r3, pointer to return value storage 7713 * is on the stack. The function's return value is a flag that tells 7714 * us if an exception was thrown. 7715 */ 7716 /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */ 7717 FETCH(r10, 1) @ r10<- BBBB 7718 add r1, rGLUE, #offGlue_retval @ r1<- &glue->retval 7719 EXPORT_PC() @ can throw 7720 sub sp, sp, #8 @ make room for arg, +64 bit align 7721 mov r0, rINST, lsr #8 @ r0<- AA 7722 str r1, [sp] @ push &glue->retval 7723 bl .LOP_EXECUTE_INLINE_RANGE_continue @ make call; will return after 7724 add sp, sp, #8 @ pop stack 7725 cmp r0, #0 @ test boolean result of inline 7726 beq common_exceptionThrown @ returned false, handle exception 7727 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7728 GET_INST_OPCODE(ip) @ extract opcode from rINST 7729 GOTO_OPCODE(ip) @ jump to next instruction 7730 7731/* ------------------------------ */ 7732 .balign 64 7733.L_OP_INVOKE_OBJECT_INIT: /* 0xf0 */ 7734/* File: armv5te/OP_INVOKE_OBJECT_INIT.S */ 7735 /* 7736 * invoke-object-init is a no-op in a "standard" interpreter. 7737 */ 7738 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 7739 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 7740 GOTO_OPCODE(ip) @ execute it 7741 7742/* ------------------------------ */ 7743 .balign 64 7744.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */ 7745/* File: armv5te/OP_RETURN_VOID_BARRIER.S */ 7746 SMP_DMB_ST 7747 b common_returnFromMethod 7748 7749/* ------------------------------ */ 7750 .balign 64 7751.L_OP_IGET_QUICK: /* 0xf2 */ 7752/* File: armv5te/OP_IGET_QUICK.S */ 7753 /* For: iget-quick, iget-object-quick */ 7754 /* op vA, vB, offset@CCCC */ 7755 mov r2, rINST, lsr #12 @ r2<- B 7756 GET_VREG(r3, r2) @ r3<- object we're operating on 7757 FETCH(r1, 1) @ r1<- field byte offset 7758 cmp r3, #0 @ check object for null 7759 mov r2, rINST, lsr #8 @ r2<- A(+) 7760 beq common_errNullObject @ object was null 7761 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7762 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7763 and r2, r2, #15 7764 GET_INST_OPCODE(ip) @ extract opcode from rINST 7765 SET_VREG(r0, r2) @ fp[A]<- r0 7766 GOTO_OPCODE(ip) @ jump to next instruction 7767 7768/* ------------------------------ */ 7769 .balign 64 7770.L_OP_IGET_WIDE_QUICK: /* 0xf3 */ 7771/* File: armv5te/OP_IGET_WIDE_QUICK.S */ 7772 /* iget-wide-quick vA, vB, offset@CCCC */ 7773 mov r2, rINST, lsr #12 @ r2<- B 7774 GET_VREG(r3, r2) @ r3<- object we're operating on 7775 FETCH(ip, 1) @ ip<- field byte offset 7776 cmp r3, #0 @ check object for null 7777 mov r2, rINST, lsr #8 @ r2<- A(+) 7778 beq common_errNullObject @ object was null 7779 ldrd r0, [r3, ip] @ r0<- obj.field (64 bits, aligned) 7780 and r2, r2, #15 7781 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7782 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 7783 GET_INST_OPCODE(ip) @ extract opcode from rINST 7784 stmia r3, {r0-r1} @ fp[A]<- r0/r1 7785 GOTO_OPCODE(ip) @ jump to next instruction 7786 7787/* ------------------------------ */ 7788 .balign 64 7789.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */ 7790/* File: armv5te/OP_IGET_OBJECT_QUICK.S */ 7791/* File: armv5te/OP_IGET_QUICK.S */ 7792 /* For: iget-quick, iget-object-quick */ 7793 /* op vA, vB, offset@CCCC */ 7794 mov r2, rINST, lsr #12 @ r2<- B 7795 GET_VREG(r3, r2) @ r3<- object we're operating on 7796 FETCH(r1, 1) @ r1<- field byte offset 7797 cmp r3, #0 @ check object for null 7798 mov r2, rINST, lsr #8 @ r2<- A(+) 7799 beq common_errNullObject @ object was null 7800 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7801 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7802 and r2, r2, #15 7803 GET_INST_OPCODE(ip) @ extract opcode from rINST 7804 SET_VREG(r0, r2) @ fp[A]<- r0 7805 GOTO_OPCODE(ip) @ jump to next instruction 7806 7807 7808/* ------------------------------ */ 7809 .balign 64 7810.L_OP_IPUT_QUICK: /* 0xf5 */ 7811/* File: armv5te/OP_IPUT_QUICK.S */ 7812 /* For: iput-quick */ 7813 /* op vA, vB, offset@CCCC */ 7814 mov r2, rINST, lsr #12 @ r2<- B 7815 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7816 FETCH(r1, 1) @ r1<- field byte offset 7817 cmp r3, #0 @ check object for null 7818 mov r2, rINST, lsr #8 @ r2<- A(+) 7819 beq common_errNullObject @ object was null 7820 and r2, r2, #15 7821 GET_VREG(r0, r2) @ r0<- fp[A] 7822 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7823 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7824 GET_INST_OPCODE(ip) @ extract opcode from rINST 7825 GOTO_OPCODE(ip) @ jump to next instruction 7826 7827/* ------------------------------ */ 7828 .balign 64 7829.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */ 7830/* File: armv5te/OP_IPUT_WIDE_QUICK.S */ 7831 /* iput-wide-quick vA, vB, offset@CCCC */ 7832 mov r0, rINST, lsr #8 @ r0<- A(+) 7833 mov r1, rINST, lsr #12 @ r1<- B 7834 and r0, r0, #15 7835 GET_VREG(r2, r1) @ r2<- fp[B], the object pointer 7836 add r3, rFP, r0, lsl #2 @ r3<- &fp[A] 7837 cmp r2, #0 @ check object for null 7838 ldmia r3, {r0-r1} @ r0/r1<- fp[A] 7839 beq common_errNullObject @ object was null 7840 FETCH(r3, 1) @ r3<- field byte offset 7841 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7842 strd r0, [r2, r3] @ obj.field (64 bits, aligned)<- r0/r1 7843 GET_INST_OPCODE(ip) @ extract opcode from rINST 7844 GOTO_OPCODE(ip) @ jump to next instruction 7845 7846/* ------------------------------ */ 7847 .balign 64 7848.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */ 7849/* File: armv5te/OP_IPUT_OBJECT_QUICK.S */ 7850 /* For: iput-object-quick */ 7851 /* op vA, vB, offset@CCCC */ 7852 mov r2, rINST, lsr #12 @ r2<- B 7853 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7854 FETCH(r1, 1) @ r1<- field byte offset 7855 cmp r3, #0 @ check object for null 7856 mov r2, rINST, lsr #8 @ r2<- A(+) 7857 beq common_errNullObject @ object was null 7858 and r2, r2, #15 7859 GET_VREG(r0, r2) @ r0<- fp[A] 7860 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 7861 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7862 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7863 cmp r0, #0 7864 strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head 7865 GET_INST_OPCODE(ip) @ extract opcode from rINST 7866 GOTO_OPCODE(ip) @ jump to next instruction 7867 7868/* ------------------------------ */ 7869 .balign 64 7870.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */ 7871/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7872 /* 7873 * Handle an optimized virtual method call. 7874 * 7875 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 7876 */ 7877 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7878 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7879 FETCH(r3, 2) @ r3<- FEDC or CCCC 7880 FETCH(r1, 1) @ r1<- BBBB 7881 .if (!0) 7882 and r3, r3, #15 @ r3<- C (or stays CCCC) 7883 .endif 7884 GET_VREG(r2, r3) @ r2<- vC ("this" ptr) 7885 cmp r2, #0 @ is "this" null? 7886 beq common_errNullObject @ null "this", throw exception 7887 ldr r2, [r2, #offObject_clazz] @ r2<- thisPtr->clazz 7888 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7889 EXPORT_PC() @ invoke must export 7890 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7891 bl common_invokeMethodNoRange @ continue on 7892 7893/* ------------------------------ */ 7894 .balign 64 7895.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */ 7896/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */ 7897/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7898 /* 7899 * Handle an optimized virtual method call. 7900 * 7901 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 7902 */ 7903 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7904 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7905 FETCH(r3, 2) @ r3<- FEDC or CCCC 7906 FETCH(r1, 1) @ r1<- BBBB 7907 .if (!1) 7908 and r3, r3, #15 @ r3<- C (or stays CCCC) 7909 .endif 7910 GET_VREG(r2, r3) @ r2<- vC ("this" ptr) 7911 cmp r2, #0 @ is "this" null? 7912 beq common_errNullObject @ null "this", throw exception 7913 ldr r2, [r2, #offObject_clazz] @ r2<- thisPtr->clazz 7914 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7915 EXPORT_PC() @ invoke must export 7916 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7917 bl common_invokeMethodRange @ continue on 7918 7919 7920/* ------------------------------ */ 7921 .balign 64 7922.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */ 7923/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7924 /* 7925 * Handle an optimized "super" method call. 7926 * 7927 * for: [opt] invoke-super-quick, invoke-super-quick/range 7928 */ 7929 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7930 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7931 FETCH(r10, 2) @ r10<- GFED or CCCC 7932 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7933 .if (!0) 7934 and r10, r10, #15 @ r10<- D (or stays CCCC) 7935 .endif 7936 FETCH(r1, 1) @ r1<- BBBB 7937 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7938 EXPORT_PC() @ must export for invoke 7939 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7940 GET_VREG(r3, r10) @ r3<- "this" 7941 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7942 cmp r3, #0 @ null "this" ref? 7943 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7944 beq common_errNullObject @ "this" is null, throw exception 7945 bl common_invokeMethodNoRange @ continue on 7946 7947/* ------------------------------ */ 7948 .balign 64 7949.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */ 7950/* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */ 7951/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7952 /* 7953 * Handle an optimized "super" method call. 7954 * 7955 * for: [opt] invoke-super-quick, invoke-super-quick/range 7956 */ 7957 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7958 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7959 FETCH(r10, 2) @ r10<- GFED or CCCC 7960 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7961 .if (!1) 7962 and r10, r10, #15 @ r10<- D (or stays CCCC) 7963 .endif 7964 FETCH(r1, 1) @ r1<- BBBB 7965 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7966 EXPORT_PC() @ must export for invoke 7967 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7968 GET_VREG(r3, r10) @ r3<- "this" 7969 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7970 cmp r3, #0 @ null "this" ref? 7971 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7972 beq common_errNullObject @ "this" is null, throw exception 7973 bl common_invokeMethodRange @ continue on 7974 7975 7976/* ------------------------------ */ 7977 .balign 64 7978.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */ 7979/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */ 7980/* File: armv5te/OP_IPUT_OBJECT.S */ 7981 /* 7982 * 32-bit instance field put. 7983 * 7984 * for: iput-object, iput-object-volatile 7985 */ 7986 /* op vA, vB, field@CCCC */ 7987 mov r0, rINST, lsr #12 @ r0<- B 7988 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7989 FETCH(r1, 1) @ r1<- field ref CCCC 7990 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7991 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7992 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7993 cmp r0, #0 @ is resolved entry null? 7994 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ no, already resolved 79958: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7996 EXPORT_PC() @ resolve() could throw 7997 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7998 bl dvmResolveInstField @ r0<- resolved InstField ptr 7999 cmp r0, #0 @ success? 8000 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ yes, finish up 8001 b common_exceptionThrown 8002 8003 8004/* ------------------------------ */ 8005 .balign 64 8006.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */ 8007/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */ 8008/* File: armv5te/OP_SGET.S */ 8009 /* 8010 * General 32-bit SGET handler. 8011 * 8012 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 8013 */ 8014 /* op vAA, field@BBBB */ 8015 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8016 FETCH(r1, 1) @ r1<- field ref BBBB 8017 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8018 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8019 cmp r0, #0 @ is resolved entry null? 8020 beq .LOP_SGET_OBJECT_VOLATILE_resolve @ yes, do resolve 8021.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0 8022 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8023 SMP_DMB @ acquiring load 8024 mov r2, rINST, lsr #8 @ r2<- AA 8025 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8026 SET_VREG(r1, r2) @ fp[AA]<- r1 8027 GET_INST_OPCODE(ip) @ extract opcode from rINST 8028 GOTO_OPCODE(ip) @ jump to next instruction 8029 8030 8031/* ------------------------------ */ 8032 .balign 64 8033.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */ 8034/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */ 8035/* File: armv5te/OP_SPUT_OBJECT.S */ 8036 /* 8037 * 32-bit SPUT handler for objects 8038 * 8039 * for: sput-object, sput-object-volatile 8040 */ 8041 /* op vAA, field@BBBB */ 8042 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8043 FETCH(r1, 1) @ r1<- field ref BBBB 8044 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8045 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8046 cmp r0, #0 @ is resolved entry null? 8047 bne .LOP_SPUT_OBJECT_VOLATILE_finish @ no, continue 8048 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 8049 EXPORT_PC() @ resolve() could throw, so export now 8050 ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz 8051 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8052 cmp r0, #0 @ success? 8053 bne .LOP_SPUT_OBJECT_VOLATILE_finish @ yes, finish 8054 b common_exceptionThrown @ no, handle exception 8055 8056 8057 8058/* ------------------------------ */ 8059 .balign 64 8060.L_OP_DISPATCH_FF: /* 0xff */ 8061/* File: armv5te/OP_DISPATCH_FF.S */ 8062 mov ip, rINST, lsr #8 @ r9<- extended opcode 8063 add ip, ip, #256 @ add offset for extended opcodes 8064 GOTO_OPCODE(ip) @ go to proper extended handler 8065 8066 8067/* ------------------------------ */ 8068 .balign 64 8069.L_OP_CONST_CLASS_JUMBO: /* 0x100 */ 8070/* File: armv5te/OP_CONST_CLASS_JUMBO.S */ 8071 /* const-class/jumbo vBBBB, Class@AAAAAAAA */ 8072 FETCH(r0, 1) @ r0<- aaaa (lo) 8073 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- glue->methodClassDex 8074 FETCH(r1, 2) @ r1<- AAAA (hi) 8075 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- dvmDex->pResClasses 8076 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8077 FETCH(r9, 3) @ r9<- BBBB 8078 ldr r0, [r2, r1, lsl #2] @ r0<- pResClasses[AAAAaaaa] 8079 cmp r0, #0 @ not yet resolved? 8080 beq .LOP_CONST_CLASS_JUMBO_resolve 8081 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8082 GET_INST_OPCODE(ip) @ extract opcode from rINST 8083 SET_VREG(r0, r9) @ vBBBB<- r0 8084 GOTO_OPCODE(ip) @ jump to next instruction 8085 8086/* ------------------------------ */ 8087 .balign 64 8088.L_OP_CHECK_CAST_JUMBO: /* 0x101 */ 8089/* File: armv5te/OP_CHECK_CAST_JUMBO.S */ 8090 /* 8091 * Check to see if a cast from one class to another is allowed. 8092 */ 8093 /* check-cast/jumbo vBBBB, class@AAAAAAAA */ 8094 FETCH(r0, 1) @ r0<- aaaa (lo) 8095 FETCH(r2, 2) @ r2<- AAAA (hi) 8096 FETCH(r3, 3) @ r3<- BBBB 8097 orr r2, r0, r2, lsl #16 @ r2<- AAAAaaaa 8098 GET_VREG(r9, r3) @ r9<- object 8099 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- pDvmDex 8100 cmp r9, #0 @ is object null? 8101 ldr r0, [r0, #offDvmDex_pResClasses] @ r0<- pDvmDex->pResClasses 8102 beq .LOP_CHECK_CAST_JUMBO_okay @ null obj, cast always succeeds 8103 ldr r1, [r0, r2, lsl #2] @ r1<- resolved class 8104 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 8105 cmp r1, #0 @ have we resolved this before? 8106 beq .LOP_CHECK_CAST_JUMBO_resolve @ not resolved, do it now 8107.LOP_CHECK_CAST_JUMBO_resolved: 8108 cmp r0, r1 @ same class (trivial success)? 8109 bne .LOP_CHECK_CAST_JUMBO_fullcheck @ no, do full check 8110 b .LOP_CHECK_CAST_JUMBO_okay @ yes, finish up 8111 8112/* ------------------------------ */ 8113 .balign 64 8114.L_OP_INSTANCE_OF_JUMBO: /* 0x102 */ 8115/* File: armv5te/OP_INSTANCE_OF_JUMBO.S */ 8116 /* 8117 * Check to see if an object reference is an instance of a class. 8118 * 8119 * Most common situation is a non-null object, being compared against 8120 * an already-resolved class. 8121 * 8122 * TODO: convert most of this into a common subroutine, shared with 8123 * OP_INSTANCE_OF.S. 8124 */ 8125 /* instance-of/jumbo vBBBB, vCCCC, class@AAAAAAAA */ 8126 FETCH(r3, 4) @ r3<- vCCCC 8127 FETCH(r9, 3) @ r9<- vBBBB 8128 GET_VREG(r0, r3) @ r0<- vCCCC (object) 8129 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- pDvmDex 8130 cmp r0, #0 @ is object null? 8131 beq .LOP_INSTANCE_OF_JUMBO_store @ null obj, not an instance, store r0 8132 FETCH(r1, 1) @ r1<- aaaa (lo) 8133 FETCH(r3, 2) @ r3<- AAAA (hi) 8134 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- pDvmDex->pResClasses 8135 orr r3, r1, r3, lsl #16 @ r3<- AAAAaaaa 8136 ldr r1, [r2, r3, lsl #2] @ r1<- resolved class 8137 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 8138 cmp r1, #0 @ have we resolved this before? 8139 beq .LOP_INSTANCE_OF_JUMBO_resolve @ not resolved, do it now 8140 b .LOP_INSTANCE_OF_JUMBO_resolved @ resolved, continue 8141 8142/* ------------------------------ */ 8143 .balign 64 8144.L_OP_NEW_INSTANCE_JUMBO: /* 0x103 */ 8145/* File: armv5te/OP_NEW_INSTANCE_JUMBO.S */ 8146 /* 8147 * Create a new instance of a class. 8148 */ 8149 /* new-instance/jumbo vBBBB, class@AAAAAAAA */ 8150 FETCH(r0, 1) @ r0<- aaaa (lo) 8151 FETCH(r1, 2) @ r1<- AAAA (hi) 8152 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 8153 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8154 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 8155 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 8156 EXPORT_PC() @ req'd for init, resolve, alloc 8157 cmp r0, #0 @ already resolved? 8158 beq .LOP_NEW_INSTANCE_JUMBO_resolve @ no, resolve it now 8159.LOP_NEW_INSTANCE_JUMBO_resolved: @ r0=class 8160 ldrb r1, [r0, #offClassObject_status] @ r1<- ClassStatus enum 8161 cmp r1, #CLASS_INITIALIZED @ has class been initialized? 8162 bne .LOP_NEW_INSTANCE_JUMBO_needinit @ no, init class now 8163.LOP_NEW_INSTANCE_JUMBO_initialized: @ r0=class 8164 mov r1, #ALLOC_DONT_TRACK @ flags for alloc call 8165 bl dvmAllocObject @ r0<- new object 8166 b .LOP_NEW_INSTANCE_JUMBO_finish @ continue 8167 8168/* ------------------------------ */ 8169 .balign 64 8170.L_OP_NEW_ARRAY_JUMBO: /* 0x104 */ 8171/* File: armv5te/OP_NEW_ARRAY_JUMBO.S */ 8172 /* 8173 * Allocate an array of objects, specified with the array class 8174 * and a count. 8175 * 8176 * The verifier guarantees that this is an array class, so we don't 8177 * check for it here. 8178 */ 8179 /* new-array/jumbo vBBBB, vCCCC, class@AAAAAAAA */ 8180 FETCH(r2, 1) @ r2<- aaaa (lo) 8181 FETCH(r3, 2) @ r3<- AAAA (hi) 8182 FETCH(r0, 4) @ r0<- vCCCC 8183 orr r2, r2, r3, lsl #16 @ r2<- AAAAaaaa 8184 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 8185 GET_VREG(r1, r0) @ r1<- vCCCC (array length) 8186 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 8187 cmp r1, #0 @ check length 8188 ldr r0, [r3, r2, lsl #2] @ r0<- resolved class 8189 bmi common_errNegativeArraySize @ negative length, bail 8190 cmp r0, #0 @ already resolved? 8191 EXPORT_PC() @ req'd for resolve, alloc 8192 bne .LOP_NEW_ARRAY_JUMBO_finish @ resolved, continue 8193 b .LOP_NEW_ARRAY_JUMBO_resolve @ do resolve now 8194 8195/* ------------------------------ */ 8196 .balign 64 8197.L_OP_FILLED_NEW_ARRAY_JUMBO: /* 0x105 */ 8198/* File: armv5te/OP_FILLED_NEW_ARRAY_JUMBO.S */ 8199 /* 8200 * Create a new array with elements filled from registers. 8201 * 8202 * TODO: convert most of this into a common subroutine, shared with 8203 * OP_FILLED_NEW_ARRAY.S. 8204 */ 8205 /* filled-new-array/jumbo {vCCCC..v(CCCC+BBBB-1)}, type@AAAAAAAA */ 8206 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 8207 FETCH(r0, 1) @ r0<- aaaa (lo) 8208 FETCH(r1, 2) @ r1<- AAAA (hi) 8209 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 8210 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8211 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 8212 EXPORT_PC() @ need for resolve and alloc 8213 cmp r0, #0 @ already resolved? 8214 bne .LOP_FILLED_NEW_ARRAY_JUMBO_continue @ yes, continue on 82158: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 8216 mov r2, #0 @ r2<- false 8217 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 8218 bl dvmResolveClass @ r0<- call(clazz, ref) 8219 cmp r0, #0 @ got null? 8220 beq common_exceptionThrown @ yes, handle exception 8221 b .LOP_FILLED_NEW_ARRAY_JUMBO_continue 8222 8223/* ------------------------------ */ 8224 .balign 64 8225.L_OP_IGET_JUMBO: /* 0x106 */ 8226/* File: armv5te/OP_IGET_JUMBO.S */ 8227 /* 8228 * Jumbo 32-bit instance field get. 8229 * 8230 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 8231 * iget-char/jumbo, iget-short/jumbo 8232 */ 8233 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8234 FETCH(r1, 1) @ r1<- aaaa (lo) 8235 FETCH(r2, 2) @ r2<- AAAA (hi) 8236 FETCH(r0, 4) @ r0<- CCCC 8237 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8238 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8239 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8240 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8241 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8242 cmp r0, #0 @ is resolved entry null? 8243 bne .LOP_IGET_JUMBO_finish @ no, already resolved 82448: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8245 EXPORT_PC() @ resolve() could throw 8246 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8247 bl dvmResolveInstField @ r0<- resolved InstField ptr 8248 b .LOP_IGET_JUMBO_resolved @ resolved, continue 8249 8250/* ------------------------------ */ 8251 .balign 64 8252.L_OP_IGET_WIDE_JUMBO: /* 0x107 */ 8253/* File: armv5te/OP_IGET_WIDE_JUMBO.S */ 8254 /* 8255 * Jumbo 64-bit instance field get. 8256 */ 8257 /* iget-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */ 8258 FETCH(r1, 1) @ r1<- aaaa (lo) 8259 FETCH(r2, 2) @ r2<- AAAA (hi) 8260 FETCH(r0, 4) @ r0<- CCCC 8261 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8262 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8263 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 8264 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8265 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8266 cmp r0, #0 @ is resolved entry null? 8267 bne .LOP_IGET_WIDE_JUMBO_finish @ no, already resolved 82688: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8269 EXPORT_PC() @ resolve() could throw 8270 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8271 bl dvmResolveInstField @ r0<- resolved InstField ptr 8272 b .LOP_IGET_WIDE_JUMBO_resolved @ resolved, continue 8273 8274/* ------------------------------ */ 8275 .balign 64 8276.L_OP_IGET_OBJECT_JUMBO: /* 0x108 */ 8277/* File: armv5te/OP_IGET_OBJECT_JUMBO.S */ 8278/* File: armv5te/OP_IGET_JUMBO.S */ 8279 /* 8280 * Jumbo 32-bit instance field get. 8281 * 8282 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 8283 * iget-char/jumbo, iget-short/jumbo 8284 */ 8285 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8286 FETCH(r1, 1) @ r1<- aaaa (lo) 8287 FETCH(r2, 2) @ r2<- AAAA (hi) 8288 FETCH(r0, 4) @ r0<- CCCC 8289 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8290 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8291 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8292 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8293 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8294 cmp r0, #0 @ is resolved entry null? 8295 bne .LOP_IGET_OBJECT_JUMBO_finish @ no, already resolved 82968: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8297 EXPORT_PC() @ resolve() could throw 8298 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8299 bl dvmResolveInstField @ r0<- resolved InstField ptr 8300 b .LOP_IGET_OBJECT_JUMBO_resolved @ resolved, continue 8301 8302 8303/* ------------------------------ */ 8304 .balign 64 8305.L_OP_IGET_BOOLEAN_JUMBO: /* 0x109 */ 8306/* File: armv5te/OP_IGET_BOOLEAN_JUMBO.S */ 8307@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrb", "sqnum":"1" } 8308/* File: armv5te/OP_IGET_JUMBO.S */ 8309 /* 8310 * Jumbo 32-bit instance field get. 8311 * 8312 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 8313 * iget-char/jumbo, iget-short/jumbo 8314 */ 8315 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8316 FETCH(r1, 1) @ r1<- aaaa (lo) 8317 FETCH(r2, 2) @ r2<- AAAA (hi) 8318 FETCH(r0, 4) @ r0<- CCCC 8319 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8320 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8321 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8322 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8323 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8324 cmp r0, #0 @ is resolved entry null? 8325 bne .LOP_IGET_BOOLEAN_JUMBO_finish @ no, already resolved 83268: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8327 EXPORT_PC() @ resolve() could throw 8328 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8329 bl dvmResolveInstField @ r0<- resolved InstField ptr 8330 b .LOP_IGET_BOOLEAN_JUMBO_resolved @ resolved, continue 8331 8332 8333/* ------------------------------ */ 8334 .balign 64 8335.L_OP_IGET_BYTE_JUMBO: /* 0x10a */ 8336/* File: armv5te/OP_IGET_BYTE_JUMBO.S */ 8337@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsb", "sqnum":"2" } 8338/* File: armv5te/OP_IGET_JUMBO.S */ 8339 /* 8340 * Jumbo 32-bit instance field get. 8341 * 8342 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 8343 * iget-char/jumbo, iget-short/jumbo 8344 */ 8345 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8346 FETCH(r1, 1) @ r1<- aaaa (lo) 8347 FETCH(r2, 2) @ r2<- AAAA (hi) 8348 FETCH(r0, 4) @ r0<- CCCC 8349 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8350 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8351 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8352 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8353 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8354 cmp r0, #0 @ is resolved entry null? 8355 bne .LOP_IGET_BYTE_JUMBO_finish @ no, already resolved 83568: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8357 EXPORT_PC() @ resolve() could throw 8358 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8359 bl dvmResolveInstField @ r0<- resolved InstField ptr 8360 b .LOP_IGET_BYTE_JUMBO_resolved @ resolved, continue 8361 8362 8363/* ------------------------------ */ 8364 .balign 64 8365.L_OP_IGET_CHAR_JUMBO: /* 0x10b */ 8366/* File: armv5te/OP_IGET_CHAR_JUMBO.S */ 8367@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrh", "sqnum":"3" } 8368/* File: armv5te/OP_IGET_JUMBO.S */ 8369 /* 8370 * Jumbo 32-bit instance field get. 8371 * 8372 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 8373 * iget-char/jumbo, iget-short/jumbo 8374 */ 8375 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8376 FETCH(r1, 1) @ r1<- aaaa (lo) 8377 FETCH(r2, 2) @ r2<- AAAA (hi) 8378 FETCH(r0, 4) @ r0<- CCCC 8379 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8380 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8381 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8382 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8383 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8384 cmp r0, #0 @ is resolved entry null? 8385 bne .LOP_IGET_CHAR_JUMBO_finish @ no, already resolved 83868: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8387 EXPORT_PC() @ resolve() could throw 8388 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8389 bl dvmResolveInstField @ r0<- resolved InstField ptr 8390 b .LOP_IGET_CHAR_JUMBO_resolved @ resolved, continue 8391 8392 8393/* ------------------------------ */ 8394 .balign 64 8395.L_OP_IGET_SHORT_JUMBO: /* 0x10c */ 8396/* File: armv5te/OP_IGET_SHORT_JUMBO.S */ 8397@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsh", "sqnum":"4" } 8398/* File: armv5te/OP_IGET_JUMBO.S */ 8399 /* 8400 * Jumbo 32-bit instance field get. 8401 * 8402 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 8403 * iget-char/jumbo, iget-short/jumbo 8404 */ 8405 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8406 FETCH(r1, 1) @ r1<- aaaa (lo) 8407 FETCH(r2, 2) @ r2<- AAAA (hi) 8408 FETCH(r0, 4) @ r0<- CCCC 8409 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8410 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8411 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8412 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8413 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8414 cmp r0, #0 @ is resolved entry null? 8415 bne .LOP_IGET_SHORT_JUMBO_finish @ no, already resolved 84168: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8417 EXPORT_PC() @ resolve() could throw 8418 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8419 bl dvmResolveInstField @ r0<- resolved InstField ptr 8420 b .LOP_IGET_SHORT_JUMBO_resolved @ resolved, continue 8421 8422 8423/* ------------------------------ */ 8424 .balign 64 8425.L_OP_IPUT_JUMBO: /* 0x10d */ 8426/* File: armv5te/OP_IPUT_JUMBO.S */ 8427 /* 8428 * Jumbo 32-bit instance field put. 8429 * 8430 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8431 * iput-short/jumbo 8432 */ 8433 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8434 FETCH(r1, 1) @ r1<- aaaa (lo) 8435 FETCH(r2, 2) @ r2<- AAAA (hi) 8436 FETCH(r0, 4) @ r0<- CCCC 8437 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8438 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8439 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8440 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8441 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8442 cmp r0, #0 @ is resolved entry null? 8443 bne .LOP_IPUT_JUMBO_finish @ no, already resolved 84448: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8445 EXPORT_PC() @ resolve() could throw 8446 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8447 bl dvmResolveInstField @ r0<- resolved InstField ptr 8448 b .LOP_IPUT_JUMBO_resolved @ resolved, continue 8449 8450/* ------------------------------ */ 8451 .balign 64 8452.L_OP_IPUT_WIDE_JUMBO: /* 0x10e */ 8453/* File: armv5te/OP_IPUT_WIDE_JUMBO.S */ 8454 /* iput-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */ 8455 FETCH(r1, 1) @ r1<- aaaa (lo) 8456 FETCH(r2, 2) @ r2<- AAAA (hi) 8457 FETCH(r0, 4) @ r0<- CCCC 8458 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8459 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8460 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 8461 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 8462 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8463 cmp r0, #0 @ is resolved entry null? 8464 bne .LOP_IPUT_WIDE_JUMBO_finish @ no, already resolved 84658: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8466 EXPORT_PC() @ resolve() could throw 8467 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8468 bl dvmResolveInstField @ r0<- resolved InstField ptr 8469 b .LOP_IPUT_WIDE_JUMBO_resolved @ resolved, continue 8470 8471/* ------------------------------ */ 8472 .balign 64 8473.L_OP_IPUT_OBJECT_JUMBO: /* 0x10f */ 8474/* File: armv5te/OP_IPUT_OBJECT_JUMBO.S */ 8475 /* 8476 * Jumbo 32-bit instance field put. 8477 */ 8478 /* iput-object/jumbo vBBBB, vCCCC, field@AAAAAAAA */ 8479 FETCH(r1, 1) @ r1<- aaaa (lo) 8480 FETCH(r2, 2) @ r2<- AAAA (hi) 8481 FETCH(r0, 4) @ r0<- CCCC 8482 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8483 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8484 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8485 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8486 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8487 cmp r0, #0 @ is resolved entry null? 8488 bne .LOP_IPUT_OBJECT_JUMBO_finish @ no, already resolved 84898: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8490 EXPORT_PC() @ resolve() could throw 8491 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8492 bl dvmResolveInstField @ r0<- resolved InstField ptr 8493 b .LOP_IPUT_OBJECT_JUMBO_resolved @ resolved, continue 8494 8495/* ------------------------------ */ 8496 .balign 64 8497.L_OP_IPUT_BOOLEAN_JUMBO: /* 0x110 */ 8498/* File: armv5te/OP_IPUT_BOOLEAN_JUMBO.S */ 8499@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"1" } 8500/* File: armv5te/OP_IPUT_JUMBO.S */ 8501 /* 8502 * Jumbo 32-bit instance field put. 8503 * 8504 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8505 * iput-short/jumbo 8506 */ 8507 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8508 FETCH(r1, 1) @ r1<- aaaa (lo) 8509 FETCH(r2, 2) @ r2<- AAAA (hi) 8510 FETCH(r0, 4) @ r0<- CCCC 8511 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8512 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8513 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8514 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8515 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8516 cmp r0, #0 @ is resolved entry null? 8517 bne .LOP_IPUT_BOOLEAN_JUMBO_finish @ no, already resolved 85188: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8519 EXPORT_PC() @ resolve() could throw 8520 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8521 bl dvmResolveInstField @ r0<- resolved InstField ptr 8522 b .LOP_IPUT_BOOLEAN_JUMBO_resolved @ resolved, continue 8523 8524 8525/* ------------------------------ */ 8526 .balign 64 8527.L_OP_IPUT_BYTE_JUMBO: /* 0x111 */ 8528/* File: armv5te/OP_IPUT_BYTE_JUMBO.S */ 8529@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"2" } 8530/* File: armv5te/OP_IPUT_JUMBO.S */ 8531 /* 8532 * Jumbo 32-bit instance field put. 8533 * 8534 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8535 * iput-short/jumbo 8536 */ 8537 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8538 FETCH(r1, 1) @ r1<- aaaa (lo) 8539 FETCH(r2, 2) @ r2<- AAAA (hi) 8540 FETCH(r0, 4) @ r0<- CCCC 8541 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8542 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8543 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8544 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8545 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8546 cmp r0, #0 @ is resolved entry null? 8547 bne .LOP_IPUT_BYTE_JUMBO_finish @ no, already resolved 85488: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8549 EXPORT_PC() @ resolve() could throw 8550 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8551 bl dvmResolveInstField @ r0<- resolved InstField ptr 8552 b .LOP_IPUT_BYTE_JUMBO_resolved @ resolved, continue 8553 8554 8555/* ------------------------------ */ 8556 .balign 64 8557.L_OP_IPUT_CHAR_JUMBO: /* 0x112 */ 8558/* File: armv5te/OP_IPUT_CHAR_JUMBO.S */ 8559@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"3" } 8560/* File: armv5te/OP_IPUT_JUMBO.S */ 8561 /* 8562 * Jumbo 32-bit instance field put. 8563 * 8564 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8565 * iput-short/jumbo 8566 */ 8567 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8568 FETCH(r1, 1) @ r1<- aaaa (lo) 8569 FETCH(r2, 2) @ r2<- AAAA (hi) 8570 FETCH(r0, 4) @ r0<- CCCC 8571 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8572 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8573 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8574 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8575 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8576 cmp r0, #0 @ is resolved entry null? 8577 bne .LOP_IPUT_CHAR_JUMBO_finish @ no, already resolved 85788: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8579 EXPORT_PC() @ resolve() could throw 8580 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8581 bl dvmResolveInstField @ r0<- resolved InstField ptr 8582 b .LOP_IPUT_CHAR_JUMBO_resolved @ resolved, continue 8583 8584 8585/* ------------------------------ */ 8586 .balign 64 8587.L_OP_IPUT_SHORT_JUMBO: /* 0x113 */ 8588/* File: armv5te/OP_IPUT_SHORT_JUMBO.S */ 8589@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"4" } 8590/* File: armv5te/OP_IPUT_JUMBO.S */ 8591 /* 8592 * Jumbo 32-bit instance field put. 8593 * 8594 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8595 * iput-short/jumbo 8596 */ 8597 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8598 FETCH(r1, 1) @ r1<- aaaa (lo) 8599 FETCH(r2, 2) @ r2<- AAAA (hi) 8600 FETCH(r0, 4) @ r0<- CCCC 8601 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8602 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8603 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8604 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8605 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8606 cmp r0, #0 @ is resolved entry null? 8607 bne .LOP_IPUT_SHORT_JUMBO_finish @ no, already resolved 86088: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8609 EXPORT_PC() @ resolve() could throw 8610 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8611 bl dvmResolveInstField @ r0<- resolved InstField ptr 8612 b .LOP_IPUT_SHORT_JUMBO_resolved @ resolved, continue 8613 8614 8615/* ------------------------------ */ 8616 .balign 64 8617.L_OP_SGET_JUMBO: /* 0x114 */ 8618/* File: armv5te/OP_SGET_JUMBO.S */ 8619 /* 8620 * Jumbo 32-bit SGET handler. 8621 * 8622 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8623 * sget-char/jumbo, sget-short/jumbo 8624 */ 8625 /* exop vBBBB, field@AAAAAAAA */ 8626 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8627 FETCH(r0, 1) @ r0<- aaaa (lo) 8628 FETCH(r1, 2) @ r1<- AAAA (hi) 8629 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8630 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8631 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8632 cmp r0, #0 @ is resolved entry null? 8633 beq .LOP_SGET_JUMBO_resolve @ yes, do resolve 8634.LOP_SGET_JUMBO_finish: @ field ptr in r0 8635 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8636 @ no-op @ acquiring load 8637 FETCH(r2, 3) @ r2<- BBBB 8638 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8639 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8640 GET_INST_OPCODE(ip) @ extract opcode from rINST 8641 GOTO_OPCODE(ip) @ jump to next instruction 8642 8643/* ------------------------------ */ 8644 .balign 64 8645.L_OP_SGET_WIDE_JUMBO: /* 0x115 */ 8646/* File: armv5te/OP_SGET_WIDE_JUMBO.S */ 8647 /* 8648 * Jumbo 64-bit SGET handler. 8649 */ 8650 /* sget-wide/jumbo 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_SGET_WIDE_JUMBO_resolve @ yes, do resolve 8659.LOP_SGET_WIDE_JUMBO_finish: 8660 FETCH(r9, 3) @ r9<- BBBB 8661 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 8662 add r9, rFP, r9, lsl #2 @ r9<- &fp[BBBB] 8663 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8664 stmia r9, {r0-r1} @ vBBBB/vBBBB+1<- r0/r1 8665 GET_INST_OPCODE(ip) @ extract opcode from rINST 8666 GOTO_OPCODE(ip) @ jump to next instruction 8667 8668/* ------------------------------ */ 8669 .balign 64 8670.L_OP_SGET_OBJECT_JUMBO: /* 0x116 */ 8671/* File: armv5te/OP_SGET_OBJECT_JUMBO.S */ 8672/* File: armv5te/OP_SGET_JUMBO.S */ 8673 /* 8674 * Jumbo 32-bit SGET handler. 8675 * 8676 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8677 * sget-char/jumbo, sget-short/jumbo 8678 */ 8679 /* exop vBBBB, field@AAAAAAAA */ 8680 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8681 FETCH(r0, 1) @ r0<- aaaa (lo) 8682 FETCH(r1, 2) @ r1<- AAAA (hi) 8683 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8684 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8685 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8686 cmp r0, #0 @ is resolved entry null? 8687 beq .LOP_SGET_OBJECT_JUMBO_resolve @ yes, do resolve 8688.LOP_SGET_OBJECT_JUMBO_finish: @ field ptr in r0 8689 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8690 @ no-op @ acquiring load 8691 FETCH(r2, 3) @ r2<- BBBB 8692 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8693 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8694 GET_INST_OPCODE(ip) @ extract opcode from rINST 8695 GOTO_OPCODE(ip) @ jump to next instruction 8696 8697 8698/* ------------------------------ */ 8699 .balign 64 8700.L_OP_SGET_BOOLEAN_JUMBO: /* 0x117 */ 8701/* File: armv5te/OP_SGET_BOOLEAN_JUMBO.S */ 8702/* File: armv5te/OP_SGET_JUMBO.S */ 8703 /* 8704 * Jumbo 32-bit SGET handler. 8705 * 8706 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8707 * sget-char/jumbo, sget-short/jumbo 8708 */ 8709 /* exop vBBBB, field@AAAAAAAA */ 8710 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8711 FETCH(r0, 1) @ r0<- aaaa (lo) 8712 FETCH(r1, 2) @ r1<- AAAA (hi) 8713 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8714 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8715 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8716 cmp r0, #0 @ is resolved entry null? 8717 beq .LOP_SGET_BOOLEAN_JUMBO_resolve @ yes, do resolve 8718.LOP_SGET_BOOLEAN_JUMBO_finish: @ field ptr in r0 8719 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8720 @ no-op @ acquiring load 8721 FETCH(r2, 3) @ r2<- BBBB 8722 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8723 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8724 GET_INST_OPCODE(ip) @ extract opcode from rINST 8725 GOTO_OPCODE(ip) @ jump to next instruction 8726 8727 8728/* ------------------------------ */ 8729 .balign 64 8730.L_OP_SGET_BYTE_JUMBO: /* 0x118 */ 8731/* File: armv5te/OP_SGET_BYTE_JUMBO.S */ 8732/* File: armv5te/OP_SGET_JUMBO.S */ 8733 /* 8734 * Jumbo 32-bit SGET handler. 8735 * 8736 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8737 * sget-char/jumbo, sget-short/jumbo 8738 */ 8739 /* exop vBBBB, field@AAAAAAAA */ 8740 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8741 FETCH(r0, 1) @ r0<- aaaa (lo) 8742 FETCH(r1, 2) @ r1<- AAAA (hi) 8743 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8744 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8745 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8746 cmp r0, #0 @ is resolved entry null? 8747 beq .LOP_SGET_BYTE_JUMBO_resolve @ yes, do resolve 8748.LOP_SGET_BYTE_JUMBO_finish: @ field ptr in r0 8749 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8750 @ no-op @ acquiring load 8751 FETCH(r2, 3) @ r2<- BBBB 8752 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8753 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8754 GET_INST_OPCODE(ip) @ extract opcode from rINST 8755 GOTO_OPCODE(ip) @ jump to next instruction 8756 8757 8758/* ------------------------------ */ 8759 .balign 64 8760.L_OP_SGET_CHAR_JUMBO: /* 0x119 */ 8761/* File: armv5te/OP_SGET_CHAR_JUMBO.S */ 8762/* File: armv5te/OP_SGET_JUMBO.S */ 8763 /* 8764 * Jumbo 32-bit SGET handler. 8765 * 8766 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8767 * sget-char/jumbo, sget-short/jumbo 8768 */ 8769 /* exop vBBBB, field@AAAAAAAA */ 8770 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8771 FETCH(r0, 1) @ r0<- aaaa (lo) 8772 FETCH(r1, 2) @ r1<- AAAA (hi) 8773 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8774 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8775 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8776 cmp r0, #0 @ is resolved entry null? 8777 beq .LOP_SGET_CHAR_JUMBO_resolve @ yes, do resolve 8778.LOP_SGET_CHAR_JUMBO_finish: @ field ptr in r0 8779 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8780 @ no-op @ acquiring load 8781 FETCH(r2, 3) @ r2<- BBBB 8782 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8783 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8784 GET_INST_OPCODE(ip) @ extract opcode from rINST 8785 GOTO_OPCODE(ip) @ jump to next instruction 8786 8787 8788/* ------------------------------ */ 8789 .balign 64 8790.L_OP_SGET_SHORT_JUMBO: /* 0x11a */ 8791/* File: armv5te/OP_SGET_SHORT_JUMBO.S */ 8792/* File: armv5te/OP_SGET_JUMBO.S */ 8793 /* 8794 * Jumbo 32-bit SGET handler. 8795 * 8796 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8797 * sget-char/jumbo, sget-short/jumbo 8798 */ 8799 /* exop vBBBB, field@AAAAAAAA */ 8800 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8801 FETCH(r0, 1) @ r0<- aaaa (lo) 8802 FETCH(r1, 2) @ r1<- AAAA (hi) 8803 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8804 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8805 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8806 cmp r0, #0 @ is resolved entry null? 8807 beq .LOP_SGET_SHORT_JUMBO_resolve @ yes, do resolve 8808.LOP_SGET_SHORT_JUMBO_finish: @ field ptr in r0 8809 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8810 @ no-op @ acquiring load 8811 FETCH(r2, 3) @ r2<- BBBB 8812 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8813 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8814 GET_INST_OPCODE(ip) @ extract opcode from rINST 8815 GOTO_OPCODE(ip) @ jump to next instruction 8816 8817 8818/* ------------------------------ */ 8819 .balign 64 8820.L_OP_SPUT_JUMBO: /* 0x11b */ 8821/* File: armv5te/OP_SPUT_JUMBO.S */ 8822 /* 8823 * Jumbo 32-bit SPUT handler. 8824 * 8825 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8826 * sput-short/jumbo 8827 */ 8828 /* exop vBBBB, field@AAAAAAAA */ 8829 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8830 FETCH(r0, 1) @ r0<- aaaa (lo) 8831 FETCH(r1, 2) @ r1<- AAAA (hi) 8832 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8833 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8834 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8835 cmp r0, #0 @ is resolved entry null? 8836 beq .LOP_SPUT_JUMBO_resolve @ yes, do resolve 8837.LOP_SPUT_JUMBO_finish: @ field ptr in r0 8838 FETCH(r2, 3) @ r2<- BBBB 8839 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8840 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8841 GET_INST_OPCODE(ip) @ extract opcode from rINST 8842 @ no-op @ releasing store 8843 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8844 GOTO_OPCODE(ip) @ jump to next instruction 8845 8846/* ------------------------------ */ 8847 .balign 64 8848.L_OP_SPUT_WIDE_JUMBO: /* 0x11c */ 8849/* File: armv5te/OP_SPUT_WIDE_JUMBO.S */ 8850 /* 8851 * Jumbo 64-bit SPUT handler. 8852 */ 8853 /* sput-wide/jumbo vBBBB, field@AAAAAAAA */ 8854 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- DvmDex 8855 FETCH(r1, 1) @ r1<- aaaa (lo) 8856 FETCH(r2, 2) @ r2<- AAAA (hi) 8857 ldr r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields 8858 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8859 FETCH(r9, 3) @ r9<- BBBB 8860 ldr r2, [r0, r1, lsl #2] @ r2<- resolved StaticField ptr 8861 add r9, rFP, r9, lsl #2 @ r9<- &fp[BBBB] 8862 cmp r2, #0 @ is resolved entry null? 8863 beq .LOP_SPUT_WIDE_JUMBO_resolve @ yes, do resolve 8864.LOP_SPUT_WIDE_JUMBO_finish: @ field ptr in r2, BBBB in r9 8865 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8866 ldmia r9, {r0-r1} @ r0/r1<- vBBBB/vBBBB+1 8867 GET_INST_OPCODE(r10) @ extract opcode from rINST 8868 strd r0, [r2, #offStaticField_value] @ field<- vBBBB/vBBBB+1 8869 GOTO_OPCODE(r10) @ jump to next instruction 8870 8871/* ------------------------------ */ 8872 .balign 64 8873.L_OP_SPUT_OBJECT_JUMBO: /* 0x11d */ 8874/* File: armv5te/OP_SPUT_OBJECT_JUMBO.S */ 8875 /* 8876 * Jumbo 32-bit SPUT handler for objects 8877 */ 8878 /* sput-object/jumbo vBBBB, field@AAAAAAAA */ 8879 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8880 FETCH(r0, 1) @ r0<- aaaa (lo) 8881 FETCH(r1, 2) @ r1<- AAAA (hi) 8882 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8883 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8884 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8885 cmp r0, #0 @ is resolved entry null? 8886 bne .LOP_SPUT_OBJECT_JUMBO_finish @ no, continue 8887 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 8888 EXPORT_PC() @ resolve() could throw, so export now 8889 ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz 8890 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8891 cmp r0, #0 @ success? 8892 bne .LOP_SPUT_OBJECT_JUMBO_finish @ yes, finish 8893 b common_exceptionThrown @ no, handle exception 8894 8895/* ------------------------------ */ 8896 .balign 64 8897.L_OP_SPUT_BOOLEAN_JUMBO: /* 0x11e */ 8898/* File: armv5te/OP_SPUT_BOOLEAN_JUMBO.S */ 8899/* File: armv5te/OP_SPUT_JUMBO.S */ 8900 /* 8901 * Jumbo 32-bit SPUT handler. 8902 * 8903 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8904 * sput-short/jumbo 8905 */ 8906 /* exop vBBBB, field@AAAAAAAA */ 8907 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8908 FETCH(r0, 1) @ r0<- aaaa (lo) 8909 FETCH(r1, 2) @ r1<- AAAA (hi) 8910 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8911 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8912 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8913 cmp r0, #0 @ is resolved entry null? 8914 beq .LOP_SPUT_BOOLEAN_JUMBO_resolve @ yes, do resolve 8915.LOP_SPUT_BOOLEAN_JUMBO_finish: @ field ptr in r0 8916 FETCH(r2, 3) @ r2<- BBBB 8917 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8918 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8919 GET_INST_OPCODE(ip) @ extract opcode from rINST 8920 @ no-op @ releasing store 8921 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8922 GOTO_OPCODE(ip) @ jump to next instruction 8923 8924 8925/* ------------------------------ */ 8926 .balign 64 8927.L_OP_SPUT_BYTE_JUMBO: /* 0x11f */ 8928/* File: armv5te/OP_SPUT_BYTE_JUMBO.S */ 8929/* File: armv5te/OP_SPUT_JUMBO.S */ 8930 /* 8931 * Jumbo 32-bit SPUT handler. 8932 * 8933 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8934 * sput-short/jumbo 8935 */ 8936 /* exop vBBBB, field@AAAAAAAA */ 8937 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8938 FETCH(r0, 1) @ r0<- aaaa (lo) 8939 FETCH(r1, 2) @ r1<- AAAA (hi) 8940 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8941 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8942 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8943 cmp r0, #0 @ is resolved entry null? 8944 beq .LOP_SPUT_BYTE_JUMBO_resolve @ yes, do resolve 8945.LOP_SPUT_BYTE_JUMBO_finish: @ field ptr in r0 8946 FETCH(r2, 3) @ r2<- BBBB 8947 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8948 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8949 GET_INST_OPCODE(ip) @ extract opcode from rINST 8950 @ no-op @ releasing store 8951 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8952 GOTO_OPCODE(ip) @ jump to next instruction 8953 8954 8955/* ------------------------------ */ 8956 .balign 64 8957.L_OP_SPUT_CHAR_JUMBO: /* 0x120 */ 8958/* File: armv5te/OP_SPUT_CHAR_JUMBO.S */ 8959/* File: armv5te/OP_SPUT_JUMBO.S */ 8960 /* 8961 * Jumbo 32-bit SPUT handler. 8962 * 8963 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8964 * sput-short/jumbo 8965 */ 8966 /* exop vBBBB, field@AAAAAAAA */ 8967 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8968 FETCH(r0, 1) @ r0<- aaaa (lo) 8969 FETCH(r1, 2) @ r1<- AAAA (hi) 8970 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8971 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8972 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8973 cmp r0, #0 @ is resolved entry null? 8974 beq .LOP_SPUT_CHAR_JUMBO_resolve @ yes, do resolve 8975.LOP_SPUT_CHAR_JUMBO_finish: @ field ptr in r0 8976 FETCH(r2, 3) @ r2<- BBBB 8977 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8978 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8979 GET_INST_OPCODE(ip) @ extract opcode from rINST 8980 @ no-op @ releasing store 8981 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8982 GOTO_OPCODE(ip) @ jump to next instruction 8983 8984 8985/* ------------------------------ */ 8986 .balign 64 8987.L_OP_SPUT_SHORT_JUMBO: /* 0x121 */ 8988/* File: armv5te/OP_SPUT_SHORT_JUMBO.S */ 8989/* File: armv5te/OP_SPUT_JUMBO.S */ 8990 /* 8991 * Jumbo 32-bit SPUT handler. 8992 * 8993 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8994 * sput-short/jumbo 8995 */ 8996 /* exop vBBBB, field@AAAAAAAA */ 8997 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8998 FETCH(r0, 1) @ r0<- aaaa (lo) 8999 FETCH(r1, 2) @ r1<- AAAA (hi) 9000 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 9001 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 9002 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 9003 cmp r0, #0 @ is resolved entry null? 9004 beq .LOP_SPUT_SHORT_JUMBO_resolve @ yes, do resolve 9005.LOP_SPUT_SHORT_JUMBO_finish: @ field ptr in r0 9006 FETCH(r2, 3) @ r2<- BBBB 9007 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 9008 GET_VREG(r1, r2) @ r1<- fp[BBBB] 9009 GET_INST_OPCODE(ip) @ extract opcode from rINST 9010 @ no-op @ releasing store 9011 str r1, [r0, #offStaticField_value] @ field<- vBBBB 9012 GOTO_OPCODE(ip) @ jump to next instruction 9013 9014 9015/* ------------------------------ */ 9016 .balign 64 9017.L_OP_INVOKE_VIRTUAL_JUMBO: /* 0x122 */ 9018/* File: armv5te/OP_INVOKE_VIRTUAL_JUMBO.S */ 9019 /* 9020 * Handle a virtual method call. 9021 */ 9022 /* invoke-virtual/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 9023 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 9024 FETCH(r0, 1) @ r1<- aaaa (lo) 9025 FETCH(r1, 2) @ r1<- AAAA (hi) 9026 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 9027 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 9028 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 9029 cmp r0, #0 @ already resolved? 9030 EXPORT_PC() @ must export for invoke 9031 bne .LOP_INVOKE_VIRTUAL_JUMBO_continue @ yes, continue on 9032 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 9033 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 9034 mov r2, #METHOD_VIRTUAL @ resolver method type 9035 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9036 cmp r0, #0 @ got null? 9037 bne .LOP_INVOKE_VIRTUAL_JUMBO_continue @ no, continue 9038 b common_exceptionThrown @ yes, handle exception 9039 9040/* ------------------------------ */ 9041 .balign 64 9042.L_OP_INVOKE_SUPER_JUMBO: /* 0x123 */ 9043/* File: armv5te/OP_INVOKE_SUPER_JUMBO.S */ 9044 /* 9045 * Handle a "super" method call. 9046 */ 9047 /* invoke-super/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 9048 FETCH(r10, 4) @ r10<- CCCC 9049 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 9050 FETCH(r0, 1) @ r1<- aaaa (lo) 9051 FETCH(r1, 2) @ r1<- AAAA (hi) 9052 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 9053 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 9054 GET_VREG(r2, r10) @ r2<- "this" ptr 9055 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 9056 cmp r2, #0 @ null "this"? 9057 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 9058 beq common_errNullObject @ null "this", throw exception 9059 cmp r0, #0 @ already resolved? 9060 ldr r9, [r9, #offMethod_clazz] @ r9<- method->clazz 9061 EXPORT_PC() @ must export for invoke 9062 bne .LOP_INVOKE_SUPER_JUMBO_continue @ resolved, continue on 9063 b .LOP_INVOKE_SUPER_JUMBO_resolve @ do resolve now 9064 9065/* ------------------------------ */ 9066 .balign 64 9067.L_OP_INVOKE_DIRECT_JUMBO: /* 0x124 */ 9068/* File: armv5te/OP_INVOKE_DIRECT_JUMBO.S */ 9069 /* 9070 * Handle a direct method call. 9071 * 9072 * (We could defer the "is 'this' pointer null" test to the common 9073 * method invocation code, and use a flag to indicate that static 9074 * calls don't count. If we do this as part of copying the arguments 9075 * out we could avoiding loading the first arg twice.) 9076 * 9077 */ 9078 /* invoke-direct/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 9079 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 9080 FETCH(r0, 1) @ r1<- aaaa (lo) 9081 FETCH(r1, 2) @ r1<- AAAA (hi) 9082 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 9083 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 9084 FETCH(r10, 4) @ r10<- CCCC 9085 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 9086 cmp r0, #0 @ already resolved? 9087 EXPORT_PC() @ must export for invoke 9088 GET_VREG(r2, r10) @ r2<- "this" ptr 9089 beq .LOP_INVOKE_DIRECT_JUMBO_resolve @ not resolved, do it now 9090.LOP_INVOKE_DIRECT_JUMBO_finish: 9091 cmp r2, #0 @ null "this" ref? 9092 bne common_invokeMethodJumbo @ no, continue on 9093 b common_errNullObject @ yes, throw exception 9094 9095/* ------------------------------ */ 9096 .balign 64 9097.L_OP_INVOKE_STATIC_JUMBO: /* 0x125 */ 9098/* File: armv5te/OP_INVOKE_STATIC_JUMBO.S */ 9099 /* 9100 * Handle a static method call. 9101 */ 9102 /* invoke-static/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 9103 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 9104 FETCH(r0, 1) @ r1<- aaaa (lo) 9105 FETCH(r1, 2) @ r1<- AAAA (hi) 9106 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 9107 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 9108 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 9109 cmp r0, #0 @ already resolved? 9110 EXPORT_PC() @ must export for invoke 9111 bne common_invokeMethodJumbo @ yes, continue on 91120: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 9113 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 9114 mov r2, #METHOD_STATIC @ resolver method type 9115 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9116 cmp r0, #0 @ got null? 9117 bne common_invokeMethodJumbo @ no, continue 9118 b common_exceptionThrown @ yes, handle exception 9119 9120/* ------------------------------ */ 9121 .balign 64 9122.L_OP_INVOKE_INTERFACE_JUMBO: /* 0x126 */ 9123/* File: armv5te/OP_INVOKE_INTERFACE_JUMBO.S */ 9124 /* 9125 * Handle an interface method call. 9126 */ 9127 /* invoke-interface/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 9128 FETCH(r2, 4) @ r2<- CCCC 9129 FETCH(r0, 1) @ r0<- aaaa (lo) 9130 FETCH(r1, 2) @ r1<- AAAA (hi) 9131 EXPORT_PC() @ must export for invoke 9132 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 9133 GET_VREG(r0, r2) @ r0<- first arg ("this") 9134 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- methodClassDex 9135 cmp r0, #0 @ null obj? 9136 ldr r2, [rGLUE, #offGlue_method] @ r2<- method 9137 beq common_errNullObject @ yes, fail 9138 ldr r0, [r0, #offObject_clazz] @ r0<- thisPtr->clazz 9139 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 9140 cmp r0, #0 @ failed? 9141 beq common_exceptionThrown @ yes, handle exception 9142 b common_invokeMethodJumbo @ jump to common handler 9143 9144/* ------------------------------ */ 9145 .balign 64 9146.L_OP_UNUSED_27FF: /* 0x127 */ 9147/* File: armv5te/OP_UNUSED_27FF.S */ 9148/* File: armv5te/unused.S */ 9149 bl common_abort 9150 9151 9152/* ------------------------------ */ 9153 .balign 64 9154.L_OP_UNUSED_28FF: /* 0x128 */ 9155/* File: armv5te/OP_UNUSED_28FF.S */ 9156/* File: armv5te/unused.S */ 9157 bl common_abort 9158 9159 9160/* ------------------------------ */ 9161 .balign 64 9162.L_OP_UNUSED_29FF: /* 0x129 */ 9163/* File: armv5te/OP_UNUSED_29FF.S */ 9164/* File: armv5te/unused.S */ 9165 bl common_abort 9166 9167 9168/* ------------------------------ */ 9169 .balign 64 9170.L_OP_UNUSED_2AFF: /* 0x12a */ 9171/* File: armv5te/OP_UNUSED_2AFF.S */ 9172/* File: armv5te/unused.S */ 9173 bl common_abort 9174 9175 9176/* ------------------------------ */ 9177 .balign 64 9178.L_OP_UNUSED_2BFF: /* 0x12b */ 9179/* File: armv5te/OP_UNUSED_2BFF.S */ 9180/* File: armv5te/unused.S */ 9181 bl common_abort 9182 9183 9184/* ------------------------------ */ 9185 .balign 64 9186.L_OP_UNUSED_2CFF: /* 0x12c */ 9187/* File: armv5te/OP_UNUSED_2CFF.S */ 9188/* File: armv5te/unused.S */ 9189 bl common_abort 9190 9191 9192/* ------------------------------ */ 9193 .balign 64 9194.L_OP_UNUSED_2DFF: /* 0x12d */ 9195/* File: armv5te/OP_UNUSED_2DFF.S */ 9196/* File: armv5te/unused.S */ 9197 bl common_abort 9198 9199 9200/* ------------------------------ */ 9201 .balign 64 9202.L_OP_UNUSED_2EFF: /* 0x12e */ 9203/* File: armv5te/OP_UNUSED_2EFF.S */ 9204/* File: armv5te/unused.S */ 9205 bl common_abort 9206 9207 9208/* ------------------------------ */ 9209 .balign 64 9210.L_OP_UNUSED_2FFF: /* 0x12f */ 9211/* File: armv5te/OP_UNUSED_2FFF.S */ 9212/* File: armv5te/unused.S */ 9213 bl common_abort 9214 9215 9216/* ------------------------------ */ 9217 .balign 64 9218.L_OP_UNUSED_30FF: /* 0x130 */ 9219/* File: armv5te/OP_UNUSED_30FF.S */ 9220/* File: armv5te/unused.S */ 9221 bl common_abort 9222 9223 9224/* ------------------------------ */ 9225 .balign 64 9226.L_OP_UNUSED_31FF: /* 0x131 */ 9227/* File: armv5te/OP_UNUSED_31FF.S */ 9228/* File: armv5te/unused.S */ 9229 bl common_abort 9230 9231 9232/* ------------------------------ */ 9233 .balign 64 9234.L_OP_UNUSED_32FF: /* 0x132 */ 9235/* File: armv5te/OP_UNUSED_32FF.S */ 9236/* File: armv5te/unused.S */ 9237 bl common_abort 9238 9239 9240/* ------------------------------ */ 9241 .balign 64 9242.L_OP_UNUSED_33FF: /* 0x133 */ 9243/* File: armv5te/OP_UNUSED_33FF.S */ 9244/* File: armv5te/unused.S */ 9245 bl common_abort 9246 9247 9248/* ------------------------------ */ 9249 .balign 64 9250.L_OP_UNUSED_34FF: /* 0x134 */ 9251/* File: armv5te/OP_UNUSED_34FF.S */ 9252/* File: armv5te/unused.S */ 9253 bl common_abort 9254 9255 9256/* ------------------------------ */ 9257 .balign 64 9258.L_OP_UNUSED_35FF: /* 0x135 */ 9259/* File: armv5te/OP_UNUSED_35FF.S */ 9260/* File: armv5te/unused.S */ 9261 bl common_abort 9262 9263 9264/* ------------------------------ */ 9265 .balign 64 9266.L_OP_UNUSED_36FF: /* 0x136 */ 9267/* File: armv5te/OP_UNUSED_36FF.S */ 9268/* File: armv5te/unused.S */ 9269 bl common_abort 9270 9271 9272/* ------------------------------ */ 9273 .balign 64 9274.L_OP_UNUSED_37FF: /* 0x137 */ 9275/* File: armv5te/OP_UNUSED_37FF.S */ 9276/* File: armv5te/unused.S */ 9277 bl common_abort 9278 9279 9280/* ------------------------------ */ 9281 .balign 64 9282.L_OP_UNUSED_38FF: /* 0x138 */ 9283/* File: armv5te/OP_UNUSED_38FF.S */ 9284/* File: armv5te/unused.S */ 9285 bl common_abort 9286 9287 9288/* ------------------------------ */ 9289 .balign 64 9290.L_OP_UNUSED_39FF: /* 0x139 */ 9291/* File: armv5te/OP_UNUSED_39FF.S */ 9292/* File: armv5te/unused.S */ 9293 bl common_abort 9294 9295 9296/* ------------------------------ */ 9297 .balign 64 9298.L_OP_UNUSED_3AFF: /* 0x13a */ 9299/* File: armv5te/OP_UNUSED_3AFF.S */ 9300/* File: armv5te/unused.S */ 9301 bl common_abort 9302 9303 9304/* ------------------------------ */ 9305 .balign 64 9306.L_OP_UNUSED_3BFF: /* 0x13b */ 9307/* File: armv5te/OP_UNUSED_3BFF.S */ 9308/* File: armv5te/unused.S */ 9309 bl common_abort 9310 9311 9312/* ------------------------------ */ 9313 .balign 64 9314.L_OP_UNUSED_3CFF: /* 0x13c */ 9315/* File: armv5te/OP_UNUSED_3CFF.S */ 9316/* File: armv5te/unused.S */ 9317 bl common_abort 9318 9319 9320/* ------------------------------ */ 9321 .balign 64 9322.L_OP_UNUSED_3DFF: /* 0x13d */ 9323/* File: armv5te/OP_UNUSED_3DFF.S */ 9324/* File: armv5te/unused.S */ 9325 bl common_abort 9326 9327 9328/* ------------------------------ */ 9329 .balign 64 9330.L_OP_UNUSED_3EFF: /* 0x13e */ 9331/* File: armv5te/OP_UNUSED_3EFF.S */ 9332/* File: armv5te/unused.S */ 9333 bl common_abort 9334 9335 9336/* ------------------------------ */ 9337 .balign 64 9338.L_OP_UNUSED_3FFF: /* 0x13f */ 9339/* File: armv5te/OP_UNUSED_3FFF.S */ 9340/* File: armv5te/unused.S */ 9341 bl common_abort 9342 9343 9344/* ------------------------------ */ 9345 .balign 64 9346.L_OP_UNUSED_40FF: /* 0x140 */ 9347/* File: armv5te/OP_UNUSED_40FF.S */ 9348/* File: armv5te/unused.S */ 9349 bl common_abort 9350 9351 9352/* ------------------------------ */ 9353 .balign 64 9354.L_OP_UNUSED_41FF: /* 0x141 */ 9355/* File: armv5te/OP_UNUSED_41FF.S */ 9356/* File: armv5te/unused.S */ 9357 bl common_abort 9358 9359 9360/* ------------------------------ */ 9361 .balign 64 9362.L_OP_UNUSED_42FF: /* 0x142 */ 9363/* File: armv5te/OP_UNUSED_42FF.S */ 9364/* File: armv5te/unused.S */ 9365 bl common_abort 9366 9367 9368/* ------------------------------ */ 9369 .balign 64 9370.L_OP_UNUSED_43FF: /* 0x143 */ 9371/* File: armv5te/OP_UNUSED_43FF.S */ 9372/* File: armv5te/unused.S */ 9373 bl common_abort 9374 9375 9376/* ------------------------------ */ 9377 .balign 64 9378.L_OP_UNUSED_44FF: /* 0x144 */ 9379/* File: armv5te/OP_UNUSED_44FF.S */ 9380/* File: armv5te/unused.S */ 9381 bl common_abort 9382 9383 9384/* ------------------------------ */ 9385 .balign 64 9386.L_OP_UNUSED_45FF: /* 0x145 */ 9387/* File: armv5te/OP_UNUSED_45FF.S */ 9388/* File: armv5te/unused.S */ 9389 bl common_abort 9390 9391 9392/* ------------------------------ */ 9393 .balign 64 9394.L_OP_UNUSED_46FF: /* 0x146 */ 9395/* File: armv5te/OP_UNUSED_46FF.S */ 9396/* File: armv5te/unused.S */ 9397 bl common_abort 9398 9399 9400/* ------------------------------ */ 9401 .balign 64 9402.L_OP_UNUSED_47FF: /* 0x147 */ 9403/* File: armv5te/OP_UNUSED_47FF.S */ 9404/* File: armv5te/unused.S */ 9405 bl common_abort 9406 9407 9408/* ------------------------------ */ 9409 .balign 64 9410.L_OP_UNUSED_48FF: /* 0x148 */ 9411/* File: armv5te/OP_UNUSED_48FF.S */ 9412/* File: armv5te/unused.S */ 9413 bl common_abort 9414 9415 9416/* ------------------------------ */ 9417 .balign 64 9418.L_OP_UNUSED_49FF: /* 0x149 */ 9419/* File: armv5te/OP_UNUSED_49FF.S */ 9420/* File: armv5te/unused.S */ 9421 bl common_abort 9422 9423 9424/* ------------------------------ */ 9425 .balign 64 9426.L_OP_UNUSED_4AFF: /* 0x14a */ 9427/* File: armv5te/OP_UNUSED_4AFF.S */ 9428/* File: armv5te/unused.S */ 9429 bl common_abort 9430 9431 9432/* ------------------------------ */ 9433 .balign 64 9434.L_OP_UNUSED_4BFF: /* 0x14b */ 9435/* File: armv5te/OP_UNUSED_4BFF.S */ 9436/* File: armv5te/unused.S */ 9437 bl common_abort 9438 9439 9440/* ------------------------------ */ 9441 .balign 64 9442.L_OP_UNUSED_4CFF: /* 0x14c */ 9443/* File: armv5te/OP_UNUSED_4CFF.S */ 9444/* File: armv5te/unused.S */ 9445 bl common_abort 9446 9447 9448/* ------------------------------ */ 9449 .balign 64 9450.L_OP_UNUSED_4DFF: /* 0x14d */ 9451/* File: armv5te/OP_UNUSED_4DFF.S */ 9452/* File: armv5te/unused.S */ 9453 bl common_abort 9454 9455 9456/* ------------------------------ */ 9457 .balign 64 9458.L_OP_UNUSED_4EFF: /* 0x14e */ 9459/* File: armv5te/OP_UNUSED_4EFF.S */ 9460/* File: armv5te/unused.S */ 9461 bl common_abort 9462 9463 9464/* ------------------------------ */ 9465 .balign 64 9466.L_OP_UNUSED_4FFF: /* 0x14f */ 9467/* File: armv5te/OP_UNUSED_4FFF.S */ 9468/* File: armv5te/unused.S */ 9469 bl common_abort 9470 9471 9472/* ------------------------------ */ 9473 .balign 64 9474.L_OP_UNUSED_50FF: /* 0x150 */ 9475/* File: armv5te/OP_UNUSED_50FF.S */ 9476/* File: armv5te/unused.S */ 9477 bl common_abort 9478 9479 9480/* ------------------------------ */ 9481 .balign 64 9482.L_OP_UNUSED_51FF: /* 0x151 */ 9483/* File: armv5te/OP_UNUSED_51FF.S */ 9484/* File: armv5te/unused.S */ 9485 bl common_abort 9486 9487 9488/* ------------------------------ */ 9489 .balign 64 9490.L_OP_UNUSED_52FF: /* 0x152 */ 9491/* File: armv5te/OP_UNUSED_52FF.S */ 9492/* File: armv5te/unused.S */ 9493 bl common_abort 9494 9495 9496/* ------------------------------ */ 9497 .balign 64 9498.L_OP_UNUSED_53FF: /* 0x153 */ 9499/* File: armv5te/OP_UNUSED_53FF.S */ 9500/* File: armv5te/unused.S */ 9501 bl common_abort 9502 9503 9504/* ------------------------------ */ 9505 .balign 64 9506.L_OP_UNUSED_54FF: /* 0x154 */ 9507/* File: armv5te/OP_UNUSED_54FF.S */ 9508/* File: armv5te/unused.S */ 9509 bl common_abort 9510 9511 9512/* ------------------------------ */ 9513 .balign 64 9514.L_OP_UNUSED_55FF: /* 0x155 */ 9515/* File: armv5te/OP_UNUSED_55FF.S */ 9516/* File: armv5te/unused.S */ 9517 bl common_abort 9518 9519 9520/* ------------------------------ */ 9521 .balign 64 9522.L_OP_UNUSED_56FF: /* 0x156 */ 9523/* File: armv5te/OP_UNUSED_56FF.S */ 9524/* File: armv5te/unused.S */ 9525 bl common_abort 9526 9527 9528/* ------------------------------ */ 9529 .balign 64 9530.L_OP_UNUSED_57FF: /* 0x157 */ 9531/* File: armv5te/OP_UNUSED_57FF.S */ 9532/* File: armv5te/unused.S */ 9533 bl common_abort 9534 9535 9536/* ------------------------------ */ 9537 .balign 64 9538.L_OP_UNUSED_58FF: /* 0x158 */ 9539/* File: armv5te/OP_UNUSED_58FF.S */ 9540/* File: armv5te/unused.S */ 9541 bl common_abort 9542 9543 9544/* ------------------------------ */ 9545 .balign 64 9546.L_OP_UNUSED_59FF: /* 0x159 */ 9547/* File: armv5te/OP_UNUSED_59FF.S */ 9548/* File: armv5te/unused.S */ 9549 bl common_abort 9550 9551 9552/* ------------------------------ */ 9553 .balign 64 9554.L_OP_UNUSED_5AFF: /* 0x15a */ 9555/* File: armv5te/OP_UNUSED_5AFF.S */ 9556/* File: armv5te/unused.S */ 9557 bl common_abort 9558 9559 9560/* ------------------------------ */ 9561 .balign 64 9562.L_OP_UNUSED_5BFF: /* 0x15b */ 9563/* File: armv5te/OP_UNUSED_5BFF.S */ 9564/* File: armv5te/unused.S */ 9565 bl common_abort 9566 9567 9568/* ------------------------------ */ 9569 .balign 64 9570.L_OP_UNUSED_5CFF: /* 0x15c */ 9571/* File: armv5te/OP_UNUSED_5CFF.S */ 9572/* File: armv5te/unused.S */ 9573 bl common_abort 9574 9575 9576/* ------------------------------ */ 9577 .balign 64 9578.L_OP_UNUSED_5DFF: /* 0x15d */ 9579/* File: armv5te/OP_UNUSED_5DFF.S */ 9580/* File: armv5te/unused.S */ 9581 bl common_abort 9582 9583 9584/* ------------------------------ */ 9585 .balign 64 9586.L_OP_UNUSED_5EFF: /* 0x15e */ 9587/* File: armv5te/OP_UNUSED_5EFF.S */ 9588/* File: armv5te/unused.S */ 9589 bl common_abort 9590 9591 9592/* ------------------------------ */ 9593 .balign 64 9594.L_OP_UNUSED_5FFF: /* 0x15f */ 9595/* File: armv5te/OP_UNUSED_5FFF.S */ 9596/* File: armv5te/unused.S */ 9597 bl common_abort 9598 9599 9600/* ------------------------------ */ 9601 .balign 64 9602.L_OP_UNUSED_60FF: /* 0x160 */ 9603/* File: armv5te/OP_UNUSED_60FF.S */ 9604/* File: armv5te/unused.S */ 9605 bl common_abort 9606 9607 9608/* ------------------------------ */ 9609 .balign 64 9610.L_OP_UNUSED_61FF: /* 0x161 */ 9611/* File: armv5te/OP_UNUSED_61FF.S */ 9612/* File: armv5te/unused.S */ 9613 bl common_abort 9614 9615 9616/* ------------------------------ */ 9617 .balign 64 9618.L_OP_UNUSED_62FF: /* 0x162 */ 9619/* File: armv5te/OP_UNUSED_62FF.S */ 9620/* File: armv5te/unused.S */ 9621 bl common_abort 9622 9623 9624/* ------------------------------ */ 9625 .balign 64 9626.L_OP_UNUSED_63FF: /* 0x163 */ 9627/* File: armv5te/OP_UNUSED_63FF.S */ 9628/* File: armv5te/unused.S */ 9629 bl common_abort 9630 9631 9632/* ------------------------------ */ 9633 .balign 64 9634.L_OP_UNUSED_64FF: /* 0x164 */ 9635/* File: armv5te/OP_UNUSED_64FF.S */ 9636/* File: armv5te/unused.S */ 9637 bl common_abort 9638 9639 9640/* ------------------------------ */ 9641 .balign 64 9642.L_OP_UNUSED_65FF: /* 0x165 */ 9643/* File: armv5te/OP_UNUSED_65FF.S */ 9644/* File: armv5te/unused.S */ 9645 bl common_abort 9646 9647 9648/* ------------------------------ */ 9649 .balign 64 9650.L_OP_UNUSED_66FF: /* 0x166 */ 9651/* File: armv5te/OP_UNUSED_66FF.S */ 9652/* File: armv5te/unused.S */ 9653 bl common_abort 9654 9655 9656/* ------------------------------ */ 9657 .balign 64 9658.L_OP_UNUSED_67FF: /* 0x167 */ 9659/* File: armv5te/OP_UNUSED_67FF.S */ 9660/* File: armv5te/unused.S */ 9661 bl common_abort 9662 9663 9664/* ------------------------------ */ 9665 .balign 64 9666.L_OP_UNUSED_68FF: /* 0x168 */ 9667/* File: armv5te/OP_UNUSED_68FF.S */ 9668/* File: armv5te/unused.S */ 9669 bl common_abort 9670 9671 9672/* ------------------------------ */ 9673 .balign 64 9674.L_OP_UNUSED_69FF: /* 0x169 */ 9675/* File: armv5te/OP_UNUSED_69FF.S */ 9676/* File: armv5te/unused.S */ 9677 bl common_abort 9678 9679 9680/* ------------------------------ */ 9681 .balign 64 9682.L_OP_UNUSED_6AFF: /* 0x16a */ 9683/* File: armv5te/OP_UNUSED_6AFF.S */ 9684/* File: armv5te/unused.S */ 9685 bl common_abort 9686 9687 9688/* ------------------------------ */ 9689 .balign 64 9690.L_OP_UNUSED_6BFF: /* 0x16b */ 9691/* File: armv5te/OP_UNUSED_6BFF.S */ 9692/* File: armv5te/unused.S */ 9693 bl common_abort 9694 9695 9696/* ------------------------------ */ 9697 .balign 64 9698.L_OP_UNUSED_6CFF: /* 0x16c */ 9699/* File: armv5te/OP_UNUSED_6CFF.S */ 9700/* File: armv5te/unused.S */ 9701 bl common_abort 9702 9703 9704/* ------------------------------ */ 9705 .balign 64 9706.L_OP_UNUSED_6DFF: /* 0x16d */ 9707/* File: armv5te/OP_UNUSED_6DFF.S */ 9708/* File: armv5te/unused.S */ 9709 bl common_abort 9710 9711 9712/* ------------------------------ */ 9713 .balign 64 9714.L_OP_UNUSED_6EFF: /* 0x16e */ 9715/* File: armv5te/OP_UNUSED_6EFF.S */ 9716/* File: armv5te/unused.S */ 9717 bl common_abort 9718 9719 9720/* ------------------------------ */ 9721 .balign 64 9722.L_OP_UNUSED_6FFF: /* 0x16f */ 9723/* File: armv5te/OP_UNUSED_6FFF.S */ 9724/* File: armv5te/unused.S */ 9725 bl common_abort 9726 9727 9728/* ------------------------------ */ 9729 .balign 64 9730.L_OP_UNUSED_70FF: /* 0x170 */ 9731/* File: armv5te/OP_UNUSED_70FF.S */ 9732/* File: armv5te/unused.S */ 9733 bl common_abort 9734 9735 9736/* ------------------------------ */ 9737 .balign 64 9738.L_OP_UNUSED_71FF: /* 0x171 */ 9739/* File: armv5te/OP_UNUSED_71FF.S */ 9740/* File: armv5te/unused.S */ 9741 bl common_abort 9742 9743 9744/* ------------------------------ */ 9745 .balign 64 9746.L_OP_UNUSED_72FF: /* 0x172 */ 9747/* File: armv5te/OP_UNUSED_72FF.S */ 9748/* File: armv5te/unused.S */ 9749 bl common_abort 9750 9751 9752/* ------------------------------ */ 9753 .balign 64 9754.L_OP_UNUSED_73FF: /* 0x173 */ 9755/* File: armv5te/OP_UNUSED_73FF.S */ 9756/* File: armv5te/unused.S */ 9757 bl common_abort 9758 9759 9760/* ------------------------------ */ 9761 .balign 64 9762.L_OP_UNUSED_74FF: /* 0x174 */ 9763/* File: armv5te/OP_UNUSED_74FF.S */ 9764/* File: armv5te/unused.S */ 9765 bl common_abort 9766 9767 9768/* ------------------------------ */ 9769 .balign 64 9770.L_OP_UNUSED_75FF: /* 0x175 */ 9771/* File: armv5te/OP_UNUSED_75FF.S */ 9772/* File: armv5te/unused.S */ 9773 bl common_abort 9774 9775 9776/* ------------------------------ */ 9777 .balign 64 9778.L_OP_UNUSED_76FF: /* 0x176 */ 9779/* File: armv5te/OP_UNUSED_76FF.S */ 9780/* File: armv5te/unused.S */ 9781 bl common_abort 9782 9783 9784/* ------------------------------ */ 9785 .balign 64 9786.L_OP_UNUSED_77FF: /* 0x177 */ 9787/* File: armv5te/OP_UNUSED_77FF.S */ 9788/* File: armv5te/unused.S */ 9789 bl common_abort 9790 9791 9792/* ------------------------------ */ 9793 .balign 64 9794.L_OP_UNUSED_78FF: /* 0x178 */ 9795/* File: armv5te/OP_UNUSED_78FF.S */ 9796/* File: armv5te/unused.S */ 9797 bl common_abort 9798 9799 9800/* ------------------------------ */ 9801 .balign 64 9802.L_OP_UNUSED_79FF: /* 0x179 */ 9803/* File: armv5te/OP_UNUSED_79FF.S */ 9804/* File: armv5te/unused.S */ 9805 bl common_abort 9806 9807 9808/* ------------------------------ */ 9809 .balign 64 9810.L_OP_UNUSED_7AFF: /* 0x17a */ 9811/* File: armv5te/OP_UNUSED_7AFF.S */ 9812/* File: armv5te/unused.S */ 9813 bl common_abort 9814 9815 9816/* ------------------------------ */ 9817 .balign 64 9818.L_OP_UNUSED_7BFF: /* 0x17b */ 9819/* File: armv5te/OP_UNUSED_7BFF.S */ 9820/* File: armv5te/unused.S */ 9821 bl common_abort 9822 9823 9824/* ------------------------------ */ 9825 .balign 64 9826.L_OP_UNUSED_7CFF: /* 0x17c */ 9827/* File: armv5te/OP_UNUSED_7CFF.S */ 9828/* File: armv5te/unused.S */ 9829 bl common_abort 9830 9831 9832/* ------------------------------ */ 9833 .balign 64 9834.L_OP_UNUSED_7DFF: /* 0x17d */ 9835/* File: armv5te/OP_UNUSED_7DFF.S */ 9836/* File: armv5te/unused.S */ 9837 bl common_abort 9838 9839 9840/* ------------------------------ */ 9841 .balign 64 9842.L_OP_UNUSED_7EFF: /* 0x17e */ 9843/* File: armv5te/OP_UNUSED_7EFF.S */ 9844/* File: armv5te/unused.S */ 9845 bl common_abort 9846 9847 9848/* ------------------------------ */ 9849 .balign 64 9850.L_OP_UNUSED_7FFF: /* 0x17f */ 9851/* File: armv5te/OP_UNUSED_7FFF.S */ 9852/* File: armv5te/unused.S */ 9853 bl common_abort 9854 9855 9856/* ------------------------------ */ 9857 .balign 64 9858.L_OP_UNUSED_80FF: /* 0x180 */ 9859/* File: armv5te/OP_UNUSED_80FF.S */ 9860/* File: armv5te/unused.S */ 9861 bl common_abort 9862 9863 9864/* ------------------------------ */ 9865 .balign 64 9866.L_OP_UNUSED_81FF: /* 0x181 */ 9867/* File: armv5te/OP_UNUSED_81FF.S */ 9868/* File: armv5te/unused.S */ 9869 bl common_abort 9870 9871 9872/* ------------------------------ */ 9873 .balign 64 9874.L_OP_UNUSED_82FF: /* 0x182 */ 9875/* File: armv5te/OP_UNUSED_82FF.S */ 9876/* File: armv5te/unused.S */ 9877 bl common_abort 9878 9879 9880/* ------------------------------ */ 9881 .balign 64 9882.L_OP_UNUSED_83FF: /* 0x183 */ 9883/* File: armv5te/OP_UNUSED_83FF.S */ 9884/* File: armv5te/unused.S */ 9885 bl common_abort 9886 9887 9888/* ------------------------------ */ 9889 .balign 64 9890.L_OP_UNUSED_84FF: /* 0x184 */ 9891/* File: armv5te/OP_UNUSED_84FF.S */ 9892/* File: armv5te/unused.S */ 9893 bl common_abort 9894 9895 9896/* ------------------------------ */ 9897 .balign 64 9898.L_OP_UNUSED_85FF: /* 0x185 */ 9899/* File: armv5te/OP_UNUSED_85FF.S */ 9900/* File: armv5te/unused.S */ 9901 bl common_abort 9902 9903 9904/* ------------------------------ */ 9905 .balign 64 9906.L_OP_UNUSED_86FF: /* 0x186 */ 9907/* File: armv5te/OP_UNUSED_86FF.S */ 9908/* File: armv5te/unused.S */ 9909 bl common_abort 9910 9911 9912/* ------------------------------ */ 9913 .balign 64 9914.L_OP_UNUSED_87FF: /* 0x187 */ 9915/* File: armv5te/OP_UNUSED_87FF.S */ 9916/* File: armv5te/unused.S */ 9917 bl common_abort 9918 9919 9920/* ------------------------------ */ 9921 .balign 64 9922.L_OP_UNUSED_88FF: /* 0x188 */ 9923/* File: armv5te/OP_UNUSED_88FF.S */ 9924/* File: armv5te/unused.S */ 9925 bl common_abort 9926 9927 9928/* ------------------------------ */ 9929 .balign 64 9930.L_OP_UNUSED_89FF: /* 0x189 */ 9931/* File: armv5te/OP_UNUSED_89FF.S */ 9932/* File: armv5te/unused.S */ 9933 bl common_abort 9934 9935 9936/* ------------------------------ */ 9937 .balign 64 9938.L_OP_UNUSED_8AFF: /* 0x18a */ 9939/* File: armv5te/OP_UNUSED_8AFF.S */ 9940/* File: armv5te/unused.S */ 9941 bl common_abort 9942 9943 9944/* ------------------------------ */ 9945 .balign 64 9946.L_OP_UNUSED_8BFF: /* 0x18b */ 9947/* File: armv5te/OP_UNUSED_8BFF.S */ 9948/* File: armv5te/unused.S */ 9949 bl common_abort 9950 9951 9952/* ------------------------------ */ 9953 .balign 64 9954.L_OP_UNUSED_8CFF: /* 0x18c */ 9955/* File: armv5te/OP_UNUSED_8CFF.S */ 9956/* File: armv5te/unused.S */ 9957 bl common_abort 9958 9959 9960/* ------------------------------ */ 9961 .balign 64 9962.L_OP_UNUSED_8DFF: /* 0x18d */ 9963/* File: armv5te/OP_UNUSED_8DFF.S */ 9964/* File: armv5te/unused.S */ 9965 bl common_abort 9966 9967 9968/* ------------------------------ */ 9969 .balign 64 9970.L_OP_UNUSED_8EFF: /* 0x18e */ 9971/* File: armv5te/OP_UNUSED_8EFF.S */ 9972/* File: armv5te/unused.S */ 9973 bl common_abort 9974 9975 9976/* ------------------------------ */ 9977 .balign 64 9978.L_OP_UNUSED_8FFF: /* 0x18f */ 9979/* File: armv5te/OP_UNUSED_8FFF.S */ 9980/* File: armv5te/unused.S */ 9981 bl common_abort 9982 9983 9984/* ------------------------------ */ 9985 .balign 64 9986.L_OP_UNUSED_90FF: /* 0x190 */ 9987/* File: armv5te/OP_UNUSED_90FF.S */ 9988/* File: armv5te/unused.S */ 9989 bl common_abort 9990 9991 9992/* ------------------------------ */ 9993 .balign 64 9994.L_OP_UNUSED_91FF: /* 0x191 */ 9995/* File: armv5te/OP_UNUSED_91FF.S */ 9996/* File: armv5te/unused.S */ 9997 bl common_abort 9998 9999 10000/* ------------------------------ */ 10001 .balign 64 10002.L_OP_UNUSED_92FF: /* 0x192 */ 10003/* File: armv5te/OP_UNUSED_92FF.S */ 10004/* File: armv5te/unused.S */ 10005 bl common_abort 10006 10007 10008/* ------------------------------ */ 10009 .balign 64 10010.L_OP_UNUSED_93FF: /* 0x193 */ 10011/* File: armv5te/OP_UNUSED_93FF.S */ 10012/* File: armv5te/unused.S */ 10013 bl common_abort 10014 10015 10016/* ------------------------------ */ 10017 .balign 64 10018.L_OP_UNUSED_94FF: /* 0x194 */ 10019/* File: armv5te/OP_UNUSED_94FF.S */ 10020/* File: armv5te/unused.S */ 10021 bl common_abort 10022 10023 10024/* ------------------------------ */ 10025 .balign 64 10026.L_OP_UNUSED_95FF: /* 0x195 */ 10027/* File: armv5te/OP_UNUSED_95FF.S */ 10028/* File: armv5te/unused.S */ 10029 bl common_abort 10030 10031 10032/* ------------------------------ */ 10033 .balign 64 10034.L_OP_UNUSED_96FF: /* 0x196 */ 10035/* File: armv5te/OP_UNUSED_96FF.S */ 10036/* File: armv5te/unused.S */ 10037 bl common_abort 10038 10039 10040/* ------------------------------ */ 10041 .balign 64 10042.L_OP_UNUSED_97FF: /* 0x197 */ 10043/* File: armv5te/OP_UNUSED_97FF.S */ 10044/* File: armv5te/unused.S */ 10045 bl common_abort 10046 10047 10048/* ------------------------------ */ 10049 .balign 64 10050.L_OP_UNUSED_98FF: /* 0x198 */ 10051/* File: armv5te/OP_UNUSED_98FF.S */ 10052/* File: armv5te/unused.S */ 10053 bl common_abort 10054 10055 10056/* ------------------------------ */ 10057 .balign 64 10058.L_OP_UNUSED_99FF: /* 0x199 */ 10059/* File: armv5te/OP_UNUSED_99FF.S */ 10060/* File: armv5te/unused.S */ 10061 bl common_abort 10062 10063 10064/* ------------------------------ */ 10065 .balign 64 10066.L_OP_UNUSED_9AFF: /* 0x19a */ 10067/* File: armv5te/OP_UNUSED_9AFF.S */ 10068/* File: armv5te/unused.S */ 10069 bl common_abort 10070 10071 10072/* ------------------------------ */ 10073 .balign 64 10074.L_OP_UNUSED_9BFF: /* 0x19b */ 10075/* File: armv5te/OP_UNUSED_9BFF.S */ 10076/* File: armv5te/unused.S */ 10077 bl common_abort 10078 10079 10080/* ------------------------------ */ 10081 .balign 64 10082.L_OP_UNUSED_9CFF: /* 0x19c */ 10083/* File: armv5te/OP_UNUSED_9CFF.S */ 10084/* File: armv5te/unused.S */ 10085 bl common_abort 10086 10087 10088/* ------------------------------ */ 10089 .balign 64 10090.L_OP_UNUSED_9DFF: /* 0x19d */ 10091/* File: armv5te/OP_UNUSED_9DFF.S */ 10092/* File: armv5te/unused.S */ 10093 bl common_abort 10094 10095 10096/* ------------------------------ */ 10097 .balign 64 10098.L_OP_UNUSED_9EFF: /* 0x19e */ 10099/* File: armv5te/OP_UNUSED_9EFF.S */ 10100/* File: armv5te/unused.S */ 10101 bl common_abort 10102 10103 10104/* ------------------------------ */ 10105 .balign 64 10106.L_OP_UNUSED_9FFF: /* 0x19f */ 10107/* File: armv5te/OP_UNUSED_9FFF.S */ 10108/* File: armv5te/unused.S */ 10109 bl common_abort 10110 10111 10112/* ------------------------------ */ 10113 .balign 64 10114.L_OP_UNUSED_A0FF: /* 0x1a0 */ 10115/* File: armv5te/OP_UNUSED_A0FF.S */ 10116/* File: armv5te/unused.S */ 10117 bl common_abort 10118 10119 10120/* ------------------------------ */ 10121 .balign 64 10122.L_OP_UNUSED_A1FF: /* 0x1a1 */ 10123/* File: armv5te/OP_UNUSED_A1FF.S */ 10124/* File: armv5te/unused.S */ 10125 bl common_abort 10126 10127 10128/* ------------------------------ */ 10129 .balign 64 10130.L_OP_UNUSED_A2FF: /* 0x1a2 */ 10131/* File: armv5te/OP_UNUSED_A2FF.S */ 10132/* File: armv5te/unused.S */ 10133 bl common_abort 10134 10135 10136/* ------------------------------ */ 10137 .balign 64 10138.L_OP_UNUSED_A3FF: /* 0x1a3 */ 10139/* File: armv5te/OP_UNUSED_A3FF.S */ 10140/* File: armv5te/unused.S */ 10141 bl common_abort 10142 10143 10144/* ------------------------------ */ 10145 .balign 64 10146.L_OP_UNUSED_A4FF: /* 0x1a4 */ 10147/* File: armv5te/OP_UNUSED_A4FF.S */ 10148/* File: armv5te/unused.S */ 10149 bl common_abort 10150 10151 10152/* ------------------------------ */ 10153 .balign 64 10154.L_OP_UNUSED_A5FF: /* 0x1a5 */ 10155/* File: armv5te/OP_UNUSED_A5FF.S */ 10156/* File: armv5te/unused.S */ 10157 bl common_abort 10158 10159 10160/* ------------------------------ */ 10161 .balign 64 10162.L_OP_UNUSED_A6FF: /* 0x1a6 */ 10163/* File: armv5te/OP_UNUSED_A6FF.S */ 10164/* File: armv5te/unused.S */ 10165 bl common_abort 10166 10167 10168/* ------------------------------ */ 10169 .balign 64 10170.L_OP_UNUSED_A7FF: /* 0x1a7 */ 10171/* File: armv5te/OP_UNUSED_A7FF.S */ 10172/* File: armv5te/unused.S */ 10173 bl common_abort 10174 10175 10176/* ------------------------------ */ 10177 .balign 64 10178.L_OP_UNUSED_A8FF: /* 0x1a8 */ 10179/* File: armv5te/OP_UNUSED_A8FF.S */ 10180/* File: armv5te/unused.S */ 10181 bl common_abort 10182 10183 10184/* ------------------------------ */ 10185 .balign 64 10186.L_OP_UNUSED_A9FF: /* 0x1a9 */ 10187/* File: armv5te/OP_UNUSED_A9FF.S */ 10188/* File: armv5te/unused.S */ 10189 bl common_abort 10190 10191 10192/* ------------------------------ */ 10193 .balign 64 10194.L_OP_UNUSED_AAFF: /* 0x1aa */ 10195/* File: armv5te/OP_UNUSED_AAFF.S */ 10196/* File: armv5te/unused.S */ 10197 bl common_abort 10198 10199 10200/* ------------------------------ */ 10201 .balign 64 10202.L_OP_UNUSED_ABFF: /* 0x1ab */ 10203/* File: armv5te/OP_UNUSED_ABFF.S */ 10204/* File: armv5te/unused.S */ 10205 bl common_abort 10206 10207 10208/* ------------------------------ */ 10209 .balign 64 10210.L_OP_UNUSED_ACFF: /* 0x1ac */ 10211/* File: armv5te/OP_UNUSED_ACFF.S */ 10212/* File: armv5te/unused.S */ 10213 bl common_abort 10214 10215 10216/* ------------------------------ */ 10217 .balign 64 10218.L_OP_UNUSED_ADFF: /* 0x1ad */ 10219/* File: armv5te/OP_UNUSED_ADFF.S */ 10220/* File: armv5te/unused.S */ 10221 bl common_abort 10222 10223 10224/* ------------------------------ */ 10225 .balign 64 10226.L_OP_UNUSED_AEFF: /* 0x1ae */ 10227/* File: armv5te/OP_UNUSED_AEFF.S */ 10228/* File: armv5te/unused.S */ 10229 bl common_abort 10230 10231 10232/* ------------------------------ */ 10233 .balign 64 10234.L_OP_UNUSED_AFFF: /* 0x1af */ 10235/* File: armv5te/OP_UNUSED_AFFF.S */ 10236/* File: armv5te/unused.S */ 10237 bl common_abort 10238 10239 10240/* ------------------------------ */ 10241 .balign 64 10242.L_OP_UNUSED_B0FF: /* 0x1b0 */ 10243/* File: armv5te/OP_UNUSED_B0FF.S */ 10244/* File: armv5te/unused.S */ 10245 bl common_abort 10246 10247 10248/* ------------------------------ */ 10249 .balign 64 10250.L_OP_UNUSED_B1FF: /* 0x1b1 */ 10251/* File: armv5te/OP_UNUSED_B1FF.S */ 10252/* File: armv5te/unused.S */ 10253 bl common_abort 10254 10255 10256/* ------------------------------ */ 10257 .balign 64 10258.L_OP_UNUSED_B2FF: /* 0x1b2 */ 10259/* File: armv5te/OP_UNUSED_B2FF.S */ 10260/* File: armv5te/unused.S */ 10261 bl common_abort 10262 10263 10264/* ------------------------------ */ 10265 .balign 64 10266.L_OP_UNUSED_B3FF: /* 0x1b3 */ 10267/* File: armv5te/OP_UNUSED_B3FF.S */ 10268/* File: armv5te/unused.S */ 10269 bl common_abort 10270 10271 10272/* ------------------------------ */ 10273 .balign 64 10274.L_OP_UNUSED_B4FF: /* 0x1b4 */ 10275/* File: armv5te/OP_UNUSED_B4FF.S */ 10276/* File: armv5te/unused.S */ 10277 bl common_abort 10278 10279 10280/* ------------------------------ */ 10281 .balign 64 10282.L_OP_UNUSED_B5FF: /* 0x1b5 */ 10283/* File: armv5te/OP_UNUSED_B5FF.S */ 10284/* File: armv5te/unused.S */ 10285 bl common_abort 10286 10287 10288/* ------------------------------ */ 10289 .balign 64 10290.L_OP_UNUSED_B6FF: /* 0x1b6 */ 10291/* File: armv5te/OP_UNUSED_B6FF.S */ 10292/* File: armv5te/unused.S */ 10293 bl common_abort 10294 10295 10296/* ------------------------------ */ 10297 .balign 64 10298.L_OP_UNUSED_B7FF: /* 0x1b7 */ 10299/* File: armv5te/OP_UNUSED_B7FF.S */ 10300/* File: armv5te/unused.S */ 10301 bl common_abort 10302 10303 10304/* ------------------------------ */ 10305 .balign 64 10306.L_OP_UNUSED_B8FF: /* 0x1b8 */ 10307/* File: armv5te/OP_UNUSED_B8FF.S */ 10308/* File: armv5te/unused.S */ 10309 bl common_abort 10310 10311 10312/* ------------------------------ */ 10313 .balign 64 10314.L_OP_UNUSED_B9FF: /* 0x1b9 */ 10315/* File: armv5te/OP_UNUSED_B9FF.S */ 10316/* File: armv5te/unused.S */ 10317 bl common_abort 10318 10319 10320/* ------------------------------ */ 10321 .balign 64 10322.L_OP_UNUSED_BAFF: /* 0x1ba */ 10323/* File: armv5te/OP_UNUSED_BAFF.S */ 10324/* File: armv5te/unused.S */ 10325 bl common_abort 10326 10327 10328/* ------------------------------ */ 10329 .balign 64 10330.L_OP_UNUSED_BBFF: /* 0x1bb */ 10331/* File: armv5te/OP_UNUSED_BBFF.S */ 10332/* File: armv5te/unused.S */ 10333 bl common_abort 10334 10335 10336/* ------------------------------ */ 10337 .balign 64 10338.L_OP_UNUSED_BCFF: /* 0x1bc */ 10339/* File: armv5te/OP_UNUSED_BCFF.S */ 10340/* File: armv5te/unused.S */ 10341 bl common_abort 10342 10343 10344/* ------------------------------ */ 10345 .balign 64 10346.L_OP_UNUSED_BDFF: /* 0x1bd */ 10347/* File: armv5te/OP_UNUSED_BDFF.S */ 10348/* File: armv5te/unused.S */ 10349 bl common_abort 10350 10351 10352/* ------------------------------ */ 10353 .balign 64 10354.L_OP_UNUSED_BEFF: /* 0x1be */ 10355/* File: armv5te/OP_UNUSED_BEFF.S */ 10356/* File: armv5te/unused.S */ 10357 bl common_abort 10358 10359 10360/* ------------------------------ */ 10361 .balign 64 10362.L_OP_UNUSED_BFFF: /* 0x1bf */ 10363/* File: armv5te/OP_UNUSED_BFFF.S */ 10364/* File: armv5te/unused.S */ 10365 bl common_abort 10366 10367 10368/* ------------------------------ */ 10369 .balign 64 10370.L_OP_UNUSED_C0FF: /* 0x1c0 */ 10371/* File: armv5te/OP_UNUSED_C0FF.S */ 10372/* File: armv5te/unused.S */ 10373 bl common_abort 10374 10375 10376/* ------------------------------ */ 10377 .balign 64 10378.L_OP_UNUSED_C1FF: /* 0x1c1 */ 10379/* File: armv5te/OP_UNUSED_C1FF.S */ 10380/* File: armv5te/unused.S */ 10381 bl common_abort 10382 10383 10384/* ------------------------------ */ 10385 .balign 64 10386.L_OP_UNUSED_C2FF: /* 0x1c2 */ 10387/* File: armv5te/OP_UNUSED_C2FF.S */ 10388/* File: armv5te/unused.S */ 10389 bl common_abort 10390 10391 10392/* ------------------------------ */ 10393 .balign 64 10394.L_OP_UNUSED_C3FF: /* 0x1c3 */ 10395/* File: armv5te/OP_UNUSED_C3FF.S */ 10396/* File: armv5te/unused.S */ 10397 bl common_abort 10398 10399 10400/* ------------------------------ */ 10401 .balign 64 10402.L_OP_UNUSED_C4FF: /* 0x1c4 */ 10403/* File: armv5te/OP_UNUSED_C4FF.S */ 10404/* File: armv5te/unused.S */ 10405 bl common_abort 10406 10407 10408/* ------------------------------ */ 10409 .balign 64 10410.L_OP_UNUSED_C5FF: /* 0x1c5 */ 10411/* File: armv5te/OP_UNUSED_C5FF.S */ 10412/* File: armv5te/unused.S */ 10413 bl common_abort 10414 10415 10416/* ------------------------------ */ 10417 .balign 64 10418.L_OP_UNUSED_C6FF: /* 0x1c6 */ 10419/* File: armv5te/OP_UNUSED_C6FF.S */ 10420/* File: armv5te/unused.S */ 10421 bl common_abort 10422 10423 10424/* ------------------------------ */ 10425 .balign 64 10426.L_OP_UNUSED_C7FF: /* 0x1c7 */ 10427/* File: armv5te/OP_UNUSED_C7FF.S */ 10428/* File: armv5te/unused.S */ 10429 bl common_abort 10430 10431 10432/* ------------------------------ */ 10433 .balign 64 10434.L_OP_UNUSED_C8FF: /* 0x1c8 */ 10435/* File: armv5te/OP_UNUSED_C8FF.S */ 10436/* File: armv5te/unused.S */ 10437 bl common_abort 10438 10439 10440/* ------------------------------ */ 10441 .balign 64 10442.L_OP_UNUSED_C9FF: /* 0x1c9 */ 10443/* File: armv5te/OP_UNUSED_C9FF.S */ 10444/* File: armv5te/unused.S */ 10445 bl common_abort 10446 10447 10448/* ------------------------------ */ 10449 .balign 64 10450.L_OP_UNUSED_CAFF: /* 0x1ca */ 10451/* File: armv5te/OP_UNUSED_CAFF.S */ 10452/* File: armv5te/unused.S */ 10453 bl common_abort 10454 10455 10456/* ------------------------------ */ 10457 .balign 64 10458.L_OP_UNUSED_CBFF: /* 0x1cb */ 10459/* File: armv5te/OP_UNUSED_CBFF.S */ 10460/* File: armv5te/unused.S */ 10461 bl common_abort 10462 10463 10464/* ------------------------------ */ 10465 .balign 64 10466.L_OP_UNUSED_CCFF: /* 0x1cc */ 10467/* File: armv5te/OP_UNUSED_CCFF.S */ 10468/* File: armv5te/unused.S */ 10469 bl common_abort 10470 10471 10472/* ------------------------------ */ 10473 .balign 64 10474.L_OP_UNUSED_CDFF: /* 0x1cd */ 10475/* File: armv5te/OP_UNUSED_CDFF.S */ 10476/* File: armv5te/unused.S */ 10477 bl common_abort 10478 10479 10480/* ------------------------------ */ 10481 .balign 64 10482.L_OP_UNUSED_CEFF: /* 0x1ce */ 10483/* File: armv5te/OP_UNUSED_CEFF.S */ 10484/* File: armv5te/unused.S */ 10485 bl common_abort 10486 10487 10488/* ------------------------------ */ 10489 .balign 64 10490.L_OP_UNUSED_CFFF: /* 0x1cf */ 10491/* File: armv5te/OP_UNUSED_CFFF.S */ 10492/* File: armv5te/unused.S */ 10493 bl common_abort 10494 10495 10496/* ------------------------------ */ 10497 .balign 64 10498.L_OP_UNUSED_D0FF: /* 0x1d0 */ 10499/* File: armv5te/OP_UNUSED_D0FF.S */ 10500/* File: armv5te/unused.S */ 10501 bl common_abort 10502 10503 10504/* ------------------------------ */ 10505 .balign 64 10506.L_OP_UNUSED_D1FF: /* 0x1d1 */ 10507/* File: armv5te/OP_UNUSED_D1FF.S */ 10508/* File: armv5te/unused.S */ 10509 bl common_abort 10510 10511 10512/* ------------------------------ */ 10513 .balign 64 10514.L_OP_UNUSED_D2FF: /* 0x1d2 */ 10515/* File: armv5te/OP_UNUSED_D2FF.S */ 10516/* File: armv5te/unused.S */ 10517 bl common_abort 10518 10519 10520/* ------------------------------ */ 10521 .balign 64 10522.L_OP_UNUSED_D3FF: /* 0x1d3 */ 10523/* File: armv5te/OP_UNUSED_D3FF.S */ 10524/* File: armv5te/unused.S */ 10525 bl common_abort 10526 10527 10528/* ------------------------------ */ 10529 .balign 64 10530.L_OP_UNUSED_D4FF: /* 0x1d4 */ 10531/* File: armv5te/OP_UNUSED_D4FF.S */ 10532/* File: armv5te/unused.S */ 10533 bl common_abort 10534 10535 10536/* ------------------------------ */ 10537 .balign 64 10538.L_OP_UNUSED_D5FF: /* 0x1d5 */ 10539/* File: armv5te/OP_UNUSED_D5FF.S */ 10540/* File: armv5te/unused.S */ 10541 bl common_abort 10542 10543 10544/* ------------------------------ */ 10545 .balign 64 10546.L_OP_UNUSED_D6FF: /* 0x1d6 */ 10547/* File: armv5te/OP_UNUSED_D6FF.S */ 10548/* File: armv5te/unused.S */ 10549 bl common_abort 10550 10551 10552/* ------------------------------ */ 10553 .balign 64 10554.L_OP_UNUSED_D7FF: /* 0x1d7 */ 10555/* File: armv5te/OP_UNUSED_D7FF.S */ 10556/* File: armv5te/unused.S */ 10557 bl common_abort 10558 10559 10560/* ------------------------------ */ 10561 .balign 64 10562.L_OP_UNUSED_D8FF: /* 0x1d8 */ 10563/* File: armv5te/OP_UNUSED_D8FF.S */ 10564/* File: armv5te/unused.S */ 10565 bl common_abort 10566 10567 10568/* ------------------------------ */ 10569 .balign 64 10570.L_OP_UNUSED_D9FF: /* 0x1d9 */ 10571/* File: armv5te/OP_UNUSED_D9FF.S */ 10572/* File: armv5te/unused.S */ 10573 bl common_abort 10574 10575 10576/* ------------------------------ */ 10577 .balign 64 10578.L_OP_UNUSED_DAFF: /* 0x1da */ 10579/* File: armv5te/OP_UNUSED_DAFF.S */ 10580/* File: armv5te/unused.S */ 10581 bl common_abort 10582 10583 10584/* ------------------------------ */ 10585 .balign 64 10586.L_OP_UNUSED_DBFF: /* 0x1db */ 10587/* File: armv5te/OP_UNUSED_DBFF.S */ 10588/* File: armv5te/unused.S */ 10589 bl common_abort 10590 10591 10592/* ------------------------------ */ 10593 .balign 64 10594.L_OP_UNUSED_DCFF: /* 0x1dc */ 10595/* File: armv5te/OP_UNUSED_DCFF.S */ 10596/* File: armv5te/unused.S */ 10597 bl common_abort 10598 10599 10600/* ------------------------------ */ 10601 .balign 64 10602.L_OP_UNUSED_DDFF: /* 0x1dd */ 10603/* File: armv5te/OP_UNUSED_DDFF.S */ 10604/* File: armv5te/unused.S */ 10605 bl common_abort 10606 10607 10608/* ------------------------------ */ 10609 .balign 64 10610.L_OP_UNUSED_DEFF: /* 0x1de */ 10611/* File: armv5te/OP_UNUSED_DEFF.S */ 10612/* File: armv5te/unused.S */ 10613 bl common_abort 10614 10615 10616/* ------------------------------ */ 10617 .balign 64 10618.L_OP_UNUSED_DFFF: /* 0x1df */ 10619/* File: armv5te/OP_UNUSED_DFFF.S */ 10620/* File: armv5te/unused.S */ 10621 bl common_abort 10622 10623 10624/* ------------------------------ */ 10625 .balign 64 10626.L_OP_UNUSED_E0FF: /* 0x1e0 */ 10627/* File: armv5te/OP_UNUSED_E0FF.S */ 10628/* File: armv5te/unused.S */ 10629 bl common_abort 10630 10631 10632/* ------------------------------ */ 10633 .balign 64 10634.L_OP_UNUSED_E1FF: /* 0x1e1 */ 10635/* File: armv5te/OP_UNUSED_E1FF.S */ 10636/* File: armv5te/unused.S */ 10637 bl common_abort 10638 10639 10640/* ------------------------------ */ 10641 .balign 64 10642.L_OP_UNUSED_E2FF: /* 0x1e2 */ 10643/* File: armv5te/OP_UNUSED_E2FF.S */ 10644/* File: armv5te/unused.S */ 10645 bl common_abort 10646 10647 10648/* ------------------------------ */ 10649 .balign 64 10650.L_OP_UNUSED_E3FF: /* 0x1e3 */ 10651/* File: armv5te/OP_UNUSED_E3FF.S */ 10652/* File: armv5te/unused.S */ 10653 bl common_abort 10654 10655 10656/* ------------------------------ */ 10657 .balign 64 10658.L_OP_UNUSED_E4FF: /* 0x1e4 */ 10659/* File: armv5te/OP_UNUSED_E4FF.S */ 10660/* File: armv5te/unused.S */ 10661 bl common_abort 10662 10663 10664/* ------------------------------ */ 10665 .balign 64 10666.L_OP_UNUSED_E5FF: /* 0x1e5 */ 10667/* File: armv5te/OP_UNUSED_E5FF.S */ 10668/* File: armv5te/unused.S */ 10669 bl common_abort 10670 10671 10672/* ------------------------------ */ 10673 .balign 64 10674.L_OP_UNUSED_E6FF: /* 0x1e6 */ 10675/* File: armv5te/OP_UNUSED_E6FF.S */ 10676/* File: armv5te/unused.S */ 10677 bl common_abort 10678 10679 10680/* ------------------------------ */ 10681 .balign 64 10682.L_OP_UNUSED_E7FF: /* 0x1e7 */ 10683/* File: armv5te/OP_UNUSED_E7FF.S */ 10684/* File: armv5te/unused.S */ 10685 bl common_abort 10686 10687 10688/* ------------------------------ */ 10689 .balign 64 10690.L_OP_UNUSED_E8FF: /* 0x1e8 */ 10691/* File: armv5te/OP_UNUSED_E8FF.S */ 10692/* File: armv5te/unused.S */ 10693 bl common_abort 10694 10695 10696/* ------------------------------ */ 10697 .balign 64 10698.L_OP_UNUSED_E9FF: /* 0x1e9 */ 10699/* File: armv5te/OP_UNUSED_E9FF.S */ 10700/* File: armv5te/unused.S */ 10701 bl common_abort 10702 10703 10704/* ------------------------------ */ 10705 .balign 64 10706.L_OP_UNUSED_EAFF: /* 0x1ea */ 10707/* File: armv5te/OP_UNUSED_EAFF.S */ 10708/* File: armv5te/unused.S */ 10709 bl common_abort 10710 10711 10712/* ------------------------------ */ 10713 .balign 64 10714.L_OP_UNUSED_EBFF: /* 0x1eb */ 10715/* File: armv5te/OP_UNUSED_EBFF.S */ 10716/* File: armv5te/unused.S */ 10717 bl common_abort 10718 10719 10720/* ------------------------------ */ 10721 .balign 64 10722.L_OP_UNUSED_ECFF: /* 0x1ec */ 10723/* File: armv5te/OP_UNUSED_ECFF.S */ 10724/* File: armv5te/unused.S */ 10725 bl common_abort 10726 10727 10728/* ------------------------------ */ 10729 .balign 64 10730.L_OP_UNUSED_EDFF: /* 0x1ed */ 10731/* File: armv5te/OP_UNUSED_EDFF.S */ 10732/* File: armv5te/unused.S */ 10733 bl common_abort 10734 10735 10736/* ------------------------------ */ 10737 .balign 64 10738.L_OP_UNUSED_EEFF: /* 0x1ee */ 10739/* File: armv5te/OP_UNUSED_EEFF.S */ 10740/* File: armv5te/unused.S */ 10741 bl common_abort 10742 10743 10744/* ------------------------------ */ 10745 .balign 64 10746.L_OP_UNUSED_EFFF: /* 0x1ef */ 10747/* File: armv5te/OP_UNUSED_EFFF.S */ 10748/* File: armv5te/unused.S */ 10749 bl common_abort 10750 10751 10752/* ------------------------------ */ 10753 .balign 64 10754.L_OP_UNUSED_F0FF: /* 0x1f0 */ 10755/* File: armv5te/OP_UNUSED_F0FF.S */ 10756/* File: armv5te/unused.S */ 10757 bl common_abort 10758 10759 10760/* ------------------------------ */ 10761 .balign 64 10762.L_OP_UNUSED_F1FF: /* 0x1f1 */ 10763/* File: armv5te/OP_UNUSED_F1FF.S */ 10764/* File: armv5te/unused.S */ 10765 bl common_abort 10766 10767 10768/* ------------------------------ */ 10769 .balign 64 10770.L_OP_UNUSED_F2FF: /* 0x1f2 */ 10771/* File: armv5te/OP_UNUSED_F2FF.S */ 10772/* File: armv5te/unused.S */ 10773 bl common_abort 10774 10775 10776/* ------------------------------ */ 10777 .balign 64 10778.L_OP_UNUSED_F3FF: /* 0x1f3 */ 10779/* File: armv5te/OP_UNUSED_F3FF.S */ 10780/* File: armv5te/unused.S */ 10781 bl common_abort 10782 10783 10784/* ------------------------------ */ 10785 .balign 64 10786.L_OP_UNUSED_F4FF: /* 0x1f4 */ 10787/* File: armv5te/OP_UNUSED_F4FF.S */ 10788/* File: armv5te/unused.S */ 10789 bl common_abort 10790 10791 10792/* ------------------------------ */ 10793 .balign 64 10794.L_OP_UNUSED_F5FF: /* 0x1f5 */ 10795/* File: armv5te/OP_UNUSED_F5FF.S */ 10796/* File: armv5te/unused.S */ 10797 bl common_abort 10798 10799 10800/* ------------------------------ */ 10801 .balign 64 10802.L_OP_UNUSED_F6FF: /* 0x1f6 */ 10803/* File: armv5te/OP_UNUSED_F6FF.S */ 10804/* File: armv5te/unused.S */ 10805 bl common_abort 10806 10807 10808/* ------------------------------ */ 10809 .balign 64 10810.L_OP_UNUSED_F7FF: /* 0x1f7 */ 10811/* File: armv5te/OP_UNUSED_F7FF.S */ 10812/* File: armv5te/unused.S */ 10813 bl common_abort 10814 10815 10816/* ------------------------------ */ 10817 .balign 64 10818.L_OP_UNUSED_F8FF: /* 0x1f8 */ 10819/* File: armv5te/OP_UNUSED_F8FF.S */ 10820/* File: armv5te/unused.S */ 10821 bl common_abort 10822 10823 10824/* ------------------------------ */ 10825 .balign 64 10826.L_OP_UNUSED_F9FF: /* 0x1f9 */ 10827/* File: armv5te/OP_UNUSED_F9FF.S */ 10828/* File: armv5te/unused.S */ 10829 bl common_abort 10830 10831 10832/* ------------------------------ */ 10833 .balign 64 10834.L_OP_UNUSED_FAFF: /* 0x1fa */ 10835/* File: armv5te/OP_UNUSED_FAFF.S */ 10836/* File: armv5te/unused.S */ 10837 bl common_abort 10838 10839 10840/* ------------------------------ */ 10841 .balign 64 10842.L_OP_UNUSED_FBFF: /* 0x1fb */ 10843/* File: armv5te/OP_UNUSED_FBFF.S */ 10844/* File: armv5te/unused.S */ 10845 bl common_abort 10846 10847 10848/* ------------------------------ */ 10849 .balign 64 10850.L_OP_UNUSED_FCFF: /* 0x1fc */ 10851/* File: armv5te/OP_UNUSED_FCFF.S */ 10852/* File: armv5te/unused.S */ 10853 bl common_abort 10854 10855 10856/* ------------------------------ */ 10857 .balign 64 10858.L_OP_UNUSED_FDFF: /* 0x1fd */ 10859/* File: armv5te/OP_UNUSED_FDFF.S */ 10860/* File: armv5te/unused.S */ 10861 bl common_abort 10862 10863 10864/* ------------------------------ */ 10865 .balign 64 10866.L_OP_UNUSED_FEFF: /* 0x1fe */ 10867/* File: armv5te/OP_UNUSED_FEFF.S */ 10868/* File: armv5te/unused.S */ 10869 bl common_abort 10870 10871 10872/* ------------------------------ */ 10873 .balign 64 10874.L_OP_THROW_VERIFICATION_ERROR_JUMBO: /* 0x1ff */ 10875/* File: armv5te/OP_THROW_VERIFICATION_ERROR_JUMBO.S */ 10876 /* 10877 * Handle a jumbo throw-verification-error instruction. This throws an 10878 * exception for an error discovered during verification. The 10879 * exception is indicated by BBBB, with some detail provided by AAAAAAAA. 10880 */ 10881 /* exop BBBB, Class@AAAAAAAA */ 10882 FETCH(r1, 1) @ r1<- aaaa (lo) 10883 FETCH(r2, 2) @ r2<- AAAA (hi) 10884 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 10885 orr r2, r1, r2, lsl #16 @ r2<- AAAAaaaa 10886 EXPORT_PC() @ export the PC 10887 FETCH(r1, 3) @ r1<- BBBB 10888 bl dvmThrowVerificationError @ always throws 10889 b common_exceptionThrown @ handle exception 10890 10891 10892 .balign 64 10893 .size dvmAsmInstructionStart, .-dvmAsmInstructionStart 10894 .global dvmAsmInstructionEnd 10895dvmAsmInstructionEnd: 10896 10897/* 10898 * =========================================================================== 10899 * Sister implementations 10900 * =========================================================================== 10901 */ 10902 .global dvmAsmSisterStart 10903 .type dvmAsmSisterStart, %function 10904 .text 10905 .balign 4 10906dvmAsmSisterStart: 10907 10908/* continuation for OP_CONST_STRING */ 10909 10910 /* 10911 * Continuation if the String has not yet been resolved. 10912 * r1: BBBB (String ref) 10913 * r9: target register 10914 */ 10915.LOP_CONST_STRING_resolve: 10916 EXPORT_PC() 10917 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 10918 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 10919 bl dvmResolveString @ r0<- String reference 10920 cmp r0, #0 @ failed? 10921 beq common_exceptionThrown @ yup, handle the exception 10922 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10923 GET_INST_OPCODE(ip) @ extract opcode from rINST 10924 SET_VREG(r0, r9) @ vAA<- r0 10925 GOTO_OPCODE(ip) @ jump to next instruction 10926 10927/* continuation for OP_CONST_STRING_JUMBO */ 10928 10929 /* 10930 * Continuation if the String has not yet been resolved. 10931 * r1: BBBBBBBB (String ref) 10932 * r9: target register 10933 */ 10934.LOP_CONST_STRING_JUMBO_resolve: 10935 EXPORT_PC() 10936 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 10937 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 10938 bl dvmResolveString @ r0<- String reference 10939 cmp r0, #0 @ failed? 10940 beq common_exceptionThrown @ yup, handle the exception 10941 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 10942 GET_INST_OPCODE(ip) @ extract opcode from rINST 10943 SET_VREG(r0, r9) @ vAA<- r0 10944 GOTO_OPCODE(ip) @ jump to next instruction 10945 10946/* continuation for OP_CONST_CLASS */ 10947 10948 /* 10949 * Continuation if the Class has not yet been resolved. 10950 * r1: BBBB (Class ref) 10951 * r9: target register 10952 */ 10953.LOP_CONST_CLASS_resolve: 10954 EXPORT_PC() 10955 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 10956 mov r2, #1 @ r2<- true 10957 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 10958 bl dvmResolveClass @ r0<- Class reference 10959 cmp r0, #0 @ failed? 10960 beq common_exceptionThrown @ yup, handle the exception 10961 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10962 GET_INST_OPCODE(ip) @ extract opcode from rINST 10963 SET_VREG(r0, r9) @ vAA<- r0 10964 GOTO_OPCODE(ip) @ jump to next instruction 10965 10966/* continuation for OP_CHECK_CAST */ 10967 10968 /* 10969 * Trivial test failed, need to perform full check. This is common. 10970 * r0 holds obj->clazz 10971 * r1 holds desired class resolved from BBBB 10972 * r9 holds object 10973 */ 10974.LOP_CHECK_CAST_fullcheck: 10975 mov r10, r1 @ avoid ClassObject getting clobbered 10976 bl dvmInstanceofNonTrivial @ r0<- boolean result 10977 cmp r0, #0 @ failed? 10978 bne .LOP_CHECK_CAST_okay @ no, success 10979 10980 @ A cast has failed. We need to throw a ClassCastException. 10981 EXPORT_PC() @ about to throw 10982 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class) 10983 mov r1, r10 @ r1<- desired class 10984 bl dvmThrowClassCastException 10985 b common_exceptionThrown 10986 10987 /* 10988 * Resolution required. This is the least-likely path. 10989 * 10990 * r2 holds BBBB 10991 * r9 holds object 10992 */ 10993.LOP_CHECK_CAST_resolve: 10994 EXPORT_PC() @ resolve() could throw 10995 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 10996 mov r1, r2 @ r1<- BBBB 10997 mov r2, #0 @ r2<- false 10998 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 10999 bl dvmResolveClass @ r0<- resolved ClassObject ptr 11000 cmp r0, #0 @ got null? 11001 beq common_exceptionThrown @ yes, handle exception 11002 mov r1, r0 @ r1<- class resolved from BBB 11003 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 11004 b .LOP_CHECK_CAST_resolved @ pick up where we left off 11005 11006/* continuation for OP_INSTANCE_OF */ 11007 11008 /* 11009 * Trivial test failed, need to perform full check. This is common. 11010 * r0 holds obj->clazz 11011 * r1 holds class resolved from BBBB 11012 * r9 holds A 11013 */ 11014.LOP_INSTANCE_OF_fullcheck: 11015 bl dvmInstanceofNonTrivial @ r0<- boolean result 11016 @ fall through to OP_INSTANCE_OF_store 11017 11018 /* 11019 * r0 holds boolean result 11020 * r9 holds A 11021 */ 11022.LOP_INSTANCE_OF_store: 11023 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11024 SET_VREG(r0, r9) @ vA<- r0 11025 GET_INST_OPCODE(ip) @ extract opcode from rINST 11026 GOTO_OPCODE(ip) @ jump to next instruction 11027 11028 /* 11029 * Trivial test succeeded, save and bail. 11030 * r9 holds A 11031 */ 11032.LOP_INSTANCE_OF_trivial: 11033 mov r0, #1 @ indicate success 11034 @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper 11035 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11036 SET_VREG(r0, r9) @ vA<- r0 11037 GET_INST_OPCODE(ip) @ extract opcode from rINST 11038 GOTO_OPCODE(ip) @ jump to next instruction 11039 11040 /* 11041 * Resolution required. This is the least-likely path. 11042 * 11043 * r3 holds BBBB 11044 * r9 holds A 11045 */ 11046.LOP_INSTANCE_OF_resolve: 11047 EXPORT_PC() @ resolve() could throw 11048 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 11049 mov r1, r3 @ r1<- BBBB 11050 mov r2, #1 @ r2<- true 11051 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 11052 bl dvmResolveClass @ r0<- resolved ClassObject ptr 11053 cmp r0, #0 @ got null? 11054 beq common_exceptionThrown @ yes, handle exception 11055 mov r1, r0 @ r1<- class resolved from BBB 11056 mov r3, rINST, lsr #12 @ r3<- B 11057 GET_VREG(r0, r3) @ r0<- vB (object) 11058 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 11059 b .LOP_INSTANCE_OF_resolved @ pick up where we left off 11060 11061/* continuation for OP_NEW_INSTANCE */ 11062 11063 .balign 32 @ minimize cache lines 11064.LOP_NEW_INSTANCE_finish: @ r0=new object 11065 mov r3, rINST, lsr #8 @ r3<- AA 11066 cmp r0, #0 @ failed? 11067 beq common_exceptionThrown @ yes, handle the exception 11068 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11069 GET_INST_OPCODE(ip) @ extract opcode from rINST 11070 SET_VREG(r0, r3) @ vAA<- r0 11071 GOTO_OPCODE(ip) @ jump to next instruction 11072 11073 /* 11074 * Class initialization required. 11075 * 11076 * r0 holds class object 11077 */ 11078.LOP_NEW_INSTANCE_needinit: 11079 mov r9, r0 @ save r0 11080 bl dvmInitClass @ initialize class 11081 cmp r0, #0 @ check boolean result 11082 mov r0, r9 @ restore r0 11083 bne .LOP_NEW_INSTANCE_initialized @ success, continue 11084 b common_exceptionThrown @ failed, deal with init exception 11085 11086 /* 11087 * Resolution required. This is the least-likely path. 11088 * 11089 * r1 holds BBBB 11090 */ 11091.LOP_NEW_INSTANCE_resolve: 11092 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 11093 mov r2, #0 @ r2<- false 11094 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 11095 bl dvmResolveClass @ r0<- resolved ClassObject ptr 11096 cmp r0, #0 @ got null? 11097 bne .LOP_NEW_INSTANCE_resolved @ no, continue 11098 b common_exceptionThrown @ yes, handle exception 11099 11100.LstrInstantiationErrorPtr: 11101 .word .LstrInstantiationError 11102 11103/* continuation for OP_NEW_ARRAY */ 11104 11105 11106 /* 11107 * Resolve class. (This is an uncommon case.) 11108 * 11109 * r1 holds array length 11110 * r2 holds class ref CCCC 11111 */ 11112.LOP_NEW_ARRAY_resolve: 11113 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 11114 mov r9, r1 @ r9<- length (save) 11115 mov r1, r2 @ r1<- CCCC 11116 mov r2, #0 @ r2<- false 11117 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 11118 bl dvmResolveClass @ r0<- call(clazz, ref) 11119 cmp r0, #0 @ got null? 11120 mov r1, r9 @ r1<- length (restore) 11121 beq common_exceptionThrown @ yes, handle exception 11122 @ fall through to OP_NEW_ARRAY_finish 11123 11124 /* 11125 * Finish allocation. 11126 * 11127 * r0 holds class 11128 * r1 holds array length 11129 */ 11130.LOP_NEW_ARRAY_finish: 11131 mov r2, #ALLOC_DONT_TRACK @ don't track in local refs table 11132 bl dvmAllocArrayByClass @ r0<- call(clazz, length, flags) 11133 cmp r0, #0 @ failed? 11134 mov r2, rINST, lsr #8 @ r2<- A+ 11135 beq common_exceptionThrown @ yes, handle the exception 11136 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11137 and r2, r2, #15 @ r2<- A 11138 GET_INST_OPCODE(ip) @ extract opcode from rINST 11139 SET_VREG(r0, r2) @ vA<- r0 11140 GOTO_OPCODE(ip) @ jump to next instruction 11141 11142/* continuation for OP_FILLED_NEW_ARRAY */ 11143 11144 /* 11145 * On entry: 11146 * r0 holds array class 11147 * r10 holds AA or BA 11148 */ 11149.LOP_FILLED_NEW_ARRAY_continue: 11150 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 11151 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 11152 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 11153 .if 0 11154 mov r1, r10 @ r1<- AA (length) 11155 .else 11156 mov r1, r10, lsr #4 @ r1<- B (length) 11157 .endif 11158 cmp rINST, #'I' @ array of ints? 11159 cmpne rINST, #'L' @ array of objects? 11160 cmpne rINST, #'[' @ array of arrays? 11161 mov r9, r1 @ save length in r9 11162 bne .LOP_FILLED_NEW_ARRAY_notimpl @ no, not handled yet 11163 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 11164 cmp r0, #0 @ null return? 11165 beq common_exceptionThrown @ alloc failed, handle exception 11166 11167 FETCH(r1, 2) @ r1<- FEDC or CCCC 11168 str r0, [rGLUE, #offGlue_retval] @ retval.l <- new array 11169 str rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type 11170 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 11171 subs r9, r9, #1 @ length--, check for neg 11172 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 11173 bmi 2f @ was zero, bail 11174 11175 @ copy values from registers into the array 11176 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 11177 .if 0 11178 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 111791: ldr r3, [r2], #4 @ r3<- *r2++ 11180 subs r9, r9, #1 @ count-- 11181 str r3, [r0], #4 @ *contents++ = vX 11182 bpl 1b 11183 @ continue at 2 11184 .else 11185 cmp r9, #4 @ length was initially 5? 11186 and r2, r10, #15 @ r2<- A 11187 bne 1f @ <= 4 args, branch 11188 GET_VREG(r3, r2) @ r3<- vA 11189 sub r9, r9, #1 @ count-- 11190 str r3, [r0, #16] @ contents[4] = vA 111911: and r2, r1, #15 @ r2<- F/E/D/C 11192 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 11193 mov r1, r1, lsr #4 @ r1<- next reg in low 4 11194 subs r9, r9, #1 @ count-- 11195 str r3, [r0], #4 @ *contents++ = vX 11196 bpl 1b 11197 @ continue at 2 11198 .endif 11199 112002: 11201 ldr r0, [rGLUE, #offGlue_retval] @ r0<- object 11202 ldr r1, [rGLUE, #offGlue_retval+4] @ r1<- type 11203 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 11204 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 11205 cmp r1, #'I' @ Is int array? 11206 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 11207 GOTO_OPCODE(ip) @ execute it 11208 11209 /* 11210 * Throw an exception indicating that we have not implemented this 11211 * mode of filled-new-array. 11212 */ 11213.LOP_FILLED_NEW_ARRAY_notimpl: 11214 ldr r0, .L_strInternalError 11215 ldr r1, .L_strFilledNewArrayNotImpl 11216 bl dvmThrowException 11217 b common_exceptionThrown 11218 11219 .if (!0) @ define in one or the other, not both 11220.L_strFilledNewArrayNotImpl: 11221 .word .LstrFilledNewArrayNotImpl 11222.L_strInternalError: 11223 .word .LstrInternalError 11224 .endif 11225 11226/* continuation for OP_FILLED_NEW_ARRAY_RANGE */ 11227 11228 /* 11229 * On entry: 11230 * r0 holds array class 11231 * r10 holds AA or BA 11232 */ 11233.LOP_FILLED_NEW_ARRAY_RANGE_continue: 11234 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 11235 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 11236 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 11237 .if 1 11238 mov r1, r10 @ r1<- AA (length) 11239 .else 11240 mov r1, r10, lsr #4 @ r1<- B (length) 11241 .endif 11242 cmp rINST, #'I' @ array of ints? 11243 cmpne rINST, #'L' @ array of objects? 11244 cmpne rINST, #'[' @ array of arrays? 11245 mov r9, r1 @ save length in r9 11246 bne .LOP_FILLED_NEW_ARRAY_RANGE_notimpl @ no, not handled yet 11247 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 11248 cmp r0, #0 @ null return? 11249 beq common_exceptionThrown @ alloc failed, handle exception 11250 11251 FETCH(r1, 2) @ r1<- FEDC or CCCC 11252 str r0, [rGLUE, #offGlue_retval] @ retval.l <- new array 11253 str rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type 11254 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 11255 subs r9, r9, #1 @ length--, check for neg 11256 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 11257 bmi 2f @ was zero, bail 11258 11259 @ copy values from registers into the array 11260 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 11261 .if 1 11262 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 112631: ldr r3, [r2], #4 @ r3<- *r2++ 11264 subs r9, r9, #1 @ count-- 11265 str r3, [r0], #4 @ *contents++ = vX 11266 bpl 1b 11267 @ continue at 2 11268 .else 11269 cmp r9, #4 @ length was initially 5? 11270 and r2, r10, #15 @ r2<- A 11271 bne 1f @ <= 4 args, branch 11272 GET_VREG(r3, r2) @ r3<- vA 11273 sub r9, r9, #1 @ count-- 11274 str r3, [r0, #16] @ contents[4] = vA 112751: and r2, r1, #15 @ r2<- F/E/D/C 11276 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 11277 mov r1, r1, lsr #4 @ r1<- next reg in low 4 11278 subs r9, r9, #1 @ count-- 11279 str r3, [r0], #4 @ *contents++ = vX 11280 bpl 1b 11281 @ continue at 2 11282 .endif 11283 112842: 11285 ldr r0, [rGLUE, #offGlue_retval] @ r0<- object 11286 ldr r1, [rGLUE, #offGlue_retval+4] @ r1<- type 11287 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 11288 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 11289 cmp r1, #'I' @ Is int array? 11290 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 11291 GOTO_OPCODE(ip) @ execute it 11292 11293 /* 11294 * Throw an exception indicating that we have not implemented this 11295 * mode of filled-new-array. 11296 */ 11297.LOP_FILLED_NEW_ARRAY_RANGE_notimpl: 11298 ldr r0, .L_strInternalError 11299 ldr r1, .L_strFilledNewArrayNotImpl 11300 bl dvmThrowException 11301 b common_exceptionThrown 11302 11303 .if (!1) @ define in one or the other, not both 11304.L_strFilledNewArrayNotImpl: 11305 .word .LstrFilledNewArrayNotImpl 11306.L_strInternalError: 11307 .word .LstrInternalError 11308 .endif 11309 11310/* continuation for OP_CMPL_FLOAT */ 11311 11312 @ Test for NaN with a second comparison. EABI forbids testing bit 11313 @ patterns, and we can't represent 0x7fc00000 in immediate form, so 11314 @ make the library call. 11315.LOP_CMPL_FLOAT_gt_or_nan: 11316 mov r1, r9 @ reverse order 11317 mov r0, r10 11318 bl __aeabi_cfcmple @ r0<- Z set if eq, C clear if < 11319 @bleq common_abort 11320 movcc r1, #1 @ (greater than) r1<- 1 11321 bcc .LOP_CMPL_FLOAT_finish 11322 mvn r1, #0 @ r1<- 1 or -1 for NaN 11323 b .LOP_CMPL_FLOAT_finish 11324 11325 11326#if 0 /* "clasic" form */ 11327 FETCH(r0, 1) @ r0<- CCBB 11328 and r2, r0, #255 @ r2<- BB 11329 mov r3, r0, lsr #8 @ r3<- CC 11330 GET_VREG(r9, r2) @ r9<- vBB 11331 GET_VREG(r10, r3) @ r10<- vCC 11332 mov r0, r9 @ r0<- vBB 11333 mov r1, r10 @ r1<- vCC 11334 bl __aeabi_fcmpeq @ r0<- (vBB == vCC) 11335 cmp r0, #0 @ equal? 11336 movne r1, #0 @ yes, result is 0 11337 bne OP_CMPL_FLOAT_finish 11338 mov r0, r9 @ r0<- vBB 11339 mov r1, r10 @ r1<- vCC 11340 bl __aeabi_fcmplt @ r0<- (vBB < vCC) 11341 cmp r0, #0 @ less than? 11342 b OP_CMPL_FLOAT_continue 11343@%break 11344 11345OP_CMPL_FLOAT_continue: 11346 mvnne r1, #0 @ yes, result is -1 11347 bne OP_CMPL_FLOAT_finish 11348 mov r0, r9 @ r0<- vBB 11349 mov r1, r10 @ r1<- vCC 11350 bl __aeabi_fcmpgt @ r0<- (vBB > vCC) 11351 cmp r0, #0 @ greater than? 11352 beq OP_CMPL_FLOAT_nan @ no, must be NaN 11353 mov r1, #1 @ yes, result is 1 11354 @ fall through to _finish 11355 11356OP_CMPL_FLOAT_finish: 11357 mov r3, rINST, lsr #8 @ r3<- AA 11358 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11359 SET_VREG(r1, r3) @ vAA<- r1 11360 GET_INST_OPCODE(ip) @ extract opcode from rINST 11361 GOTO_OPCODE(ip) @ jump to next instruction 11362 11363 /* 11364 * This is expected to be uncommon, so we double-branch (once to here, 11365 * again back to _finish). 11366 */ 11367OP_CMPL_FLOAT_nan: 11368 mvn r1, #0 @ r1<- 1 or -1 for NaN 11369 b OP_CMPL_FLOAT_finish 11370 11371#endif 11372 11373/* continuation for OP_CMPG_FLOAT */ 11374 11375 @ Test for NaN with a second comparison. EABI forbids testing bit 11376 @ patterns, and we can't represent 0x7fc00000 in immediate form, so 11377 @ make the library call. 11378.LOP_CMPG_FLOAT_gt_or_nan: 11379 mov r1, r9 @ reverse order 11380 mov r0, r10 11381 bl __aeabi_cfcmple @ r0<- Z set if eq, C clear if < 11382 @bleq common_abort 11383 movcc r1, #1 @ (greater than) r1<- 1 11384 bcc .LOP_CMPG_FLOAT_finish 11385 mov r1, #1 @ r1<- 1 or -1 for NaN 11386 b .LOP_CMPG_FLOAT_finish 11387 11388 11389#if 0 /* "clasic" form */ 11390 FETCH(r0, 1) @ r0<- CCBB 11391 and r2, r0, #255 @ r2<- BB 11392 mov r3, r0, lsr #8 @ r3<- CC 11393 GET_VREG(r9, r2) @ r9<- vBB 11394 GET_VREG(r10, r3) @ r10<- vCC 11395 mov r0, r9 @ r0<- vBB 11396 mov r1, r10 @ r1<- vCC 11397 bl __aeabi_fcmpeq @ r0<- (vBB == vCC) 11398 cmp r0, #0 @ equal? 11399 movne r1, #0 @ yes, result is 0 11400 bne OP_CMPG_FLOAT_finish 11401 mov r0, r9 @ r0<- vBB 11402 mov r1, r10 @ r1<- vCC 11403 bl __aeabi_fcmplt @ r0<- (vBB < vCC) 11404 cmp r0, #0 @ less than? 11405 b OP_CMPG_FLOAT_continue 11406@%break 11407 11408OP_CMPG_FLOAT_continue: 11409 mvnne r1, #0 @ yes, result is -1 11410 bne OP_CMPG_FLOAT_finish 11411 mov r0, r9 @ r0<- vBB 11412 mov r1, r10 @ r1<- vCC 11413 bl __aeabi_fcmpgt @ r0<- (vBB > vCC) 11414 cmp r0, #0 @ greater than? 11415 beq OP_CMPG_FLOAT_nan @ no, must be NaN 11416 mov r1, #1 @ yes, result is 1 11417 @ fall through to _finish 11418 11419OP_CMPG_FLOAT_finish: 11420 mov r3, rINST, lsr #8 @ r3<- AA 11421 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11422 SET_VREG(r1, r3) @ vAA<- r1 11423 GET_INST_OPCODE(ip) @ extract opcode from rINST 11424 GOTO_OPCODE(ip) @ jump to next instruction 11425 11426 /* 11427 * This is expected to be uncommon, so we double-branch (once to here, 11428 * again back to _finish). 11429 */ 11430OP_CMPG_FLOAT_nan: 11431 mov r1, #1 @ r1<- 1 or -1 for NaN 11432 b OP_CMPG_FLOAT_finish 11433 11434#endif 11435 11436/* continuation for OP_CMPL_DOUBLE */ 11437 11438 @ Test for NaN with a second comparison. EABI forbids testing bit 11439 @ patterns, and we can't represent 0x7fc00000 in immediate form, so 11440 @ make the library call. 11441.LOP_CMPL_DOUBLE_gt_or_nan: 11442 ldmia r10, {r0-r1} @ reverse order 11443 ldmia r9, {r2-r3} 11444 bl __aeabi_cdcmple @ r0<- Z set if eq, C clear if < 11445 @bleq common_abort 11446 movcc r1, #1 @ (greater than) r1<- 1 11447 bcc .LOP_CMPL_DOUBLE_finish 11448 mvn r1, #0 @ r1<- 1 or -1 for NaN 11449 b .LOP_CMPL_DOUBLE_finish 11450 11451/* continuation for OP_CMPG_DOUBLE */ 11452 11453 @ Test for NaN with a second comparison. EABI forbids testing bit 11454 @ patterns, and we can't represent 0x7fc00000 in immediate form, so 11455 @ make the library call. 11456.LOP_CMPG_DOUBLE_gt_or_nan: 11457 ldmia r10, {r0-r1} @ reverse order 11458 ldmia r9, {r2-r3} 11459 bl __aeabi_cdcmple @ r0<- Z set if eq, C clear if < 11460 @bleq common_abort 11461 movcc r1, #1 @ (greater than) r1<- 1 11462 bcc .LOP_CMPG_DOUBLE_finish 11463 mov r1, #1 @ r1<- 1 or -1 for NaN 11464 b .LOP_CMPG_DOUBLE_finish 11465 11466/* continuation for OP_CMP_LONG */ 11467 11468.LOP_CMP_LONG_less: 11469 mvn r1, #0 @ r1<- -1 11470 @ Want to cond code the next mov so we can avoid branch, but don't see it; 11471 @ instead, we just replicate the tail end. 11472 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11473 SET_VREG(r1, r9) @ vAA<- r1 11474 GET_INST_OPCODE(ip) @ extract opcode from rINST 11475 GOTO_OPCODE(ip) @ jump to next instruction 11476 11477.LOP_CMP_LONG_greater: 11478 mov r1, #1 @ r1<- 1 11479 @ fall through to _finish 11480 11481.LOP_CMP_LONG_finish: 11482 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11483 SET_VREG(r1, r9) @ vAA<- r1 11484 GET_INST_OPCODE(ip) @ extract opcode from rINST 11485 GOTO_OPCODE(ip) @ jump to next instruction 11486 11487/* continuation for OP_AGET_WIDE */ 11488 11489.LOP_AGET_WIDE_finish: 11490 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11491 ldrd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 11492 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 11493 GET_INST_OPCODE(ip) @ extract opcode from rINST 11494 stmia r9, {r2-r3} @ vAA/vAA+1<- r2/r3 11495 GOTO_OPCODE(ip) @ jump to next instruction 11496 11497/* continuation for OP_APUT_WIDE */ 11498 11499.LOP_APUT_WIDE_finish: 11500 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11501 ldmia r9, {r2-r3} @ r2/r3<- vAA/vAA+1 11502 GET_INST_OPCODE(ip) @ extract opcode from rINST 11503 strd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 11504 GOTO_OPCODE(ip) @ jump to next instruction 11505 11506/* continuation for OP_APUT_OBJECT */ 11507 /* 11508 * On entry: 11509 * rINST = vBB (arrayObj) 11510 * r9 = vAA (obj) 11511 * r10 = offset into array (vBB + vCC * width) 11512 */ 11513.LOP_APUT_OBJECT_finish: 11514 cmp r9, #0 @ storing null reference? 11515 beq .LOP_APUT_OBJECT_skip_check @ yes, skip type checks 11516 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 11517 ldr r1, [rINST, #offObject_clazz] @ r1<- arrayObj->clazz 11518 bl dvmCanPutArrayElement @ test object type vs. array type 11519 cmp r0, #0 @ okay? 11520 beq .LOP_APUT_OBJECT_throw @ no 11521 mov r1, rINST @ r1<- arrayObj 11522 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11523 ldr r2, [rGLUE, #offGlue_cardTable] @ get biased CT base 11524 add r10, #offArrayObject_contents @ r0<- pointer to slot 11525 GET_INST_OPCODE(ip) @ extract opcode from rINST 11526 str r9, [r10] @ vBB[vCC]<- vAA 11527 strb r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head 11528 GOTO_OPCODE(ip) @ jump to next instruction 11529.LOP_APUT_OBJECT_skip_check: 11530 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11531 GET_INST_OPCODE(ip) @ extract opcode from rINST 11532 str r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA 11533 GOTO_OPCODE(ip) @ jump to next instruction 11534.LOP_APUT_OBJECT_throw: 11535 @ The types don't match. We need to throw an ArrayStoreException. 11536 ldr r0, [r9, #offObject_clazz] 11537 ldr r1, [rINST, #offObject_clazz] 11538 EXPORT_PC() 11539 bl dvmThrowArrayStoreException 11540 b common_exceptionThrown 11541 11542/* continuation for OP_IGET */ 11543 11544 /* 11545 * Currently: 11546 * r0 holds resolved field 11547 * r9 holds object 11548 */ 11549.LOP_IGET_finish: 11550 @bl common_squeak0 11551 cmp r9, #0 @ check object for null 11552 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11553 beq common_errNullObject @ object was null 11554 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11555 @ no-op @ acquiring load 11556 mov r2, rINST, lsr #8 @ r2<- A+ 11557 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11558 and r2, r2, #15 @ r2<- A 11559 GET_INST_OPCODE(ip) @ extract opcode from rINST 11560 SET_VREG(r0, r2) @ fp[A]<- r0 11561 GOTO_OPCODE(ip) @ jump to next instruction 11562 11563/* continuation for OP_IGET_WIDE */ 11564 11565 /* 11566 * Currently: 11567 * r0 holds resolved field 11568 * r9 holds object 11569 */ 11570.LOP_IGET_WIDE_finish: 11571 cmp r9, #0 @ check object for null 11572 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11573 beq common_errNullObject @ object was null 11574 .if 0 11575 add r0, r9, r3 @ r0<- address of field 11576 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 11577 .else 11578 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 11579 .endif 11580 mov r2, rINST, lsr #8 @ r2<- A+ 11581 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11582 and r2, r2, #15 @ r2<- A 11583 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 11584 GET_INST_OPCODE(ip) @ extract opcode from rINST 11585 stmia r3, {r0-r1} @ fp[A]<- r0/r1 11586 GOTO_OPCODE(ip) @ jump to next instruction 11587 11588/* continuation for OP_IGET_OBJECT */ 11589 11590 /* 11591 * Currently: 11592 * r0 holds resolved field 11593 * r9 holds object 11594 */ 11595.LOP_IGET_OBJECT_finish: 11596 @bl common_squeak0 11597 cmp r9, #0 @ check object for null 11598 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11599 beq common_errNullObject @ object was null 11600 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11601 @ no-op @ acquiring load 11602 mov r2, rINST, lsr #8 @ r2<- A+ 11603 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11604 and r2, r2, #15 @ r2<- A 11605 GET_INST_OPCODE(ip) @ extract opcode from rINST 11606 SET_VREG(r0, r2) @ fp[A]<- r0 11607 GOTO_OPCODE(ip) @ jump to next instruction 11608 11609/* continuation for OP_IGET_BOOLEAN */ 11610 11611 /* 11612 * Currently: 11613 * r0 holds resolved field 11614 * r9 holds object 11615 */ 11616.LOP_IGET_BOOLEAN_finish: 11617 @bl common_squeak1 11618 cmp r9, #0 @ check object for null 11619 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11620 beq common_errNullObject @ object was null 11621 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11622 @ no-op @ acquiring load 11623 mov r2, rINST, lsr #8 @ r2<- A+ 11624 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11625 and r2, r2, #15 @ r2<- A 11626 GET_INST_OPCODE(ip) @ extract opcode from rINST 11627 SET_VREG(r0, r2) @ fp[A]<- r0 11628 GOTO_OPCODE(ip) @ jump to next instruction 11629 11630/* continuation for OP_IGET_BYTE */ 11631 11632 /* 11633 * Currently: 11634 * r0 holds resolved field 11635 * r9 holds object 11636 */ 11637.LOP_IGET_BYTE_finish: 11638 @bl common_squeak2 11639 cmp r9, #0 @ check object for null 11640 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11641 beq common_errNullObject @ object was null 11642 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11643 @ no-op @ acquiring load 11644 mov r2, rINST, lsr #8 @ r2<- A+ 11645 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11646 and r2, r2, #15 @ r2<- A 11647 GET_INST_OPCODE(ip) @ extract opcode from rINST 11648 SET_VREG(r0, r2) @ fp[A]<- r0 11649 GOTO_OPCODE(ip) @ jump to next instruction 11650 11651/* continuation for OP_IGET_CHAR */ 11652 11653 /* 11654 * Currently: 11655 * r0 holds resolved field 11656 * r9 holds object 11657 */ 11658.LOP_IGET_CHAR_finish: 11659 @bl common_squeak3 11660 cmp r9, #0 @ check object for null 11661 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11662 beq common_errNullObject @ object was null 11663 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11664 @ no-op @ acquiring load 11665 mov r2, rINST, lsr #8 @ r2<- A+ 11666 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11667 and r2, r2, #15 @ r2<- A 11668 GET_INST_OPCODE(ip) @ extract opcode from rINST 11669 SET_VREG(r0, r2) @ fp[A]<- r0 11670 GOTO_OPCODE(ip) @ jump to next instruction 11671 11672/* continuation for OP_IGET_SHORT */ 11673 11674 /* 11675 * Currently: 11676 * r0 holds resolved field 11677 * r9 holds object 11678 */ 11679.LOP_IGET_SHORT_finish: 11680 @bl common_squeak4 11681 cmp r9, #0 @ check object for null 11682 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11683 beq common_errNullObject @ object was null 11684 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11685 @ no-op @ acquiring load 11686 mov r2, rINST, lsr #8 @ r2<- A+ 11687 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11688 and r2, r2, #15 @ r2<- A 11689 GET_INST_OPCODE(ip) @ extract opcode from rINST 11690 SET_VREG(r0, r2) @ fp[A]<- r0 11691 GOTO_OPCODE(ip) @ jump to next instruction 11692 11693/* continuation for OP_IPUT */ 11694 11695 /* 11696 * Currently: 11697 * r0 holds resolved field 11698 * r9 holds object 11699 */ 11700.LOP_IPUT_finish: 11701 @bl common_squeak0 11702 mov r1, rINST, lsr #8 @ r1<- A+ 11703 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11704 and r1, r1, #15 @ r1<- A 11705 cmp r9, #0 @ check object for null 11706 GET_VREG(r0, r1) @ r0<- fp[A] 11707 beq common_errNullObject @ object was null 11708 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11709 GET_INST_OPCODE(ip) @ extract opcode from rINST 11710 @ no-op @ releasing store 11711 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11712 GOTO_OPCODE(ip) @ jump to next instruction 11713 11714/* continuation for OP_IPUT_WIDE */ 11715 11716 /* 11717 * Currently: 11718 * r0 holds resolved field 11719 * r9 holds object 11720 */ 11721.LOP_IPUT_WIDE_finish: 11722 mov r2, rINST, lsr #8 @ r2<- A+ 11723 cmp r9, #0 @ check object for null 11724 and r2, r2, #15 @ r2<- A 11725 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11726 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 11727 beq common_errNullObject @ object was null 11728 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11729 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 11730 GET_INST_OPCODE(r10) @ extract opcode from rINST 11731 .if 0 11732 add r2, r9, r3 @ r2<- target address 11733 bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2 11734 .else 11735 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 11736 .endif 11737 GOTO_OPCODE(r10) @ jump to next instruction 11738 11739/* continuation for OP_IPUT_OBJECT */ 11740 11741 /* 11742 * Currently: 11743 * r0 holds resolved field 11744 * r9 holds object 11745 */ 11746.LOP_IPUT_OBJECT_finish: 11747 @bl common_squeak0 11748 mov r1, rINST, lsr #8 @ r1<- A+ 11749 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11750 and r1, r1, #15 @ r1<- A 11751 cmp r9, #0 @ check object for null 11752 GET_VREG(r0, r1) @ r0<- fp[A] 11753 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 11754 beq common_errNullObject @ object was null 11755 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11756 GET_INST_OPCODE(ip) @ extract opcode from rINST 11757 @ no-op @ releasing store 11758 str r0, [r9, r3] @ obj.field (32 bits)<- r0 11759 cmp r0, #0 @ stored a null reference? 11760 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 11761 GOTO_OPCODE(ip) @ jump to next instruction 11762 11763/* continuation for OP_IPUT_BOOLEAN */ 11764 11765 /* 11766 * Currently: 11767 * r0 holds resolved field 11768 * r9 holds object 11769 */ 11770.LOP_IPUT_BOOLEAN_finish: 11771 @bl common_squeak1 11772 mov r1, rINST, lsr #8 @ r1<- A+ 11773 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11774 and r1, r1, #15 @ r1<- A 11775 cmp r9, #0 @ check object for null 11776 GET_VREG(r0, r1) @ r0<- fp[A] 11777 beq common_errNullObject @ object was null 11778 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11779 GET_INST_OPCODE(ip) @ extract opcode from rINST 11780 @ no-op @ releasing store 11781 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11782 GOTO_OPCODE(ip) @ jump to next instruction 11783 11784/* continuation for OP_IPUT_BYTE */ 11785 11786 /* 11787 * Currently: 11788 * r0 holds resolved field 11789 * r9 holds object 11790 */ 11791.LOP_IPUT_BYTE_finish: 11792 @bl common_squeak2 11793 mov r1, rINST, lsr #8 @ r1<- A+ 11794 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11795 and r1, r1, #15 @ r1<- A 11796 cmp r9, #0 @ check object for null 11797 GET_VREG(r0, r1) @ r0<- fp[A] 11798 beq common_errNullObject @ object was null 11799 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11800 GET_INST_OPCODE(ip) @ extract opcode from rINST 11801 @ no-op @ releasing store 11802 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11803 GOTO_OPCODE(ip) @ jump to next instruction 11804 11805/* continuation for OP_IPUT_CHAR */ 11806 11807 /* 11808 * Currently: 11809 * r0 holds resolved field 11810 * r9 holds object 11811 */ 11812.LOP_IPUT_CHAR_finish: 11813 @bl common_squeak3 11814 mov r1, rINST, lsr #8 @ r1<- A+ 11815 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11816 and r1, r1, #15 @ r1<- A 11817 cmp r9, #0 @ check object for null 11818 GET_VREG(r0, r1) @ r0<- fp[A] 11819 beq common_errNullObject @ object was null 11820 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11821 GET_INST_OPCODE(ip) @ extract opcode from rINST 11822 @ no-op @ releasing store 11823 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11824 GOTO_OPCODE(ip) @ jump to next instruction 11825 11826/* continuation for OP_IPUT_SHORT */ 11827 11828 /* 11829 * Currently: 11830 * r0 holds resolved field 11831 * r9 holds object 11832 */ 11833.LOP_IPUT_SHORT_finish: 11834 @bl common_squeak4 11835 mov r1, rINST, lsr #8 @ r1<- A+ 11836 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11837 and r1, r1, #15 @ r1<- A 11838 cmp r9, #0 @ check object for null 11839 GET_VREG(r0, r1) @ r0<- fp[A] 11840 beq common_errNullObject @ object was null 11841 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11842 GET_INST_OPCODE(ip) @ extract opcode from rINST 11843 @ no-op @ releasing store 11844 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11845 GOTO_OPCODE(ip) @ jump to next instruction 11846 11847/* continuation for OP_SGET */ 11848 11849 /* 11850 * Continuation if the field has not yet been resolved. 11851 * r1: BBBB field ref 11852 */ 11853.LOP_SGET_resolve: 11854 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11855 EXPORT_PC() @ resolve() could throw, so export now 11856 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11857 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11858 cmp r0, #0 @ success? 11859 bne .LOP_SGET_finish @ yes, finish 11860 b common_exceptionThrown @ no, handle exception 11861 11862/* continuation for OP_SGET_WIDE */ 11863 11864 /* 11865 * Continuation if the field has not yet been resolved. 11866 * r1: BBBB field ref 11867 * 11868 * Returns StaticField pointer in r0. 11869 */ 11870.LOP_SGET_WIDE_resolve: 11871 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11872 EXPORT_PC() @ resolve() could throw, so export now 11873 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11874 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11875 cmp r0, #0 @ success? 11876 bne .LOP_SGET_WIDE_finish @ yes, finish 11877 b common_exceptionThrown @ no, handle exception 11878 11879/* continuation for OP_SGET_OBJECT */ 11880 11881 /* 11882 * Continuation if the field has not yet been resolved. 11883 * r1: BBBB field ref 11884 */ 11885.LOP_SGET_OBJECT_resolve: 11886 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11887 EXPORT_PC() @ resolve() could throw, so export now 11888 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11889 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11890 cmp r0, #0 @ success? 11891 bne .LOP_SGET_OBJECT_finish @ yes, finish 11892 b common_exceptionThrown @ no, handle exception 11893 11894/* continuation for OP_SGET_BOOLEAN */ 11895 11896 /* 11897 * Continuation if the field has not yet been resolved. 11898 * r1: BBBB field ref 11899 */ 11900.LOP_SGET_BOOLEAN_resolve: 11901 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11902 EXPORT_PC() @ resolve() could throw, so export now 11903 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11904 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11905 cmp r0, #0 @ success? 11906 bne .LOP_SGET_BOOLEAN_finish @ yes, finish 11907 b common_exceptionThrown @ no, handle exception 11908 11909/* continuation for OP_SGET_BYTE */ 11910 11911 /* 11912 * Continuation if the field has not yet been resolved. 11913 * r1: BBBB field ref 11914 */ 11915.LOP_SGET_BYTE_resolve: 11916 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11917 EXPORT_PC() @ resolve() could throw, so export now 11918 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11919 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11920 cmp r0, #0 @ success? 11921 bne .LOP_SGET_BYTE_finish @ yes, finish 11922 b common_exceptionThrown @ no, handle exception 11923 11924/* continuation for OP_SGET_CHAR */ 11925 11926 /* 11927 * Continuation if the field has not yet been resolved. 11928 * r1: BBBB field ref 11929 */ 11930.LOP_SGET_CHAR_resolve: 11931 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11932 EXPORT_PC() @ resolve() could throw, so export now 11933 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11934 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11935 cmp r0, #0 @ success? 11936 bne .LOP_SGET_CHAR_finish @ yes, finish 11937 b common_exceptionThrown @ no, handle exception 11938 11939/* continuation for OP_SGET_SHORT */ 11940 11941 /* 11942 * Continuation if the field has not yet been resolved. 11943 * r1: BBBB field ref 11944 */ 11945.LOP_SGET_SHORT_resolve: 11946 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11947 EXPORT_PC() @ resolve() could throw, so export now 11948 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11949 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11950 cmp r0, #0 @ success? 11951 bne .LOP_SGET_SHORT_finish @ yes, finish 11952 b common_exceptionThrown @ no, handle exception 11953 11954/* continuation for OP_SPUT */ 11955 11956 /* 11957 * Continuation if the field has not yet been resolved. 11958 * r1: BBBB field ref 11959 */ 11960.LOP_SPUT_resolve: 11961 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11962 EXPORT_PC() @ resolve() could throw, so export now 11963 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11964 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11965 cmp r0, #0 @ success? 11966 bne .LOP_SPUT_finish @ yes, finish 11967 b common_exceptionThrown @ no, handle exception 11968 11969/* continuation for OP_SPUT_WIDE */ 11970 11971 /* 11972 * Continuation if the field has not yet been resolved. 11973 * r1: BBBB field ref 11974 * r9: &fp[AA] 11975 * 11976 * Returns StaticField pointer in r2. 11977 */ 11978.LOP_SPUT_WIDE_resolve: 11979 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11980 EXPORT_PC() @ resolve() could throw, so export now 11981 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11982 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11983 cmp r0, #0 @ success? 11984 mov r2, r0 @ copy to r2 11985 bne .LOP_SPUT_WIDE_finish @ yes, finish 11986 b common_exceptionThrown @ no, handle exception 11987 11988/* continuation for OP_SPUT_OBJECT */ 11989.LOP_SPUT_OBJECT_finish: @ field ptr in r0 11990 mov r2, rINST, lsr #8 @ r2<- AA 11991 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11992 GET_VREG(r1, r2) @ r1<- fp[AA] 11993 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 11994 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 11995 GET_INST_OPCODE(ip) @ extract opcode from rINST 11996 @ no-op @ releasing store 11997 str r1, [r0, #offStaticField_value] @ field<- vAA 11998 cmp r1, #0 @ stored a null object? 11999 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 12000 GOTO_OPCODE(ip) @ jump to next instruction 12001 12002/* continuation for OP_SPUT_BOOLEAN */ 12003 12004 /* 12005 * Continuation if the field has not yet been resolved. 12006 * r1: BBBB field ref 12007 */ 12008.LOP_SPUT_BOOLEAN_resolve: 12009 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12010 EXPORT_PC() @ resolve() could throw, so export now 12011 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12012 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12013 cmp r0, #0 @ success? 12014 bne .LOP_SPUT_BOOLEAN_finish @ yes, finish 12015 b common_exceptionThrown @ no, handle exception 12016 12017/* continuation for OP_SPUT_BYTE */ 12018 12019 /* 12020 * Continuation if the field has not yet been resolved. 12021 * r1: BBBB field ref 12022 */ 12023.LOP_SPUT_BYTE_resolve: 12024 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12025 EXPORT_PC() @ resolve() could throw, so export now 12026 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12027 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12028 cmp r0, #0 @ success? 12029 bne .LOP_SPUT_BYTE_finish @ yes, finish 12030 b common_exceptionThrown @ no, handle exception 12031 12032/* continuation for OP_SPUT_CHAR */ 12033 12034 /* 12035 * Continuation if the field has not yet been resolved. 12036 * r1: BBBB field ref 12037 */ 12038.LOP_SPUT_CHAR_resolve: 12039 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12040 EXPORT_PC() @ resolve() could throw, so export now 12041 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12042 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12043 cmp r0, #0 @ success? 12044 bne .LOP_SPUT_CHAR_finish @ yes, finish 12045 b common_exceptionThrown @ no, handle exception 12046 12047/* continuation for OP_SPUT_SHORT */ 12048 12049 /* 12050 * Continuation if the field has not yet been resolved. 12051 * r1: BBBB field ref 12052 */ 12053.LOP_SPUT_SHORT_resolve: 12054 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12055 EXPORT_PC() @ resolve() could throw, so export now 12056 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12057 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12058 cmp r0, #0 @ success? 12059 bne .LOP_SPUT_SHORT_finish @ yes, finish 12060 b common_exceptionThrown @ no, handle exception 12061 12062/* continuation for OP_INVOKE_VIRTUAL */ 12063 12064 /* 12065 * At this point: 12066 * r0 = resolved base method 12067 * r10 = C or CCCC (index of first arg, which is the "this" ptr) 12068 */ 12069.LOP_INVOKE_VIRTUAL_continue: 12070 GET_VREG(r1, r10) @ r1<- "this" ptr 12071 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 12072 cmp r1, #0 @ is "this" null? 12073 beq common_errNullObject @ null "this", throw exception 12074 ldr r3, [r1, #offObject_clazz] @ r1<- thisPtr->clazz 12075 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 12076 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 12077 bl common_invokeMethodNoRange @ continue on 12078 12079/* continuation for OP_INVOKE_SUPER */ 12080 12081 /* 12082 * At this point: 12083 * r0 = resolved base method 12084 * r9 = method->clazz 12085 */ 12086.LOP_INVOKE_SUPER_continue: 12087 ldr r1, [r9, #offClassObject_super] @ r1<- method->clazz->super 12088 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 12089 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 12090 EXPORT_PC() @ must export for invoke 12091 cmp r2, r3 @ compare (methodIndex, vtableCount) 12092 bcs .LOP_INVOKE_SUPER_nsm @ method not present in superclass 12093 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 12094 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 12095 bl common_invokeMethodNoRange @ continue on 12096 12097.LOP_INVOKE_SUPER_resolve: 12098 mov r0, r9 @ r0<- method->clazz 12099 mov r2, #METHOD_VIRTUAL @ resolver method type 12100 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 12101 cmp r0, #0 @ got null? 12102 bne .LOP_INVOKE_SUPER_continue @ no, continue 12103 b common_exceptionThrown @ yes, handle exception 12104 12105 /* 12106 * Throw a NoSuchMethodError with the method name as the message. 12107 * r0 = resolved base method 12108 */ 12109.LOP_INVOKE_SUPER_nsm: 12110 ldr r1, [r0, #offMethod_name] @ r1<- method name 12111 b common_errNoSuchMethod 12112 12113/* continuation for OP_INVOKE_DIRECT */ 12114 12115 /* 12116 * On entry: 12117 * r1 = reference (BBBB or CCCC) 12118 * r10 = "this" register 12119 */ 12120.LOP_INVOKE_DIRECT_resolve: 12121 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 12122 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 12123 mov r2, #METHOD_DIRECT @ resolver method type 12124 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 12125 cmp r0, #0 @ got null? 12126 GET_VREG(r2, r10) @ r2<- "this" ptr (reload) 12127 bne .LOP_INVOKE_DIRECT_finish @ no, continue 12128 b common_exceptionThrown @ yes, handle exception 12129 12130/* continuation for OP_INVOKE_VIRTUAL_RANGE */ 12131 12132 /* 12133 * At this point: 12134 * r0 = resolved base method 12135 * r10 = C or CCCC (index of first arg, which is the "this" ptr) 12136 */ 12137.LOP_INVOKE_VIRTUAL_RANGE_continue: 12138 GET_VREG(r1, r10) @ r1<- "this" ptr 12139 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 12140 cmp r1, #0 @ is "this" null? 12141 beq common_errNullObject @ null "this", throw exception 12142 ldr r3, [r1, #offObject_clazz] @ r1<- thisPtr->clazz 12143 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 12144 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 12145 bl common_invokeMethodRange @ continue on 12146 12147/* continuation for OP_INVOKE_SUPER_RANGE */ 12148 12149 /* 12150 * At this point: 12151 * r0 = resolved base method 12152 * r9 = method->clazz 12153 */ 12154.LOP_INVOKE_SUPER_RANGE_continue: 12155 ldr r1, [r9, #offClassObject_super] @ r1<- method->clazz->super 12156 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 12157 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 12158 EXPORT_PC() @ must export for invoke 12159 cmp r2, r3 @ compare (methodIndex, vtableCount) 12160 bcs .LOP_INVOKE_SUPER_RANGE_nsm @ method not present in superclass 12161 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 12162 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 12163 bl common_invokeMethodRange @ continue on 12164 12165.LOP_INVOKE_SUPER_RANGE_resolve: 12166 mov r0, r9 @ r0<- method->clazz 12167 mov r2, #METHOD_VIRTUAL @ resolver method type 12168 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 12169 cmp r0, #0 @ got null? 12170 bne .LOP_INVOKE_SUPER_RANGE_continue @ no, continue 12171 b common_exceptionThrown @ yes, handle exception 12172 12173 /* 12174 * Throw a NoSuchMethodError with the method name as the message. 12175 * r0 = resolved base method 12176 */ 12177.LOP_INVOKE_SUPER_RANGE_nsm: 12178 ldr r1, [r0, #offMethod_name] @ r1<- method name 12179 b common_errNoSuchMethod 12180 12181/* continuation for OP_INVOKE_DIRECT_RANGE */ 12182 12183 /* 12184 * On entry: 12185 * r1 = reference (BBBB or CCCC) 12186 * r10 = "this" register 12187 */ 12188.LOP_INVOKE_DIRECT_RANGE_resolve: 12189 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 12190 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 12191 mov r2, #METHOD_DIRECT @ resolver method type 12192 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 12193 cmp r0, #0 @ got null? 12194 GET_VREG(r2, r10) @ r2<- "this" ptr (reload) 12195 bne .LOP_INVOKE_DIRECT_RANGE_finish @ no, continue 12196 b common_exceptionThrown @ yes, handle exception 12197 12198/* continuation for OP_FLOAT_TO_LONG */ 12199/* 12200 * Convert the float in r0 to a long in r0/r1. 12201 * 12202 * We have to clip values to long min/max per the specification. The 12203 * expected common case is a "reasonable" value that converts directly 12204 * to modest integer. The EABI convert function isn't doing this for us. 12205 */ 12206f2l_doconv: 12207 stmfd sp!, {r4, lr} 12208 mov r1, #0x5f000000 @ (float)maxlong 12209 mov r4, r0 12210 bl __aeabi_fcmpge @ is arg >= maxlong? 12211 cmp r0, #0 @ nonzero == yes 12212 mvnne r0, #0 @ return maxlong (7fffffff) 12213 mvnne r1, #0x80000000 12214 ldmnefd sp!, {r4, pc} 12215 12216 mov r0, r4 @ recover arg 12217 mov r1, #0xdf000000 @ (float)minlong 12218 bl __aeabi_fcmple @ is arg <= minlong? 12219 cmp r0, #0 @ nonzero == yes 12220 movne r0, #0 @ return minlong (80000000) 12221 movne r1, #0x80000000 12222 ldmnefd sp!, {r4, pc} 12223 12224 mov r0, r4 @ recover arg 12225 mov r1, r4 12226 bl __aeabi_fcmpeq @ is arg == self? 12227 cmp r0, #0 @ zero == no 12228 moveq r1, #0 @ return zero for NaN 12229 ldmeqfd sp!, {r4, pc} 12230 12231 mov r0, r4 @ recover arg 12232 bl __aeabi_f2lz @ convert float to long 12233 ldmfd sp!, {r4, pc} 12234 12235/* continuation for OP_DOUBLE_TO_LONG */ 12236/* 12237 * Convert the double in r0/r1 to a long in r0/r1. 12238 * 12239 * We have to clip values to long min/max per the specification. The 12240 * expected common case is a "reasonable" value that converts directly 12241 * to modest integer. The EABI convert function isn't doing this for us. 12242 */ 12243d2l_doconv: 12244 stmfd sp!, {r4, r5, lr} @ save regs 12245 mov r3, #0x43000000 @ maxlong, as a double (high word) 12246 add r3, #0x00e00000 @ 0x43e00000 12247 mov r2, #0 @ maxlong, as a double (low word) 12248 sub sp, sp, #4 @ align for EABI 12249 mov r4, r0 @ save a copy of r0 12250 mov r5, r1 @ and r1 12251 bl __aeabi_dcmpge @ is arg >= maxlong? 12252 cmp r0, #0 @ nonzero == yes 12253 mvnne r0, #0 @ return maxlong (7fffffffffffffff) 12254 mvnne r1, #0x80000000 12255 bne 1f 12256 12257 mov r0, r4 @ recover arg 12258 mov r1, r5 12259 mov r3, #0xc3000000 @ minlong, as a double (high word) 12260 add r3, #0x00e00000 @ 0xc3e00000 12261 mov r2, #0 @ minlong, as a double (low word) 12262 bl __aeabi_dcmple @ is arg <= minlong? 12263 cmp r0, #0 @ nonzero == yes 12264 movne r0, #0 @ return minlong (8000000000000000) 12265 movne r1, #0x80000000 12266 bne 1f 12267 12268 mov r0, r4 @ recover arg 12269 mov r1, r5 12270 mov r2, r4 @ compare against self 12271 mov r3, r5 12272 bl __aeabi_dcmpeq @ is arg == self? 12273 cmp r0, #0 @ zero == no 12274 moveq r1, #0 @ return zero for NaN 12275 beq 1f 12276 12277 mov r0, r4 @ recover arg 12278 mov r1, r5 12279 bl __aeabi_d2lz @ convert double to long 12280 122811: 12282 add sp, sp, #4 12283 ldmfd sp!, {r4, r5, pc} 12284 12285/* continuation for OP_MUL_LONG */ 12286 12287.LOP_MUL_LONG_finish: 12288 GET_INST_OPCODE(ip) @ extract opcode from rINST 12289 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 12290 GOTO_OPCODE(ip) @ jump to next instruction 12291 12292/* continuation for OP_SHL_LONG */ 12293 12294.LOP_SHL_LONG_finish: 12295 mov r0, r0, asl r2 @ r0<- r0 << r2 12296 GET_INST_OPCODE(ip) @ extract opcode from rINST 12297 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 12298 GOTO_OPCODE(ip) @ jump to next instruction 12299 12300/* continuation for OP_SHR_LONG */ 12301 12302.LOP_SHR_LONG_finish: 12303 mov r1, r1, asr r2 @ r1<- r1 >> r2 12304 GET_INST_OPCODE(ip) @ extract opcode from rINST 12305 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 12306 GOTO_OPCODE(ip) @ jump to next instruction 12307 12308/* continuation for OP_USHR_LONG */ 12309 12310.LOP_USHR_LONG_finish: 12311 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 12312 GET_INST_OPCODE(ip) @ extract opcode from rINST 12313 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 12314 GOTO_OPCODE(ip) @ jump to next instruction 12315 12316/* continuation for OP_SHL_LONG_2ADDR */ 12317 12318.LOP_SHL_LONG_2ADDR_finish: 12319 GET_INST_OPCODE(ip) @ extract opcode from rINST 12320 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 12321 GOTO_OPCODE(ip) @ jump to next instruction 12322 12323/* continuation for OP_SHR_LONG_2ADDR */ 12324 12325.LOP_SHR_LONG_2ADDR_finish: 12326 GET_INST_OPCODE(ip) @ extract opcode from rINST 12327 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 12328 GOTO_OPCODE(ip) @ jump to next instruction 12329 12330/* continuation for OP_USHR_LONG_2ADDR */ 12331 12332.LOP_USHR_LONG_2ADDR_finish: 12333 GET_INST_OPCODE(ip) @ extract opcode from rINST 12334 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 12335 GOTO_OPCODE(ip) @ jump to next instruction 12336 12337/* continuation for OP_IGET_VOLATILE */ 12338 12339 /* 12340 * Currently: 12341 * r0 holds resolved field 12342 * r9 holds object 12343 */ 12344.LOP_IGET_VOLATILE_finish: 12345 @bl common_squeak0 12346 cmp r9, #0 @ check object for null 12347 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12348 beq common_errNullObject @ object was null 12349 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12350 SMP_DMB @ acquiring load 12351 mov r2, rINST, lsr #8 @ r2<- A+ 12352 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 12353 and r2, r2, #15 @ r2<- A 12354 GET_INST_OPCODE(ip) @ extract opcode from rINST 12355 SET_VREG(r0, r2) @ fp[A]<- r0 12356 GOTO_OPCODE(ip) @ jump to next instruction 12357 12358/* continuation for OP_IPUT_VOLATILE */ 12359 12360 /* 12361 * Currently: 12362 * r0 holds resolved field 12363 * r9 holds object 12364 */ 12365.LOP_IPUT_VOLATILE_finish: 12366 @bl common_squeak0 12367 mov r1, rINST, lsr #8 @ r1<- A+ 12368 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12369 and r1, r1, #15 @ r1<- A 12370 cmp r9, #0 @ check object for null 12371 GET_VREG(r0, r1) @ r0<- fp[A] 12372 beq common_errNullObject @ object was null 12373 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 12374 GET_INST_OPCODE(ip) @ extract opcode from rINST 12375 SMP_DMB @ releasing store 12376 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12377 GOTO_OPCODE(ip) @ jump to next instruction 12378 12379/* continuation for OP_SGET_VOLATILE */ 12380 12381 /* 12382 * Continuation if the field has not yet been resolved. 12383 * r1: BBBB field ref 12384 */ 12385.LOP_SGET_VOLATILE_resolve: 12386 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12387 EXPORT_PC() @ resolve() could throw, so export now 12388 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12389 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12390 cmp r0, #0 @ success? 12391 bne .LOP_SGET_VOLATILE_finish @ yes, finish 12392 b common_exceptionThrown @ no, handle exception 12393 12394/* continuation for OP_SPUT_VOLATILE */ 12395 12396 /* 12397 * Continuation if the field has not yet been resolved. 12398 * r1: BBBB field ref 12399 */ 12400.LOP_SPUT_VOLATILE_resolve: 12401 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12402 EXPORT_PC() @ resolve() could throw, so export now 12403 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12404 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12405 cmp r0, #0 @ success? 12406 bne .LOP_SPUT_VOLATILE_finish @ yes, finish 12407 b common_exceptionThrown @ no, handle exception 12408 12409/* continuation for OP_IGET_OBJECT_VOLATILE */ 12410 12411 /* 12412 * Currently: 12413 * r0 holds resolved field 12414 * r9 holds object 12415 */ 12416.LOP_IGET_OBJECT_VOLATILE_finish: 12417 @bl common_squeak0 12418 cmp r9, #0 @ check object for null 12419 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12420 beq common_errNullObject @ object was null 12421 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12422 SMP_DMB @ acquiring load 12423 mov r2, rINST, lsr #8 @ r2<- A+ 12424 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 12425 and r2, r2, #15 @ r2<- A 12426 GET_INST_OPCODE(ip) @ extract opcode from rINST 12427 SET_VREG(r0, r2) @ fp[A]<- r0 12428 GOTO_OPCODE(ip) @ jump to next instruction 12429 12430/* continuation for OP_IGET_WIDE_VOLATILE */ 12431 12432 /* 12433 * Currently: 12434 * r0 holds resolved field 12435 * r9 holds object 12436 */ 12437.LOP_IGET_WIDE_VOLATILE_finish: 12438 cmp r9, #0 @ check object for null 12439 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12440 beq common_errNullObject @ object was null 12441 .if 1 12442 add r0, r9, r3 @ r0<- address of field 12443 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 12444 .else 12445 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 12446 .endif 12447 mov r2, rINST, lsr #8 @ r2<- A+ 12448 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 12449 and r2, r2, #15 @ r2<- A 12450 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 12451 GET_INST_OPCODE(ip) @ extract opcode from rINST 12452 stmia r3, {r0-r1} @ fp[A]<- r0/r1 12453 GOTO_OPCODE(ip) @ jump to next instruction 12454 12455/* continuation for OP_IPUT_WIDE_VOLATILE */ 12456 12457 /* 12458 * Currently: 12459 * r0 holds resolved field 12460 * r9 holds object 12461 */ 12462.LOP_IPUT_WIDE_VOLATILE_finish: 12463 mov r2, rINST, lsr #8 @ r2<- A+ 12464 cmp r9, #0 @ check object for null 12465 and r2, r2, #15 @ r2<- A 12466 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12467 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 12468 beq common_errNullObject @ object was null 12469 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 12470 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 12471 GET_INST_OPCODE(r10) @ extract opcode from rINST 12472 .if 1 12473 add r2, r9, r3 @ r2<- target address 12474 bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2 12475 .else 12476 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 12477 .endif 12478 GOTO_OPCODE(r10) @ jump to next instruction 12479 12480/* continuation for OP_SGET_WIDE_VOLATILE */ 12481 12482 /* 12483 * Continuation if the field has not yet been resolved. 12484 * r1: BBBB field ref 12485 * 12486 * Returns StaticField pointer in r0. 12487 */ 12488.LOP_SGET_WIDE_VOLATILE_resolve: 12489 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12490 EXPORT_PC() @ resolve() could throw, so export now 12491 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12492 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12493 cmp r0, #0 @ success? 12494 bne .LOP_SGET_WIDE_VOLATILE_finish @ yes, finish 12495 b common_exceptionThrown @ no, handle exception 12496 12497/* continuation for OP_SPUT_WIDE_VOLATILE */ 12498 12499 /* 12500 * Continuation if the field has not yet been resolved. 12501 * r1: BBBB field ref 12502 * r9: &fp[AA] 12503 * 12504 * Returns StaticField pointer in r2. 12505 */ 12506.LOP_SPUT_WIDE_VOLATILE_resolve: 12507 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12508 EXPORT_PC() @ resolve() could throw, so export now 12509 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12510 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12511 cmp r0, #0 @ success? 12512 mov r2, r0 @ copy to r2 12513 bne .LOP_SPUT_WIDE_VOLATILE_finish @ yes, finish 12514 b common_exceptionThrown @ no, handle exception 12515 12516/* continuation for OP_EXECUTE_INLINE */ 12517 12518 /* 12519 * Extract args, call function. 12520 * r0 = #of args (0-4) 12521 * r10 = call index 12522 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 12523 * 12524 * Other ideas: 12525 * - Use a jump table from the main piece to jump directly into the 12526 * AND/LDR pairs. Costs a data load, saves a branch. 12527 * - Have five separate pieces that do the loading, so we can work the 12528 * interleave a little better. Increases code size. 12529 */ 12530.LOP_EXECUTE_INLINE_continue: 12531 rsb r0, r0, #4 @ r0<- 4-r0 12532 FETCH(r9, 2) @ r9<- FEDC 12533 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 12534 bl common_abort @ (skipped due to ARM prefetch) 125354: and ip, r9, #0xf000 @ isolate F 12536 ldr r3, [rFP, ip, lsr #10] @ r3<- vF (shift right 12, left 2) 125373: and ip, r9, #0x0f00 @ isolate E 12538 ldr r2, [rFP, ip, lsr #6] @ r2<- vE 125392: and ip, r9, #0x00f0 @ isolate D 12540 ldr r1, [rFP, ip, lsr #2] @ r1<- vD 125411: and ip, r9, #0x000f @ isolate C 12542 ldr r0, [rFP, ip, lsl #2] @ r0<- vC 125430: 12544 ldr r9, .LOP_EXECUTE_INLINE_table @ table of InlineOperation 12545 ldr pc, [r9, r10, lsl #4] @ sizeof=16, "func" is first entry 12546 @ (not reached) 12547 12548.LOP_EXECUTE_INLINE_table: 12549 .word gDvmInlineOpsTable 12550 12551/* continuation for OP_EXECUTE_INLINE_RANGE */ 12552 12553 /* 12554 * Extract args, call function. 12555 * r0 = #of args (0-4) 12556 * r10 = call index 12557 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 12558 */ 12559.LOP_EXECUTE_INLINE_RANGE_continue: 12560 rsb r0, r0, #4 @ r0<- 4-r0 12561 FETCH(r9, 2) @ r9<- CCCC 12562 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 12563 bl common_abort @ (skipped due to ARM prefetch) 125644: add ip, r9, #3 @ base+3 12565 GET_VREG(r3, ip) @ r3<- vBase[3] 125663: add ip, r9, #2 @ base+2 12567 GET_VREG(r2, ip) @ r2<- vBase[2] 125682: add ip, r9, #1 @ base+1 12569 GET_VREG(r1, ip) @ r1<- vBase[1] 125701: add ip, r9, #0 @ (nop) 12571 GET_VREG(r0, ip) @ r0<- vBase[0] 125720: 12573 ldr r9, .LOP_EXECUTE_INLINE_RANGE_table @ table of InlineOperation 12574 ldr pc, [r9, r10, lsl #4] @ sizeof=16, "func" is first entry 12575 @ (not reached) 12576 12577.LOP_EXECUTE_INLINE_RANGE_table: 12578 .word gDvmInlineOpsTable 12579 12580/* continuation for OP_IPUT_OBJECT_VOLATILE */ 12581 12582 /* 12583 * Currently: 12584 * r0 holds resolved field 12585 * r9 holds object 12586 */ 12587.LOP_IPUT_OBJECT_VOLATILE_finish: 12588 @bl common_squeak0 12589 mov r1, rINST, lsr #8 @ r1<- A+ 12590 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12591 and r1, r1, #15 @ r1<- A 12592 cmp r9, #0 @ check object for null 12593 GET_VREG(r0, r1) @ r0<- fp[A] 12594 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 12595 beq common_errNullObject @ object was null 12596 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 12597 GET_INST_OPCODE(ip) @ extract opcode from rINST 12598 SMP_DMB @ releasing store 12599 str r0, [r9, r3] @ obj.field (32 bits)<- r0 12600 cmp r0, #0 @ stored a null reference? 12601 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 12602 GOTO_OPCODE(ip) @ jump to next instruction 12603 12604/* continuation for OP_SGET_OBJECT_VOLATILE */ 12605 12606 /* 12607 * Continuation if the field has not yet been resolved. 12608 * r1: BBBB field ref 12609 */ 12610.LOP_SGET_OBJECT_VOLATILE_resolve: 12611 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12612 EXPORT_PC() @ resolve() could throw, so export now 12613 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12614 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12615 cmp r0, #0 @ success? 12616 bne .LOP_SGET_OBJECT_VOLATILE_finish @ yes, finish 12617 b common_exceptionThrown @ no, handle exception 12618 12619/* continuation for OP_SPUT_OBJECT_VOLATILE */ 12620.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0 12621 mov r2, rINST, lsr #8 @ r2<- AA 12622 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 12623 GET_VREG(r1, r2) @ r1<- fp[AA] 12624 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 12625 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 12626 GET_INST_OPCODE(ip) @ extract opcode from rINST 12627 SMP_DMB @ releasing store 12628 str r1, [r0, #offStaticField_value] @ field<- vAA 12629 cmp r1, #0 @ stored a null object? 12630 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 12631 GOTO_OPCODE(ip) @ jump to next instruction 12632 12633/* continuation for OP_CONST_CLASS_JUMBO */ 12634 12635 /* 12636 * Continuation if the Class has not yet been resolved. 12637 * r1: AAAAAAAA (Class ref) 12638 * r9: target register 12639 */ 12640.LOP_CONST_CLASS_JUMBO_resolve: 12641 EXPORT_PC() 12642 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 12643 mov r2, #1 @ r2<- true 12644 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 12645 bl dvmResolveClass @ r0<- Class reference 12646 cmp r0, #0 @ failed? 12647 beq common_exceptionThrown @ yup, handle the exception 12648 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 12649 GET_INST_OPCODE(ip) @ extract opcode from rINST 12650 SET_VREG(r0, r9) @ vBBBB<- r0 12651 GOTO_OPCODE(ip) @ jump to next instruction 12652 12653/* continuation for OP_CHECK_CAST_JUMBO */ 12654 12655 /* 12656 * Trivial test failed, need to perform full check. This is common. 12657 * r0 holds obj->clazz 12658 * r1 holds desired class resolved from AAAAAAAA 12659 * r9 holds object 12660 */ 12661.LOP_CHECK_CAST_JUMBO_fullcheck: 12662 mov r10, r1 @ avoid ClassObject getting clobbered 12663 bl dvmInstanceofNonTrivial @ r0<- boolean result 12664 cmp r0, #0 @ failed? 12665 bne .LOP_CHECK_CAST_JUMBO_okay @ no, success 12666 12667 @ A cast has failed. We need to throw a ClassCastException. 12668 EXPORT_PC() @ about to throw 12669 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class) 12670 mov r1, r10 @ r1<- desired class 12671 bl dvmThrowClassCastException 12672 b common_exceptionThrown 12673 12674 /* 12675 * Advance PC and get the next opcode. 12676 */ 12677.LOP_CHECK_CAST_JUMBO_okay: 12678 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 12679 GET_INST_OPCODE(ip) @ extract opcode from rINST 12680 GOTO_OPCODE(ip) @ jump to next instruction 12681 12682 /* 12683 * Resolution required. This is the least-likely path. 12684 * 12685 * r2 holds AAAAAAAA 12686 * r9 holds object 12687 */ 12688.LOP_CHECK_CAST_JUMBO_resolve: 12689 EXPORT_PC() @ resolve() could throw 12690 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 12691 mov r1, r2 @ r1<- AAAAAAAA 12692 mov r2, #0 @ r2<- false 12693 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 12694 bl dvmResolveClass @ r0<- resolved ClassObject ptr 12695 cmp r0, #0 @ got null? 12696 beq common_exceptionThrown @ yes, handle exception 12697 mov r1, r0 @ r1<- class resolved from AAAAAAAA 12698 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 12699 b .LOP_CHECK_CAST_JUMBO_resolved @ pick up where we left off 12700 12701/* continuation for OP_INSTANCE_OF_JUMBO */ 12702 12703 /* 12704 * Class resolved, determine type of check necessary. This is common. 12705 * r0 holds obj->clazz 12706 * r1 holds class resolved from AAAAAAAA 12707 * r9 holds BBBB 12708 */ 12709.LOP_INSTANCE_OF_JUMBO_resolved: 12710 cmp r0, r1 @ same class (trivial success)? 12711 beq .LOP_INSTANCE_OF_JUMBO_trivial @ yes, trivial finish 12712 @ fall through to OP_INSTANCE_OF_JUMBO_fullcheck 12713 12714 /* 12715 * Trivial test failed, need to perform full check. This is common. 12716 * r0 holds obj->clazz 12717 * r1 holds class resolved from AAAAAAAA 12718 * r9 holds BBBB 12719 */ 12720.LOP_INSTANCE_OF_JUMBO_fullcheck: 12721 bl dvmInstanceofNonTrivial @ r0<- boolean result 12722 @ fall through to OP_INSTANCE_OF_JUMBO_store 12723 12724 /* 12725 * r0 holds boolean result 12726 * r9 holds BBBB 12727 */ 12728.LOP_INSTANCE_OF_JUMBO_store: 12729 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12730 SET_VREG(r0, r9) @ vBBBB<- r0 12731 GET_INST_OPCODE(ip) @ extract opcode from rINST 12732 GOTO_OPCODE(ip) @ jump to next instruction 12733 12734 /* 12735 * Trivial test succeeded, save and bail. 12736 * r9 holds BBBB 12737 */ 12738.LOP_INSTANCE_OF_JUMBO_trivial: 12739 mov r0, #1 @ indicate success 12740 @ could b OP_INSTANCE_OF_JUMBO_store, but copying is faster and cheaper 12741 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12742 SET_VREG(r0, r9) @ vBBBB<- r0 12743 GET_INST_OPCODE(ip) @ extract opcode from rINST 12744 GOTO_OPCODE(ip) @ jump to next instruction 12745 12746 /* 12747 * Resolution required. This is the least-likely path. 12748 * 12749 * r3 holds AAAAAAAA 12750 * r9 holds BBBB 12751 */ 12752 12753.LOP_INSTANCE_OF_JUMBO_resolve: 12754 EXPORT_PC() @ resolve() could throw 12755 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 12756 mov r1, r3 @ r1<- AAAAAAAA 12757 mov r2, #1 @ r2<- true 12758 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 12759 bl dvmResolveClass @ r0<- resolved ClassObject ptr 12760 cmp r0, #0 @ got null? 12761 beq common_exceptionThrown @ yes, handle exception 12762 FETCH(r3, 4) @ r3<- vCCCC 12763 mov r1, r0 @ r1<- class resolved from AAAAAAAA 12764 GET_VREG(r0, r3) @ r0<- vCCCC (object) 12765 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 12766 b .LOP_INSTANCE_OF_JUMBO_resolved @ pick up where we left off 12767 12768/* continuation for OP_NEW_INSTANCE_JUMBO */ 12769 12770 .balign 32 @ minimize cache lines 12771.LOP_NEW_INSTANCE_JUMBO_finish: @ r0=new object 12772 FETCH(r3, 3) @ r3<- BBBB 12773 cmp r0, #0 @ failed? 12774 beq common_exceptionThrown @ yes, handle the exception 12775 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 12776 GET_INST_OPCODE(ip) @ extract opcode from rINST 12777 SET_VREG(r0, r3) @ vBBBB<- r0 12778 GOTO_OPCODE(ip) @ jump to next instruction 12779 12780 /* 12781 * Class initialization required. 12782 * 12783 * r0 holds class object 12784 */ 12785.LOP_NEW_INSTANCE_JUMBO_needinit: 12786 mov r9, r0 @ save r0 12787 bl dvmInitClass @ initialize class 12788 cmp r0, #0 @ check boolean result 12789 mov r0, r9 @ restore r0 12790 bne .LOP_NEW_INSTANCE_JUMBO_initialized @ success, continue 12791 b common_exceptionThrown @ failed, deal with init exception 12792 12793 /* 12794 * Resolution required. This is the least-likely path. 12795 * 12796 * r1 holds AAAAAAAA 12797 */ 12798.LOP_NEW_INSTANCE_JUMBO_resolve: 12799 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 12800 mov r2, #0 @ r2<- false 12801 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 12802 bl dvmResolveClass @ r0<- resolved ClassObject ptr 12803 cmp r0, #0 @ got null? 12804 bne .LOP_NEW_INSTANCE_JUMBO_resolved @ no, continue 12805 b common_exceptionThrown @ yes, handle exception 12806 12807/* continuation for OP_NEW_ARRAY_JUMBO */ 12808 12809 12810 /* 12811 * Resolve class. (This is an uncommon case.) 12812 * 12813 * r1 holds array length 12814 * r2 holds class ref AAAAAAAA 12815 */ 12816.LOP_NEW_ARRAY_JUMBO_resolve: 12817 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 12818 mov r9, r1 @ r9<- length (save) 12819 mov r1, r2 @ r1<- AAAAAAAA 12820 mov r2, #0 @ r2<- false 12821 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 12822 bl dvmResolveClass @ r0<- call(clazz, ref) 12823 cmp r0, #0 @ got null? 12824 mov r1, r9 @ r1<- length (restore) 12825 beq common_exceptionThrown @ yes, handle exception 12826 @ fall through to OP_NEW_ARRAY_JUMBO_finish 12827 12828 /* 12829 * Finish allocation. 12830 * 12831 * r0 holds class 12832 * r1 holds array length 12833 */ 12834.LOP_NEW_ARRAY_JUMBO_finish: 12835 mov r2, #ALLOC_DONT_TRACK @ don't track in local refs table 12836 bl dvmAllocArrayByClass @ r0<- call(clazz, length, flags) 12837 cmp r0, #0 @ failed? 12838 FETCH(r2, 3) @ r2<- vBBBB 12839 beq common_exceptionThrown @ yes, handle the exception 12840 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12841 GET_INST_OPCODE(ip) @ extract opcode from rINST 12842 SET_VREG(r0, r2) @ vBBBB<- r0 12843 GOTO_OPCODE(ip) @ jump to next instruction 12844 12845/* continuation for OP_FILLED_NEW_ARRAY_JUMBO */ 12846 12847 /* 12848 * On entry: 12849 * r0 holds array class 12850 */ 12851.LOP_FILLED_NEW_ARRAY_JUMBO_continue: 12852 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 12853 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 12854 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 12855 FETCH(r1, 3) @ r1<- BBBB (length) 12856 cmp rINST, #'I' @ array of ints? 12857 cmpne rINST, #'L' @ array of objects? 12858 cmpne rINST, #'[' @ array of arrays? 12859 mov r9, r1 @ save length in r9 12860 bne .LOP_FILLED_NEW_ARRAY_JUMBO_notimpl @ no, not handled yet 12861 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 12862 cmp r0, #0 @ null return? 12863 beq common_exceptionThrown @ alloc failed, handle exception 12864 12865 FETCH(r1, 4) @ r1<- CCCC 12866 str r0, [rGLUE, #offGlue_retval] @ retval.l <- new array 12867 str rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type 12868 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 12869 subs r9, r9, #1 @ length--, check for neg 12870 FETCH_ADVANCE_INST(5) @ advance to next instr, load rINST 12871 bmi 2f @ was zero, bail 12872 12873 @ copy values from registers into the array 12874 @ r0=array, r1=CCCC, r9=BBBB (length) 12875 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 128761: ldr r3, [r2], #4 @ r3<- *r2++ 12877 subs r9, r9, #1 @ count-- 12878 str r3, [r0], #4 @ *contents++ = vX 12879 bpl 1b 12880 128812: ldr r0, [rGLUE, #offGlue_retval] @ r0<- object 12882 ldr r1, [rGLUE, #offGlue_retval+4] @ r1<- type 12883 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 12884 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 12885 cmp r1, #'I' @ Is int array? 12886 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 12887 GOTO_OPCODE(ip) @ execute it 12888 12889 /* 12890 * Throw an exception indicating that we have not implemented this 12891 * mode of filled-new-array. 12892 */ 12893.LOP_FILLED_NEW_ARRAY_JUMBO_notimpl: 12894 ldr r0, .L_strInternalError 12895 ldr r1, .L_strFilledNewArrayNotImpl 12896 bl dvmThrowException 12897 b common_exceptionThrown 12898 12899/* continuation for OP_IGET_JUMBO */ 12900 12901 /* 12902 * Currently: 12903 * r0 holds resolved field 12904 * r9 holds object 12905 */ 12906.LOP_IGET_JUMBO_resolved: 12907 cmp r0, #0 @ resolution unsuccessful? 12908 beq common_exceptionThrown @ yes, throw exception 12909 @ fall through to OP_IGET_JUMBO_finish 12910 12911 /* 12912 * Currently: 12913 * r0 holds resolved field 12914 * r9 holds object 12915 */ 12916.LOP_IGET_JUMBO_finish: 12917 @bl common_squeak0 12918 cmp r9, #0 @ check object for null 12919 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12920 beq common_errNullObject @ object was null 12921 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12922 @ no-op @ acquiring load 12923 FETCH(r2, 3) @ r2<- BBBB 12924 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12925 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12926 GET_INST_OPCODE(ip) @ extract opcode from rINST 12927 GOTO_OPCODE(ip) @ jump to next instruction 12928 12929/* continuation for OP_IGET_WIDE_JUMBO */ 12930 12931 /* 12932 * Currently: 12933 * r0 holds resolved field 12934 * r9 holds object 12935 */ 12936.LOP_IGET_WIDE_JUMBO_resolved: 12937 cmp r0, #0 @ resolution unsuccessful? 12938 beq common_exceptionThrown @ yes, throw exception 12939 @ fall through to OP_IGET_WIDE_JUMBO_finish 12940 12941 /* 12942 * Currently: 12943 * r0 holds resolved field 12944 * r9 holds object 12945 */ 12946.LOP_IGET_WIDE_JUMBO_finish: 12947 cmp r9, #0 @ check object for null 12948 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12949 beq common_errNullObject @ object was null 12950 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 12951 FETCH(r2, 3) @ r2<- BBBB 12952 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12953 add r3, rFP, r2, lsl #2 @ r3<- &fp[BBBB] 12954 GET_INST_OPCODE(ip) @ extract opcode from rINST 12955 stmia r3, {r0-r1} @ fp[BBBB]<- r0/r1 12956 GOTO_OPCODE(ip) @ jump to next instruction 12957 12958/* continuation for OP_IGET_OBJECT_JUMBO */ 12959 12960 /* 12961 * Currently: 12962 * r0 holds resolved field 12963 * r9 holds object 12964 */ 12965.LOP_IGET_OBJECT_JUMBO_resolved: 12966 cmp r0, #0 @ resolution unsuccessful? 12967 beq common_exceptionThrown @ yes, throw exception 12968 @ fall through to OP_IGET_OBJECT_JUMBO_finish 12969 12970 /* 12971 * Currently: 12972 * r0 holds resolved field 12973 * r9 holds object 12974 */ 12975.LOP_IGET_OBJECT_JUMBO_finish: 12976 @bl common_squeak0 12977 cmp r9, #0 @ check object for null 12978 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12979 beq common_errNullObject @ object was null 12980 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12981 @ no-op @ acquiring load 12982 FETCH(r2, 3) @ r2<- BBBB 12983 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12984 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12985 GET_INST_OPCODE(ip) @ extract opcode from rINST 12986 GOTO_OPCODE(ip) @ jump to next instruction 12987 12988/* continuation for OP_IGET_BOOLEAN_JUMBO */ 12989 12990 /* 12991 * Currently: 12992 * r0 holds resolved field 12993 * r9 holds object 12994 */ 12995.LOP_IGET_BOOLEAN_JUMBO_resolved: 12996 cmp r0, #0 @ resolution unsuccessful? 12997 beq common_exceptionThrown @ yes, throw exception 12998 @ fall through to OP_IGET_BOOLEAN_JUMBO_finish 12999 13000 /* 13001 * Currently: 13002 * r0 holds resolved field 13003 * r9 holds object 13004 */ 13005.LOP_IGET_BOOLEAN_JUMBO_finish: 13006 @bl common_squeak1 13007 cmp r9, #0 @ check object for null 13008 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 13009 beq common_errNullObject @ object was null 13010 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 13011 @ no-op @ acquiring load 13012 FETCH(r2, 3) @ r2<- BBBB 13013 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 13014 SET_VREG(r0, r2) @ fp[BBBB]<- r0 13015 GET_INST_OPCODE(ip) @ extract opcode from rINST 13016 GOTO_OPCODE(ip) @ jump to next instruction 13017 13018/* continuation for OP_IGET_BYTE_JUMBO */ 13019 13020 /* 13021 * Currently: 13022 * r0 holds resolved field 13023 * r9 holds object 13024 */ 13025.LOP_IGET_BYTE_JUMBO_resolved: 13026 cmp r0, #0 @ resolution unsuccessful? 13027 beq common_exceptionThrown @ yes, throw exception 13028 @ fall through to OP_IGET_BYTE_JUMBO_finish 13029 13030 /* 13031 * Currently: 13032 * r0 holds resolved field 13033 * r9 holds object 13034 */ 13035.LOP_IGET_BYTE_JUMBO_finish: 13036 @bl common_squeak2 13037 cmp r9, #0 @ check object for null 13038 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 13039 beq common_errNullObject @ object was null 13040 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 13041 @ no-op @ acquiring load 13042 FETCH(r2, 3) @ r2<- BBBB 13043 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 13044 SET_VREG(r0, r2) @ fp[BBBB]<- r0 13045 GET_INST_OPCODE(ip) @ extract opcode from rINST 13046 GOTO_OPCODE(ip) @ jump to next instruction 13047 13048/* continuation for OP_IGET_CHAR_JUMBO */ 13049 13050 /* 13051 * Currently: 13052 * r0 holds resolved field 13053 * r9 holds object 13054 */ 13055.LOP_IGET_CHAR_JUMBO_resolved: 13056 cmp r0, #0 @ resolution unsuccessful? 13057 beq common_exceptionThrown @ yes, throw exception 13058 @ fall through to OP_IGET_CHAR_JUMBO_finish 13059 13060 /* 13061 * Currently: 13062 * r0 holds resolved field 13063 * r9 holds object 13064 */ 13065.LOP_IGET_CHAR_JUMBO_finish: 13066 @bl common_squeak3 13067 cmp r9, #0 @ check object for null 13068 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 13069 beq common_errNullObject @ object was null 13070 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 13071 @ no-op @ acquiring load 13072 FETCH(r2, 3) @ r2<- BBBB 13073 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 13074 SET_VREG(r0, r2) @ fp[BBBB]<- r0 13075 GET_INST_OPCODE(ip) @ extract opcode from rINST 13076 GOTO_OPCODE(ip) @ jump to next instruction 13077 13078/* continuation for OP_IGET_SHORT_JUMBO */ 13079 13080 /* 13081 * Currently: 13082 * r0 holds resolved field 13083 * r9 holds object 13084 */ 13085.LOP_IGET_SHORT_JUMBO_resolved: 13086 cmp r0, #0 @ resolution unsuccessful? 13087 beq common_exceptionThrown @ yes, throw exception 13088 @ fall through to OP_IGET_SHORT_JUMBO_finish 13089 13090 /* 13091 * Currently: 13092 * r0 holds resolved field 13093 * r9 holds object 13094 */ 13095.LOP_IGET_SHORT_JUMBO_finish: 13096 @bl common_squeak4 13097 cmp r9, #0 @ check object for null 13098 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 13099 beq common_errNullObject @ object was null 13100 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 13101 @ no-op @ acquiring load 13102 FETCH(r2, 3) @ r2<- BBBB 13103 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 13104 SET_VREG(r0, r2) @ fp[BBBB]<- r0 13105 GET_INST_OPCODE(ip) @ extract opcode from rINST 13106 GOTO_OPCODE(ip) @ jump to next instruction 13107 13108/* continuation for OP_IPUT_JUMBO */ 13109 13110 /* 13111 * Currently: 13112 * r0 holds resolved field 13113 * r9 holds object 13114 */ 13115.LOP_IPUT_JUMBO_resolved: 13116 cmp r0, #0 @ resolution unsuccessful? 13117 beq common_exceptionThrown @ yes, throw exception 13118 @ fall through to OP_IPUT_JUMBO_finish 13119 13120 /* 13121 * Currently: 13122 * r0 holds resolved field 13123 * r9 holds object 13124 */ 13125.LOP_IPUT_JUMBO_finish: 13126 @bl common_squeak0 13127 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 13128 FETCH(r1, 3) @ r1<- BBBB 13129 cmp r9, #0 @ check object for null 13130 GET_VREG(r0, r1) @ r0<- fp[BBBB] 13131 beq common_errNullObject @ object was null 13132 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 13133 GET_INST_OPCODE(ip) @ extract opcode from rINST 13134 @ no-op @ releasing store 13135 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 13136 GOTO_OPCODE(ip) @ jump to next instruction 13137 13138/* continuation for OP_IPUT_WIDE_JUMBO */ 13139 13140 /* 13141 * Currently: 13142 * r0 holds resolved field 13143 * r9 holds object 13144 */ 13145.LOP_IPUT_WIDE_JUMBO_resolved: 13146 cmp r0, #0 @ resolution unsuccessful? 13147 beq common_exceptionThrown @ yes, throw exception 13148 @ fall through to OP_IPUT_WIDE_JUMBO_finish 13149 13150 /* 13151 * Currently: 13152 * r0 holds resolved field 13153 * r9 holds object 13154 */ 13155.LOP_IPUT_WIDE_JUMBO_finish: 13156 cmp r9, #0 @ check object for null 13157 FETCH(r2, 3) @ r1<- BBBB 13158 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 13159 add r2, rFP, r2, lsl #2 @ r3<- &fp[BBBB] 13160 beq common_errNullObject @ object was null 13161 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 13162 ldmia r2, {r0-r1} @ r0/r1<- fp[BBBB] 13163 GET_INST_OPCODE(r10) @ extract opcode from rINST 13164 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 13165 GOTO_OPCODE(r10) @ jump to next instruction 13166 13167/* continuation for OP_IPUT_OBJECT_JUMBO */ 13168 13169 /* 13170 * Currently: 13171 * r0 holds resolved field 13172 * r9 holds object 13173 */ 13174.LOP_IPUT_OBJECT_JUMBO_resolved: 13175 cmp r0, #0 @ resolution unsuccessful? 13176 beq common_exceptionThrown @ yes, throw exception 13177 @ fall through to OP_IPUT_OBJECT_JUMBO_finish 13178 13179 /* 13180 * Currently: 13181 * r0 holds resolved field 13182 * r9 holds object 13183 */ 13184.LOP_IPUT_OBJECT_JUMBO_finish: 13185 @bl common_squeak0 13186 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 13187 FETCH(r1, 3) @ r1<- BBBB 13188 cmp r9, #0 @ check object for null 13189 GET_VREG(r0, r1) @ r0<- fp[BBBB] 13190 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 13191 beq common_errNullObject @ object was null 13192 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 13193 GET_INST_OPCODE(ip) @ extract opcode from rINST 13194 @ no-op @ releasing store 13195 str r0, [r9, r3] @ obj.field (32 bits)<- r0 13196 cmp r0, #0 @ stored a null reference? 13197 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 13198 GOTO_OPCODE(ip) @ jump to next instruction 13199 13200/* continuation for OP_IPUT_BOOLEAN_JUMBO */ 13201 13202 /* 13203 * Currently: 13204 * r0 holds resolved field 13205 * r9 holds object 13206 */ 13207.LOP_IPUT_BOOLEAN_JUMBO_resolved: 13208 cmp r0, #0 @ resolution unsuccessful? 13209 beq common_exceptionThrown @ yes, throw exception 13210 @ fall through to OP_IPUT_BOOLEAN_JUMBO_finish 13211 13212 /* 13213 * Currently: 13214 * r0 holds resolved field 13215 * r9 holds object 13216 */ 13217.LOP_IPUT_BOOLEAN_JUMBO_finish: 13218 @bl common_squeak1 13219 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 13220 FETCH(r1, 3) @ r1<- BBBB 13221 cmp r9, #0 @ check object for null 13222 GET_VREG(r0, r1) @ r0<- fp[BBBB] 13223 beq common_errNullObject @ object was null 13224 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 13225 GET_INST_OPCODE(ip) @ extract opcode from rINST 13226 @ no-op @ releasing store 13227 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 13228 GOTO_OPCODE(ip) @ jump to next instruction 13229 13230/* continuation for OP_IPUT_BYTE_JUMBO */ 13231 13232 /* 13233 * Currently: 13234 * r0 holds resolved field 13235 * r9 holds object 13236 */ 13237.LOP_IPUT_BYTE_JUMBO_resolved: 13238 cmp r0, #0 @ resolution unsuccessful? 13239 beq common_exceptionThrown @ yes, throw exception 13240 @ fall through to OP_IPUT_BYTE_JUMBO_finish 13241 13242 /* 13243 * Currently: 13244 * r0 holds resolved field 13245 * r9 holds object 13246 */ 13247.LOP_IPUT_BYTE_JUMBO_finish: 13248 @bl common_squeak2 13249 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 13250 FETCH(r1, 3) @ r1<- BBBB 13251 cmp r9, #0 @ check object for null 13252 GET_VREG(r0, r1) @ r0<- fp[BBBB] 13253 beq common_errNullObject @ object was null 13254 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 13255 GET_INST_OPCODE(ip) @ extract opcode from rINST 13256 @ no-op @ releasing store 13257 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 13258 GOTO_OPCODE(ip) @ jump to next instruction 13259 13260/* continuation for OP_IPUT_CHAR_JUMBO */ 13261 13262 /* 13263 * Currently: 13264 * r0 holds resolved field 13265 * r9 holds object 13266 */ 13267.LOP_IPUT_CHAR_JUMBO_resolved: 13268 cmp r0, #0 @ resolution unsuccessful? 13269 beq common_exceptionThrown @ yes, throw exception 13270 @ fall through to OP_IPUT_CHAR_JUMBO_finish 13271 13272 /* 13273 * Currently: 13274 * r0 holds resolved field 13275 * r9 holds object 13276 */ 13277.LOP_IPUT_CHAR_JUMBO_finish: 13278 @bl common_squeak3 13279 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 13280 FETCH(r1, 3) @ r1<- BBBB 13281 cmp r9, #0 @ check object for null 13282 GET_VREG(r0, r1) @ r0<- fp[BBBB] 13283 beq common_errNullObject @ object was null 13284 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 13285 GET_INST_OPCODE(ip) @ extract opcode from rINST 13286 @ no-op @ releasing store 13287 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 13288 GOTO_OPCODE(ip) @ jump to next instruction 13289 13290/* continuation for OP_IPUT_SHORT_JUMBO */ 13291 13292 /* 13293 * Currently: 13294 * r0 holds resolved field 13295 * r9 holds object 13296 */ 13297.LOP_IPUT_SHORT_JUMBO_resolved: 13298 cmp r0, #0 @ resolution unsuccessful? 13299 beq common_exceptionThrown @ yes, throw exception 13300 @ fall through to OP_IPUT_SHORT_JUMBO_finish 13301 13302 /* 13303 * Currently: 13304 * r0 holds resolved field 13305 * r9 holds object 13306 */ 13307.LOP_IPUT_SHORT_JUMBO_finish: 13308 @bl common_squeak4 13309 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 13310 FETCH(r1, 3) @ r1<- BBBB 13311 cmp r9, #0 @ check object for null 13312 GET_VREG(r0, r1) @ r0<- fp[BBBB] 13313 beq common_errNullObject @ object was null 13314 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 13315 GET_INST_OPCODE(ip) @ extract opcode from rINST 13316 @ no-op @ releasing store 13317 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 13318 GOTO_OPCODE(ip) @ jump to next instruction 13319 13320/* continuation for OP_SGET_JUMBO */ 13321 13322 /* 13323 * Continuation if the field has not yet been resolved. 13324 * r1: AAAAAAAA field ref 13325 */ 13326.LOP_SGET_JUMBO_resolve: 13327 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13328 EXPORT_PC() @ resolve() could throw, so export now 13329 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13330 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13331 cmp r0, #0 @ success? 13332 bne .LOP_SGET_JUMBO_finish @ yes, finish 13333 b common_exceptionThrown @ no, handle exception 13334 13335/* continuation for OP_SGET_WIDE_JUMBO */ 13336 13337 /* 13338 * Continuation if the field has not yet been resolved. 13339 * r1: BBBB field ref 13340 * 13341 * Returns StaticField pointer in r0. 13342 */ 13343.LOP_SGET_WIDE_JUMBO_resolve: 13344 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13345 EXPORT_PC() @ resolve() could throw, so export now 13346 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13347 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13348 cmp r0, #0 @ success? 13349 bne .LOP_SGET_WIDE_JUMBO_finish @ yes, finish 13350 b common_exceptionThrown @ no, handle exception 13351 13352/* continuation for OP_SGET_OBJECT_JUMBO */ 13353 13354 /* 13355 * Continuation if the field has not yet been resolved. 13356 * r1: AAAAAAAA field ref 13357 */ 13358.LOP_SGET_OBJECT_JUMBO_resolve: 13359 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13360 EXPORT_PC() @ resolve() could throw, so export now 13361 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13362 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13363 cmp r0, #0 @ success? 13364 bne .LOP_SGET_OBJECT_JUMBO_finish @ yes, finish 13365 b common_exceptionThrown @ no, handle exception 13366 13367/* continuation for OP_SGET_BOOLEAN_JUMBO */ 13368 13369 /* 13370 * Continuation if the field has not yet been resolved. 13371 * r1: AAAAAAAA field ref 13372 */ 13373.LOP_SGET_BOOLEAN_JUMBO_resolve: 13374 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13375 EXPORT_PC() @ resolve() could throw, so export now 13376 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13377 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13378 cmp r0, #0 @ success? 13379 bne .LOP_SGET_BOOLEAN_JUMBO_finish @ yes, finish 13380 b common_exceptionThrown @ no, handle exception 13381 13382/* continuation for OP_SGET_BYTE_JUMBO */ 13383 13384 /* 13385 * Continuation if the field has not yet been resolved. 13386 * r1: AAAAAAAA field ref 13387 */ 13388.LOP_SGET_BYTE_JUMBO_resolve: 13389 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13390 EXPORT_PC() @ resolve() could throw, so export now 13391 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13392 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13393 cmp r0, #0 @ success? 13394 bne .LOP_SGET_BYTE_JUMBO_finish @ yes, finish 13395 b common_exceptionThrown @ no, handle exception 13396 13397/* continuation for OP_SGET_CHAR_JUMBO */ 13398 13399 /* 13400 * Continuation if the field has not yet been resolved. 13401 * r1: AAAAAAAA field ref 13402 */ 13403.LOP_SGET_CHAR_JUMBO_resolve: 13404 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13405 EXPORT_PC() @ resolve() could throw, so export now 13406 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13407 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13408 cmp r0, #0 @ success? 13409 bne .LOP_SGET_CHAR_JUMBO_finish @ yes, finish 13410 b common_exceptionThrown @ no, handle exception 13411 13412/* continuation for OP_SGET_SHORT_JUMBO */ 13413 13414 /* 13415 * Continuation if the field has not yet been resolved. 13416 * r1: AAAAAAAA field ref 13417 */ 13418.LOP_SGET_SHORT_JUMBO_resolve: 13419 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13420 EXPORT_PC() @ resolve() could throw, so export now 13421 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13422 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13423 cmp r0, #0 @ success? 13424 bne .LOP_SGET_SHORT_JUMBO_finish @ yes, finish 13425 b common_exceptionThrown @ no, handle exception 13426 13427/* continuation for OP_SPUT_JUMBO */ 13428 13429 /* 13430 * Continuation if the field has not yet been resolved. 13431 * r1: AAAAAAAA field ref 13432 */ 13433.LOP_SPUT_JUMBO_resolve: 13434 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13435 EXPORT_PC() @ resolve() could throw, so export now 13436 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13437 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13438 cmp r0, #0 @ success? 13439 bne .LOP_SPUT_JUMBO_finish @ yes, finish 13440 b common_exceptionThrown @ no, handle exception 13441 13442/* continuation for OP_SPUT_WIDE_JUMBO */ 13443 13444 /* 13445 * Continuation if the field has not yet been resolved. 13446 * r1: BBBB field ref 13447 * r9: &fp[AA] 13448 * 13449 * Returns StaticField pointer in r2. 13450 */ 13451.LOP_SPUT_WIDE_JUMBO_resolve: 13452 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13453 EXPORT_PC() @ resolve() could throw, so export now 13454 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13455 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13456 cmp r0, #0 @ success? 13457 mov r2, r0 @ copy to r2 13458 bne .LOP_SPUT_WIDE_JUMBO_finish @ yes, finish 13459 b common_exceptionThrown @ no, handle exception 13460 13461/* continuation for OP_SPUT_OBJECT_JUMBO */ 13462 13463.LOP_SPUT_OBJECT_JUMBO_finish: @ field ptr in r0 13464 FETCH(r2, 3) @ r2<- BBBB 13465 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 13466 GET_VREG(r1, r2) @ r1<- fp[BBBB] 13467 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 13468 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 13469 GET_INST_OPCODE(ip) @ extract opcode from rINST 13470 @ no-op @ releasing store 13471 str r1, [r0, #offStaticField_value] @ field<- vBBBB 13472 cmp r1, #0 @ stored a null object? 13473 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 13474 GOTO_OPCODE(ip) @ jump to next instruction 13475 13476/* continuation for OP_SPUT_BOOLEAN_JUMBO */ 13477 13478 /* 13479 * Continuation if the field has not yet been resolved. 13480 * r1: AAAAAAAA field ref 13481 */ 13482.LOP_SPUT_BOOLEAN_JUMBO_resolve: 13483 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13484 EXPORT_PC() @ resolve() could throw, so export now 13485 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13486 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13487 cmp r0, #0 @ success? 13488 bne .LOP_SPUT_BOOLEAN_JUMBO_finish @ yes, finish 13489 b common_exceptionThrown @ no, handle exception 13490 13491/* continuation for OP_SPUT_BYTE_JUMBO */ 13492 13493 /* 13494 * Continuation if the field has not yet been resolved. 13495 * r1: AAAAAAAA field ref 13496 */ 13497.LOP_SPUT_BYTE_JUMBO_resolve: 13498 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13499 EXPORT_PC() @ resolve() could throw, so export now 13500 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13501 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13502 cmp r0, #0 @ success? 13503 bne .LOP_SPUT_BYTE_JUMBO_finish @ yes, finish 13504 b common_exceptionThrown @ no, handle exception 13505 13506/* continuation for OP_SPUT_CHAR_JUMBO */ 13507 13508 /* 13509 * Continuation if the field has not yet been resolved. 13510 * r1: AAAAAAAA field ref 13511 */ 13512.LOP_SPUT_CHAR_JUMBO_resolve: 13513 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13514 EXPORT_PC() @ resolve() could throw, so export now 13515 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13516 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13517 cmp r0, #0 @ success? 13518 bne .LOP_SPUT_CHAR_JUMBO_finish @ yes, finish 13519 b common_exceptionThrown @ no, handle exception 13520 13521/* continuation for OP_SPUT_SHORT_JUMBO */ 13522 13523 /* 13524 * Continuation if the field has not yet been resolved. 13525 * r1: AAAAAAAA field ref 13526 */ 13527.LOP_SPUT_SHORT_JUMBO_resolve: 13528 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13529 EXPORT_PC() @ resolve() could throw, so export now 13530 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13531 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13532 cmp r0, #0 @ success? 13533 bne .LOP_SPUT_SHORT_JUMBO_finish @ yes, finish 13534 b common_exceptionThrown @ no, handle exception 13535 13536/* continuation for OP_INVOKE_VIRTUAL_JUMBO */ 13537 13538 /* 13539 * At this point: 13540 * r0 = resolved base method 13541 */ 13542.LOP_INVOKE_VIRTUAL_JUMBO_continue: 13543 FETCH(r10, 4) @ r10<- CCCC 13544 GET_VREG(r1, r10) @ r1<- "this" ptr 13545 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 13546 cmp r1, #0 @ is "this" null? 13547 beq common_errNullObject @ null "this", throw exception 13548 ldr r3, [r1, #offObject_clazz] @ r1<- thisPtr->clazz 13549 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 13550 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 13551 bl common_invokeMethodJumbo @ continue on 13552 13553/* continuation for OP_INVOKE_SUPER_JUMBO */ 13554 13555 /* 13556 * At this point: 13557 * r0 = resolved base method 13558 * r9 = method->clazz 13559 */ 13560.LOP_INVOKE_SUPER_JUMBO_continue: 13561 ldr r1, [r9, #offClassObject_super] @ r1<- method->clazz->super 13562 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 13563 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 13564 EXPORT_PC() @ must export for invoke 13565 cmp r2, r3 @ compare (methodIndex, vtableCount) 13566 bcs .LOP_INVOKE_SUPER_JUMBO_nsm @ method not present in superclass 13567 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 13568 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 13569 bl common_invokeMethodJumbo @ continue on 13570 13571.LOP_INVOKE_SUPER_JUMBO_resolve: 13572 mov r0, r9 @ r0<- method->clazz 13573 mov r2, #METHOD_VIRTUAL @ resolver method type 13574 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 13575 cmp r0, #0 @ got null? 13576 bne .LOP_INVOKE_SUPER_JUMBO_continue @ no, continue 13577 b common_exceptionThrown @ yes, handle exception 13578 13579 /* 13580 * Throw a NoSuchMethodError with the method name as the message. 13581 * r0 = resolved base method 13582 */ 13583.LOP_INVOKE_SUPER_JUMBO_nsm: 13584 ldr r1, [r0, #offMethod_name] @ r1<- method name 13585 b common_errNoSuchMethod 13586 13587/* continuation for OP_INVOKE_DIRECT_JUMBO */ 13588 13589 /* 13590 * On entry: 13591 * r1 = reference (CCCC) 13592 * r10 = "this" register 13593 */ 13594.LOP_INVOKE_DIRECT_JUMBO_resolve: 13595 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 13596 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 13597 mov r2, #METHOD_DIRECT @ resolver method type 13598 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 13599 cmp r0, #0 @ got null? 13600 GET_VREG(r2, r10) @ r2<- "this" ptr (reload) 13601 bne .LOP_INVOKE_DIRECT_JUMBO_finish @ no, continue 13602 b common_exceptionThrown @ yes, handle exception 13603 13604 .size dvmAsmSisterStart, .-dvmAsmSisterStart 13605 .global dvmAsmSisterEnd 13606dvmAsmSisterEnd: 13607 13608/* File: armv5te/footer.S */ 13609 13610/* 13611 * =========================================================================== 13612 * Common subroutines and data 13613 * =========================================================================== 13614 */ 13615 13616 13617 13618 .text 13619 .align 2 13620 13621#if defined(WITH_JIT) 13622#if defined(WITH_SELF_VERIFICATION) 13623 .global dvmJitToInterpPunt 13624dvmJitToInterpPunt: 13625 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13626 mov r2,#kSVSPunt @ r2<- interpreter entry point 13627 mov r3, #0 13628 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13629 b jitSVShadowRunEnd @ doesn't return 13630 13631 .global dvmJitToInterpSingleStep 13632dvmJitToInterpSingleStep: 13633 str lr,[rGLUE,#offGlue_jitResumeNPC] 13634 str r1,[rGLUE,#offGlue_jitResumeDPC] 13635 mov r2,#kSVSSingleStep @ r2<- interpreter entry point 13636 b jitSVShadowRunEnd @ doesn't return 13637 13638 .global dvmJitToInterpNoChainNoProfile 13639dvmJitToInterpNoChainNoProfile: 13640 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13641 mov r0,rPC @ pass our target PC 13642 mov r2,#kSVSNoProfile @ r2<- interpreter entry point 13643 mov r3, #0 @ 0 means !inJitCodeCache 13644 str r3, [r10, #offThread_inJitCodeCache] @ back to the interp land 13645 b jitSVShadowRunEnd @ doesn't return 13646 13647 .global dvmJitToInterpTraceSelectNoChain 13648dvmJitToInterpTraceSelectNoChain: 13649 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13650 mov r0,rPC @ pass our target PC 13651 mov r2,#kSVSTraceSelect @ r2<- interpreter entry point 13652 mov r3, #0 @ 0 means !inJitCodeCache 13653 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13654 b jitSVShadowRunEnd @ doesn't return 13655 13656 .global dvmJitToInterpTraceSelect 13657dvmJitToInterpTraceSelect: 13658 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13659 ldr r0,[lr, #-1] @ pass our target PC 13660 mov r2,#kSVSTraceSelect @ r2<- interpreter entry point 13661 mov r3, #0 @ 0 means !inJitCodeCache 13662 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13663 b jitSVShadowRunEnd @ doesn't return 13664 13665 .global dvmJitToInterpBackwardBranch 13666dvmJitToInterpBackwardBranch: 13667 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13668 ldr r0,[lr, #-1] @ pass our target PC 13669 mov r2,#kSVSBackwardBranch @ r2<- interpreter entry point 13670 mov r3, #0 @ 0 means !inJitCodeCache 13671 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13672 b jitSVShadowRunEnd @ doesn't return 13673 13674 .global dvmJitToInterpNormal 13675dvmJitToInterpNormal: 13676 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13677 ldr r0,[lr, #-1] @ pass our target PC 13678 mov r2,#kSVSNormal @ r2<- interpreter entry point 13679 mov r3, #0 @ 0 means !inJitCodeCache 13680 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13681 b jitSVShadowRunEnd @ doesn't return 13682 13683 .global dvmJitToInterpNoChain 13684dvmJitToInterpNoChain: 13685 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13686 mov r0,rPC @ pass our target PC 13687 mov r2,#kSVSNoChain @ r2<- interpreter entry point 13688 mov r3, #0 @ 0 means !inJitCodeCache 13689 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13690 b jitSVShadowRunEnd @ doesn't return 13691#else 13692/* 13693 * Return from the translation cache to the interpreter when the compiler is 13694 * having issues translating/executing a Dalvik instruction. We have to skip 13695 * the code cache lookup otherwise it is possible to indefinitely bouce 13696 * between the interpreter and the code cache if the instruction that fails 13697 * to be compiled happens to be at a trace start. 13698 */ 13699 .global dvmJitToInterpPunt 13700dvmJitToInterpPunt: 13701 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13702 mov rPC, r0 13703#if defined(WITH_JIT_TUNING) 13704 mov r0,lr 13705 bl dvmBumpPunt; 13706#endif 13707 EXPORT_PC() 13708 mov r0, #0 13709 str r0, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13710 adrl rIBASE, dvmAsmInstructionStart 13711 FETCH_INST() 13712 GET_INST_OPCODE(ip) 13713 GOTO_OPCODE(ip) 13714 13715/* 13716 * Return to the interpreter to handle a single instruction. 13717 * On entry: 13718 * r0 <= PC 13719 * r1 <= PC of resume instruction 13720 * lr <= resume point in translation 13721 */ 13722 .global dvmJitToInterpSingleStep 13723dvmJitToInterpSingleStep: 13724 str lr,[rGLUE,#offGlue_jitResumeNPC] 13725 str r1,[rGLUE,#offGlue_jitResumeDPC] 13726 mov r1,#kInterpEntryInstr 13727 @ enum is 4 byte in aapcs-EABI 13728 str r1, [rGLUE, #offGlue_entryPoint] 13729 mov rPC,r0 13730 EXPORT_PC() 13731 13732 adrl rIBASE, dvmAsmInstructionStart 13733 mov r2,#kJitSingleStep @ Ask for single step and then revert 13734 str r2,[rGLUE,#offGlue_jitState] 13735 mov r1,#1 @ set changeInterp to bail to debug interp 13736 b common_gotoBail 13737 13738/* 13739 * Return from the translation cache and immediately request 13740 * a translation for the exit target. Commonly used for callees. 13741 */ 13742 .global dvmJitToInterpTraceSelectNoChain 13743dvmJitToInterpTraceSelectNoChain: 13744#if defined(WITH_JIT_TUNING) 13745 bl dvmBumpNoChain 13746#endif 13747 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13748 mov r0,rPC 13749 bl dvmJitGetTraceAddr @ Is there a translation? 13750 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13751 mov r1, rPC @ arg1 of translation may need this 13752 mov lr, #0 @ in case target is HANDLER_INTERPRET 13753 cmp r0,#0 @ !0 means translation exists 13754 bxne r0 @ continue native execution if so 13755 b 2f @ branch over to use the interpreter 13756 13757/* 13758 * Return from the translation cache and immediately request 13759 * a translation for the exit target. Commonly used following 13760 * invokes. 13761 */ 13762 .global dvmJitToInterpTraceSelect 13763dvmJitToInterpTraceSelect: 13764 ldr rPC,[lr, #-1] @ get our target PC 13765 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13766 add rINST,lr,#-5 @ save start of chain branch 13767 add rINST, #-4 @ .. which is 9 bytes back 13768 mov r0,rPC 13769 bl dvmJitGetTraceAddr @ Is there a translation? 13770 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13771 cmp r0,#0 13772 beq 2f 13773 mov r1,rINST 13774 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 13775 mov r1, rPC @ arg1 of translation may need this 13776 mov lr, #0 @ in case target is HANDLER_INTERPRET 13777 cmp r0,#0 @ successful chain? 13778 bxne r0 @ continue native execution 13779 b toInterpreter @ didn't chain - resume with interpreter 13780 13781/* No translation, so request one if profiling isn't disabled*/ 137822: 13783 adrl rIBASE, dvmAsmInstructionStart 13784 GET_JIT_PROF_TABLE(r0) 13785 FETCH_INST() 13786 cmp r0, #0 13787 movne r2,#kJitTSelectRequestHot @ ask for trace selection 13788 bne common_selectTrace 13789 GET_INST_OPCODE(ip) 13790 GOTO_OPCODE(ip) 13791 13792/* 13793 * Return from the translation cache to the interpreter. 13794 * The return was done with a BLX from thumb mode, and 13795 * the following 32-bit word contains the target rPC value. 13796 * Note that lr (r14) will have its low-order bit set to denote 13797 * its thumb-mode origin. 13798 * 13799 * We'll need to stash our lr origin away, recover the new 13800 * target and then check to see if there is a translation available 13801 * for our new target. If so, we do a translation chain and 13802 * go back to native execution. Otherwise, it's back to the 13803 * interpreter (after treating this entry as a potential 13804 * trace start). 13805 */ 13806 .global dvmJitToInterpNormal 13807dvmJitToInterpNormal: 13808 ldr rPC,[lr, #-1] @ get our target PC 13809 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13810 add rINST,lr,#-5 @ save start of chain branch 13811 add rINST,#-4 @ .. which is 9 bytes back 13812#if defined(WITH_JIT_TUNING) 13813 bl dvmBumpNormal 13814#endif 13815 mov r0,rPC 13816 bl dvmJitGetTraceAddr @ Is there a translation? 13817 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13818 cmp r0,#0 13819 beq toInterpreter @ go if not, otherwise do chain 13820 mov r1,rINST 13821 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 13822 mov r1, rPC @ arg1 of translation may need this 13823 mov lr, #0 @ in case target is HANDLER_INTERPRET 13824 cmp r0,#0 @ successful chain? 13825 bxne r0 @ continue native execution 13826 b toInterpreter @ didn't chain - resume with interpreter 13827 13828/* 13829 * Return from the translation cache to the interpreter to do method invocation. 13830 * Check if translation exists for the callee, but don't chain to it. 13831 */ 13832 .global dvmJitToInterpNoChainNoProfile 13833dvmJitToInterpNoChainNoProfile: 13834#if defined(WITH_JIT_TUNING) 13835 bl dvmBumpNoChain 13836#endif 13837 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13838 mov r0,rPC 13839 bl dvmJitGetTraceAddr @ Is there a translation? 13840 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13841 mov r1, rPC @ arg1 of translation may need this 13842 mov lr, #0 @ in case target is HANDLER_INTERPRET 13843 cmp r0,#0 13844 bxne r0 @ continue native execution if so 13845 EXPORT_PC() 13846 adrl rIBASE, dvmAsmInstructionStart 13847 FETCH_INST() 13848 GET_INST_OPCODE(ip) @ extract opcode from rINST 13849 GOTO_OPCODE(ip) @ jump to next instruction 13850 13851/* 13852 * Return from the translation cache to the interpreter to do method invocation. 13853 * Check if translation exists for the callee, but don't chain to it. 13854 */ 13855 .global dvmJitToInterpNoChain 13856dvmJitToInterpNoChain: 13857#if defined(WITH_JIT_TUNING) 13858 bl dvmBumpNoChain 13859#endif 13860 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13861 mov r0,rPC 13862 bl dvmJitGetTraceAddr @ Is there a translation? 13863 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13864 mov r1, rPC @ arg1 of translation may need this 13865 mov lr, #0 @ in case target is HANDLER_INTERPRET 13866 cmp r0,#0 13867 bxne r0 @ continue native execution if so 13868#endif 13869 13870/* 13871 * No translation, restore interpreter regs and start interpreting. 13872 * rGLUE & rFP were preserved in the translated code, and rPC has 13873 * already been restored by the time we get here. We'll need to set 13874 * up rIBASE & rINST, and load the address of the JitTable into r0. 13875 */ 13876toInterpreter: 13877 EXPORT_PC() 13878 adrl rIBASE, dvmAsmInstructionStart 13879 FETCH_INST() 13880 GET_JIT_PROF_TABLE(r0) 13881 @ NOTE: intended fallthrough 13882 13883/* 13884 * Common code to update potential trace start counter, and initiate 13885 * a trace-build if appropriate. On entry, rPC should point to the 13886 * next instruction to execute, and rINST should be already loaded with 13887 * the next opcode word, and r0 holds a pointer to the jit profile 13888 * table (pJitProfTable). 13889 */ 13890common_testUpdateProfile: 13891 cmp r0,#0 13892 GET_INST_OPCODE(ip) 13893 GOTO_OPCODE_IFEQ(ip) @ if not profiling, fallthrough otherwise */ 13894 13895common_updateProfile: 13896 eor r3,rPC,rPC,lsr #12 @ cheap, but fast hash function 13897 lsl r3,r3,#(32 - JIT_PROF_SIZE_LOG_2) @ shift out excess bits 13898 ldrb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter 13899 GET_INST_OPCODE(ip) 13900 subs r1,r1,#1 @ decrement counter 13901 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it 13902 GOTO_OPCODE_IFNE(ip) @ if not threshold, fallthrough otherwise */ 13903 13904/* 13905 * Here, we switch to the debug interpreter to request 13906 * trace selection. First, though, check to see if there 13907 * is already a native translation in place (and, if so, 13908 * jump to it now). 13909 */ 13910 GET_JIT_THRESHOLD(r1) 13911 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13912 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter 13913 EXPORT_PC() 13914 mov r0,rPC 13915 bl dvmJitGetTraceAddr @ r0<- dvmJitGetTraceAddr(rPC) 13916 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13917 mov r1, rPC @ arg1 of translation may need this 13918 mov lr, #0 @ in case target is HANDLER_INTERPRET 13919 cmp r0,#0 13920#if !defined(WITH_SELF_VERIFICATION) 13921 bxne r0 @ jump to the translation 13922 mov r2,#kJitTSelectRequest @ ask for trace selection 13923 @ fall-through to common_selectTrace 13924#else 13925 moveq r2,#kJitTSelectRequest @ ask for trace selection 13926 beq common_selectTrace 13927 /* 13928 * At this point, we have a target translation. However, if 13929 * that translation is actually the interpret-only pseudo-translation 13930 * we want to treat it the same as no translation. 13931 */ 13932 mov r10, r0 @ save target 13933 bl dvmCompilerGetInterpretTemplate 13934 cmp r0, r10 @ special case? 13935 bne jitSVShadowRunStart @ set up self verification shadow space 13936 @ Need to clear the inJitCodeCache flag 13937 ldr r10, [rGLUE, #offGlue_self] @ r10 <- glue->self 13938 mov r3, #0 @ 0 means not in the JIT code cache 13939 str r3, [r10, #offThread_inJitCodeCache] @ back to the interp land 13940 GET_INST_OPCODE(ip) 13941 GOTO_OPCODE(ip) 13942 /* no return */ 13943#endif 13944 13945/* 13946 * On entry: 13947 * r2 is jit state, e.g. kJitTSelectRequest or kJitTSelectRequestHot 13948 */ 13949common_selectTrace: 13950 str r2,[rGLUE,#offGlue_jitState] 13951 mov r2,#kInterpEntryInstr @ normal entry reason 13952 str r2,[rGLUE,#offGlue_entryPoint] 13953 mov r1,#1 @ set changeInterp 13954 b common_gotoBail 13955 13956#if defined(WITH_SELF_VERIFICATION) 13957/* 13958 * Save PC and registers to shadow memory for self verification mode 13959 * before jumping to native translation. 13960 * On entry: 13961 * rPC, rFP, rGLUE: the values that they should contain 13962 * r10: the address of the target translation. 13963 */ 13964jitSVShadowRunStart: 13965 mov r0,rPC @ r0<- program counter 13966 mov r1,rFP @ r1<- frame pointer 13967 mov r2,rGLUE @ r2<- InterpState pointer 13968 mov r3,r10 @ r3<- target translation 13969 bl dvmSelfVerificationSaveState @ save registers to shadow space 13970 ldr rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space 13971 add rGLUE,r0,#offShadowSpace_interpState @ rGLUE<- rGLUE in shadow space 13972 bx r10 @ jump to the translation 13973 13974/* 13975 * Restore PC, registers, and interpState to original values 13976 * before jumping back to the interpreter. 13977 */ 13978jitSVShadowRunEnd: 13979 mov r1,rFP @ pass ending fp 13980 bl dvmSelfVerificationRestoreState @ restore pc and fp values 13981 ldr rPC,[r0,#offShadowSpace_startPC] @ restore PC 13982 ldr rFP,[r0,#offShadowSpace_fp] @ restore FP 13983 ldr rGLUE,[r0,#offShadowSpace_glue] @ restore InterpState 13984 ldr r1,[r0,#offShadowSpace_svState] @ get self verification state 13985 cmp r1,#0 @ check for punt condition 13986 beq 1f 13987 mov r2,#kJitSelfVerification @ ask for self verification 13988 str r2,[rGLUE,#offGlue_jitState] 13989 mov r2,#kInterpEntryInstr @ normal entry reason 13990 str r2,[rGLUE,#offGlue_entryPoint] 13991 mov r1,#1 @ set changeInterp 13992 b common_gotoBail 13993 139941: @ exit to interpreter without check 13995 EXPORT_PC() 13996 adrl rIBASE, dvmAsmInstructionStart 13997 FETCH_INST() 13998 GET_INST_OPCODE(ip) 13999 GOTO_OPCODE(ip) 14000#endif 14001 14002#endif 14003 14004/* 14005 * Common code when a backward branch is taken. 14006 * 14007 * TODO: we could avoid a branch by just setting r0 and falling through 14008 * into the common_periodicChecks code, and having a test on r0 at the 14009 * end determine if we should return to the caller or update & branch to 14010 * the next instr. 14011 * 14012 * On entry: 14013 * r9 is PC adjustment *in bytes* 14014 */ 14015common_backwardBranch: 14016 mov r0, #kInterpEntryInstr 14017 bl common_periodicChecks 14018#if defined(WITH_JIT) 14019 GET_JIT_PROF_TABLE(r0) 14020 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 14021 cmp r0,#0 14022 bne common_updateProfile 14023 GET_INST_OPCODE(ip) 14024 GOTO_OPCODE(ip) 14025#else 14026 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 14027 GET_INST_OPCODE(ip) @ extract opcode from rINST 14028 GOTO_OPCODE(ip) @ jump to next instruction 14029#endif 14030 14031 14032/* 14033 * Need to see if the thread needs to be suspended or debugger/profiler 14034 * activity has begun. If so, we suspend the thread or side-exit to 14035 * the debug interpreter as appropriate. 14036 * 14037 * The common case is no activity on any of these, so we want to figure 14038 * that out quickly. If something is up, we can then sort out what. 14039 * 14040 * We want to be fast if the VM was built without debugger or profiler 14041 * support, but we also need to recognize that the system is usually 14042 * shipped with both of these enabled. 14043 * 14044 * TODO: reduce this so we're just checking a single location. 14045 * 14046 * On entry: 14047 * r0 is reentry type, e.g. kInterpEntryInstr (for debugger/profiling) 14048 * r9 is trampoline PC adjustment *in bytes* 14049 */ 14050common_periodicChecks: 14051 ldr r1, [rGLUE, #offGlue_pInterpBreak] @ r3<- &interpBreak 14052 /* speculatively load address of thread-specific suspend count */ 14053 ldr r3, [rGLUE, #offGlue_pSelfSuspendCount] @ r3<- &suspendCount 14054 ldr r1, [r1] @ r1<- interpBreak 14055 /* speculatively load thread-specific suspend count */ 14056 ldr ip, [r3] @ ip<- suspendCount (int) 14057 cmp r1, #0 @ anything unusual? 14058 bxeq lr @ return if not 14059 /* 14060 * One or more interesting events have happened. Figure out what. 14061 * 14062 * r0 still holds the reentry type. 14063 */ 14064 cmp ip, #0 @ want suspend? 14065 beq 3f @ no, must be something else 14066 14067 stmfd sp!, {r0, lr} @ preserve r0 and lr 14068#if defined(WITH_JIT) 14069 /* 14070 * Refresh the Jit's cached copy of profile table pointer. This pointer 14071 * doubles as the Jit's on/off switch. 14072 */ 14073 ldr r3, [rGLUE, #offGlue_ppJitProfTable] @ r3<-&gDvmJit.pJitProfTable 14074 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 14075 ldr r3, [r3] @ r3 <- pJitProfTable 14076 EXPORT_PC() @ need for precise GC 14077 str r3, [rGLUE, #offGlue_pJitProfTable] @ refresh Jit's on/off switch 14078#else 14079 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 14080 EXPORT_PC() @ need for precise GC 14081#endif 14082 bl dvmCheckSuspendPending @ do full check, suspend if necessary 14083 ldmfd sp!, {r0, lr} @ restore r0 and lr 14084 14085 /* 14086 * Reload the interpBreak flags - they may have changed while we 14087 * were suspended. 14088 */ 14089 ldr r1, [rGLUE, #offGlue_pInterpBreak] @ r1<- &interpBreak 14090 ldr r1, [r1] @ r1<- interpBreak 140913: 14092 /* 14093 * TODO: this code is too fragile. Need a general mechanism 14094 * to identify what actions to take by submode. Some profiling modes 14095 * (instruction count) need to single-step, while method tracing 14096 * may not. Debugging with breakpoints can run unfettered, but 14097 * source-level single-stepping requires Dalvik singlestepping. 14098 * GC may require a one-shot action and then full-speed resumption. 14099 */ 14100 ands r1, #(kSubModeDebuggerActive | kSubModeEmulatorTrace | kSubModeInstCounting) 14101 bxeq lr @ nothing to do, return 14102 14103 @ debugger/profiler enabled, bail out; glue->entryPoint was set above 14104 str r0, [rGLUE, #offGlue_entryPoint] @ store r0, need for debug/prof 14105 add rPC, rPC, r9 @ update rPC 14106 mov r1, #1 @ "want switch" = true 14107 b common_gotoBail @ side exit 14108 14109 14110/* 14111 * The equivalent of "goto bail", this calls through the "bail handler". 14112 * 14113 * State registers will be saved to the "glue" area before bailing. 14114 * 14115 * On entry: 14116 * r1 is "bool changeInterp", indicating if we want to switch to the 14117 * other interpreter or just bail all the way out 14118 */ 14119common_gotoBail: 14120 SAVE_PC_FP_TO_GLUE() @ export state to "glue" 14121 mov r0, rGLUE @ r0<- glue ptr 14122 b dvmMterpStdBail @ call(glue, changeInterp) 14123 14124 @add r1, r1, #1 @ using (boolean+1) 14125 @add r0, rGLUE, #offGlue_jmpBuf @ r0<- &glue->jmpBuf 14126 @bl _longjmp @ does not return 14127 @bl common_abort 14128 14129 14130/* 14131 * Common code for jumbo method invocation. 14132 * NOTE: this adjusts rPC to account for the difference in instruction width. 14133 * As a result, the savedPc in the stack frame will not be wholly accurate. So 14134 * long as that is only used for source file line number calculations, we're 14135 * okay. 14136 * 14137 * On entry: 14138 * r0 is "Method* methodToCall", the method we're trying to call 14139 */ 14140common_invokeMethodJumbo: 14141.LinvokeNewJumbo: 14142 @ prepare to copy args to "outs" area of current frame 14143 add rPC, rPC, #4 @ adjust pc to make return consistent 14144 FETCH(r2, 1) @ r2<- BBBB (arg count) 14145 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 14146 cmp r2, #0 @ no args? 14147 beq .LinvokeArgsDone @ if no args, skip the rest 14148 FETCH(r1, 2) @ r1<- CCCC 14149 b .LinvokeRangeArgs @ handle args like invoke range 14150 14151/* 14152 * Common code for method invocation with range. 14153 * 14154 * On entry: 14155 * r0 is "Method* methodToCall", the method we're trying to call 14156 */ 14157common_invokeMethodRange: 14158.LinvokeNewRange: 14159 @ prepare to copy args to "outs" area of current frame 14160 movs r2, rINST, lsr #8 @ r2<- AA (arg count) -- test for zero 14161 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 14162 beq .LinvokeArgsDone @ if no args, skip the rest 14163 FETCH(r1, 2) @ r1<- CCCC 14164 14165.LinvokeRangeArgs: 14166 @ r0=methodToCall, r1=CCCC, r2=count, r10=outs 14167 @ (very few methods have > 10 args; could unroll for common cases) 14168 add r3, rFP, r1, lsl #2 @ r3<- &fp[CCCC] 14169 sub r10, r10, r2, lsl #2 @ r10<- "outs" area, for call args 141701: ldr r1, [r3], #4 @ val = *fp++ 14171 subs r2, r2, #1 @ count-- 14172 str r1, [r10], #4 @ *outs++ = val 14173 bne 1b @ ...while count != 0 14174 b .LinvokeArgsDone 14175 14176/* 14177 * Common code for method invocation without range. 14178 * 14179 * On entry: 14180 * r0 is "Method* methodToCall", the method we're trying to call 14181 */ 14182common_invokeMethodNoRange: 14183.LinvokeNewNoRange: 14184 @ prepare to copy args to "outs" area of current frame 14185 movs r2, rINST, lsr #12 @ r2<- B (arg count) -- test for zero 14186 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 14187 FETCH(r1, 2) @ r1<- GFED (load here to hide latency) 14188 beq .LinvokeArgsDone 14189 14190 @ r0=methodToCall, r1=GFED, r2=count, r10=outs 14191.LinvokeNonRange: 14192 rsb r2, r2, #5 @ r2<- 5-r2 14193 add pc, pc, r2, lsl #4 @ computed goto, 4 instrs each 14194 bl common_abort @ (skipped due to ARM prefetch) 141955: and ip, rINST, #0x0f00 @ isolate A 14196 ldr r2, [rFP, ip, lsr #6] @ r2<- vA (shift right 8, left 2) 14197 mov r0, r0 @ nop 14198 str r2, [r10, #-4]! @ *--outs = vA 141994: and ip, r1, #0xf000 @ isolate G 14200 ldr r2, [rFP, ip, lsr #10] @ r2<- vG (shift right 12, left 2) 14201 mov r0, r0 @ nop 14202 str r2, [r10, #-4]! @ *--outs = vG 142033: and ip, r1, #0x0f00 @ isolate F 14204 ldr r2, [rFP, ip, lsr #6] @ r2<- vF 14205 mov r0, r0 @ nop 14206 str r2, [r10, #-4]! @ *--outs = vF 142072: and ip, r1, #0x00f0 @ isolate E 14208 ldr r2, [rFP, ip, lsr #2] @ r2<- vE 14209 mov r0, r0 @ nop 14210 str r2, [r10, #-4]! @ *--outs = vE 142111: and ip, r1, #0x000f @ isolate D 14212 ldr r2, [rFP, ip, lsl #2] @ r2<- vD 14213 mov r0, r0 @ nop 14214 str r2, [r10, #-4]! @ *--outs = vD 142150: @ fall through to .LinvokeArgsDone 14216 14217.LinvokeArgsDone: @ r0=methodToCall 14218 ldrh r9, [r0, #offMethod_registersSize] @ r9<- methodToCall->regsSize 14219 ldrh r3, [r0, #offMethod_outsSize] @ r3<- methodToCall->outsSize 14220 ldr r2, [r0, #offMethod_insns] @ r2<- method->insns 14221 ldr rINST, [r0, #offMethod_clazz] @ rINST<- method->clazz 14222 @ find space for the new stack frame, check for overflow 14223 SAVEAREA_FROM_FP(r1, rFP) @ r1<- stack save area 14224 sub r1, r1, r9, lsl #2 @ r1<- newFp (old savearea - regsSize) 14225 SAVEAREA_FROM_FP(r10, r1) @ r10<- newSaveArea 14226@ bl common_dumpRegs 14227 ldr r9, [rGLUE, #offGlue_interpStackEnd] @ r9<- interpStackEnd 14228 sub r3, r10, r3, lsl #2 @ r3<- bottom (newsave - outsSize) 14229 cmp r3, r9 @ bottom < interpStackEnd? 14230 ldr lr, [rGLUE, #offGlue_pInterpBreak] 14231 ldr r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags 14232 blo .LstackOverflow @ yes, this frame will overflow stack 14233 14234 @ set up newSaveArea 14235 ldr lr, [lr] @ lr<- active submodes 14236#ifdef EASY_GDB 14237 SAVEAREA_FROM_FP(ip, rFP) @ ip<- stack save area 14238 str ip, [r10, #offStackSaveArea_prevSave] 14239#endif 14240 str rFP, [r10, #offStackSaveArea_prevFrame] 14241 str rPC, [r10, #offStackSaveArea_savedPc] 14242#if defined(WITH_JIT) 14243 mov r9, #0 14244 str r9, [r10, #offStackSaveArea_returnAddr] 14245#endif 14246 ands lr, #kSubModeMethodTrace @ method tracing? 14247 beq 1f @ skip if not 14248 stmfd sp!, {r0-r3} @ preserve r0-r3 14249 mov r1, r6 14250 @ r0=methodToCall, r1=rGlue 14251 bl dvmFastMethodTraceEnter 14252 ldmfd sp!, {r0-r3} @ restore r0-r3 142531: 14254 str r0, [r10, #offStackSaveArea_method] 14255 tst r3, #ACC_NATIVE 14256 bne .LinvokeNative 14257 14258 /* 14259 stmfd sp!, {r0-r3} 14260 bl common_printNewline 14261 mov r0, rFP 14262 mov r1, #0 14263 bl dvmDumpFp 14264 ldmfd sp!, {r0-r3} 14265 stmfd sp!, {r0-r3} 14266 mov r0, r1 14267 mov r1, r10 14268 bl dvmDumpFp 14269 bl common_printNewline 14270 ldmfd sp!, {r0-r3} 14271 */ 14272 14273 ldrh r9, [r2] @ r9 <- load INST from new PC 14274 ldr r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex 14275 mov rPC, r2 @ publish new rPC 14276 ldr r2, [rGLUE, #offGlue_self] @ r2<- glue->self 14277 14278 @ Update "glue" values for the new method 14279 @ r0=methodToCall, r1=newFp, r2=self, r3=newMethodClass, r9=newINST 14280 str r0, [rGLUE, #offGlue_method] @ glue->method = methodToCall 14281 str r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ... 14282#if defined(WITH_JIT) 14283 GET_JIT_PROF_TABLE(r0) 14284 mov rFP, r1 @ fp = newFp 14285 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 14286 mov rINST, r9 @ publish new rINST 14287 str r1, [r2, #offThread_curFrame] @ self->curFrame = newFp 14288 cmp r0,#0 14289 bne common_updateProfile 14290 GOTO_OPCODE(ip) @ jump to next instruction 14291#else 14292 mov rFP, r1 @ fp = newFp 14293 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 14294 mov rINST, r9 @ publish new rINST 14295 str r1, [r2, #offThread_curFrame] @ self->curFrame = newFp 14296 GOTO_OPCODE(ip) @ jump to next instruction 14297#endif 14298 14299.LinvokeNative: 14300 @ Prep for the native call 14301 @ r0=methodToCall, r1=newFp, r10=newSaveArea 14302 ldr r3, [rGLUE, #offGlue_self] @ r3<- glue->self 14303 ldr lr, [rGLUE, #offGlue_pInterpBreak] 14304 ldr r9, [r3, #offThread_jniLocal_topCookie] @ r9<- thread->localRef->... 14305 str r1, [r3, #offThread_curFrame] @ self->curFrame = newFp 14306 str r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top 14307 ldr lr, [lr] @ lr<- active submodes 14308 mov r9, r3 @ r9<- glue->self (preserve) 14309 14310 mov r2, r0 @ r2<- methodToCall 14311 mov r0, r1 @ r0<- newFp (points to args) 14312 add r1, rGLUE, #offGlue_retval @ r1<- &retval 14313 14314#ifdef ASSIST_DEBUGGER 14315 /* insert fake function header to help gdb find the stack frame */ 14316 b .Lskip 14317 .type dalvik_mterp, %function 14318dalvik_mterp: 14319 .fnstart 14320 MTERP_ENTRY1 14321 MTERP_ENTRY2 14322.Lskip: 14323#endif 14324 14325 ands lr, #kSubModeMethodTrace @ method tracing? 14326 beq 110f @ hop if not 14327 @ r2=JNIMethod, r6=rGLUE 14328 stmfd sp!, {r2,r6} 14329 14330 mov lr, pc @ set return addr 14331 ldr pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 14332 14333 @ r0=JNIMethod, r1=rGLUE 14334 ldmfd sp!, {r0-r1} 14335 bl dvmFastNativeMethodTraceExit 14336 b 220f 14337110: 14338 mov lr, pc @ set return addr 14339 ldr pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 14340220: 14341#if defined(WITH_JIT) 14342 ldr r3, [rGLUE, #offGlue_ppJitProfTable] @ Refresh Jit's on/off status 14343#endif 14344 14345 @ native return; r9=self, r10=newSaveArea 14346 @ equivalent to dvmPopJniLocals 14347 ldr r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top 14348 ldr r1, [r9, #offThread_exception] @ check for exception 14349#if defined(WITH_JIT) 14350 ldr r3, [r3] @ r3 <- gDvmJit.pProfTable 14351#endif 14352 str rFP, [r9, #offThread_curFrame] @ self->curFrame = fp 14353 cmp r1, #0 @ null? 14354 str r0, [r9, #offThread_jniLocal_topCookie] @ new top <- old top 14355#if defined(WITH_JIT) 14356 str r3, [rGLUE, #offGlue_pJitProfTable] @ refresh cached on/off switch 14357#endif 14358 bne common_exceptionThrown @ no, handle exception 14359 14360 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 14361 GET_INST_OPCODE(ip) @ extract opcode from rINST 14362 GOTO_OPCODE(ip) @ jump to next instruction 14363 14364.LstackOverflow: @ r0=methodToCall 14365 mov r1, r0 @ r1<- methodToCall 14366 ldr r0, [rGLUE, #offGlue_self] @ r0<- self 14367 bl dvmHandleStackOverflow 14368 b common_exceptionThrown 14369#ifdef ASSIST_DEBUGGER 14370 .fnend 14371#endif 14372 14373 14374 /* 14375 * Common code for method invocation, calling through "glue code". 14376 * 14377 * TODO: now that we have range and non-range invoke handlers, this 14378 * needs to be split into two. Maybe just create entry points 14379 * that set r9 and jump here? 14380 * 14381 * On entry: 14382 * r0 is "Method* methodToCall", the method we're trying to call 14383 * r9 is "bool methodCallRange", indicating if this is a /range variant 14384 */ 14385 .if 0 14386.LinvokeOld: 14387 sub sp, sp, #8 @ space for args + pad 14388 FETCH(ip, 2) @ ip<- FEDC or CCCC 14389 mov r2, r0 @ A2<- methodToCall 14390 mov r0, rGLUE @ A0<- glue 14391 SAVE_PC_FP_TO_GLUE() @ export state to "glue" 14392 mov r1, r9 @ A1<- methodCallRange 14393 mov r3, rINST, lsr #8 @ A3<- AA 14394 str ip, [sp, #0] @ A4<- ip 14395 bl dvmMterp_invokeMethod @ call the C invokeMethod 14396 add sp, sp, #8 @ remove arg area 14397 b common_resumeAfterGlueCall @ continue to next instruction 14398 .endif 14399 14400 14401 14402/* 14403 * Common code for handling a return instruction. 14404 * 14405 * This does not return. 14406 */ 14407common_returnFromMethod: 14408.LreturnNew: 14409 mov r0, #kInterpEntryReturn 14410 mov r9, #0 14411 bl common_periodicChecks 14412 14413 ldr lr, [rGLUE, #offGlue_pInterpBreak] 14414 SAVEAREA_FROM_FP(r0, rFP) 14415 ldr lr, [lr] @ lr<- active submodes 14416 ldr r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc 14417 ands lr, #kSubModeMethodTrace @ method tracing? 14418 beq 333f 14419 stmfd sp!, {r0-r3} @ preserve r0-r3 14420 mov r0, r6 14421 @ r0=rGlue 14422 bl dvmFastJavaMethodTraceExit 14423 ldmfd sp!, {r0-r3} @ restore r0-r3 14424333: 14425 ldr rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame 14426 ldr r3, [rGLUE, #offGlue_self] @ r3<- glue->self 14427 ldr r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)] 14428 @ r2<- method we're returning to 14429 cmp r2, #0 @ is this a break frame? 14430#if defined(WORKAROUND_CORTEX_A9_745320) 14431 /* Don't use conditional loads if the HW defect exists */ 14432 beq 101f 14433 ldr r10, [r2, #offMethod_clazz] @ r10<- method->clazz 14434101: 14435#else 14436 ldrne r10, [r2, #offMethod_clazz] @ r10<- method->clazz 14437#endif 14438 mov r1, #0 @ "want switch" = false 14439 beq common_gotoBail @ break frame, bail out completely 14440 14441 PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST 14442 str r2, [rGLUE, #offGlue_method]@ glue->method = newSave->method 14443 ldr r1, [r10, #offClassObject_pDvmDex] @ r1<- method->clazz->pDvmDex 14444 str rFP, [r3, #offThread_curFrame] @ self->curFrame = fp 14445#if defined(WITH_JIT) 14446 ldr r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr 14447 mov rPC, r9 @ publish new rPC 14448 str r1, [rGLUE, #offGlue_methodClassDex] 14449 str r10, [r3, #offThread_inJitCodeCache] @ may return to JIT'ed land 14450 cmp r10, #0 @ caller is compiled code 14451 blxne r10 14452 GET_INST_OPCODE(ip) @ extract opcode from rINST 14453 GOTO_OPCODE(ip) @ jump to next instruction 14454#else 14455 GET_INST_OPCODE(ip) @ extract opcode from rINST 14456 mov rPC, r9 @ publish new rPC 14457 str r1, [rGLUE, #offGlue_methodClassDex] 14458 GOTO_OPCODE(ip) @ jump to next instruction 14459#endif 14460 14461 /* 14462 * Return handling, calls through "glue code". 14463 */ 14464 .if 0 14465.LreturnOld: 14466 SAVE_PC_FP_TO_GLUE() @ export state 14467 mov r0, rGLUE @ arg to function 14468 bl dvmMterp_returnFromMethod 14469 b common_resumeAfterGlueCall 14470 .endif 14471 14472 14473/* 14474 * Somebody has thrown an exception. Handle it. 14475 * 14476 * If the exception processing code returns to us (instead of falling 14477 * out of the interpreter), continue with whatever the next instruction 14478 * now happens to be. 14479 * 14480 * This does not return. 14481 */ 14482 .global dvmMterpCommonExceptionThrown 14483dvmMterpCommonExceptionThrown: 14484common_exceptionThrown: 14485.LexceptionNew: 14486 mov r0, #kInterpEntryThrow 14487 mov r9, #0 14488 bl common_periodicChecks 14489 14490 ldr r10, [rGLUE, #offGlue_self] @ r10<- glue->self 14491 ldr r9, [r10, #offThread_exception] @ r9<- self->exception 14492 mov r1, r10 @ r1<- self 14493 mov r0, r9 @ r0<- exception 14494 bl dvmAddTrackedAlloc @ don't let the exception be GCed 14495 mov r3, #0 @ r3<- NULL 14496 str r3, [r10, #offThread_exception] @ self->exception = NULL 14497 14498 /* set up args and a local for "&fp" */ 14499 /* (str sp, [sp, #-4]! would be perfect here, but is discouraged) */ 14500 str rFP, [sp, #-4]! @ *--sp = fp 14501 mov ip, sp @ ip<- &fp 14502 mov r3, #0 @ r3<- false 14503 str ip, [sp, #-4]! @ *--sp = &fp 14504 ldr r1, [rGLUE, #offGlue_method] @ r1<- glue->method 14505 mov r0, r10 @ r0<- self 14506 ldr r1, [r1, #offMethod_insns] @ r1<- method->insns 14507 mov r2, r9 @ r2<- exception 14508 sub r1, rPC, r1 @ r1<- pc - method->insns 14509 mov r1, r1, asr #1 @ r1<- offset in code units 14510 14511 /* call, r0 gets catchRelPc (a code-unit offset) */ 14512 bl dvmFindCatchBlock @ call(self, relPc, exc, scan?, &fp) 14513 14514 /* fix earlier stack overflow if necessary; may trash rFP */ 14515 ldrb r1, [r10, #offThread_stackOverflowed] 14516 cmp r1, #0 @ did we overflow earlier? 14517 beq 1f @ no, skip ahead 14518 mov rFP, r0 @ save relPc result in rFP 14519 mov r0, r10 @ r0<- self 14520 mov r1, r9 @ r1<- exception 14521 bl dvmCleanupStackOverflow @ call(self) 14522 mov r0, rFP @ restore result 145231: 14524 14525 /* update frame pointer and check result from dvmFindCatchBlock */ 14526 ldr rFP, [sp, #4] @ retrieve the updated rFP 14527 cmp r0, #0 @ is catchRelPc < 0? 14528 add sp, sp, #8 @ restore stack 14529 bmi .LnotCaughtLocally 14530 14531 /* adjust locals to match self->curFrame and updated PC */ 14532 SAVEAREA_FROM_FP(r1, rFP) @ r1<- new save area 14533 ldr r1, [r1, #offStackSaveArea_method] @ r1<- new method 14534 str r1, [rGLUE, #offGlue_method] @ glue->method = new method 14535 ldr r2, [r1, #offMethod_clazz] @ r2<- method->clazz 14536 ldr r3, [r1, #offMethod_insns] @ r3<- method->insns 14537 ldr r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex 14538 add rPC, r3, r0, asl #1 @ rPC<- method->insns + catchRelPc 14539 str r2, [rGLUE, #offGlue_methodClassDex] @ glue->pDvmDex = meth... 14540 14541 /* release the tracked alloc on the exception */ 14542 mov r0, r9 @ r0<- exception 14543 mov r1, r10 @ r1<- self 14544 bl dvmReleaseTrackedAlloc @ release the exception 14545 14546 /* restore the exception if the handler wants it */ 14547 FETCH_INST() @ load rINST from rPC 14548 GET_INST_OPCODE(ip) @ extract opcode from rINST 14549 cmp ip, #OP_MOVE_EXCEPTION @ is it "move-exception"? 14550 streq r9, [r10, #offThread_exception] @ yes, restore the exception 14551 GOTO_OPCODE(ip) @ jump to next instruction 14552 14553.LnotCaughtLocally: @ r9=exception, r10=self 14554 /* fix stack overflow if necessary */ 14555 ldrb r1, [r10, #offThread_stackOverflowed] 14556 cmp r1, #0 @ did we overflow earlier? 14557 movne r0, r10 @ if yes: r0<- self 14558 movne r1, r9 @ if yes: r1<- exception 14559 blne dvmCleanupStackOverflow @ if yes: call(self) 14560 14561 @ may want to show "not caught locally" debug messages here 14562#if DVM_SHOW_EXCEPTION >= 2 14563 /* call __android_log_print(prio, tag, format, ...) */ 14564 /* "Exception %s from %s:%d not caught locally" */ 14565 @ dvmLineNumFromPC(method, pc - method->insns) 14566 ldr r0, [rGLUE, #offGlue_method] 14567 ldr r1, [r0, #offMethod_insns] 14568 sub r1, rPC, r1 14569 asr r1, r1, #1 14570 bl dvmLineNumFromPC 14571 str r0, [sp, #-4]! 14572 @ dvmGetMethodSourceFile(method) 14573 ldr r0, [rGLUE, #offGlue_method] 14574 bl dvmGetMethodSourceFile 14575 str r0, [sp, #-4]! 14576 @ exception->clazz->descriptor 14577 ldr r3, [r9, #offObject_clazz] 14578 ldr r3, [r3, #offClassObject_descriptor] 14579 @ 14580 ldr r2, strExceptionNotCaughtLocally 14581 ldr r1, strLogTag 14582 mov r0, #3 @ LOG_DEBUG 14583 bl __android_log_print 14584#endif 14585 str r9, [r10, #offThread_exception] @ restore exception 14586 mov r0, r9 @ r0<- exception 14587 mov r1, r10 @ r1<- self 14588 bl dvmReleaseTrackedAlloc @ release the exception 14589 mov r1, #0 @ "want switch" = false 14590 b common_gotoBail @ bail out 14591 14592 14593 /* 14594 * Exception handling, calls through "glue code". 14595 */ 14596 .if 0 14597.LexceptionOld: 14598 SAVE_PC_FP_TO_GLUE() @ export state 14599 mov r0, rGLUE @ arg to function 14600 bl dvmMterp_exceptionThrown 14601 b common_resumeAfterGlueCall 14602 .endif 14603 14604 14605/* 14606 * After returning from a "glued" function, pull out the updated 14607 * values and start executing at the next instruction. 14608 */ 14609common_resumeAfterGlueCall: 14610 LOAD_PC_FP_FROM_GLUE() @ pull rPC and rFP out of glue 14611 FETCH_INST() @ load rINST from rPC 14612 GET_INST_OPCODE(ip) @ extract opcode from rINST 14613 GOTO_OPCODE(ip) @ jump to next instruction 14614 14615/* 14616 * Invalid array index. Note that our calling convention is strange; we use r1 14617 * and r3 because those just happen to be the registers all our callers are 14618 * using. We shuffle them here before calling the C function. 14619 * r1: index 14620 * r3: size 14621 */ 14622common_errArrayIndex: 14623 EXPORT_PC() 14624 mov r0, r1 14625 mov r1, r3 14626 bl dvmThrowAIOOBE 14627 b common_exceptionThrown 14628 14629/* 14630 * Integer divide or mod by zero. 14631 */ 14632common_errDivideByZero: 14633 EXPORT_PC() 14634 ldr r0, strArithmeticException 14635 ldr r1, strDivideByZero 14636 bl dvmThrowException 14637 b common_exceptionThrown 14638 14639/* 14640 * Attempt to allocate an array with a negative size. 14641 */ 14642common_errNegativeArraySize: 14643 EXPORT_PC() 14644 ldr r0, strNegativeArraySizeException 14645 mov r1, #0 14646 bl dvmThrowException 14647 b common_exceptionThrown 14648 14649/* 14650 * Invocation of a non-existent method. 14651 */ 14652common_errNoSuchMethod: 14653 EXPORT_PC() 14654 ldr r0, strNoSuchMethodError 14655 mov r1, #0 14656 bl dvmThrowException 14657 b common_exceptionThrown 14658 14659/* 14660 * We encountered a null object when we weren't expecting one. We 14661 * export the PC, throw a NullPointerException, and goto the exception 14662 * processing code. 14663 */ 14664common_errNullObject: 14665 EXPORT_PC() 14666 ldr r0, strNullPointerException 14667 mov r1, #0 14668 bl dvmThrowException 14669 b common_exceptionThrown 14670 14671/* 14672 * For debugging, cause an immediate fault. The source address will 14673 * be in lr (use a bl instruction to jump here). 14674 */ 14675common_abort: 14676 ldr pc, .LdeadFood 14677.LdeadFood: 14678 .word 0xdeadf00d 14679 14680/* 14681 * Spit out a "we were here", preserving all registers. (The attempt 14682 * to save ip won't work, but we need to save an even number of 14683 * registers for EABI 64-bit stack alignment.) 14684 */ 14685 .macro SQUEAK num 14686common_squeak\num: 14687 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14688 ldr r0, strSqueak 14689 mov r1, #\num 14690 bl printf 14691 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14692 bx lr 14693 .endm 14694 14695 SQUEAK 0 14696 SQUEAK 1 14697 SQUEAK 2 14698 SQUEAK 3 14699 SQUEAK 4 14700 SQUEAK 5 14701 14702/* 14703 * Spit out the number in r0, preserving registers. 14704 */ 14705common_printNum: 14706 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14707 mov r1, r0 14708 ldr r0, strSqueak 14709 bl printf 14710 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14711 bx lr 14712 14713/* 14714 * Print a newline, preserving registers. 14715 */ 14716common_printNewline: 14717 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14718 ldr r0, strNewline 14719 bl printf 14720 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14721 bx lr 14722 14723 /* 14724 * Print the 32-bit quantity in r0 as a hex value, preserving registers. 14725 */ 14726common_printHex: 14727 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14728 mov r1, r0 14729 ldr r0, strPrintHex 14730 bl printf 14731 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14732 bx lr 14733 14734/* 14735 * Print the 64-bit quantity in r0-r1, preserving registers. 14736 */ 14737common_printLong: 14738 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14739 mov r3, r1 14740 mov r2, r0 14741 ldr r0, strPrintLong 14742 bl printf 14743 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14744 bx lr 14745 14746/* 14747 * Print full method info. Pass the Method* in r0. Preserves regs. 14748 */ 14749common_printMethod: 14750 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14751 bl dvmMterpPrintMethod 14752 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14753 bx lr 14754 14755/* 14756 * Call a C helper function that dumps regs and possibly some 14757 * additional info. Requires the C function to be compiled in. 14758 */ 14759 .if 0 14760common_dumpRegs: 14761 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14762 bl dvmMterpDumpArmRegs 14763 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14764 bx lr 14765 .endif 14766 14767#if 0 14768/* 14769 * Experiment on VFP mode. 14770 * 14771 * uint32_t setFPSCR(uint32_t val, uint32_t mask) 14772 * 14773 * Updates the bits specified by "mask", setting them to the values in "val". 14774 */ 14775setFPSCR: 14776 and r0, r0, r1 @ make sure no stray bits are set 14777 fmrx r2, fpscr @ get VFP reg 14778 mvn r1, r1 @ bit-invert mask 14779 and r2, r2, r1 @ clear masked bits 14780 orr r2, r2, r0 @ set specified bits 14781 fmxr fpscr, r2 @ set VFP reg 14782 mov r0, r2 @ return new value 14783 bx lr 14784 14785 .align 2 14786 .global dvmConfigureFP 14787 .type dvmConfigureFP, %function 14788dvmConfigureFP: 14789 stmfd sp!, {ip, lr} 14790 /* 0x03000000 sets DN/FZ */ 14791 /* 0x00009f00 clears the six exception enable flags */ 14792 bl common_squeak0 14793 mov r0, #0x03000000 @ r0<- 0x03000000 14794 add r1, r0, #0x9f00 @ r1<- 0x03009f00 14795 bl setFPSCR 14796 ldmfd sp!, {ip, pc} 14797#endif 14798 14799 14800/* 14801 * String references, must be close to the code that uses them. 14802 */ 14803 .align 2 14804strArithmeticException: 14805 .word .LstrArithmeticException 14806strDivideByZero: 14807 .word .LstrDivideByZero 14808strNegativeArraySizeException: 14809 .word .LstrNegativeArraySizeException 14810strNoSuchMethodError: 14811 .word .LstrNoSuchMethodError 14812strNullPointerException: 14813 .word .LstrNullPointerException 14814 14815strLogTag: 14816 .word .LstrLogTag 14817strExceptionNotCaughtLocally: 14818 .word .LstrExceptionNotCaughtLocally 14819 14820strNewline: 14821 .word .LstrNewline 14822strSqueak: 14823 .word .LstrSqueak 14824strPrintHex: 14825 .word .LstrPrintHex 14826strPrintLong: 14827 .word .LstrPrintLong 14828 14829/* 14830 * Zero-terminated ASCII string data. 14831 * 14832 * On ARM we have two choices: do like gcc does, and LDR from a .word 14833 * with the address, or use an ADR pseudo-op to get the address 14834 * directly. ADR saves 4 bytes and an indirection, but it's using a 14835 * PC-relative addressing mode and hence has a limited range, which 14836 * makes it not work well with mergeable string sections. 14837 */ 14838 .section .rodata.str1.4,"aMS",%progbits,1 14839 14840.LstrBadEntryPoint: 14841 .asciz "Bad entry point %d\n" 14842.LstrArithmeticException: 14843 .asciz "Ljava/lang/ArithmeticException;" 14844.LstrDivideByZero: 14845 .asciz "divide by zero" 14846.LstrFilledNewArrayNotImpl: 14847 .asciz "filled-new-array only implemented for objects and 'int'" 14848.LstrInternalError: 14849 .asciz "Ljava/lang/InternalError;" 14850.LstrInstantiationError: 14851 .asciz "Ljava/lang/InstantiationError;" 14852.LstrNegativeArraySizeException: 14853 .asciz "Ljava/lang/NegativeArraySizeException;" 14854.LstrNoSuchMethodError: 14855 .asciz "Ljava/lang/NoSuchMethodError;" 14856.LstrNullPointerException: 14857 .asciz "Ljava/lang/NullPointerException;" 14858 14859.LstrLogTag: 14860 .asciz "mterp" 14861.LstrExceptionNotCaughtLocally: 14862 .asciz "Exception %s from %s:%d not caught locally\n" 14863 14864.LstrNewline: 14865 .asciz "\n" 14866.LstrSqueak: 14867 .asciz "<%d>" 14868.LstrPrintHex: 14869 .asciz "<0x%x>" 14870.LstrPrintLong: 14871 .asciz "<%lld>" 14872 14873