InterpAsm-x86.S revision 9f601a917c8878204482c37aec7005054b6776fa
1/* 2 * This file was generated automatically by gen-mterp.py for 'x86'. 3 * 4 * --> DO NOT EDIT <-- 5 */ 6 7/* File: x86/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 * 32-bit x86 definitions and declarations. 25 */ 26 27/* 28386 ABI general notes: 29 30Caller save set: 31 eax, edx, ecx, st(0)-st(7) 32Callee save set: 33 ebx, esi, edi, ebp 34Return regs: 35 32-bit in eax 36 64-bit in edx:eax (low-order 32 in eax) 37 fp on top of fp stack st(0) 38 39Parameters passed on stack, pushed right-to-left. On entry to target, first 40parm is at 4(%esp). Traditional entry code is: 41 42functEntry: 43 push %ebp # save old frame pointer 44 mov %ebp,%esp # establish new frame pointer 45 sub FrameSize,%esp # Allocate storage for spill, locals & outs 46 47Once past the prologue, arguments are referenced at ((argno + 2)*4)(%ebp) 48 49Alignment of stack not strictly required, but should be for performance. We'll 50align frame sizes to 16-byte multiples. 51 52If we're not doing variable stack allocation (alloca), the frame pointer can be 53eliminated and all arg references adjusted to be esp relative. 54 55Mterp notes: 56 57Some key interpreter variables will be assigned to registers. Note that each 58will also have an associated spill location (mostly useful for those assigned 59to callee save registers). 60 61 nick reg purpose 62 rPC edi interpreted program counter, used for fetching instructions 63 rFP esi interpreted frame pointer, used for accessing locals and args 64 rINSTw bx first 16-bit code of current instruction 65 rINSTbl bl opcode portion of instruction word 66 rINSTbh bh high byte of inst word, usually contains src/tgt reg names 67 68Notes: 69 o High order 16 bits of ebx must be zero on entry to handler 70 o rPC, rFP, rINSTw/rINSTbl valid on handler entry and exit 71 o eax, edx and ecx are scratch, rINSTw/ebx sometimes scratch 72 73*/ 74 75#define rSELF (%ebp) 76#define rPC %esi 77#define rFP %edi 78#define rINST %ebx 79#define rINSTw %bx 80#define rINSTbh %bh 81#define rINSTbl %bl 82 83 84/* Frame diagram while executing dvmMterpStdRun, high to low addresses */ 85#define IN_ARG0 ( 12) 86#define CALLER_RP ( 8) 87#define PREV_FP ( 4) 88#define rSELF_SPILL ( 0) /* <- dvmMterpStdRun ebp */ 89/* Spill offsets relative to %ebp */ 90#define EDI_SPILL ( -4) 91#define ESI_SPILL ( -8) 92#define EBX_SPILL (-12) /* <- esp following dmMterpStdRun header */ 93#define rPC_SPILL (-16) 94#define rFP_SPILL (-20) 95#define rINST_SPILL (-24) 96#define TMP_SPILL1 (-28) 97#define TMP_SPILL2 (-32) 98#define TMP_SPILL3 (-36) 99#define LOCAL0_OFFSET (-40) 100#define LOCAL1_OFFSET (-44) 101#define LOCAL2_OFFSET (-48) 102#define LOCAL3_OFFSET (-52) 103/* Out Arg offsets, relative to %sp */ 104#define OUT_ARG4 ( 16) 105#define OUT_ARG3 ( 12) 106#define OUT_ARG2 ( 8) 107#define OUT_ARG1 ( 4) 108#define OUT_ARG0 ( 0) /* <- dvmMterpStdRun esp */ 109#define FRAME_SIZE 80 110 111#define SPILL(reg) movl reg##,reg##_SPILL(%ebp) 112#define UNSPILL(reg) movl reg##_SPILL(%ebp),reg 113#define SPILL_TMP1(reg) movl reg,TMP_SPILL1(%ebp) 114#define UNSPILL_TMP1(reg) movl TMP_SPILL1(%ebp),reg 115#define SPILL_TMP2(reg) movl reg,TMP_SPILL2(%ebp) 116#define UNSPILL_TMP2(reg) movl TMP_SPILL2(%ebp),reg 117#define SPILL_TMP3(reg) movl reg,TMP_SPILL3(%ebp) 118#define UNSPILL_TMP3(reg) movl TMP_SPILL3(%ebp),reg 119 120#if defined(WITH_JIT) 121.macro GET_JIT_PROF_TABLE _self _reg 122 movl offThread_pJitProfTable(\_self),\_reg 123.endm 124.macro GET_JIT_THRESHOLD _self _reg 125 movl offThread_jitThreshold(\_self),\_reg 126.endm 127#endif 128 129/* save/restore the PC and/or FP from the self struct */ 130.macro SAVE_PC_FP_TO_SELF _reg 131 movl rSELF,\_reg 132 movl rPC,offThread_pc(\_reg) 133 movl rFP,offThread_fp(\_reg) 134.endm 135 136.macro LOAD_PC_FP_FROM_SELF 137 movl rSELF,rFP 138 movl offThread_pc(rFP),rPC 139 movl offThread_fp(rFP),rFP 140.endm 141 142/* The interpreter assumes a properly aligned stack on entry, and 143 * will preserve 16-byte alignment. 144 */ 145 146/* 147 * "export" the PC to the interpreted stack frame, f/b/o future exception 148 * objects. Must * be done *before* something calls dvmThrowException. 149 * 150 * In C this is "SAVEAREA_FROM_FP(fp)->xtra.currentPc = pc", i.e. 151 * fp - sizeof(StackSaveArea) + offsetof(SaveArea, xtra.currentPc) 152 * 153 * It's okay to do this more than once. 154 */ 155.macro EXPORT_PC 156 movl rPC, (-sizeofStackSaveArea + offStackSaveArea_currentPc)(rFP) 157.endm 158 159/* 160 * Given a frame pointer, find the stack save area. 161 * 162 * In C this is "((StackSaveArea*)(_fp) -1)". 163 */ 164.macro SAVEAREA_FROM_FP _reg 165 leal -sizeofStackSaveArea(rFP), \_reg 166.endm 167 168/* 169 * Fetch the next instruction from rPC into rINSTw. Does not advance rPC. 170 */ 171.macro FETCH_INST 172 movzwl (rPC),rINST 173.endm 174 175/* 176 * Fetch the opcode byte and zero-extend it into _reg. Must be used 177 * in conjunction with GOTO_NEXT_R 178 */ 179.macro FETCH_INST_R _reg 180 movzbl (rPC),\_reg 181.endm 182 183/* 184 * Fetch the opcode byte at _count words offset from rPC and zero-extend 185 * it into _reg. Must be used in conjunction with GOTO_NEXT_R 186 */ 187.macro FETCH_INST_OPCODE _count _reg 188 movzbl \_count*2(rPC),\_reg 189.endm 190 191/* 192 * Fetch the nth instruction word from rPC into rINSTw. Does not advance 193 * rPC, and _count is in words 194 */ 195.macro FETCH_INST_WORD _count 196 movzwl \_count*2(rPC),rINST 197.endm 198 199/* 200 * Fetch instruction word indexed (used for branching). 201 * Index is in instruction word units. 202 */ 203.macro FETCH_INST_INDEXED _reg 204 movzwl (rPC,\_reg,2),rINST 205.endm 206 207/* 208 * Advance rPC by instruction count 209 */ 210.macro ADVANCE_PC _count 211 leal 2*\_count(rPC),rPC 212.endm 213 214/* 215 * Advance rPC by branch offset in register 216 */ 217.macro ADVANCE_PC_INDEXED _reg 218 leal (rPC,\_reg,2),rPC 219.endm 220 221.macro GOTO_NEXT 222 movzx rINSTbl,%eax 223 movzbl rINSTbh,rINST 224 jmp *dvmAsmInstructionJmpTable(,%eax,4) 225.endm 226 227 /* 228 * Version of GOTO_NEXT that assumes _reg preloaded with opcode. 229 * Should be paired with FETCH_INST_R 230 */ 231.macro GOTO_NEXT_R _reg 232 movzbl 1(rPC),rINST 233 jmp *dvmAsmInstructionJmpTable(,\_reg,4) 234.endm 235 236 /* 237 * Jumbo version of GOTO_NEXT that assumes _reg preloaded with table 238 * offset of the jumbo instruction, which is the top half of the extended 239 * opcode + 0x100. Loads rINST with BBBB field, similar to GOTO_NEXT_R 240 */ 241.macro GOTO_NEXT_JUMBO_R _reg 242 movzwl 6(rPC),rINST 243 jmp *dvmAsmInstructionJmpTable(,\_reg,4) 244.endm 245 246/* 247 * Get/set the 32-bit value from a Dalvik register. 248 */ 249.macro GET_VREG_R _reg _vreg 250 movl (rFP,\_vreg,4),\_reg 251.endm 252 253.macro SET_VREG _reg _vreg 254 movl \_reg,(rFP,\_vreg,4) 255.endm 256 257.macro GET_VREG_WORD _reg _vreg _offset 258 movl 4*(\_offset)(rFP,\_vreg,4),\_reg 259.endm 260 261.macro SET_VREG_WORD _reg _vreg _offset 262 movl \_reg,4*(\_offset)(rFP,\_vreg,4) 263.endm 264 265#if 1 266 267#define rFinish %edx 268 269/* Macros for x86-atom handlers */ 270 /* 271 * Get the 32-bit value from a dalvik register. 272 */ 273 274 .macro GET_VREG _vreg 275 movl (rFP,\_vreg, 4), \_vreg 276 .endm 277 278 /* 279 * Fetch the next instruction from the specified offset. Advances rPC 280 * to point to the next instruction. "_count" is in 16-bit code units. 281 * 282 * This must come AFTER anything that can throw an exception, or the 283 * exception catch may miss. (This also implies that it must come after 284 * EXPORT_PC()) 285 */ 286 287 .macro FETCH_ADVANCE_INST _count 288 add $(\_count*2), rPC 289 movzwl (rPC), rINST 290 .endm 291 292 /* 293 * Fetch the next instruction from an offset specified by _reg. Updates 294 * rPC to point to the next instruction. "_reg" must specify the distance 295 * in bytes, *not* 16-bit code units, and may be a signed value. 296 */ 297 298 .macro FETCH_ADVANCE_INST_RB _reg 299 addl \_reg, rPC 300 movzwl (rPC), rINST 301 .endm 302 303 /* 304 * Fetch a half-word code unit from an offset past the current PC. The 305 * "_count" value is in 16-bit code units. Does not advance rPC. 306 * For example, given instruction of format: AA|op BBBB, it 307 * fetches BBBB. 308 */ 309 310 .macro FETCH _count _reg 311 movzwl (\_count*2)(rPC), \_reg 312 .endm 313 314 /* 315 * Fetch a half-word code unit from an offset past the current PC. The 316 * "_count" value is in 16-bit code units. Does not advance rPC. 317 * This variant treats the value as signed. 318 */ 319 320 .macro FETCHs _count _reg 321 movswl (\_count*2)(rPC), \_reg 322 .endm 323 324 /* 325 * Fetch the first byte from an offset past the current PC. The 326 * "_count" value is in 16-bit code units. Does not advance rPC. 327 * For example, given instruction of format: AA|op CC|BB, it 328 * fetches BB. 329 */ 330 331 .macro FETCH_BB _count _reg 332 movzbl (\_count*2)(rPC), \_reg 333 .endm 334 335 /* 336 * Fetch the second byte from an offset past the current PC. The 337 * "_count" value is in 16-bit code units. Does not advance rPC. 338 * For example, given instruction of format: AA|op CC|BB, it 339 * fetches CC. 340 */ 341 342 .macro FETCH_CC _count _reg 343 movzbl (\_count*2 + 1)(rPC), \_reg 344 .endm 345 346 /* 347 * Fetch the second byte from an offset past the current PC. The 348 * "_count" value is in 16-bit code units. Does not advance rPC. 349 * This variant treats the value as signed. 350 */ 351 352 .macro FETCH_CCs _count _reg 353 movsbl (\_count*2 + 1)(rPC), \_reg 354 .endm 355 356 357 /* 358 * Fetch one byte from an offset past the current PC. Pass in the same 359 * "_count" as you would for FETCH, and an additional 0/1 indicating which 360 * byte of the halfword you want (lo/hi). 361 */ 362 363 .macro FETCH_B _reg _count _byte 364 movzbl (\_count*2+\_byte)(rPC), \_reg 365 .endm 366 367 /* 368 * Put the instruction's opcode field into the specified register. 369 */ 370 371 .macro GET_INST_OPCODE _reg 372 movzbl rINSTbl, \_reg 373 .endm 374 375 /* 376 * Begin executing the opcode in _reg. 377 */ 378 379 .macro GOTO_OPCODE _reg 380 shl $6, \_reg 381 addl $dvmAsmInstructionStart,\_reg 382 jmp *\_reg 383 .endm 384 385 386 387 /* 388 * Macros pair attempts to speed up FETCH_INST, GET_INST_OPCODE and GOTO_OPCODE 389 * by using a jump table. _rFinish should must be the same register for 390 * both macros. 391 */ 392 393 .macro FFETCH _rFinish 394 movzbl (rPC), \_rFinish 395 .endm 396 397 .macro FGETOP_JMPa _rFinish 398 movzbl 1(rPC), rINST 399 jmp *dvmAsmInstructionJmpTable(,\_rFinish, 4) 400 .endm 401 402 /* 403 * Macro pair attempts to speed up FETCH_INST, GET_INST_OPCODE and GOTO_OPCODE 404 * by using a jump table. _rFinish and _count should must be the same register for 405 * both macros. 406 */ 407 408 .macro FFETCH_ADV _count _rFinish 409 movzbl (\_count*2)(rPC), \_rFinish 410 .endm 411 412 .macro FGETOP_JMP _count _rFinish 413 movzbl (\_count*2 + 1)(rPC), rINST 414 addl $(\_count*2), rPC 415 jmp *dvmAsmInstructionJmpTable(,\_rFinish, 4) 416 .endm 417 418 .macro FGETOP_JMP2 _rFinish 419 movzbl 1(rPC), rINST 420 jmp *dvmAsmInstructionJmpTable(,\_rFinish, 4) 421 .endm 422 423 .macro OLD_JMP_1 _count _rFinish 424 movzbl (\_count*2)(rPC), \_rFinish 425 shl $6, \_rFinish 426 .endm 427 428 .macro OLD_JMP_2 _rFinish 429 addl $dvmAsmInstructionStart,\_rFinish 430 .endm 431 432 .macro OLD_JMP_3 _count 433 addl $(\_count*2), rPC 434 .endm 435 436 .macro OLD_JMP_4 _rFinish 437 movzbl 1(rPC), rINST 438 jmp *\_rFinish 439 .endm 440 441 .macro OLD_JMP_A_1 _reg _rFinish 442 movzbl (rPC, \_reg), \_rFinish 443 shl $6, \_rFinish 444 .endm 445 446 .macro OLD_JMP_A_2 _rFinish 447 addl $dvmAsmInstructionStart,\_rFinish 448 .endm 449 450 .macro OLD_JMP_A_3 _reg _rFinish 451 addl \_reg, rPC 452 movzbl 1(rPC, \_reg), rINST 453 jmp *\_rFinish 454 .endm 455 456 /* 457 * Macro pair attempts to speed up FETCH_INST, GET_INST_OPCODE and GOTO_OPCODE 458 * by using a jump table. _rFinish and _reg should must be the same register for 459 * both macros. 460 */ 461 462 .macro FFETCH_ADV_RB _reg _rFinish 463 movzbl (\_reg, rPC), \_rFinish 464 .endm 465 466 .macro FGETOP_RB_JMP _reg _rFinish 467 movzbl 1(\_reg, rPC), rINST 468 addl \_reg, rPC 469 jmp *dvmAsmInstructionJmpTable(,\_rFinish, 4) 470 .endm 471 472 /* 473 * Attempts to speed up FETCH_INST, GET_INST_OPCODE using 474 * a jump table. This macro should be called before FINISH_JMP where 475 * rFinish should be the same register containing the opcode value. 476 * This is an attempt to split up FINISH in order to reduce or remove 477 * potential stalls due to the wait for rFINISH. 478 */ 479 480 .macro FINISH_FETCH _rFinish 481 movzbl (rPC), \_rFinish 482 movzbl 1(rPC), rINST 483 .endm 484 485 486 /* 487 * Attempts to speed up FETCH_ADVANCE_INST, GET_INST_OPCODE using 488 * a jump table. This macro should be called before FINISH_JMP where 489 * rFinish should be the same register containing the opcode value. 490 * This is an attempt to split up FINISH in order to reduce or remove 491 * potential stalls due to the wait for rFINISH. 492 */ 493 494 .macro FINISH_FETCH_ADVANCE _count _rFinish 495 movzbl (\_count*2)(rPC), \_rFinish 496 movzbl (\_count*2 + 1)(rPC), rINST 497 addl $(\_count*2), rPC 498 .endm 499 500 /* 501 * Attempts to speed up FETCH_ADVANCE_INST_RB, GET_INST_OPCODE using 502 * a jump table. This macro should be called before FINISH_JMP where 503 * rFinish should be the same register containing the opcode value. 504 * This is an attempt to split up FINISH in order to reduce or remove 505 * potential stalls due to the wait for rFINISH. 506 */ 507 508 .macro FINISH_FETCH_ADVANCE_RB _reg _rFinish 509 movzbl (\_reg, rPC), \_rFinish 510 movzbl 1(\_reg, rPC), rINST 511 addl \_reg, rPC 512 .endm 513 514 /* 515 * Attempts to speed up GOTO_OPCODE using a jump table. This macro should 516 * be called after a FINISH_FETCH* instruction where rFinish should be the 517 * same register containing the opcode value. This is an attempt to split up 518 * FINISH in order to reduce or remove potential stalls due to the wait for rFINISH. 519 */ 520 521 .macro FINISH_JMP _rFinish 522 jmp *dvmAsmInstructionJmpTable(,\_rFinish, 4) 523 .endm 524 525 /* 526 * Attempts to speed up FETCH_INST, GET_INST_OPCODE, GOTO_OPCODE by using 527 * a jump table. Uses a single macro - but it should be faster if we 528 * split up the fetch for rFinish and the jump using rFinish. 529 */ 530 531 .macro FINISH_A 532 movzbl (rPC), rFinish 533 movzbl 1(rPC), rINST 534 jmp *dvmAsmInstructionJmpTable(,rFinish, 4) 535 .endm 536 537 /* 538 * Attempts to speed up FETCH_ADVANCE_INST, GET_INST_OPCODE, 539 * GOTO_OPCODE by using a jump table. Uses a single macro - 540 * but it should be faster if we split up the fetch for rFinish 541 * and the jump using rFinish. 542 */ 543 544 .macro FINISH _count 545 movzbl (\_count*2)(rPC), rFinish 546 movzbl (\_count*2 + 1)(rPC), rINST 547 addl $(\_count*2), rPC 548 jmp *dvmAsmInstructionJmpTable(,rFinish, 4) 549 .endm 550 551 /* 552 * Attempts to speed up FETCH_ADVANCE_INST_RB, GET_INST_OPCODE, 553 * GOTO_OPCODE by using a jump table. Uses a single macro - 554 * but it should be faster if we split up the fetch for rFinish 555 * and the jump using rFinish. 556 */ 557 558 .macro FINISH_RB _reg _rFinish 559 movzbl (\_reg, rPC), \_rFinish 560 movzbl 1(\_reg, rPC), rINST 561 addl \_reg, rPC 562 jmp *dvmAsmInstructionJmpTable(,\_rFinish, 4) 563 .endm 564 565#define sReg0 LOCAL0_OFFSET(%ebp) 566#define sReg1 LOCAL1_OFFSET(%ebp) 567#define sReg2 LOCAL2_OFFSET(%ebp) 568#define sReg3 LOCAL3_OFFSET(%ebp) 569 570 /* 571 * Hard coded helper values. 572 */ 573 574.balign 16 575 576.LdoubNeg: 577 .quad 0x8000000000000000 578 579.L64bits: 580 .quad 0xFFFFFFFFFFFFFFFF 581 582.LshiftMask2: 583 .quad 0x0000000000000000 584.LshiftMask: 585 .quad 0x000000000000003F 586 587.Lvalue64: 588 .quad 0x0000000000000040 589 590.LvaluePosInfLong: 591 .quad 0x7FFFFFFFFFFFFFFF 592 593.LvalueNegInfLong: 594 .quad 0x8000000000000000 595 596.LvalueNanLong: 597 .quad 0x0000000000000000 598 599.LintMin: 600.long 0x80000000 601 602.LintMax: 603.long 0x7FFFFFFF 604#endif 605 606 607/* 608 * This is a #include, not a %include, because we want the C pre-processor 609 * to expand the macros into assembler assignment statements. 610 */ 611#include "../common/asm-constants.h" 612 613#if defined(WITH_JIT) 614#include "../common/jit-config.h" 615#endif 616 617 618 .global dvmAsmInstructionStart 619 .type dvmAsmInstructionStart, %function 620dvmAsmInstructionStart = .L_OP_NOP 621 .text 622 623/* ------------------------------ */ 624 .balign 64 625.L_OP_NOP: /* 0x00 */ 626/* File: x86/OP_NOP.S */ 627 FETCH_INST_OPCODE 1 %edx 628 ADVANCE_PC 1 629 GOTO_NEXT_R %edx 630 631/* ------------------------------ */ 632 .balign 64 633.L_OP_MOVE: /* 0x01 */ 634/* File: x86/OP_MOVE.S */ 635 /* for move, move-object, long-to-int */ 636 /* op vA, vB */ 637 movzbl rINSTbl,%eax # eax<- BA 638 andb $0xf,%al # eax<- A 639 shrl $4,rINST # rINST<- B 640 GET_VREG_R %ecx rINST 641 FETCH_INST_OPCODE 1 %edx 642 ADVANCE_PC 1 643 SET_VREG %ecx %eax # fp[A]<-fp[B] 644 GOTO_NEXT_R %edx 645 646/* ------------------------------ */ 647 .balign 64 648.L_OP_MOVE_FROM16: /* 0x02 */ 649/* File: x86/OP_MOVE_FROM16.S */ 650 /* for: move/from16, move-object/from16 */ 651 /* op vAA, vBBBB */ 652 movzx rINSTbl,%eax # eax <= AA 653 movw 2(rPC),rINSTw # rINSTw <= BBBB 654 GET_VREG_R %ecx rINST # ecx<- fp[BBBB] 655 FETCH_INST_OPCODE 2 %edx 656 ADVANCE_PC 2 657 SET_VREG %ecx %eax # fp[AA]<- ecx] 658 GOTO_NEXT_R %edx 659 660/* ------------------------------ */ 661 .balign 64 662.L_OP_MOVE_16: /* 0x03 */ 663/* File: x86/OP_MOVE_16.S */ 664 /* for: move/16, move-object/16 */ 665 /* op vAAAA, vBBBB */ 666 movzwl 4(rPC),%ecx # ecx<- BBBB 667 movzwl 2(rPC),%eax # eax<- AAAA 668 GET_VREG_R %ecx %ecx 669 FETCH_INST_OPCODE 3 %edx 670 ADVANCE_PC 3 671 SET_VREG %ecx %eax 672 GOTO_NEXT_R %edx 673 674/* ------------------------------ */ 675 .balign 64 676.L_OP_MOVE_WIDE: /* 0x04 */ 677/* File: x86/OP_MOVE_WIDE.S */ 678 /* move-wide vA, vB */ 679 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 680 movzbl rINSTbl,%ecx # ecx <- BA 681 sarl $4,rINST # rINST<- B 682 GET_VREG_WORD %eax rINST 0 # eax<- v[B+0] 683 GET_VREG_WORD rINST rINST 1 # rINST<- v[B+1] 684 andb $0xf,%cl # ecx <- A 685 FETCH_INST_OPCODE 1 %edx 686 SET_VREG_WORD rINST %ecx 1 # v[A+1]<- rINST 687 ADVANCE_PC 1 688 SET_VREG_WORD %eax %ecx 0 # v[A+0]<- eax 689 GOTO_NEXT_R %edx 690 691/* ------------------------------ */ 692 .balign 64 693.L_OP_MOVE_WIDE_FROM16: /* 0x05 */ 694/* File: x86/OP_MOVE_WIDE_FROM16.S */ 695 /* move-wide/from16 vAA, vBBBB */ 696 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 697 movzwl 2(rPC),%ecx # ecx<- BBBB 698 movzbl rINSTbl,%eax # eax<- AAAA 699 GET_VREG_WORD rINST %ecx 0 # rINST<- v[BBBB+0] 700 GET_VREG_WORD %ecx %ecx 1 # ecx<- v[BBBB+1] 701 FETCH_INST_OPCODE 2 %edx 702 ADVANCE_PC 2 703 SET_VREG_WORD rINST %eax 0 # v[AAAA+0]<- rINST 704 SET_VREG_WORD %ecx %eax 1 # v[AAAA+1]<- eax 705 GOTO_NEXT_R %edx 706 707/* ------------------------------ */ 708 .balign 64 709.L_OP_MOVE_WIDE_16: /* 0x06 */ 710/* File: x86/OP_MOVE_WIDE_16.S */ 711 /* move-wide/16 vAAAA, vBBBB */ 712 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 713 movzwl 4(rPC),%ecx # ecx<- BBBB 714 movzwl 2(rPC),%eax # eax<- AAAA 715 GET_VREG_WORD rINST %ecx 0 # rINSTw_WORD<- v[BBBB+0] 716 GET_VREG_WORD %ecx %ecx 1 # ecx<- v[BBBB+1] 717 FETCH_INST_OPCODE 3 %edx 718 SET_VREG_WORD rINST %eax 0 # v[AAAA+0]<- rINST 719 ADVANCE_PC 3 720 SET_VREG_WORD %ecx %eax 1 # v[AAAA+1]<- ecx 721 GOTO_NEXT_R %edx 722 723/* ------------------------------ */ 724 .balign 64 725.L_OP_MOVE_OBJECT: /* 0x07 */ 726/* File: x86/OP_MOVE_OBJECT.S */ 727/* File: x86/OP_MOVE.S */ 728 /* for move, move-object, long-to-int */ 729 /* op vA, vB */ 730 movzbl rINSTbl,%eax # eax<- BA 731 andb $0xf,%al # eax<- A 732 shrl $4,rINST # rINST<- B 733 GET_VREG_R %ecx rINST 734 FETCH_INST_OPCODE 1 %edx 735 ADVANCE_PC 1 736 SET_VREG %ecx %eax # fp[A]<-fp[B] 737 GOTO_NEXT_R %edx 738 739 740/* ------------------------------ */ 741 .balign 64 742.L_OP_MOVE_OBJECT_FROM16: /* 0x08 */ 743/* File: x86/OP_MOVE_OBJECT_FROM16.S */ 744/* File: x86/OP_MOVE_FROM16.S */ 745 /* for: move/from16, move-object/from16 */ 746 /* op vAA, vBBBB */ 747 movzx rINSTbl,%eax # eax <= AA 748 movw 2(rPC),rINSTw # rINSTw <= BBBB 749 GET_VREG_R %ecx rINST # ecx<- fp[BBBB] 750 FETCH_INST_OPCODE 2 %edx 751 ADVANCE_PC 2 752 SET_VREG %ecx %eax # fp[AA]<- ecx] 753 GOTO_NEXT_R %edx 754 755 756/* ------------------------------ */ 757 .balign 64 758.L_OP_MOVE_OBJECT_16: /* 0x09 */ 759/* File: x86/OP_MOVE_OBJECT_16.S */ 760/* File: x86/OP_MOVE_16.S */ 761 /* for: move/16, move-object/16 */ 762 /* op vAAAA, vBBBB */ 763 movzwl 4(rPC),%ecx # ecx<- BBBB 764 movzwl 2(rPC),%eax # eax<- AAAA 765 GET_VREG_R %ecx %ecx 766 FETCH_INST_OPCODE 3 %edx 767 ADVANCE_PC 3 768 SET_VREG %ecx %eax 769 GOTO_NEXT_R %edx 770 771 772/* ------------------------------ */ 773 .balign 64 774.L_OP_MOVE_RESULT: /* 0x0a */ 775/* File: x86/OP_MOVE_RESULT.S */ 776 /* for: move-result, move-result-object */ 777 /* op vAA */ 778 movl rSELF,%eax # eax<- rSELF 779 movzx rINSTbl,%ecx # ecx<- AA 780 movl offThread_retval(%eax),%eax # eax<- self->retval.l 781 FETCH_INST_OPCODE 1 %edx 782 ADVANCE_PC 1 783 SET_VREG %eax %ecx # fp[AA]<- retval.l 784 GOTO_NEXT_R %edx 785 786/* ------------------------------ */ 787 .balign 64 788.L_OP_MOVE_RESULT_WIDE: /* 0x0b */ 789/* File: x86/OP_MOVE_RESULT_WIDE.S */ 790 /* move-result-wide vAA */ 791 movl rSELF,%ecx 792 movl offThread_retval(%ecx),%eax 793 movl 4+offThread_retval(%ecx),%ecx 794 FETCH_INST_OPCODE 1 %edx 795 SET_VREG_WORD %eax rINST 0 # v[AA+0] <- eax 796 SET_VREG_WORD %ecx rINST 1 # v[AA+1] <- ecx 797 ADVANCE_PC 1 798 GOTO_NEXT_R %edx 799 800/* ------------------------------ */ 801 .balign 64 802.L_OP_MOVE_RESULT_OBJECT: /* 0x0c */ 803/* File: x86/OP_MOVE_RESULT_OBJECT.S */ 804/* File: x86/OP_MOVE_RESULT.S */ 805 /* for: move-result, move-result-object */ 806 /* op vAA */ 807 movl rSELF,%eax # eax<- rSELF 808 movzx rINSTbl,%ecx # ecx<- AA 809 movl offThread_retval(%eax),%eax # eax<- self->retval.l 810 FETCH_INST_OPCODE 1 %edx 811 ADVANCE_PC 1 812 SET_VREG %eax %ecx # fp[AA]<- retval.l 813 GOTO_NEXT_R %edx 814 815 816/* ------------------------------ */ 817 .balign 64 818.L_OP_MOVE_EXCEPTION: /* 0x0d */ 819/* File: x86/OP_MOVE_EXCEPTION.S */ 820 /* move-exception vAA */ 821 movl rSELF,%ecx 822 movl offThread_exception(%ecx),%eax # eax<- dvmGetException bypass 823 SET_VREG %eax rINST # fp[AA]<- exception object 824 FETCH_INST_OPCODE 1 %edx 825 ADVANCE_PC 1 826 movl $0,offThread_exception(%ecx) # dvmClearException bypass 827 GOTO_NEXT_R %edx 828 829/* ------------------------------ */ 830 .balign 64 831.L_OP_RETURN_VOID: /* 0x0e */ 832/* File: x86/OP_RETURN_VOID.S */ 833 jmp common_returnFromMethod 834 835/* ------------------------------ */ 836 .balign 64 837.L_OP_RETURN: /* 0x0f */ 838/* File: x86/OP_RETURN.S */ 839 /* 840 * Return a 32-bit value. Copies the return value into the "self" 841 * structure, then jumps to the return handler. 842 * 843 * for: return, return-object 844 */ 845 /* op vAA */ 846 movl rSELF,%ecx 847 GET_VREG_R %eax rINST # eax<- vAA 848 movl %eax,offThread_retval(%ecx) # retval.i <- AA 849 jmp common_returnFromMethod 850 851/* ------------------------------ */ 852 .balign 64 853.L_OP_RETURN_WIDE: /* 0x10 */ 854/* File: x86/OP_RETURN_WIDE.S */ 855 /* 856 * Return a 64-bit value. Copies the return value into the "self" 857 * structure, then jumps to the return handler. 858 */ 859 /* return-wide vAA */ 860 movl rSELF,%ecx 861 GET_VREG_WORD %eax rINST 0 # eax<- v[AA+0] 862 GET_VREG_WORD rINST rINST 1 # rINST<- v[AA+1] 863 movl %eax,offThread_retval(%ecx) 864 movl rINST,4+offThread_retval(%ecx) 865 jmp common_returnFromMethod 866 867/* ------------------------------ */ 868 .balign 64 869.L_OP_RETURN_OBJECT: /* 0x11 */ 870/* File: x86/OP_RETURN_OBJECT.S */ 871/* File: x86/OP_RETURN.S */ 872 /* 873 * Return a 32-bit value. Copies the return value into the "self" 874 * structure, then jumps to the return handler. 875 * 876 * for: return, return-object 877 */ 878 /* op vAA */ 879 movl rSELF,%ecx 880 GET_VREG_R %eax rINST # eax<- vAA 881 movl %eax,offThread_retval(%ecx) # retval.i <- AA 882 jmp common_returnFromMethod 883 884 885/* ------------------------------ */ 886 .balign 64 887.L_OP_CONST_4: /* 0x12 */ 888/* File: x86/OP_CONST_4.S */ 889 /* const/4 vA, #+B */ 890 movsx rINSTbl,%eax # eax<-ssssssBx 891 movl $0xf,%ecx 892 andl %eax,%ecx # ecx<- A 893 FETCH_INST_OPCODE 1 %edx 894 ADVANCE_PC 1 895 sarl $4,%eax 896 SET_VREG %eax %ecx 897 GOTO_NEXT_R %edx 898 899/* ------------------------------ */ 900 .balign 64 901.L_OP_CONST_16: /* 0x13 */ 902/* File: x86/OP_CONST_16.S */ 903 /* const/16 vAA, #+BBBB */ 904 movswl 2(rPC),%ecx # ecx<- ssssBBBB 905 movl rINST,%eax # eax<- AA 906 FETCH_INST_OPCODE 2 %edx 907 ADVANCE_PC 2 908 SET_VREG %ecx %eax # vAA<- ssssBBBB 909 GOTO_NEXT_R %edx 910 911/* ------------------------------ */ 912 .balign 64 913.L_OP_CONST: /* 0x14 */ 914/* File: x86/OP_CONST.S */ 915 /* const vAA, #+BBBBbbbb */ 916 movl 2(rPC),%eax # grab all 32 bits at once 917 movl rINST,%ecx # ecx<- AA 918 FETCH_INST_OPCODE 3 %edx 919 ADVANCE_PC 3 920 SET_VREG %eax %ecx # vAA<- eax 921 GOTO_NEXT_R %edx 922 923/* ------------------------------ */ 924 .balign 64 925.L_OP_CONST_HIGH16: /* 0x15 */ 926/* File: x86/OP_CONST_HIGH16.S */ 927 /* const/high16 vAA, #+BBBB0000 */ 928 movzwl 2(rPC),%eax # eax<- 0000BBBB 929 movl rINST,%ecx # ecx<- AA 930 FETCH_INST_OPCODE 2 %edx 931 ADVANCE_PC 2 932 sall $16,%eax # eax<- BBBB0000 933 SET_VREG %eax %ecx # vAA<- eax 934 GOTO_NEXT_R %edx 935 936/* ------------------------------ */ 937 .balign 64 938.L_OP_CONST_WIDE_16: /* 0x16 */ 939/* File: x86/OP_CONST_WIDE_16.S */ 940 /* const-wide/16 vAA, #+BBBB */ 941 movswl 2(rPC),%eax # eax<- ssssBBBB 942 cltd # rPC:eax<- ssssssssssssBBBB 943 SET_VREG_WORD %edx rINST 1 # store msw 944 FETCH_INST_OPCODE 2 %edx 945 SET_VREG_WORD %eax rINST 0 # store lsw 946 ADVANCE_PC 2 947 GOTO_NEXT_R %edx 948 949/* ------------------------------ */ 950 .balign 64 951.L_OP_CONST_WIDE_32: /* 0x17 */ 952/* File: x86/OP_CONST_WIDE_32.S */ 953 /* const-wide/32 vAA, #+BBBBbbbb */ 954 movl 2(rPC),%eax # eax<- BBBBbbbb 955 cltd # rPC:eax<- ssssssssssssBBBB 956 SET_VREG_WORD %edx rINST,1 # store msw 957 FETCH_INST_OPCODE 3 %edx 958 SET_VREG_WORD %eax rINST 0 # store lsw 959 ADVANCE_PC 3 960 GOTO_NEXT_R %edx 961 962/* ------------------------------ */ 963 .balign 64 964.L_OP_CONST_WIDE: /* 0x18 */ 965/* File: x86/OP_CONST_WIDE.S */ 966 /* const-wide vAA, #+HHHHhhhhBBBBbbbb */ 967 movl 2(rPC),%eax # eax<- lsw 968 movzbl rINSTbl,%ecx # ecx<- AA 969 movl 6(rPC),rINST # rINST<- msw 970 leal (rFP,%ecx,4),%ecx # dst addr 971 movl rINST,4(%ecx) 972 FETCH_INST_OPCODE 5 %edx 973 movl %eax,(%ecx) 974 ADVANCE_PC 5 975 GOTO_NEXT_R %edx 976 977/* ------------------------------ */ 978 .balign 64 979.L_OP_CONST_WIDE_HIGH16: /* 0x19 */ 980/* File: x86/OP_CONST_WIDE_HIGH16.S */ 981 /* const-wide/high16 vAA, #+BBBB000000000000 */ 982 movzwl 2(rPC),%eax # eax<- 0000BBBB 983 FETCH_INST_OPCODE 2 %edx 984 ADVANCE_PC 2 985 sall $16,%eax # eax<- BBBB0000 986 SET_VREG_WORD %eax rINST 1 # v[AA+1]<- eax 987 xorl %eax,%eax 988 SET_VREG_WORD %eax rINST 0 # v[AA+0]<- eax 989 GOTO_NEXT_R %edx 990 991/* ------------------------------ */ 992 .balign 64 993.L_OP_CONST_STRING: /* 0x1a */ 994/* File: x86/OP_CONST_STRING.S */ 995 996 /* const/string vAA, String@BBBB */ 997 movl rSELF,%ecx 998 movzwl 2(rPC),%eax # eax<- BBBB 999 movl offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex 1000 movl offDvmDex_pResStrings(%ecx),%ecx # ecx<- dvmDex->pResStrings 1001 movl (%ecx,%eax,4),%eax # eax<- rResString[BBBB] 1002 movl rINST,%ecx 1003 FETCH_INST_OPCODE 2 %edx 1004 testl %eax,%eax # resolved yet? 1005 je .LOP_CONST_STRING_resolve 1006 SET_VREG %eax %ecx # vAA<- rResString[BBBB] 1007 ADVANCE_PC 2 1008 GOTO_NEXT_R %edx 1009 1010/* ------------------------------ */ 1011 .balign 64 1012.L_OP_CONST_STRING_JUMBO: /* 0x1b */ 1013/* File: x86/OP_CONST_STRING_JUMBO.S */ 1014 1015 /* const/string vAA, String@BBBBBBBB */ 1016 movl rSELF,%ecx 1017 movl 2(rPC),%eax # eax<- BBBBBBBB 1018 movl offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex 1019 movl offDvmDex_pResStrings(%ecx),%ecx # ecx<- dvmDex->pResStrings 1020 movl (%ecx,%eax,4),%eax # eax<- rResString[BBBB] 1021 movl rINST,%ecx 1022 FETCH_INST_OPCODE 3 %edx 1023 testl %eax,%eax # resolved yet? 1024 je .LOP_CONST_STRING_JUMBO_resolve 1025 SET_VREG %eax %ecx # vAA<- rResString[BBBB] 1026 ADVANCE_PC 3 1027 GOTO_NEXT_R %edx 1028 1029/* ------------------------------ */ 1030 .balign 64 1031.L_OP_CONST_CLASS: /* 0x1c */ 1032/* File: x86/OP_CONST_CLASS.S */ 1033 1034 /* const/class vAA, Class@BBBB */ 1035 movl rSELF,%ecx 1036 movzwl 2(rPC),%eax # eax<- BBBB 1037 movl offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex 1038 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- dvmDex->pResClasses 1039 movl (%ecx,%eax,4),%eax # eax<- rResClasses[BBBB] 1040 movl rINST,%ecx 1041 FETCH_INST_OPCODE 2 %edx 1042 testl %eax,%eax # resolved yet? 1043 je .LOP_CONST_CLASS_resolve 1044 SET_VREG %eax %ecx # vAA<- rResClasses[BBBB] 1045 ADVANCE_PC 2 1046 GOTO_NEXT_R %edx 1047 1048/* ------------------------------ */ 1049 .balign 64 1050.L_OP_MONITOR_ENTER: /* 0x1d */ 1051/* File: x86/OP_MONITOR_ENTER.S */ 1052 /* 1053 * Synchronize on an object. 1054 */ 1055 /* monitor-enter vAA */ 1056 movl rSELF,%ecx 1057 GET_VREG_R %eax rINST # eax<- vAA 1058 FETCH_INST_WORD 1 1059 testl %eax,%eax # null object? 1060 EXPORT_PC # need for precise GC 1061 jne .LOP_MONITOR_ENTER_continue 1062 jmp common_errNullObject 1063 1064/* ------------------------------ */ 1065 .balign 64 1066.L_OP_MONITOR_EXIT: /* 0x1e */ 1067/* File: x86/OP_MONITOR_EXIT.S */ 1068 /* 1069 * Unlock an object. 1070 * 1071 * Exceptions that occur when unlocking a monitor need to appear as 1072 * if they happened at the following instruction. See the Dalvik 1073 * instruction spec. 1074 */ 1075 /* monitor-exit vAA */ 1076 GET_VREG_R %eax rINST 1077 movl rSELF,%ecx 1078 EXPORT_PC 1079 testl %eax,%eax # null object? 1080 je .LOP_MONITOR_EXIT_errNullObject # go if so 1081 movl %eax,OUT_ARG1(%esp) 1082 movl %ecx,OUT_ARG0(%esp) 1083 jmp .LOP_MONITOR_EXIT_continue 1084 1085/* ------------------------------ */ 1086 .balign 64 1087.L_OP_CHECK_CAST: /* 0x1f */ 1088/* File: x86/OP_CHECK_CAST.S */ 1089 /* 1090 * Check to see if a cast from one class to another is allowed. 1091 */ 1092 /* check-cast vAA, class@BBBB */ 1093 movl rSELF,%ecx 1094 GET_VREG_R rINST,rINST # rINST<- vAA (object) 1095 movzwl 2(rPC),%eax # eax<- BBBB 1096 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 1097 testl rINST,rINST # is oject null? 1098 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 1099 je .LOP_CHECK_CAST_okay # null obj, cast always succeeds 1100 movl (%ecx,%eax,4),%eax # eax<- resolved class 1101 movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz 1102 testl %eax,%eax # have we resolved this before? 1103 je .LOP_CHECK_CAST_resolve # no, go do it now 1104.LOP_CHECK_CAST_resolved: 1105 cmpl %eax,%ecx # same class (trivial success)? 1106 jne .LOP_CHECK_CAST_fullcheck # no, do full check 1107.LOP_CHECK_CAST_okay: 1108 FETCH_INST_OPCODE 2 %edx 1109 ADVANCE_PC 2 1110 GOTO_NEXT_R %edx 1111 1112/* ------------------------------ */ 1113 .balign 64 1114.L_OP_INSTANCE_OF: /* 0x20 */ 1115/* File: x86/OP_INSTANCE_OF.S */ 1116 /* 1117 * Check to see if an object reference is an instance of a class. 1118 * 1119 * Most common situation is a non-null object, being compared against 1120 * an already-resolved class. 1121 */ 1122 /* instance-of vA, vB, class@CCCC */ 1123 movl rINST,%eax # eax<- BA 1124 sarl $4,%eax # eax<- B 1125 GET_VREG_R %eax %eax # eax<- vB (obj) 1126 movl rSELF,%ecx 1127 testl %eax,%eax # object null? 1128 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 1129 je .LOP_INSTANCE_OF_store # null obj, not instance, store it 1130 movzwl 2(rPC),%edx # edx<- CCCC 1131 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 1132 movl (%ecx,%edx,4),%ecx # ecx<- resolved class 1133 movl offObject_clazz(%eax),%eax # eax<- obj->clazz 1134 testl %ecx,%ecx # have we resolved this before? 1135 je .LOP_INSTANCE_OF_resolve # not resolved, do it now 1136.LOP_INSTANCE_OF_resolved: # eax<- obj->clazz, ecx<- resolved class 1137 cmpl %eax,%ecx # same class (trivial success)? 1138 je .LOP_INSTANCE_OF_trivial # yes, trivial finish 1139 jmp .LOP_INSTANCE_OF_fullcheck # no, do full check 1140 1141/* ------------------------------ */ 1142 .balign 64 1143.L_OP_ARRAY_LENGTH: /* 0x21 */ 1144/* File: x86/OP_ARRAY_LENGTH.S */ 1145 /* 1146 * Return the length of an array. 1147 */ 1148 mov rINST,%eax # eax<- BA 1149 sarl $4,rINST # rINST<- B 1150 GET_VREG_R %ecx rINST # ecx<- vB (object ref) 1151 andb $0xf,%al # eax<- A 1152 testl %ecx,%ecx # is null? 1153 je common_errNullObject 1154 FETCH_INST_OPCODE 1 %edx 1155 movl offArrayObject_length(%ecx),%ecx 1156 ADVANCE_PC 1 1157 SET_VREG %ecx %eax 1158 GOTO_NEXT_R %edx 1159 1160/* ------------------------------ */ 1161 .balign 64 1162.L_OP_NEW_INSTANCE: /* 0x22 */ 1163/* File: x86/OP_NEW_INSTANCE.S */ 1164 /* 1165 * Create a new instance of a class. 1166 */ 1167 /* new-instance vAA, class@BBBB */ 1168 movl rSELF,%ecx 1169 movzwl 2(rPC),%eax # eax<- BBBB 1170 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 1171 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 1172 EXPORT_PC 1173 movl (%ecx,%eax,4),%ecx # ecx<- resolved class 1174 testl %ecx,%ecx # resolved? 1175 je .LOP_NEW_INSTANCE_resolve # no, go do it 1176.LOP_NEW_INSTANCE_resolved: # on entry, ecx<- class 1177 cmpb $CLASS_INITIALIZED,offClassObject_status(%ecx) 1178 je .LOP_NEW_INSTANCE_initialized 1179 jmp .LOP_NEW_INSTANCE_needinit 1180 1181/* ------------------------------ */ 1182 .balign 64 1183.L_OP_NEW_ARRAY: /* 0x23 */ 1184/* File: x86/OP_NEW_ARRAY.S */ 1185 /* 1186 * Allocate an array of objects, specified with the array class 1187 * and a count. 1188 * 1189 * The verifier guarantees that this is an array class, so we don't 1190 * check for it here. 1191 */ 1192 /* new-array vA, vB, class@CCCC */ 1193 movl rSELF,%ecx 1194 EXPORT_PC 1195 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 1196 movzwl 2(rPC),%eax # eax<- CCCC 1197 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 1198 movl (%ecx,%eax,4),%ecx # ecx<- resolved class 1199 movzbl rINSTbl,%eax 1200 sarl $4,%eax # eax<- B 1201 GET_VREG_R %eax %eax # eax<- vB (array length) 1202 andb $0xf,rINSTbl # rINST<- A 1203 testl %eax,%eax 1204 js common_errNegativeArraySize # bail 1205 testl %ecx,%ecx # already resolved? 1206 jne .LOP_NEW_ARRAY_finish # yes, fast path 1207 jmp .LOP_NEW_ARRAY_resolve # resolve now 1208 1209/* ------------------------------ */ 1210 .balign 64 1211.L_OP_FILLED_NEW_ARRAY: /* 0x24 */ 1212/* File: x86/OP_FILLED_NEW_ARRAY.S */ 1213 /* 1214 * Create a new array with elements filled from registers. 1215 * 1216 * for: filled-new-array, filled-new-array/range 1217 */ 1218 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1219 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1220 movl rSELF,%eax 1221 movl offThread_methodClassDex(%eax),%eax # eax<- pDvmDex 1222 movzwl 2(rPC),%ecx # ecx<- BBBB 1223 movl offDvmDex_pResClasses(%eax),%eax # eax<- pDvmDex->pResClasses 1224 movl (%eax,%ecx,4),%eax # eax<- resolved class 1225 EXPORT_PC 1226 testl %eax,%eax # already resolved? 1227 jne .LOP_FILLED_NEW_ARRAY_continue # yes, continue 1228 # less frequent path, so we'll redo some work 1229 movl rSELF,%eax 1230 movl $0,OUT_ARG2(%esp) # arg2<- false 1231 movl %ecx,OUT_ARG1(%esp) # arg1<- BBBB 1232 movl offThread_method(%eax),%eax # eax<- self->method 1233 jmp .LOP_FILLED_NEW_ARRAY_more 1234 1235/* ------------------------------ */ 1236 .balign 64 1237.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */ 1238/* File: x86/OP_FILLED_NEW_ARRAY_RANGE.S */ 1239/* File: x86/OP_FILLED_NEW_ARRAY.S */ 1240 /* 1241 * Create a new array with elements filled from registers. 1242 * 1243 * for: filled-new-array, filled-new-array/range 1244 */ 1245 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1246 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1247 movl rSELF,%eax 1248 movl offThread_methodClassDex(%eax),%eax # eax<- pDvmDex 1249 movzwl 2(rPC),%ecx # ecx<- BBBB 1250 movl offDvmDex_pResClasses(%eax),%eax # eax<- pDvmDex->pResClasses 1251 movl (%eax,%ecx,4),%eax # eax<- resolved class 1252 EXPORT_PC 1253 testl %eax,%eax # already resolved? 1254 jne .LOP_FILLED_NEW_ARRAY_RANGE_continue # yes, continue 1255 # less frequent path, so we'll redo some work 1256 movl rSELF,%eax 1257 movl $0,OUT_ARG2(%esp) # arg2<- false 1258 movl %ecx,OUT_ARG1(%esp) # arg1<- BBBB 1259 movl offThread_method(%eax),%eax # eax<- self->method 1260 jmp .LOP_FILLED_NEW_ARRAY_RANGE_more 1261 1262 1263/* ------------------------------ */ 1264 .balign 64 1265.L_OP_FILL_ARRAY_DATA: /* 0x26 */ 1266/* File: x86/OP_FILL_ARRAY_DATA.S */ 1267 /* fill-array-data vAA, +BBBBBBBB */ 1268 movl 2(rPC),%ecx # ecx<- BBBBbbbb 1269 leal (rPC,%ecx,2),%ecx # ecx<- PC + BBBBbbbb*2 1270 GET_VREG_R %eax rINST 1271 EXPORT_PC 1272 movl %eax,OUT_ARG0(%esp) 1273 movl %ecx,OUT_ARG1(%esp) 1274 call dvmInterpHandleFillArrayData 1275 FETCH_INST_OPCODE 3 %edx 1276 testl %eax,%eax # exception thrown? 1277 je common_exceptionThrown 1278 ADVANCE_PC 3 1279 GOTO_NEXT_R %edx 1280 1281/* ------------------------------ */ 1282 .balign 64 1283.L_OP_THROW: /* 0x27 */ 1284/* File: x86/OP_THROW.S */ 1285 /* 1286 * Throw an exception object in the current thread. 1287 */ 1288 /* throw vAA */ 1289 EXPORT_PC 1290 GET_VREG_R %eax rINST # eax<- exception object 1291 movl rSELF,%ecx # ecx<- self 1292 testl %eax,%eax # null object? 1293 je common_errNullObject 1294 movl %eax,offThread_exception(%ecx) # thread->exception<- obj 1295 jmp common_exceptionThrown 1296 1297/* ------------------------------ */ 1298 .balign 64 1299.L_OP_GOTO: /* 0x28 */ 1300/* File: x86/OP_GOTO.S */ 1301 /* 1302 * Unconditional branch, 8-bit offset. 1303 * 1304 * The branch distance is a signed code-unit offset, which we need to 1305 * double to get a byte offset. 1306 */ 1307 /* goto +AA */ 1308 movsbl rINSTbl,rINST # ebx<- ssssssAA 1309 testl rINST,rINST # test for <0 1310 js common_backwardBranch 1311 movl rINST,%eax 1312 FETCH_INST_INDEXED %eax 1313 ADVANCE_PC_INDEXED %eax 1314 GOTO_NEXT 1315 1316/* ------------------------------ */ 1317 .balign 64 1318.L_OP_GOTO_16: /* 0x29 */ 1319/* File: x86/OP_GOTO_16.S */ 1320 /* 1321 * Unconditional branch, 16-bit offset. 1322 * 1323 * The branch distance is a signed code-unit offset 1324 */ 1325 /* goto/16 +AAAA */ 1326 movswl 2(rPC),rINST # rINST<- ssssAAAA 1327 testl rINST,rINST # test for <0 1328 js common_backwardBranch 1329 movl rINST,%eax 1330 FETCH_INST_INDEXED %eax 1331 ADVANCE_PC_INDEXED %eax 1332 GOTO_NEXT 1333 1334/* ------------------------------ */ 1335 .balign 64 1336.L_OP_GOTO_32: /* 0x2a */ 1337/* File: x86/OP_GOTO_32.S */ 1338 /* 1339 * Unconditional branch, 32-bit offset. 1340 * 1341 * The branch distance is a signed code-unit offset. 1342 * 1343 * Unlike most opcodes, this one is allowed to branch to itself, so 1344 * our "backward branch" test must be "<=0" instead of "<0". 1345 */ 1346 /* goto/32 AAAAAAAA */ 1347 movl 2(rPC),rINST # rINST<- AAAAAAAA 1348 cmpl $0,rINST # test for <= 0 1349 jle common_backwardBranch 1350 movl rINST,%eax 1351 FETCH_INST_INDEXED %eax 1352 ADVANCE_PC_INDEXED %eax 1353 GOTO_NEXT 1354 1355/* ------------------------------ */ 1356 .balign 64 1357.L_OP_PACKED_SWITCH: /* 0x2b */ 1358/* File: x86/OP_PACKED_SWITCH.S */ 1359 /* 1360 * Handle a packed-switch or sparse-switch instruction. In both cases 1361 * we decode it and hand it off to a helper function. 1362 * 1363 * We don't really expect backward branches in a switch statement, but 1364 * they're perfectly legal, so we check for them here. 1365 * 1366 * for: packed-switch, sparse-switch 1367 */ 1368 /* op vAA, +BBBB */ 1369 movl 2(rPC),%ecx # ecx<- BBBBbbbb 1370 GET_VREG_R %eax rINST # eax<- vAA 1371 leal (rPC,%ecx,2),%ecx # ecx<- PC + BBBBbbbb*2 1372 movl %eax,OUT_ARG1(%esp) # ARG1<- vAA 1373 movl %ecx,OUT_ARG0(%esp) # ARG0<- switchData 1374 call dvmInterpHandlePackedSwitch 1375 testl %eax,%eax 1376 movl %eax,rINST # set up word offset 1377 jle common_backwardBranch # check on special actions 1378 ADVANCE_PC_INDEXED rINST 1379 FETCH_INST 1380 GOTO_NEXT 1381 1382/* ------------------------------ */ 1383 .balign 64 1384.L_OP_SPARSE_SWITCH: /* 0x2c */ 1385/* File: x86/OP_SPARSE_SWITCH.S */ 1386/* File: x86/OP_PACKED_SWITCH.S */ 1387 /* 1388 * Handle a packed-switch or sparse-switch instruction. In both cases 1389 * we decode it and hand it off to a helper function. 1390 * 1391 * We don't really expect backward branches in a switch statement, but 1392 * they're perfectly legal, so we check for them here. 1393 * 1394 * for: packed-switch, sparse-switch 1395 */ 1396 /* op vAA, +BBBB */ 1397 movl 2(rPC),%ecx # ecx<- BBBBbbbb 1398 GET_VREG_R %eax rINST # eax<- vAA 1399 leal (rPC,%ecx,2),%ecx # ecx<- PC + BBBBbbbb*2 1400 movl %eax,OUT_ARG1(%esp) # ARG1<- vAA 1401 movl %ecx,OUT_ARG0(%esp) # ARG0<- switchData 1402 call dvmInterpHandleSparseSwitch 1403 testl %eax,%eax 1404 movl %eax,rINST # set up word offset 1405 jle common_backwardBranch # check on special actions 1406 ADVANCE_PC_INDEXED rINST 1407 FETCH_INST 1408 GOTO_NEXT 1409 1410 1411/* ------------------------------ */ 1412 .balign 64 1413.L_OP_CMPL_FLOAT: /* 0x2d */ 1414/* File: x86/OP_CMPL_FLOAT.S */ 1415/* File: x86/OP_CMPG_DOUBLE.S */ 1416 /* float/double_cmp[gl] vAA, vBB, vCC */ 1417 movzbl 3(rPC),%eax # eax<- CC 1418 movzbl 2(rPC),%ecx # ecx<- BB 1419 .if 0 1420 fldl (rFP,%eax,4) 1421 fldl (rFP,%ecx,4) 1422 .else 1423 flds (rFP,%eax,4) 1424 flds (rFP,%ecx,4) 1425 .endif 1426 xorl %ecx,%ecx 1427 fucompp # z if equal, p set if NaN, c set if st0 < st1 1428 fnstsw %ax 1429 sahf 1430 movl rINST,%eax 1431 FETCH_INST_OPCODE 2 %edx 1432 jp .LOP_CMPL_FLOAT_isNaN 1433 je .LOP_CMPL_FLOAT_finish 1434 sbbl %ecx,%ecx 1435 jb .LOP_CMPL_FLOAT_finish 1436 incl %ecx 1437.LOP_CMPL_FLOAT_finish: 1438 SET_VREG %ecx %eax 1439 ADVANCE_PC 2 1440 GOTO_NEXT_R %edx 1441 1442 1443/* ------------------------------ */ 1444 .balign 64 1445.L_OP_CMPG_FLOAT: /* 0x2e */ 1446/* File: x86/OP_CMPG_FLOAT.S */ 1447/* File: x86/OP_CMPG_DOUBLE.S */ 1448 /* float/double_cmp[gl] vAA, vBB, vCC */ 1449 movzbl 3(rPC),%eax # eax<- CC 1450 movzbl 2(rPC),%ecx # ecx<- BB 1451 .if 0 1452 fldl (rFP,%eax,4) 1453 fldl (rFP,%ecx,4) 1454 .else 1455 flds (rFP,%eax,4) 1456 flds (rFP,%ecx,4) 1457 .endif 1458 xorl %ecx,%ecx 1459 fucompp # z if equal, p set if NaN, c set if st0 < st1 1460 fnstsw %ax 1461 sahf 1462 movl rINST,%eax 1463 FETCH_INST_OPCODE 2 %edx 1464 jp .LOP_CMPG_FLOAT_isNaN 1465 je .LOP_CMPG_FLOAT_finish 1466 sbbl %ecx,%ecx 1467 jb .LOP_CMPG_FLOAT_finish 1468 incl %ecx 1469.LOP_CMPG_FLOAT_finish: 1470 SET_VREG %ecx %eax 1471 ADVANCE_PC 2 1472 GOTO_NEXT_R %edx 1473 1474 1475/* ------------------------------ */ 1476 .balign 64 1477.L_OP_CMPL_DOUBLE: /* 0x2f */ 1478/* File: x86/OP_CMPL_DOUBLE.S */ 1479/* File: x86/OP_CMPG_DOUBLE.S */ 1480 /* float/double_cmp[gl] vAA, vBB, vCC */ 1481 movzbl 3(rPC),%eax # eax<- CC 1482 movzbl 2(rPC),%ecx # ecx<- BB 1483 .if 1 1484 fldl (rFP,%eax,4) 1485 fldl (rFP,%ecx,4) 1486 .else 1487 flds (rFP,%eax,4) 1488 flds (rFP,%ecx,4) 1489 .endif 1490 xorl %ecx,%ecx 1491 fucompp # z if equal, p set if NaN, c set if st0 < st1 1492 fnstsw %ax 1493 sahf 1494 movl rINST,%eax 1495 FETCH_INST_OPCODE 2 %edx 1496 jp .LOP_CMPL_DOUBLE_isNaN 1497 je .LOP_CMPL_DOUBLE_finish 1498 sbbl %ecx,%ecx 1499 jb .LOP_CMPL_DOUBLE_finish 1500 incl %ecx 1501.LOP_CMPL_DOUBLE_finish: 1502 SET_VREG %ecx %eax 1503 ADVANCE_PC 2 1504 GOTO_NEXT_R %edx 1505 1506 1507/* ------------------------------ */ 1508 .balign 64 1509.L_OP_CMPG_DOUBLE: /* 0x30 */ 1510/* File: x86/OP_CMPG_DOUBLE.S */ 1511 /* float/double_cmp[gl] vAA, vBB, vCC */ 1512 movzbl 3(rPC),%eax # eax<- CC 1513 movzbl 2(rPC),%ecx # ecx<- BB 1514 .if 1 1515 fldl (rFP,%eax,4) 1516 fldl (rFP,%ecx,4) 1517 .else 1518 flds (rFP,%eax,4) 1519 flds (rFP,%ecx,4) 1520 .endif 1521 xorl %ecx,%ecx 1522 fucompp # z if equal, p set if NaN, c set if st0 < st1 1523 fnstsw %ax 1524 sahf 1525 movl rINST,%eax 1526 FETCH_INST_OPCODE 2 %edx 1527 jp .LOP_CMPG_DOUBLE_isNaN 1528 je .LOP_CMPG_DOUBLE_finish 1529 sbbl %ecx,%ecx 1530 jb .LOP_CMPG_DOUBLE_finish 1531 incl %ecx 1532.LOP_CMPG_DOUBLE_finish: 1533 SET_VREG %ecx %eax 1534 ADVANCE_PC 2 1535 GOTO_NEXT_R %edx 1536 1537/* ------------------------------ */ 1538 .balign 64 1539.L_OP_CMP_LONG: /* 0x31 */ 1540/* File: x86/OP_CMP_LONG.S */ 1541 /* 1542 * Compare two 64-bit values. Puts 0, 1, or -1 into the destination 1543 * register based on the results of the comparison. 1544 */ 1545 /* cmp-long vAA, vBB, vCC */ 1546 movzbl 2(rPC),%ecx # ecx<- BB 1547 movzbl 3(rPC),%edx # edx<- CC 1548 GET_VREG_WORD %eax %ecx,1 # eax<- v[BB+1] 1549 GET_VREG_WORD %ecx %ecx 0 # ecx<- v[BB+0] 1550 cmpl 4(rFP,%edx,4),%eax 1551 jl .LOP_CMP_LONG_smaller 1552 jg .LOP_CMP_LONG_bigger 1553 sub (rFP,%edx,4),%ecx 1554 ja .LOP_CMP_LONG_bigger 1555 jb .LOP_CMP_LONG_smaller 1556 jmp .LOP_CMP_LONG_finish 1557 1558/* ------------------------------ */ 1559 .balign 64 1560.L_OP_IF_EQ: /* 0x32 */ 1561/* File: x86/OP_IF_EQ.S */ 1562/* File: x86/bincmp.S */ 1563 /* 1564 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1565 * fragment that specifies the *reverse* comparison to perform, e.g. 1566 * for "if-le" you would use "gt". 1567 * 1568 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1569 */ 1570 /* if-cmp vA, vB, +CCCC */ 1571 movzx rINSTbl,%ecx # ecx <- A+ 1572 andb $0xf,%cl # ecx <- A 1573 GET_VREG_R %eax %ecx # eax <- vA 1574 sarl $4,rINST # rINST<- B 1575 cmpl (rFP,rINST,4),%eax # compare (vA, vB) 1576 movswl 2(rPC),rINST # Get signed branch offset 1577 movl $2,%eax # assume not taken 1578 jne 1f 1579 testl rINST,rINST 1580 js common_backwardBranch 1581 movl rINST,%eax 15821: 1583 FETCH_INST_INDEXED %eax 1584 ADVANCE_PC_INDEXED %eax 1585 GOTO_NEXT 1586 1587 1588/* ------------------------------ */ 1589 .balign 64 1590.L_OP_IF_NE: /* 0x33 */ 1591/* File: x86/OP_IF_NE.S */ 1592/* File: x86/bincmp.S */ 1593 /* 1594 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1595 * fragment that specifies the *reverse* comparison to perform, e.g. 1596 * for "if-le" you would use "gt". 1597 * 1598 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1599 */ 1600 /* if-cmp vA, vB, +CCCC */ 1601 movzx rINSTbl,%ecx # ecx <- A+ 1602 andb $0xf,%cl # ecx <- A 1603 GET_VREG_R %eax %ecx # eax <- vA 1604 sarl $4,rINST # rINST<- B 1605 cmpl (rFP,rINST,4),%eax # compare (vA, vB) 1606 movswl 2(rPC),rINST # Get signed branch offset 1607 movl $2,%eax # assume not taken 1608 je 1f 1609 testl rINST,rINST 1610 js common_backwardBranch 1611 movl rINST,%eax 16121: 1613 FETCH_INST_INDEXED %eax 1614 ADVANCE_PC_INDEXED %eax 1615 GOTO_NEXT 1616 1617 1618/* ------------------------------ */ 1619 .balign 64 1620.L_OP_IF_LT: /* 0x34 */ 1621/* File: x86/OP_IF_LT.S */ 1622/* File: x86/bincmp.S */ 1623 /* 1624 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1625 * fragment that specifies the *reverse* comparison to perform, e.g. 1626 * for "if-le" you would use "gt". 1627 * 1628 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1629 */ 1630 /* if-cmp vA, vB, +CCCC */ 1631 movzx rINSTbl,%ecx # ecx <- A+ 1632 andb $0xf,%cl # ecx <- A 1633 GET_VREG_R %eax %ecx # eax <- vA 1634 sarl $4,rINST # rINST<- B 1635 cmpl (rFP,rINST,4),%eax # compare (vA, vB) 1636 movswl 2(rPC),rINST # Get signed branch offset 1637 movl $2,%eax # assume not taken 1638 jge 1f 1639 testl rINST,rINST 1640 js common_backwardBranch 1641 movl rINST,%eax 16421: 1643 FETCH_INST_INDEXED %eax 1644 ADVANCE_PC_INDEXED %eax 1645 GOTO_NEXT 1646 1647 1648/* ------------------------------ */ 1649 .balign 64 1650.L_OP_IF_GE: /* 0x35 */ 1651/* File: x86/OP_IF_GE.S */ 1652/* File: x86/bincmp.S */ 1653 /* 1654 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1655 * fragment that specifies the *reverse* comparison to perform, e.g. 1656 * for "if-le" you would use "gt". 1657 * 1658 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1659 */ 1660 /* if-cmp vA, vB, +CCCC */ 1661 movzx rINSTbl,%ecx # ecx <- A+ 1662 andb $0xf,%cl # ecx <- A 1663 GET_VREG_R %eax %ecx # eax <- vA 1664 sarl $4,rINST # rINST<- B 1665 cmpl (rFP,rINST,4),%eax # compare (vA, vB) 1666 movswl 2(rPC),rINST # Get signed branch offset 1667 movl $2,%eax # assume not taken 1668 jl 1f 1669 testl rINST,rINST 1670 js common_backwardBranch 1671 movl rINST,%eax 16721: 1673 FETCH_INST_INDEXED %eax 1674 ADVANCE_PC_INDEXED %eax 1675 GOTO_NEXT 1676 1677 1678/* ------------------------------ */ 1679 .balign 64 1680.L_OP_IF_GT: /* 0x36 */ 1681/* File: x86/OP_IF_GT.S */ 1682/* File: x86/bincmp.S */ 1683 /* 1684 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1685 * fragment that specifies the *reverse* comparison to perform, e.g. 1686 * for "if-le" you would use "gt". 1687 * 1688 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1689 */ 1690 /* if-cmp vA, vB, +CCCC */ 1691 movzx rINSTbl,%ecx # ecx <- A+ 1692 andb $0xf,%cl # ecx <- A 1693 GET_VREG_R %eax %ecx # eax <- vA 1694 sarl $4,rINST # rINST<- B 1695 cmpl (rFP,rINST,4),%eax # compare (vA, vB) 1696 movswl 2(rPC),rINST # Get signed branch offset 1697 movl $2,%eax # assume not taken 1698 jle 1f 1699 testl rINST,rINST 1700 js common_backwardBranch 1701 movl rINST,%eax 17021: 1703 FETCH_INST_INDEXED %eax 1704 ADVANCE_PC_INDEXED %eax 1705 GOTO_NEXT 1706 1707 1708/* ------------------------------ */ 1709 .balign 64 1710.L_OP_IF_LE: /* 0x37 */ 1711/* File: x86/OP_IF_LE.S */ 1712/* File: x86/bincmp.S */ 1713 /* 1714 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1715 * fragment that specifies the *reverse* comparison to perform, e.g. 1716 * for "if-le" you would use "gt". 1717 * 1718 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1719 */ 1720 /* if-cmp vA, vB, +CCCC */ 1721 movzx rINSTbl,%ecx # ecx <- A+ 1722 andb $0xf,%cl # ecx <- A 1723 GET_VREG_R %eax %ecx # eax <- vA 1724 sarl $4,rINST # rINST<- B 1725 cmpl (rFP,rINST,4),%eax # compare (vA, vB) 1726 movswl 2(rPC),rINST # Get signed branch offset 1727 movl $2,%eax # assume not taken 1728 jg 1f 1729 testl rINST,rINST 1730 js common_backwardBranch 1731 movl rINST,%eax 17321: 1733 FETCH_INST_INDEXED %eax 1734 ADVANCE_PC_INDEXED %eax 1735 GOTO_NEXT 1736 1737 1738/* ------------------------------ */ 1739 .balign 64 1740.L_OP_IF_EQZ: /* 0x38 */ 1741/* File: x86/OP_IF_EQZ.S */ 1742/* File: x86/zcmp.S */ 1743 /* 1744 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1745 * fragment that specifies the *reverse* comparison to perform, e.g. 1746 * for "if-le" you would use "gt". 1747 * 1748 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1749 */ 1750 /* if-cmp vAA, +BBBB */ 1751 cmpl $0,(rFP,rINST,4) # compare (vA, 0) 1752 movswl 2(rPC),rINST # fetch signed displacement 1753 movl $2,%eax # assume branch not taken 1754 jne 1f 1755 testl rINST,rINST 1756 js common_backwardBranch 1757 movl rINST,%eax 17581: 1759 FETCH_INST_INDEXED %eax 1760 ADVANCE_PC_INDEXED %eax 1761 GOTO_NEXT 1762 1763 1764/* ------------------------------ */ 1765 .balign 64 1766.L_OP_IF_NEZ: /* 0x39 */ 1767/* File: x86/OP_IF_NEZ.S */ 1768/* File: x86/zcmp.S */ 1769 /* 1770 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1771 * fragment that specifies the *reverse* comparison to perform, e.g. 1772 * for "if-le" you would use "gt". 1773 * 1774 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1775 */ 1776 /* if-cmp vAA, +BBBB */ 1777 cmpl $0,(rFP,rINST,4) # compare (vA, 0) 1778 movswl 2(rPC),rINST # fetch signed displacement 1779 movl $2,%eax # assume branch not taken 1780 je 1f 1781 testl rINST,rINST 1782 js common_backwardBranch 1783 movl rINST,%eax 17841: 1785 FETCH_INST_INDEXED %eax 1786 ADVANCE_PC_INDEXED %eax 1787 GOTO_NEXT 1788 1789 1790/* ------------------------------ */ 1791 .balign 64 1792.L_OP_IF_LTZ: /* 0x3a */ 1793/* File: x86/OP_IF_LTZ.S */ 1794/* File: x86/zcmp.S */ 1795 /* 1796 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1797 * fragment that specifies the *reverse* comparison to perform, e.g. 1798 * for "if-le" you would use "gt". 1799 * 1800 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1801 */ 1802 /* if-cmp vAA, +BBBB */ 1803 cmpl $0,(rFP,rINST,4) # compare (vA, 0) 1804 movswl 2(rPC),rINST # fetch signed displacement 1805 movl $2,%eax # assume branch not taken 1806 jge 1f 1807 testl rINST,rINST 1808 js common_backwardBranch 1809 movl rINST,%eax 18101: 1811 FETCH_INST_INDEXED %eax 1812 ADVANCE_PC_INDEXED %eax 1813 GOTO_NEXT 1814 1815 1816/* ------------------------------ */ 1817 .balign 64 1818.L_OP_IF_GEZ: /* 0x3b */ 1819/* File: x86/OP_IF_GEZ.S */ 1820/* File: x86/zcmp.S */ 1821 /* 1822 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1823 * fragment that specifies the *reverse* comparison to perform, e.g. 1824 * for "if-le" you would use "gt". 1825 * 1826 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1827 */ 1828 /* if-cmp vAA, +BBBB */ 1829 cmpl $0,(rFP,rINST,4) # compare (vA, 0) 1830 movswl 2(rPC),rINST # fetch signed displacement 1831 movl $2,%eax # assume branch not taken 1832 jl 1f 1833 testl rINST,rINST 1834 js common_backwardBranch 1835 movl rINST,%eax 18361: 1837 FETCH_INST_INDEXED %eax 1838 ADVANCE_PC_INDEXED %eax 1839 GOTO_NEXT 1840 1841 1842/* ------------------------------ */ 1843 .balign 64 1844.L_OP_IF_GTZ: /* 0x3c */ 1845/* File: x86/OP_IF_GTZ.S */ 1846/* File: x86/zcmp.S */ 1847 /* 1848 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1849 * fragment that specifies the *reverse* comparison to perform, e.g. 1850 * for "if-le" you would use "gt". 1851 * 1852 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1853 */ 1854 /* if-cmp vAA, +BBBB */ 1855 cmpl $0,(rFP,rINST,4) # compare (vA, 0) 1856 movswl 2(rPC),rINST # fetch signed displacement 1857 movl $2,%eax # assume branch not taken 1858 jle 1f 1859 testl rINST,rINST 1860 js common_backwardBranch 1861 movl rINST,%eax 18621: 1863 FETCH_INST_INDEXED %eax 1864 ADVANCE_PC_INDEXED %eax 1865 GOTO_NEXT 1866 1867 1868/* ------------------------------ */ 1869 .balign 64 1870.L_OP_IF_LEZ: /* 0x3d */ 1871/* File: x86/OP_IF_LEZ.S */ 1872/* File: x86/zcmp.S */ 1873 /* 1874 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1875 * fragment that specifies the *reverse* comparison to perform, e.g. 1876 * for "if-le" you would use "gt". 1877 * 1878 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1879 */ 1880 /* if-cmp vAA, +BBBB */ 1881 cmpl $0,(rFP,rINST,4) # compare (vA, 0) 1882 movswl 2(rPC),rINST # fetch signed displacement 1883 movl $2,%eax # assume branch not taken 1884 jg 1f 1885 testl rINST,rINST 1886 js common_backwardBranch 1887 movl rINST,%eax 18881: 1889 FETCH_INST_INDEXED %eax 1890 ADVANCE_PC_INDEXED %eax 1891 GOTO_NEXT 1892 1893 1894/* ------------------------------ */ 1895 .balign 64 1896.L_OP_UNUSED_3E: /* 0x3e */ 1897/* File: x86/OP_UNUSED_3E.S */ 1898/* File: x86/unused.S */ 1899 jmp common_abort 1900 1901 1902/* ------------------------------ */ 1903 .balign 64 1904.L_OP_UNUSED_3F: /* 0x3f */ 1905/* File: x86/OP_UNUSED_3F.S */ 1906/* File: x86/unused.S */ 1907 jmp common_abort 1908 1909 1910/* ------------------------------ */ 1911 .balign 64 1912.L_OP_UNUSED_40: /* 0x40 */ 1913/* File: x86/OP_UNUSED_40.S */ 1914/* File: x86/unused.S */ 1915 jmp common_abort 1916 1917 1918/* ------------------------------ */ 1919 .balign 64 1920.L_OP_UNUSED_41: /* 0x41 */ 1921/* File: x86/OP_UNUSED_41.S */ 1922/* File: x86/unused.S */ 1923 jmp common_abort 1924 1925 1926/* ------------------------------ */ 1927 .balign 64 1928.L_OP_UNUSED_42: /* 0x42 */ 1929/* File: x86/OP_UNUSED_42.S */ 1930/* File: x86/unused.S */ 1931 jmp common_abort 1932 1933 1934/* ------------------------------ */ 1935 .balign 64 1936.L_OP_UNUSED_43: /* 0x43 */ 1937/* File: x86/OP_UNUSED_43.S */ 1938/* File: x86/unused.S */ 1939 jmp common_abort 1940 1941 1942/* ------------------------------ */ 1943 .balign 64 1944.L_OP_AGET: /* 0x44 */ 1945/* File: x86/OP_AGET.S */ 1946 /* 1947 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1948 * 1949 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1950 */ 1951 /* op vAA, vBB, vCC */ 1952 movzbl 2(rPC),%eax # eax<- BB 1953 movzbl 3(rPC),%ecx # ecx<- CC 1954 GET_VREG_R %eax %eax # eax<- vBB (array object) 1955 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 1956 testl %eax,%eax # null array object? 1957 je common_errNullObject # bail if so 1958 cmpl offArrayObject_length(%eax),%ecx 1959 jae common_errArrayIndex # index >= length, bail. Expects 1960 # arrayObj in eax 1961 # index in ecx 1962 movl offArrayObject_contents(%eax,%ecx,4),%eax 1963.LOP_AGET_finish: 1964 FETCH_INST_OPCODE 2 %edx 1965 SET_VREG %eax rINST 1966 ADVANCE_PC 2 1967 GOTO_NEXT_R %edx 1968 1969/* ------------------------------ */ 1970 .balign 64 1971.L_OP_AGET_WIDE: /* 0x45 */ 1972/* File: x86/OP_AGET_WIDE.S */ 1973 /* 1974 * Array get, 64 bits. vAA <- vBB[vCC]. 1975 * 1976 */ 1977 /* op vAA, vBB, vCC */ 1978 movzbl 2(rPC),%eax # eax<- BB 1979 movzbl 3(rPC),%ecx # ecx<- CC 1980 GET_VREG_R %eax %eax # eax<- vBB (array object) 1981 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 1982 testl %eax,%eax # null array object? 1983 je common_errNullObject # bail if so 1984 cmpl offArrayObject_length(%eax),%ecx 1985 jb .LOP_AGET_WIDE_finish # index < length, OK 1986 jmp common_errArrayIndex # index >= length, bail. Expects 1987 # arrayObj in eax 1988 # index in ecx 1989 1990/* ------------------------------ */ 1991 .balign 64 1992.L_OP_AGET_OBJECT: /* 0x46 */ 1993/* File: x86/OP_AGET_OBJECT.S */ 1994/* File: x86/OP_AGET.S */ 1995 /* 1996 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1997 * 1998 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1999 */ 2000 /* op vAA, vBB, vCC */ 2001 movzbl 2(rPC),%eax # eax<- BB 2002 movzbl 3(rPC),%ecx # ecx<- CC 2003 GET_VREG_R %eax %eax # eax<- vBB (array object) 2004 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2005 testl %eax,%eax # null array object? 2006 je common_errNullObject # bail if so 2007 cmpl offArrayObject_length(%eax),%ecx 2008 jae common_errArrayIndex # index >= length, bail. Expects 2009 # arrayObj in eax 2010 # index in ecx 2011 movl offArrayObject_contents(%eax,%ecx,4),%eax 2012.LOP_AGET_OBJECT_finish: 2013 FETCH_INST_OPCODE 2 %edx 2014 SET_VREG %eax rINST 2015 ADVANCE_PC 2 2016 GOTO_NEXT_R %edx 2017 2018 2019/* ------------------------------ */ 2020 .balign 64 2021.L_OP_AGET_BOOLEAN: /* 0x47 */ 2022/* File: x86/OP_AGET_BOOLEAN.S */ 2023/* File: x86/OP_AGET.S */ 2024 /* 2025 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2026 * 2027 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2028 */ 2029 /* op vAA, vBB, vCC */ 2030 movzbl 2(rPC),%eax # eax<- BB 2031 movzbl 3(rPC),%ecx # ecx<- CC 2032 GET_VREG_R %eax %eax # eax<- vBB (array object) 2033 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2034 testl %eax,%eax # null array object? 2035 je common_errNullObject # bail if so 2036 cmpl offArrayObject_length(%eax),%ecx 2037 jae common_errArrayIndex # index >= length, bail. Expects 2038 # arrayObj in eax 2039 # index in ecx 2040 movzbl offArrayObject_contents(%eax,%ecx,1),%eax 2041.LOP_AGET_BOOLEAN_finish: 2042 FETCH_INST_OPCODE 2 %edx 2043 SET_VREG %eax rINST 2044 ADVANCE_PC 2 2045 GOTO_NEXT_R %edx 2046 2047 2048/* ------------------------------ */ 2049 .balign 64 2050.L_OP_AGET_BYTE: /* 0x48 */ 2051/* File: x86/OP_AGET_BYTE.S */ 2052/* File: x86/OP_AGET.S */ 2053 /* 2054 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2055 * 2056 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2057 */ 2058 /* op vAA, vBB, vCC */ 2059 movzbl 2(rPC),%eax # eax<- BB 2060 movzbl 3(rPC),%ecx # ecx<- CC 2061 GET_VREG_R %eax %eax # eax<- vBB (array object) 2062 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2063 testl %eax,%eax # null array object? 2064 je common_errNullObject # bail if so 2065 cmpl offArrayObject_length(%eax),%ecx 2066 jae common_errArrayIndex # index >= length, bail. Expects 2067 # arrayObj in eax 2068 # index in ecx 2069 movsbl offArrayObject_contents(%eax,%ecx,1),%eax 2070.LOP_AGET_BYTE_finish: 2071 FETCH_INST_OPCODE 2 %edx 2072 SET_VREG %eax rINST 2073 ADVANCE_PC 2 2074 GOTO_NEXT_R %edx 2075 2076 2077/* ------------------------------ */ 2078 .balign 64 2079.L_OP_AGET_CHAR: /* 0x49 */ 2080/* File: x86/OP_AGET_CHAR.S */ 2081/* File: x86/OP_AGET.S */ 2082 /* 2083 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2084 * 2085 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2086 */ 2087 /* op vAA, vBB, vCC */ 2088 movzbl 2(rPC),%eax # eax<- BB 2089 movzbl 3(rPC),%ecx # ecx<- CC 2090 GET_VREG_R %eax %eax # eax<- vBB (array object) 2091 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2092 testl %eax,%eax # null array object? 2093 je common_errNullObject # bail if so 2094 cmpl offArrayObject_length(%eax),%ecx 2095 jae common_errArrayIndex # index >= length, bail. Expects 2096 # arrayObj in eax 2097 # index in ecx 2098 movzwl offArrayObject_contents(%eax,%ecx,2),%eax 2099.LOP_AGET_CHAR_finish: 2100 FETCH_INST_OPCODE 2 %edx 2101 SET_VREG %eax rINST 2102 ADVANCE_PC 2 2103 GOTO_NEXT_R %edx 2104 2105 2106/* ------------------------------ */ 2107 .balign 64 2108.L_OP_AGET_SHORT: /* 0x4a */ 2109/* File: x86/OP_AGET_SHORT.S */ 2110/* File: x86/OP_AGET.S */ 2111 /* 2112 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2113 * 2114 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2115 */ 2116 /* op vAA, vBB, vCC */ 2117 movzbl 2(rPC),%eax # eax<- BB 2118 movzbl 3(rPC),%ecx # ecx<- CC 2119 GET_VREG_R %eax %eax # eax<- vBB (array object) 2120 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2121 testl %eax,%eax # null array object? 2122 je common_errNullObject # bail if so 2123 cmpl offArrayObject_length(%eax),%ecx 2124 jae common_errArrayIndex # index >= length, bail. Expects 2125 # arrayObj in eax 2126 # index in ecx 2127 movswl offArrayObject_contents(%eax,%ecx,2),%eax 2128.LOP_AGET_SHORT_finish: 2129 FETCH_INST_OPCODE 2 %edx 2130 SET_VREG %eax rINST 2131 ADVANCE_PC 2 2132 GOTO_NEXT_R %edx 2133 2134 2135/* ------------------------------ */ 2136 .balign 64 2137.L_OP_APUT: /* 0x4b */ 2138/* File: x86/OP_APUT.S */ 2139 /* 2140 * Array put, 32 bits or less. vBB[vCC] <- vAA 2141 * 2142 * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short 2143 */ 2144 /* op vAA, vBB, vCC */ 2145 movzbl 2(rPC),%eax # eax<- BB 2146 movzbl 3(rPC),%ecx # ecx<- CC 2147 GET_VREG_R %eax %eax # eax<- vBB (array object) 2148 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2149 testl %eax,%eax # null array object? 2150 je common_errNullObject # bail if so 2151 cmpl offArrayObject_length(%eax),%ecx 2152 jae common_errArrayIndex # index >= length, bail. Expects: 2153 # arrayObj in eax 2154 # index in ecx 2155 leal offArrayObject_contents(%eax,%ecx,4),%eax 2156.LOP_APUT_finish: 2157 GET_VREG_R %ecx rINST 2158 FETCH_INST_OPCODE 2 %edx 2159 movl %ecx,(%eax) 2160 ADVANCE_PC 2 2161 GOTO_NEXT_R %edx 2162 2163/* ------------------------------ */ 2164 .balign 64 2165.L_OP_APUT_WIDE: /* 0x4c */ 2166/* File: x86/OP_APUT_WIDE.S */ 2167 /* 2168 * Array put, 64 bits. vBB[vCC]<-vAA. 2169 * 2170 */ 2171 /* op vAA, vBB, vCC */ 2172 movzbl 2(rPC),%eax # eax<- BB 2173 movzbl 3(rPC),%ecx # ecx<- CC 2174 GET_VREG_R %eax %eax # eax<- vBB (array object) 2175 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2176 testl %eax,%eax # null array object? 2177 je common_errNullObject # bail if so 2178 cmpl offArrayObject_length(%eax),%ecx 2179 jb .LOP_APUT_WIDE_finish # index < length, OK 2180 jmp common_errArrayIndex # index >= length, bail. Expects: 2181 # arrayObj in eax 2182 # index in ecx 2183 2184/* ------------------------------ */ 2185 .balign 64 2186.L_OP_APUT_OBJECT: /* 0x4d */ 2187/* File: x86/OP_APUT_OBJECT.S */ 2188 /* 2189 * Array put, 32 bits or less. vBB[vCC] <- vAA 2190 * 2191 * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short 2192 */ 2193 /* op vAA, vBB, vCC */ 2194 movzbl 2(rPC),%eax # eax<- BB 2195 movzbl 3(rPC),%ecx # ecx<- CC 2196 GET_VREG_R %eax %eax # eax<- vBB (array object) 2197 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2198 GET_VREG_R rINST rINST # rINST<- vAA 2199 testl %eax,%eax # null array object? 2200 je common_errNullObject # bail if so 2201 cmpl offArrayObject_length(%eax),%ecx 2202 jb .LOP_APUT_OBJECT_continue 2203 jmp common_errArrayIndex # index >= length, bail. Expects 2204 # arrayObj in eax 2205 # index in ecx 2206 2207/* ------------------------------ */ 2208 .balign 64 2209.L_OP_APUT_BOOLEAN: /* 0x4e */ 2210/* File: x86/OP_APUT_BOOLEAN.S */ 2211/* File: x86/OP_APUT.S */ 2212 /* 2213 * Array put, 32 bits or less. vBB[vCC] <- vAA 2214 * 2215 * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short 2216 */ 2217 /* op vAA, vBB, vCC */ 2218 movzbl 2(rPC),%eax # eax<- BB 2219 movzbl 3(rPC),%ecx # ecx<- CC 2220 GET_VREG_R %eax %eax # eax<- vBB (array object) 2221 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2222 testl %eax,%eax # null array object? 2223 je common_errNullObject # bail if so 2224 cmpl offArrayObject_length(%eax),%ecx 2225 jae common_errArrayIndex # index >= length, bail. Expects: 2226 # arrayObj in eax 2227 # index in ecx 2228 leal offArrayObject_contents(%eax,%ecx,1),%eax 2229.LOP_APUT_BOOLEAN_finish: 2230 GET_VREG_R %ecx rINST 2231 FETCH_INST_OPCODE 2 %edx 2232 movb %cl,(%eax) 2233 ADVANCE_PC 2 2234 GOTO_NEXT_R %edx 2235 2236 2237/* ------------------------------ */ 2238 .balign 64 2239.L_OP_APUT_BYTE: /* 0x4f */ 2240/* File: x86/OP_APUT_BYTE.S */ 2241/* File: x86/OP_APUT.S */ 2242 /* 2243 * Array put, 32 bits or less. vBB[vCC] <- vAA 2244 * 2245 * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short 2246 */ 2247 /* op vAA, vBB, vCC */ 2248 movzbl 2(rPC),%eax # eax<- BB 2249 movzbl 3(rPC),%ecx # ecx<- CC 2250 GET_VREG_R %eax %eax # eax<- vBB (array object) 2251 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2252 testl %eax,%eax # null array object? 2253 je common_errNullObject # bail if so 2254 cmpl offArrayObject_length(%eax),%ecx 2255 jae common_errArrayIndex # index >= length, bail. Expects: 2256 # arrayObj in eax 2257 # index in ecx 2258 leal offArrayObject_contents(%eax,%ecx,1),%eax 2259.LOP_APUT_BYTE_finish: 2260 GET_VREG_R %ecx rINST 2261 FETCH_INST_OPCODE 2 %edx 2262 movb %cl,(%eax) 2263 ADVANCE_PC 2 2264 GOTO_NEXT_R %edx 2265 2266 2267/* ------------------------------ */ 2268 .balign 64 2269.L_OP_APUT_CHAR: /* 0x50 */ 2270/* File: x86/OP_APUT_CHAR.S */ 2271/* File: x86/OP_APUT.S */ 2272 /* 2273 * Array put, 32 bits or less. vBB[vCC] <- vAA 2274 * 2275 * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short 2276 */ 2277 /* op vAA, vBB, vCC */ 2278 movzbl 2(rPC),%eax # eax<- BB 2279 movzbl 3(rPC),%ecx # ecx<- CC 2280 GET_VREG_R %eax %eax # eax<- vBB (array object) 2281 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2282 testl %eax,%eax # null array object? 2283 je common_errNullObject # bail if so 2284 cmpl offArrayObject_length(%eax),%ecx 2285 jae common_errArrayIndex # index >= length, bail. Expects: 2286 # arrayObj in eax 2287 # index in ecx 2288 leal offArrayObject_contents(%eax,%ecx,2),%eax 2289.LOP_APUT_CHAR_finish: 2290 GET_VREG_R %ecx rINST 2291 FETCH_INST_OPCODE 2 %edx 2292 movw %cx,(%eax) 2293 ADVANCE_PC 2 2294 GOTO_NEXT_R %edx 2295 2296 2297/* ------------------------------ */ 2298 .balign 64 2299.L_OP_APUT_SHORT: /* 0x51 */ 2300/* File: x86/OP_APUT_SHORT.S */ 2301/* File: x86/OP_APUT.S */ 2302 /* 2303 * Array put, 32 bits or less. vBB[vCC] <- vAA 2304 * 2305 * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short 2306 */ 2307 /* op vAA, vBB, vCC */ 2308 movzbl 2(rPC),%eax # eax<- BB 2309 movzbl 3(rPC),%ecx # ecx<- CC 2310 GET_VREG_R %eax %eax # eax<- vBB (array object) 2311 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2312 testl %eax,%eax # null array object? 2313 je common_errNullObject # bail if so 2314 cmpl offArrayObject_length(%eax),%ecx 2315 jae common_errArrayIndex # index >= length, bail. Expects: 2316 # arrayObj in eax 2317 # index in ecx 2318 leal offArrayObject_contents(%eax,%ecx,2),%eax 2319.LOP_APUT_SHORT_finish: 2320 GET_VREG_R %ecx rINST 2321 FETCH_INST_OPCODE 2 %edx 2322 movw %cx,(%eax) 2323 ADVANCE_PC 2 2324 GOTO_NEXT_R %edx 2325 2326 2327/* ------------------------------ */ 2328 .balign 64 2329.L_OP_IGET: /* 0x52 */ 2330/* File: x86/OP_IGET.S */ 2331 /* 2332 * General 32-bit instance field get. 2333 * 2334 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2335 */ 2336 /* op vA, vB, field@CCCC */ 2337 movl rSELF,%ecx 2338 movzwl 2(rPC),%edx # edx<- 0000CCCC 2339 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2340 movzbl rINSTbl,%ecx # ecx<- BA 2341 sarl $4,%ecx # ecx<- B 2342 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2343 andb $0xf,rINSTbl # rINST<- A 2344 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2345 movl (%eax,%edx,4),%eax # resolved entry 2346 testl %eax,%eax # is resolved entry null? 2347 jne .LOP_IGET_finish # no, already resolved 2348 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 2349 movl rSELF,%edx 2350 jmp .LOP_IGET_resolve 2351 2352/* ------------------------------ */ 2353 .balign 64 2354.L_OP_IGET_WIDE: /* 0x53 */ 2355/* File: x86/OP_IGET_WIDE.S */ 2356 /* 2357 * 64-bit instance field get. 2358 * 2359 */ 2360 /* op vA, vB, field@CCCC */ 2361 movl rSELF,%ecx 2362 movzwl 2(rPC),%edx # edx<- 0000CCCC 2363 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2364 movzbl rINSTbl,%ecx # ecx<- BA 2365 sarl $4,%ecx # ecx<- B 2366 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2367 andb $0xf,rINSTbl # rINST<- A 2368 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2369 movl (%eax,%edx,4),%eax # resolved entry 2370 testl %eax,%eax # is resolved entry null? 2371 jne .LOP_IGET_WIDE_finish # no, already resolved 2372 movl %edx,OUT_ARG1(%esp) # for dvmResolveInstField 2373 movl rSELF,%edx 2374 jmp .LOP_IGET_WIDE_resolve 2375 2376/* ------------------------------ */ 2377 .balign 64 2378.L_OP_IGET_OBJECT: /* 0x54 */ 2379/* File: x86/OP_IGET_OBJECT.S */ 2380/* File: x86/OP_IGET.S */ 2381 /* 2382 * General 32-bit instance field get. 2383 * 2384 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2385 */ 2386 /* op vA, vB, field@CCCC */ 2387 movl rSELF,%ecx 2388 movzwl 2(rPC),%edx # edx<- 0000CCCC 2389 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2390 movzbl rINSTbl,%ecx # ecx<- BA 2391 sarl $4,%ecx # ecx<- B 2392 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2393 andb $0xf,rINSTbl # rINST<- A 2394 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2395 movl (%eax,%edx,4),%eax # resolved entry 2396 testl %eax,%eax # is resolved entry null? 2397 jne .LOP_IGET_OBJECT_finish # no, already resolved 2398 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 2399 movl rSELF,%edx 2400 jmp .LOP_IGET_OBJECT_resolve 2401 2402 2403/* ------------------------------ */ 2404 .balign 64 2405.L_OP_IGET_BOOLEAN: /* 0x55 */ 2406/* File: x86/OP_IGET_BOOLEAN.S */ 2407/* File: x86/OP_IGET.S */ 2408 /* 2409 * General 32-bit instance field get. 2410 * 2411 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2412 */ 2413 /* op vA, vB, field@CCCC */ 2414 movl rSELF,%ecx 2415 movzwl 2(rPC),%edx # edx<- 0000CCCC 2416 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2417 movzbl rINSTbl,%ecx # ecx<- BA 2418 sarl $4,%ecx # ecx<- B 2419 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2420 andb $0xf,rINSTbl # rINST<- A 2421 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2422 movl (%eax,%edx,4),%eax # resolved entry 2423 testl %eax,%eax # is resolved entry null? 2424 jne .LOP_IGET_BOOLEAN_finish # no, already resolved 2425 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 2426 movl rSELF,%edx 2427 jmp .LOP_IGET_BOOLEAN_resolve 2428 2429 2430/* ------------------------------ */ 2431 .balign 64 2432.L_OP_IGET_BYTE: /* 0x56 */ 2433/* File: x86/OP_IGET_BYTE.S */ 2434/* File: x86/OP_IGET.S */ 2435 /* 2436 * General 32-bit instance field get. 2437 * 2438 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2439 */ 2440 /* op vA, vB, field@CCCC */ 2441 movl rSELF,%ecx 2442 movzwl 2(rPC),%edx # edx<- 0000CCCC 2443 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2444 movzbl rINSTbl,%ecx # ecx<- BA 2445 sarl $4,%ecx # ecx<- B 2446 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2447 andb $0xf,rINSTbl # rINST<- A 2448 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2449 movl (%eax,%edx,4),%eax # resolved entry 2450 testl %eax,%eax # is resolved entry null? 2451 jne .LOP_IGET_BYTE_finish # no, already resolved 2452 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 2453 movl rSELF,%edx 2454 jmp .LOP_IGET_BYTE_resolve 2455 2456 2457/* ------------------------------ */ 2458 .balign 64 2459.L_OP_IGET_CHAR: /* 0x57 */ 2460/* File: x86/OP_IGET_CHAR.S */ 2461/* File: x86/OP_IGET.S */ 2462 /* 2463 * General 32-bit instance field get. 2464 * 2465 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2466 */ 2467 /* op vA, vB, field@CCCC */ 2468 movl rSELF,%ecx 2469 movzwl 2(rPC),%edx # edx<- 0000CCCC 2470 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2471 movzbl rINSTbl,%ecx # ecx<- BA 2472 sarl $4,%ecx # ecx<- B 2473 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2474 andb $0xf,rINSTbl # rINST<- A 2475 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2476 movl (%eax,%edx,4),%eax # resolved entry 2477 testl %eax,%eax # is resolved entry null? 2478 jne .LOP_IGET_CHAR_finish # no, already resolved 2479 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 2480 movl rSELF,%edx 2481 jmp .LOP_IGET_CHAR_resolve 2482 2483 2484/* ------------------------------ */ 2485 .balign 64 2486.L_OP_IGET_SHORT: /* 0x58 */ 2487/* File: x86/OP_IGET_SHORT.S */ 2488/* File: x86/OP_IGET.S */ 2489 /* 2490 * General 32-bit instance field get. 2491 * 2492 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2493 */ 2494 /* op vA, vB, field@CCCC */ 2495 movl rSELF,%ecx 2496 movzwl 2(rPC),%edx # edx<- 0000CCCC 2497 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2498 movzbl rINSTbl,%ecx # ecx<- BA 2499 sarl $4,%ecx # ecx<- B 2500 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2501 andb $0xf,rINSTbl # rINST<- A 2502 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2503 movl (%eax,%edx,4),%eax # resolved entry 2504 testl %eax,%eax # is resolved entry null? 2505 jne .LOP_IGET_SHORT_finish # no, already resolved 2506 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 2507 movl rSELF,%edx 2508 jmp .LOP_IGET_SHORT_resolve 2509 2510 2511/* ------------------------------ */ 2512 .balign 64 2513.L_OP_IPUT: /* 0x59 */ 2514/* File: x86/OP_IPUT.S */ 2515 2516 /* 2517 * General 32-bit instance field put. 2518 * 2519 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 2520 */ 2521 /* op vA, vB, field@CCCC */ 2522 movl rSELF,%ecx 2523 movzwl 2(rPC),%edx # %edx<- 0000CCCC 2524 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2525 movzbl rINSTbl,%ecx # ecx<- BA 2526 sarl $4,%ecx # ecx<- B 2527 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2528 andb $0xf,rINSTbl # rINST<- A 2529 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2530 movl (%eax,%edx,4),%eax # resolved entry 2531 testl %eax,%eax # is resolved entry null? 2532 jne .LOP_IPUT_finish # no, already resolved 2533 movl %edx,OUT_ARG1(%esp) 2534 movl rSELF,%edx 2535 jmp .LOP_IPUT_resolve 2536 2537/* ------------------------------ */ 2538 .balign 64 2539.L_OP_IPUT_WIDE: /* 0x5a */ 2540/* File: x86/OP_IPUT_WIDE.S */ 2541 /* 2542 * 64-bit instance field put. 2543 * 2544 */ 2545 /* op vA, vB, field@CCCC */ 2546 movl rSELF,%ecx 2547 movzwl 2(rPC),%edx # edx<- 0000CCCC 2548 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2549 movzbl rINSTbl,%ecx # ecx<- BA 2550 sarl $4,%ecx # ecx<- B 2551 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2552 andb $0xf,rINSTbl # rINST<- A 2553 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2554 movl (%eax,%edx,4),%eax # resolved entry 2555 testl %eax,%eax # is resolved entry null? 2556 jne .LOP_IPUT_WIDE_finish # no, already resolved 2557 movl %edx,OUT_ARG1(%esp) 2558 movl rSELF,%edx 2559 jmp .LOP_IPUT_WIDE_resolve 2560 2561/* ------------------------------ */ 2562 .balign 64 2563.L_OP_IPUT_OBJECT: /* 0x5b */ 2564/* File: x86/OP_IPUT_OBJECT.S */ 2565 /* 2566 * Object field put. 2567 * 2568 * for: iput-object 2569 */ 2570 /* op vA, vB, field@CCCC */ 2571 movl rSELF,%ecx 2572 movzwl 2(rPC),%edx # edx<- 0000CCCC 2573 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2574 movzbl rINSTbl,%ecx # ecx<- BA 2575 sarl $4,%ecx # ecx<- B 2576 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2577 andb $0xf,rINSTbl # rINST<- A 2578 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2579 movl (%eax,%edx,4),%eax # resolved entry 2580 testl %eax,%eax # is resolved entry null? 2581 jne .LOP_IPUT_OBJECT_finish # no, already resolved 2582 movl %edx,OUT_ARG1(%esp) 2583 movl rSELF,%edx 2584 jmp .LOP_IPUT_OBJECT_resolve 2585 2586/* ------------------------------ */ 2587 .balign 64 2588.L_OP_IPUT_BOOLEAN: /* 0x5c */ 2589/* File: x86/OP_IPUT_BOOLEAN.S */ 2590/* File: x86/OP_IPUT.S */ 2591 2592 /* 2593 * General 32-bit instance field put. 2594 * 2595 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 2596 */ 2597 /* op vA, vB, field@CCCC */ 2598 movl rSELF,%ecx 2599 movzwl 2(rPC),%edx # %edx<- 0000CCCC 2600 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2601 movzbl rINSTbl,%ecx # ecx<- BA 2602 sarl $4,%ecx # ecx<- B 2603 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2604 andb $0xf,rINSTbl # rINST<- A 2605 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2606 movl (%eax,%edx,4),%eax # resolved entry 2607 testl %eax,%eax # is resolved entry null? 2608 jne .LOP_IPUT_BOOLEAN_finish # no, already resolved 2609 movl %edx,OUT_ARG1(%esp) 2610 movl rSELF,%edx 2611 jmp .LOP_IPUT_BOOLEAN_resolve 2612 2613 2614/* ------------------------------ */ 2615 .balign 64 2616.L_OP_IPUT_BYTE: /* 0x5d */ 2617/* File: x86/OP_IPUT_BYTE.S */ 2618/* File: x86/OP_IPUT.S */ 2619 2620 /* 2621 * General 32-bit instance field put. 2622 * 2623 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 2624 */ 2625 /* op vA, vB, field@CCCC */ 2626 movl rSELF,%ecx 2627 movzwl 2(rPC),%edx # %edx<- 0000CCCC 2628 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2629 movzbl rINSTbl,%ecx # ecx<- BA 2630 sarl $4,%ecx # ecx<- B 2631 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2632 andb $0xf,rINSTbl # rINST<- A 2633 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2634 movl (%eax,%edx,4),%eax # resolved entry 2635 testl %eax,%eax # is resolved entry null? 2636 jne .LOP_IPUT_BYTE_finish # no, already resolved 2637 movl %edx,OUT_ARG1(%esp) 2638 movl rSELF,%edx 2639 jmp .LOP_IPUT_BYTE_resolve 2640 2641 2642/* ------------------------------ */ 2643 .balign 64 2644.L_OP_IPUT_CHAR: /* 0x5e */ 2645/* File: x86/OP_IPUT_CHAR.S */ 2646/* File: x86/OP_IPUT.S */ 2647 2648 /* 2649 * General 32-bit instance field put. 2650 * 2651 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 2652 */ 2653 /* op vA, vB, field@CCCC */ 2654 movl rSELF,%ecx 2655 movzwl 2(rPC),%edx # %edx<- 0000CCCC 2656 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2657 movzbl rINSTbl,%ecx # ecx<- BA 2658 sarl $4,%ecx # ecx<- B 2659 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2660 andb $0xf,rINSTbl # rINST<- A 2661 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2662 movl (%eax,%edx,4),%eax # resolved entry 2663 testl %eax,%eax # is resolved entry null? 2664 jne .LOP_IPUT_CHAR_finish # no, already resolved 2665 movl %edx,OUT_ARG1(%esp) 2666 movl rSELF,%edx 2667 jmp .LOP_IPUT_CHAR_resolve 2668 2669 2670/* ------------------------------ */ 2671 .balign 64 2672.L_OP_IPUT_SHORT: /* 0x5f */ 2673/* File: x86/OP_IPUT_SHORT.S */ 2674/* File: x86/OP_IPUT.S */ 2675 2676 /* 2677 * General 32-bit instance field put. 2678 * 2679 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 2680 */ 2681 /* op vA, vB, field@CCCC */ 2682 movl rSELF,%ecx 2683 movzwl 2(rPC),%edx # %edx<- 0000CCCC 2684 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 2685 movzbl rINSTbl,%ecx # ecx<- BA 2686 sarl $4,%ecx # ecx<- B 2687 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2688 andb $0xf,rINSTbl # rINST<- A 2689 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2690 movl (%eax,%edx,4),%eax # resolved entry 2691 testl %eax,%eax # is resolved entry null? 2692 jne .LOP_IPUT_SHORT_finish # no, already resolved 2693 movl %edx,OUT_ARG1(%esp) 2694 movl rSELF,%edx 2695 jmp .LOP_IPUT_SHORT_resolve 2696 2697 2698/* ------------------------------ */ 2699 .balign 64 2700.L_OP_SGET: /* 0x60 */ 2701/* File: x86/OP_SGET.S */ 2702 /* 2703 * General 32-bit SGET handler. 2704 * 2705 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2706 */ 2707 /* op vAA, field@BBBB */ 2708 movl rSELF,%ecx 2709 movzwl 2(rPC),%eax # eax<- field ref BBBB 2710 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2711 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2712 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2713 testl %eax,%eax # resolved entry null? 2714 je .LOP_SGET_resolve # if not, make it so 2715.LOP_SGET_finish: # field ptr in eax 2716 movl offStaticField_value(%eax),%eax 2717 FETCH_INST_OPCODE 2 %edx 2718 ADVANCE_PC 2 2719 SET_VREG %eax rINST 2720 GOTO_NEXT_R %edx 2721 2722/* ------------------------------ */ 2723 .balign 64 2724.L_OP_SGET_WIDE: /* 0x61 */ 2725/* File: x86/OP_SGET_WIDE.S */ 2726 /* 2727 * 64-bit SGET handler. 2728 * 2729 */ 2730 /* sget-wide vAA, field@BBBB */ 2731 movl rSELF,%ecx 2732 movzwl 2(rPC),%eax # eax<- field ref BBBB 2733 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2734 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2735 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2736 testl %eax,%eax # resolved entry null? 2737 je .LOP_SGET_WIDE_resolve # if not, make it so 2738.LOP_SGET_WIDE_finish: # field ptr in eax 2739 movl offStaticField_value(%eax),%ecx # ecx<- lsw 2740 movl 4+offStaticField_value(%eax),%eax # eax<- msw 2741 FETCH_INST_OPCODE 2 %edx 2742 ADVANCE_PC 2 2743 SET_VREG_WORD %ecx rINST 0 2744 SET_VREG_WORD %eax rINST 1 2745 GOTO_NEXT_R %edx 2746 2747/* ------------------------------ */ 2748 .balign 64 2749.L_OP_SGET_OBJECT: /* 0x62 */ 2750/* File: x86/OP_SGET_OBJECT.S */ 2751/* File: x86/OP_SGET.S */ 2752 /* 2753 * General 32-bit SGET handler. 2754 * 2755 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2756 */ 2757 /* op vAA, field@BBBB */ 2758 movl rSELF,%ecx 2759 movzwl 2(rPC),%eax # eax<- field ref BBBB 2760 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2761 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2762 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2763 testl %eax,%eax # resolved entry null? 2764 je .LOP_SGET_OBJECT_resolve # if not, make it so 2765.LOP_SGET_OBJECT_finish: # field ptr in eax 2766 movl offStaticField_value(%eax),%eax 2767 FETCH_INST_OPCODE 2 %edx 2768 ADVANCE_PC 2 2769 SET_VREG %eax rINST 2770 GOTO_NEXT_R %edx 2771 2772 2773/* ------------------------------ */ 2774 .balign 64 2775.L_OP_SGET_BOOLEAN: /* 0x63 */ 2776/* File: x86/OP_SGET_BOOLEAN.S */ 2777/* File: x86/OP_SGET.S */ 2778 /* 2779 * General 32-bit SGET handler. 2780 * 2781 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2782 */ 2783 /* op vAA, field@BBBB */ 2784 movl rSELF,%ecx 2785 movzwl 2(rPC),%eax # eax<- field ref BBBB 2786 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2787 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2788 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2789 testl %eax,%eax # resolved entry null? 2790 je .LOP_SGET_BOOLEAN_resolve # if not, make it so 2791.LOP_SGET_BOOLEAN_finish: # field ptr in eax 2792 movl offStaticField_value(%eax),%eax 2793 FETCH_INST_OPCODE 2 %edx 2794 ADVANCE_PC 2 2795 SET_VREG %eax rINST 2796 GOTO_NEXT_R %edx 2797 2798 2799/* ------------------------------ */ 2800 .balign 64 2801.L_OP_SGET_BYTE: /* 0x64 */ 2802/* File: x86/OP_SGET_BYTE.S */ 2803/* File: x86/OP_SGET.S */ 2804 /* 2805 * General 32-bit SGET handler. 2806 * 2807 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2808 */ 2809 /* op vAA, field@BBBB */ 2810 movl rSELF,%ecx 2811 movzwl 2(rPC),%eax # eax<- field ref BBBB 2812 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2813 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2814 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2815 testl %eax,%eax # resolved entry null? 2816 je .LOP_SGET_BYTE_resolve # if not, make it so 2817.LOP_SGET_BYTE_finish: # field ptr in eax 2818 movl offStaticField_value(%eax),%eax 2819 FETCH_INST_OPCODE 2 %edx 2820 ADVANCE_PC 2 2821 SET_VREG %eax rINST 2822 GOTO_NEXT_R %edx 2823 2824 2825/* ------------------------------ */ 2826 .balign 64 2827.L_OP_SGET_CHAR: /* 0x65 */ 2828/* File: x86/OP_SGET_CHAR.S */ 2829/* File: x86/OP_SGET.S */ 2830 /* 2831 * General 32-bit SGET handler. 2832 * 2833 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2834 */ 2835 /* op vAA, field@BBBB */ 2836 movl rSELF,%ecx 2837 movzwl 2(rPC),%eax # eax<- field ref BBBB 2838 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2839 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2840 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2841 testl %eax,%eax # resolved entry null? 2842 je .LOP_SGET_CHAR_resolve # if not, make it so 2843.LOP_SGET_CHAR_finish: # field ptr in eax 2844 movl offStaticField_value(%eax),%eax 2845 FETCH_INST_OPCODE 2 %edx 2846 ADVANCE_PC 2 2847 SET_VREG %eax rINST 2848 GOTO_NEXT_R %edx 2849 2850 2851/* ------------------------------ */ 2852 .balign 64 2853.L_OP_SGET_SHORT: /* 0x66 */ 2854/* File: x86/OP_SGET_SHORT.S */ 2855/* File: x86/OP_SGET.S */ 2856 /* 2857 * General 32-bit SGET handler. 2858 * 2859 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2860 */ 2861 /* op vAA, field@BBBB */ 2862 movl rSELF,%ecx 2863 movzwl 2(rPC),%eax # eax<- field ref BBBB 2864 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2865 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2866 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2867 testl %eax,%eax # resolved entry null? 2868 je .LOP_SGET_SHORT_resolve # if not, make it so 2869.LOP_SGET_SHORT_finish: # field ptr in eax 2870 movl offStaticField_value(%eax),%eax 2871 FETCH_INST_OPCODE 2 %edx 2872 ADVANCE_PC 2 2873 SET_VREG %eax rINST 2874 GOTO_NEXT_R %edx 2875 2876 2877/* ------------------------------ */ 2878 .balign 64 2879.L_OP_SPUT: /* 0x67 */ 2880/* File: x86/OP_SPUT.S */ 2881 /* 2882 * General 32-bit SPUT handler. 2883 * 2884 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2885 */ 2886 /* op vAA, field@BBBB */ 2887 movl rSELF,%ecx 2888 movzwl 2(rPC),%eax # eax<- field ref BBBB 2889 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2890 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2891 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2892 testl %eax,%eax # resolved entry null? 2893 je .LOP_SPUT_resolve # if not, make it so 2894.LOP_SPUT_finish: # field ptr in eax 2895 GET_VREG_R %ecx rINST 2896 FETCH_INST_OPCODE 2 %edx 2897 ADVANCE_PC 2 2898 movl %ecx,offStaticField_value(%eax) 2899 GOTO_NEXT_R %edx 2900 2901/* ------------------------------ */ 2902 .balign 64 2903.L_OP_SPUT_WIDE: /* 0x68 */ 2904/* File: x86/OP_SPUT_WIDE.S */ 2905 /* 2906 * General 32-bit SPUT handler. 2907 * 2908 * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short 2909 */ 2910 /* op vAA, field@BBBB */ 2911 movl rSELF,%ecx 2912 movzwl 2(rPC),%eax # eax<- field ref BBBB 2913 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2914 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2915 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2916 testl %eax,%eax # resolved entry null? 2917 je .LOP_SPUT_WIDE_resolve # if not, make it so 2918.LOP_SPUT_WIDE_finish: # field ptr in eax 2919 GET_VREG_WORD %ecx rINST 0 # rINST<- lsw 2920 GET_VREG_WORD rINST rINST 1 # ecx<- msw 2921 FETCH_INST_OPCODE 2 %edx 2922 ADVANCE_PC 2 2923 movl %ecx,offStaticField_value(%eax) 2924 movl rINST,4+offStaticField_value(%eax) 2925 GOTO_NEXT_R %edx 2926 2927/* ------------------------------ */ 2928 .balign 64 2929.L_OP_SPUT_OBJECT: /* 0x69 */ 2930/* File: x86/OP_SPUT_OBJECT.S */ 2931 /* 2932 * SPUT object handler. 2933 */ 2934 /* op vAA, field@BBBB */ 2935 movl rSELF,%ecx 2936 movzwl 2(rPC),%eax # eax<- field ref BBBB 2937 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2938 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2939 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField 2940 testl %eax,%eax # resolved entry null? 2941 je .LOP_SPUT_OBJECT_resolve # if not, make it so 2942.LOP_SPUT_OBJECT_finish: # field ptr in eax 2943 movzbl rINSTbl,%ecx # ecx<- AA 2944 GET_VREG_R %ecx %ecx 2945 jmp .LOP_SPUT_OBJECT_continue 2946 2947/* ------------------------------ */ 2948 .balign 64 2949.L_OP_SPUT_BOOLEAN: /* 0x6a */ 2950/* File: x86/OP_SPUT_BOOLEAN.S */ 2951/* File: x86/OP_SPUT.S */ 2952 /* 2953 * General 32-bit SPUT handler. 2954 * 2955 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2956 */ 2957 /* op vAA, field@BBBB */ 2958 movl rSELF,%ecx 2959 movzwl 2(rPC),%eax # eax<- field ref BBBB 2960 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2961 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2962 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2963 testl %eax,%eax # resolved entry null? 2964 je .LOP_SPUT_BOOLEAN_resolve # if not, make it so 2965.LOP_SPUT_BOOLEAN_finish: # field ptr in eax 2966 GET_VREG_R %ecx rINST 2967 FETCH_INST_OPCODE 2 %edx 2968 ADVANCE_PC 2 2969 movl %ecx,offStaticField_value(%eax) 2970 GOTO_NEXT_R %edx 2971 2972 2973/* ------------------------------ */ 2974 .balign 64 2975.L_OP_SPUT_BYTE: /* 0x6b */ 2976/* File: x86/OP_SPUT_BYTE.S */ 2977/* File: x86/OP_SPUT.S */ 2978 /* 2979 * General 32-bit SPUT handler. 2980 * 2981 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2982 */ 2983 /* op vAA, field@BBBB */ 2984 movl rSELF,%ecx 2985 movzwl 2(rPC),%eax # eax<- field ref BBBB 2986 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2987 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2988 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2989 testl %eax,%eax # resolved entry null? 2990 je .LOP_SPUT_BYTE_resolve # if not, make it so 2991.LOP_SPUT_BYTE_finish: # field ptr in eax 2992 GET_VREG_R %ecx rINST 2993 FETCH_INST_OPCODE 2 %edx 2994 ADVANCE_PC 2 2995 movl %ecx,offStaticField_value(%eax) 2996 GOTO_NEXT_R %edx 2997 2998 2999/* ------------------------------ */ 3000 .balign 64 3001.L_OP_SPUT_CHAR: /* 0x6c */ 3002/* File: x86/OP_SPUT_CHAR.S */ 3003/* File: x86/OP_SPUT.S */ 3004 /* 3005 * General 32-bit SPUT handler. 3006 * 3007 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3008 */ 3009 /* op vAA, field@BBBB */ 3010 movl rSELF,%ecx 3011 movzwl 2(rPC),%eax # eax<- field ref BBBB 3012 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 3013 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 3014 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 3015 testl %eax,%eax # resolved entry null? 3016 je .LOP_SPUT_CHAR_resolve # if not, make it so 3017.LOP_SPUT_CHAR_finish: # field ptr in eax 3018 GET_VREG_R %ecx rINST 3019 FETCH_INST_OPCODE 2 %edx 3020 ADVANCE_PC 2 3021 movl %ecx,offStaticField_value(%eax) 3022 GOTO_NEXT_R %edx 3023 3024 3025/* ------------------------------ */ 3026 .balign 64 3027.L_OP_SPUT_SHORT: /* 0x6d */ 3028/* File: x86/OP_SPUT_SHORT.S */ 3029/* File: x86/OP_SPUT.S */ 3030 /* 3031 * General 32-bit SPUT handler. 3032 * 3033 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3034 */ 3035 /* op vAA, field@BBBB */ 3036 movl rSELF,%ecx 3037 movzwl 2(rPC),%eax # eax<- field ref BBBB 3038 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 3039 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 3040 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 3041 testl %eax,%eax # resolved entry null? 3042 je .LOP_SPUT_SHORT_resolve # if not, make it so 3043.LOP_SPUT_SHORT_finish: # field ptr in eax 3044 GET_VREG_R %ecx rINST 3045 FETCH_INST_OPCODE 2 %edx 3046 ADVANCE_PC 2 3047 movl %ecx,offStaticField_value(%eax) 3048 GOTO_NEXT_R %edx 3049 3050 3051/* ------------------------------ */ 3052 .balign 64 3053.L_OP_INVOKE_VIRTUAL: /* 0x6e */ 3054/* File: x86/OP_INVOKE_VIRTUAL.S */ 3055 3056 /* 3057 * Handle a virtual method call. 3058 * 3059 * for: invoke-virtual, invoke-virtual/range 3060 */ 3061 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3062 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3063 movl rSELF,%eax 3064 movzwl 2(rPC),%ecx # ecx<- BBBB 3065 movl offThread_methodClassDex(%eax),%eax # eax<- pDvmDex 3066 EXPORT_PC 3067 movl offDvmDex_pResMethods(%eax),%eax # eax<- pDvmDex->pResMethods 3068 movl (%eax,%ecx,4),%eax # eax<- resolved baseMethod 3069 testl %eax,%eax # already resolved? 3070 jne .LOP_INVOKE_VIRTUAL_continue # yes, continue 3071 movl rSELF,%eax 3072 movl %ecx,OUT_ARG1(%esp) # arg1<- ref 3073 movl offThread_method(%eax),%eax # eax<- self->method 3074 jmp .LOP_INVOKE_VIRTUAL_more 3075 3076/* ------------------------------ */ 3077 .balign 64 3078.L_OP_INVOKE_SUPER: /* 0x6f */ 3079/* File: x86/OP_INVOKE_SUPER.S */ 3080 /* 3081 * Handle a "super" method call. 3082 * 3083 * for: invoke-super, invoke-super/range 3084 */ 3085 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3086 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3087 movl rSELF,rINST 3088 movzwl 2(rPC),%eax # eax<- BBBB 3089 movl offThread_methodClassDex(rINST),%ecx # ecx<- pDvmDex 3090 EXPORT_PC 3091 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 3092 movl (%ecx,%eax,4),%ecx # ecx<- resolved baseMethod 3093 movl offThread_method(rINST),%eax # eax<- method 3094 movzwl 4(rPC),rINST # rINST<- GFED or CCCC 3095 .if (!0) 3096 andl $0xf,rINST # rINST<- D (or stays CCCC) 3097 .endif 3098 GET_VREG_R rINST rINST # rINST<- "this" ptr 3099 testl rINST,rINST # null "this"? 3100 je common_errNullObject # yes, throw 3101 movl offMethod_clazz(%eax),%eax # eax<- method->clazz 3102 testl %ecx,%ecx # already resolved? 3103 jne .LOP_INVOKE_SUPER_continue # yes - go on 3104 jmp .LOP_INVOKE_SUPER_resolve 3105 3106/* ------------------------------ */ 3107 .balign 64 3108.L_OP_INVOKE_DIRECT: /* 0x70 */ 3109/* File: x86/OP_INVOKE_DIRECT.S */ 3110 /* 3111 * Handle a direct method call. 3112 * 3113 * (We could defer the "is 'this' pointer null" test to the common 3114 * method invocation code, and use a flag to indicate that static 3115 * calls don't count. If we do this as part of copying the arguments 3116 * out we could avoiding loading the first arg twice.) 3117 * 3118 * for: invoke-direct, invoke-direct/range 3119 */ 3120 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3121 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3122 movl rSELF,%ecx 3123 movzwl 2(rPC),%eax # eax<- BBBB 3124 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 3125 EXPORT_PC 3126 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 3127 movzwl 4(rPC),%edx # edx<- GFED or CCCC 3128 movl (%ecx,%eax,4),%eax # eax<- resolved methodToCall 3129 .if (!0) 3130 andl $0xf,%edx # edx<- D (or stays CCCC) 3131 .endif 3132 testl %eax,%eax # already resolved? 3133 GET_VREG_R %ecx %edx # ecx<- "this" ptr 3134 je .LOP_INVOKE_DIRECT_resolve # not resolved, do it now 3135.LOP_INVOKE_DIRECT_finish: 3136 testl %ecx,%ecx # null "this"? 3137 jne common_invokeMethodNoRange # no, continue on 3138 jmp common_errNullObject 3139 3140/* ------------------------------ */ 3141 .balign 64 3142.L_OP_INVOKE_STATIC: /* 0x71 */ 3143/* File: x86/OP_INVOKE_STATIC.S */ 3144 /* 3145 * Handle a static method call. 3146 * 3147 * for: invoke-static, invoke-static/range 3148 */ 3149 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3150 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3151 movl rSELF,%ecx 3152 movzwl 2(rPC),%eax # eax<- BBBB 3153 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 3154 EXPORT_PC 3155 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 3156 movl (%ecx,%eax,4),%eax # eax<- resolved methodToCall 3157 testl %eax,%eax 3158 jne common_invokeMethodNoRange 3159 movl rSELF,%ecx 3160 movl offThread_method(%ecx),%ecx # ecx<- self->method 3161 movzwl 2(rPC),%eax 3162 movl offMethod_clazz(%ecx),%ecx# ecx<- method->clazz 3163 movl %eax,OUT_ARG1(%esp) # arg1<- BBBB 3164 movl %ecx,OUT_ARG0(%esp) # arg0<- clazz 3165 jmp .LOP_INVOKE_STATIC_continue 3166 3167/* ------------------------------ */ 3168 .balign 64 3169.L_OP_INVOKE_INTERFACE: /* 0x72 */ 3170/* File: x86/OP_INVOKE_INTERFACE.S */ 3171 /* 3172 * Handle an interface method call. 3173 * 3174 * for: invoke-interface, invoke-interface/range 3175 */ 3176 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3177 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3178 movzwl 4(rPC),%eax # eax<- FEDC or CCCC 3179 movl rSELF,%ecx 3180 .if (!0) 3181 andl $0xf,%eax # eax<- C (or stays CCCC) 3182 .endif 3183 GET_VREG_R %eax %eax # eax<- "this" 3184 EXPORT_PC 3185 testl %eax,%eax # null this? 3186 je common_errNullObject # yes, fail 3187 movl offObject_clazz(%eax),%eax# eax<- thisPtr->clazz 3188 movl %eax,OUT_ARG0(%esp) # arg0<- class 3189 movl offThread_methodClassDex(%ecx),%eax # eax<- methodClassDex 3190 movl offThread_method(%ecx),%ecx # ecx<- method 3191 movl %eax,OUT_ARG3(%esp) # arg3<- dex 3192 movzwl 2(rPC),%eax # eax<- BBBB 3193 movl %ecx,OUT_ARG2(%esp) # arg2<- method 3194 movl %eax,OUT_ARG1(%esp) # arg1<- BBBB 3195 jmp .LOP_INVOKE_INTERFACE_continue 3196 3197/* ------------------------------ */ 3198 .balign 64 3199.L_OP_UNUSED_73: /* 0x73 */ 3200/* File: x86/OP_UNUSED_73.S */ 3201/* File: x86/unused.S */ 3202 jmp common_abort 3203 3204 3205/* ------------------------------ */ 3206 .balign 64 3207.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */ 3208/* File: x86/OP_INVOKE_VIRTUAL_RANGE.S */ 3209/* File: x86/OP_INVOKE_VIRTUAL.S */ 3210 3211 /* 3212 * Handle a virtual method call. 3213 * 3214 * for: invoke-virtual, invoke-virtual/range 3215 */ 3216 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3217 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3218 movl rSELF,%eax 3219 movzwl 2(rPC),%ecx # ecx<- BBBB 3220 movl offThread_methodClassDex(%eax),%eax # eax<- pDvmDex 3221 EXPORT_PC 3222 movl offDvmDex_pResMethods(%eax),%eax # eax<- pDvmDex->pResMethods 3223 movl (%eax,%ecx,4),%eax # eax<- resolved baseMethod 3224 testl %eax,%eax # already resolved? 3225 jne .LOP_INVOKE_VIRTUAL_RANGE_continue # yes, continue 3226 movl rSELF,%eax 3227 movl %ecx,OUT_ARG1(%esp) # arg1<- ref 3228 movl offThread_method(%eax),%eax # eax<- self->method 3229 jmp .LOP_INVOKE_VIRTUAL_RANGE_more 3230 3231 3232/* ------------------------------ */ 3233 .balign 64 3234.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */ 3235/* File: x86/OP_INVOKE_SUPER_RANGE.S */ 3236/* File: x86/OP_INVOKE_SUPER.S */ 3237 /* 3238 * Handle a "super" method call. 3239 * 3240 * for: invoke-super, invoke-super/range 3241 */ 3242 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3243 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3244 movl rSELF,rINST 3245 movzwl 2(rPC),%eax # eax<- BBBB 3246 movl offThread_methodClassDex(rINST),%ecx # ecx<- pDvmDex 3247 EXPORT_PC 3248 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 3249 movl (%ecx,%eax,4),%ecx # ecx<- resolved baseMethod 3250 movl offThread_method(rINST),%eax # eax<- method 3251 movzwl 4(rPC),rINST # rINST<- GFED or CCCC 3252 .if (!1) 3253 andl $0xf,rINST # rINST<- D (or stays CCCC) 3254 .endif 3255 GET_VREG_R rINST rINST # rINST<- "this" ptr 3256 testl rINST,rINST # null "this"? 3257 je common_errNullObject # yes, throw 3258 movl offMethod_clazz(%eax),%eax # eax<- method->clazz 3259 testl %ecx,%ecx # already resolved? 3260 jne .LOP_INVOKE_SUPER_RANGE_continue # yes - go on 3261 jmp .LOP_INVOKE_SUPER_RANGE_resolve 3262 3263 3264/* ------------------------------ */ 3265 .balign 64 3266.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */ 3267/* File: x86/OP_INVOKE_DIRECT_RANGE.S */ 3268/* File: x86/OP_INVOKE_DIRECT.S */ 3269 /* 3270 * Handle a direct method call. 3271 * 3272 * (We could defer the "is 'this' pointer null" test to the common 3273 * method invocation code, and use a flag to indicate that static 3274 * calls don't count. If we do this as part of copying the arguments 3275 * out we could avoiding loading the first arg twice.) 3276 * 3277 * for: invoke-direct, invoke-direct/range 3278 */ 3279 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3280 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3281 movl rSELF,%ecx 3282 movzwl 2(rPC),%eax # eax<- BBBB 3283 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 3284 EXPORT_PC 3285 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 3286 movzwl 4(rPC),%edx # edx<- GFED or CCCC 3287 movl (%ecx,%eax,4),%eax # eax<- resolved methodToCall 3288 .if (!1) 3289 andl $0xf,%edx # edx<- D (or stays CCCC) 3290 .endif 3291 testl %eax,%eax # already resolved? 3292 GET_VREG_R %ecx %edx # ecx<- "this" ptr 3293 je .LOP_INVOKE_DIRECT_RANGE_resolve # not resolved, do it now 3294.LOP_INVOKE_DIRECT_RANGE_finish: 3295 testl %ecx,%ecx # null "this"? 3296 jne common_invokeMethodRange # no, continue on 3297 jmp common_errNullObject 3298 3299 3300/* ------------------------------ */ 3301 .balign 64 3302.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */ 3303/* File: x86/OP_INVOKE_STATIC_RANGE.S */ 3304/* File: x86/OP_INVOKE_STATIC.S */ 3305 /* 3306 * Handle a static method call. 3307 * 3308 * for: invoke-static, invoke-static/range 3309 */ 3310 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3311 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3312 movl rSELF,%ecx 3313 movzwl 2(rPC),%eax # eax<- BBBB 3314 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 3315 EXPORT_PC 3316 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 3317 movl (%ecx,%eax,4),%eax # eax<- resolved methodToCall 3318 testl %eax,%eax 3319 jne common_invokeMethodRange 3320 movl rSELF,%ecx 3321 movl offThread_method(%ecx),%ecx # ecx<- self->method 3322 movzwl 2(rPC),%eax 3323 movl offMethod_clazz(%ecx),%ecx# ecx<- method->clazz 3324 movl %eax,OUT_ARG1(%esp) # arg1<- BBBB 3325 movl %ecx,OUT_ARG0(%esp) # arg0<- clazz 3326 jmp .LOP_INVOKE_STATIC_RANGE_continue 3327 3328 3329/* ------------------------------ */ 3330 .balign 64 3331.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */ 3332/* File: x86/OP_INVOKE_INTERFACE_RANGE.S */ 3333/* File: x86/OP_INVOKE_INTERFACE.S */ 3334 /* 3335 * Handle an interface method call. 3336 * 3337 * for: invoke-interface, invoke-interface/range 3338 */ 3339 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3340 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3341 movzwl 4(rPC),%eax # eax<- FEDC or CCCC 3342 movl rSELF,%ecx 3343 .if (!1) 3344 andl $0xf,%eax # eax<- C (or stays CCCC) 3345 .endif 3346 GET_VREG_R %eax %eax # eax<- "this" 3347 EXPORT_PC 3348 testl %eax,%eax # null this? 3349 je common_errNullObject # yes, fail 3350 movl offObject_clazz(%eax),%eax# eax<- thisPtr->clazz 3351 movl %eax,OUT_ARG0(%esp) # arg0<- class 3352 movl offThread_methodClassDex(%ecx),%eax # eax<- methodClassDex 3353 movl offThread_method(%ecx),%ecx # ecx<- method 3354 movl %eax,OUT_ARG3(%esp) # arg3<- dex 3355 movzwl 2(rPC),%eax # eax<- BBBB 3356 movl %ecx,OUT_ARG2(%esp) # arg2<- method 3357 movl %eax,OUT_ARG1(%esp) # arg1<- BBBB 3358 jmp .LOP_INVOKE_INTERFACE_RANGE_continue 3359 3360 3361/* ------------------------------ */ 3362 .balign 64 3363.L_OP_UNUSED_79: /* 0x79 */ 3364/* File: x86/OP_UNUSED_79.S */ 3365/* File: x86/unused.S */ 3366 jmp common_abort 3367 3368 3369/* ------------------------------ */ 3370 .balign 64 3371.L_OP_UNUSED_7A: /* 0x7a */ 3372/* File: x86/OP_UNUSED_7A.S */ 3373/* File: x86/unused.S */ 3374 jmp common_abort 3375 3376 3377/* ------------------------------ */ 3378 .balign 64 3379.L_OP_NEG_INT: /* 0x7b */ 3380/* File: x86/OP_NEG_INT.S */ 3381/* File: x86/unop.S */ 3382 /* 3383 * Generic 32-bit unary operation. Provide an "instr" line that 3384 * specifies an instruction that performs "result = op eax". 3385 */ 3386 /* unop vA, vB */ 3387 movzbl rINSTbl,%ecx # ecx<- A+ 3388 sarl $4,rINST # rINST<- B 3389 GET_VREG_R %eax rINST # eax<- vB 3390 andb $0xf,%cl # ecx<- A 3391 FETCH_INST_OPCODE 1 %edx 3392 ADVANCE_PC 1 3393 3394 3395 negl %eax 3396 SET_VREG %eax %ecx 3397 GOTO_NEXT_R %edx 3398 3399 3400/* ------------------------------ */ 3401 .balign 64 3402.L_OP_NOT_INT: /* 0x7c */ 3403/* File: x86/OP_NOT_INT.S */ 3404/* File: x86/unop.S */ 3405 /* 3406 * Generic 32-bit unary operation. Provide an "instr" line that 3407 * specifies an instruction that performs "result = op eax". 3408 */ 3409 /* unop vA, vB */ 3410 movzbl rINSTbl,%ecx # ecx<- A+ 3411 sarl $4,rINST # rINST<- B 3412 GET_VREG_R %eax rINST # eax<- vB 3413 andb $0xf,%cl # ecx<- A 3414 FETCH_INST_OPCODE 1 %edx 3415 ADVANCE_PC 1 3416 3417 3418 notl %eax 3419 SET_VREG %eax %ecx 3420 GOTO_NEXT_R %edx 3421 3422 3423/* ------------------------------ */ 3424 .balign 64 3425.L_OP_NEG_LONG: /* 0x7d */ 3426/* File: x86/OP_NEG_LONG.S */ 3427 /* unop vA, vB */ 3428 movzbl rINSTbl,%ecx # ecx<- BA 3429 sarl $4,%ecx # ecx<- B 3430 andb $0xf,rINSTbl # rINST<- A 3431 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 3432 GET_VREG_WORD %ecx %ecx 1 # ecx<- v[B+1] 3433 negl %eax 3434 adcl $0,%ecx 3435 negl %ecx 3436 FETCH_INST_OPCODE 1 %edx 3437 SET_VREG_WORD %eax rINST 0 # v[A+0]<- eax 3438 SET_VREG_WORD %ecx rINST 1 # v[A+1]<- ecx 3439 ADVANCE_PC 1 3440 GOTO_NEXT_R %edx 3441 3442/* ------------------------------ */ 3443 .balign 64 3444.L_OP_NOT_LONG: /* 0x7e */ 3445/* File: x86/OP_NOT_LONG.S */ 3446 /* unop vA, vB */ 3447 movzbl rINSTbl,%ecx # ecx<- BA 3448 sarl $4,%ecx # ecx<- B 3449 andb $0xf,rINSTbl # rINST<- A 3450 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 3451 GET_VREG_WORD %ecx %ecx 1 # ecx<- v[B+1] 3452 FETCH_INST_OPCODE 1 %edx 3453 notl %eax 3454 notl %ecx 3455 SET_VREG_WORD %eax rINST 0 # v[A+0]<- eax 3456 SET_VREG_WORD %ecx rINST 1 # v[A+1]<- ecx 3457 ADVANCE_PC 1 3458 GOTO_NEXT_R %edx 3459 3460/* ------------------------------ */ 3461 .balign 64 3462.L_OP_NEG_FLOAT: /* 0x7f */ 3463/* File: x86/OP_NEG_FLOAT.S */ 3464/* File: x86/fpcvt.S */ 3465 /* 3466 * Generic 32-bit FP conversion operation. 3467 */ 3468 /* unop vA, vB */ 3469 movzbl rINSTbl,%ecx # ecx<- A+ 3470 sarl $4,rINST # rINST<- B 3471 flds (rFP,rINST,4) # %st0<- vB 3472 andb $0xf,%cl # ecx<- A 3473 FETCH_INST_OPCODE 1 %edx 3474 ADVANCE_PC 1 3475 fchs 3476 fstps (rFP,%ecx,4) # vA<- %st0 3477 GOTO_NEXT_R %edx 3478 3479 3480/* ------------------------------ */ 3481 .balign 64 3482.L_OP_NEG_DOUBLE: /* 0x80 */ 3483/* File: x86/OP_NEG_DOUBLE.S */ 3484/* File: x86/fpcvt.S */ 3485 /* 3486 * Generic 32-bit FP conversion operation. 3487 */ 3488 /* unop vA, vB */ 3489 movzbl rINSTbl,%ecx # ecx<- A+ 3490 sarl $4,rINST # rINST<- B 3491 fldl (rFP,rINST,4) # %st0<- vB 3492 andb $0xf,%cl # ecx<- A 3493 FETCH_INST_OPCODE 1 %edx 3494 ADVANCE_PC 1 3495 fchs 3496 fstpl (rFP,%ecx,4) # vA<- %st0 3497 GOTO_NEXT_R %edx 3498 3499 3500/* ------------------------------ */ 3501 .balign 64 3502.L_OP_INT_TO_LONG: /* 0x81 */ 3503/* File: x86/OP_INT_TO_LONG.S */ 3504 /* int to long vA, vB */ 3505 movzbl rINSTbl,%eax # eax<- +A 3506 sarl $4,%eax # eax<- B 3507 GET_VREG_R %eax %eax # eax<- vB 3508 andb $0xf,rINSTbl # rINST<- A 3509 cltd # edx:eax<- sssssssBBBBBBBB 3510 SET_VREG_WORD %edx rINST 1 # v[A+1]<- edx/rPC 3511 FETCH_INST_OPCODE 1 %edx 3512 SET_VREG_WORD %eax rINST 0 # v[A+0]<- %eax 3513 ADVANCE_PC 1 3514 GOTO_NEXT_R %edx 3515 3516/* ------------------------------ */ 3517 .balign 64 3518.L_OP_INT_TO_FLOAT: /* 0x82 */ 3519/* File: x86/OP_INT_TO_FLOAT.S */ 3520/* File: x86/fpcvt.S */ 3521 /* 3522 * Generic 32-bit FP conversion operation. 3523 */ 3524 /* unop vA, vB */ 3525 movzbl rINSTbl,%ecx # ecx<- A+ 3526 sarl $4,rINST # rINST<- B 3527 fildl (rFP,rINST,4) # %st0<- vB 3528 andb $0xf,%cl # ecx<- A 3529 FETCH_INST_OPCODE 1 %edx 3530 ADVANCE_PC 1 3531 3532 fstps (rFP,%ecx,4) # vA<- %st0 3533 GOTO_NEXT_R %edx 3534 3535 3536/* ------------------------------ */ 3537 .balign 64 3538.L_OP_INT_TO_DOUBLE: /* 0x83 */ 3539/* File: x86/OP_INT_TO_DOUBLE.S */ 3540/* File: x86/fpcvt.S */ 3541 /* 3542 * Generic 32-bit FP conversion operation. 3543 */ 3544 /* unop vA, vB */ 3545 movzbl rINSTbl,%ecx # ecx<- A+ 3546 sarl $4,rINST # rINST<- B 3547 fildl (rFP,rINST,4) # %st0<- vB 3548 andb $0xf,%cl # ecx<- A 3549 FETCH_INST_OPCODE 1 %edx 3550 ADVANCE_PC 1 3551 3552 fstpl (rFP,%ecx,4) # vA<- %st0 3553 GOTO_NEXT_R %edx 3554 3555 3556/* ------------------------------ */ 3557 .balign 64 3558.L_OP_LONG_TO_INT: /* 0x84 */ 3559/* File: x86/OP_LONG_TO_INT.S */ 3560/* we ignore the high word, making this equivalent to a 32-bit reg move */ 3561/* File: x86/OP_MOVE.S */ 3562 /* for move, move-object, long-to-int */ 3563 /* op vA, vB */ 3564 movzbl rINSTbl,%eax # eax<- BA 3565 andb $0xf,%al # eax<- A 3566 shrl $4,rINST # rINST<- B 3567 GET_VREG_R %ecx rINST 3568 FETCH_INST_OPCODE 1 %edx 3569 ADVANCE_PC 1 3570 SET_VREG %ecx %eax # fp[A]<-fp[B] 3571 GOTO_NEXT_R %edx 3572 3573 3574/* ------------------------------ */ 3575 .balign 64 3576.L_OP_LONG_TO_FLOAT: /* 0x85 */ 3577/* File: x86/OP_LONG_TO_FLOAT.S */ 3578/* File: x86/fpcvt.S */ 3579 /* 3580 * Generic 32-bit FP conversion operation. 3581 */ 3582 /* unop vA, vB */ 3583 movzbl rINSTbl,%ecx # ecx<- A+ 3584 sarl $4,rINST # rINST<- B 3585 fildll (rFP,rINST,4) # %st0<- vB 3586 andb $0xf,%cl # ecx<- A 3587 FETCH_INST_OPCODE 1 %edx 3588 ADVANCE_PC 1 3589 3590 fstps (rFP,%ecx,4) # vA<- %st0 3591 GOTO_NEXT_R %edx 3592 3593 3594/* ------------------------------ */ 3595 .balign 64 3596.L_OP_LONG_TO_DOUBLE: /* 0x86 */ 3597/* File: x86/OP_LONG_TO_DOUBLE.S */ 3598/* File: x86/fpcvt.S */ 3599 /* 3600 * Generic 32-bit FP conversion operation. 3601 */ 3602 /* unop vA, vB */ 3603 movzbl rINSTbl,%ecx # ecx<- A+ 3604 sarl $4,rINST # rINST<- B 3605 fildll (rFP,rINST,4) # %st0<- vB 3606 andb $0xf,%cl # ecx<- A 3607 FETCH_INST_OPCODE 1 %edx 3608 ADVANCE_PC 1 3609 3610 fstpl (rFP,%ecx,4) # vA<- %st0 3611 GOTO_NEXT_R %edx 3612 3613 3614/* ------------------------------ */ 3615 .balign 64 3616.L_OP_FLOAT_TO_INT: /* 0x87 */ 3617/* File: x86/OP_FLOAT_TO_INT.S */ 3618/* File: x86/cvtfp_int.S */ 3619/* On fp to int conversions, Java requires that 3620 * if the result > maxint, it should be clamped to maxint. If it is less 3621 * than minint, it should be clamped to minint. If it is a nan, the result 3622 * should be zero. Further, the rounding mode is to truncate. This model 3623 * differs from what is delivered normally via the x86 fpu, so we have 3624 * to play some games. 3625 */ 3626 /* float/double to int/long vA, vB */ 3627 movzbl rINSTbl,%ecx # ecx<- A+ 3628 sarl $4,rINST # rINST<- B 3629 .if 0 3630 fldl (rFP,rINST,4) # %st0<- vB 3631 .else 3632 flds (rFP,rINST,4) # %st0<- vB 3633 .endif 3634 ftst 3635 fnstcw LOCAL0_OFFSET(%ebp) # remember original rounding mode 3636 movzwl LOCAL0_OFFSET(%ebp),%eax 3637 movb $0xc,%ah 3638 movw %ax,LOCAL0_OFFSET+2(%ebp) 3639 fldcw LOCAL0_OFFSET+2(%ebp) # set "to zero" rounding mode 3640 FETCH_INST_OPCODE 1 %edx 3641 andb $0xf,%cl # ecx<- A 3642 .if 0 3643 fistpll (rFP,%ecx,4) # convert and store 3644 .else 3645 fistpl (rFP,%ecx,4) # convert and store 3646 .endif 3647 fldcw LOCAL0_OFFSET(%ebp) # restore previous rounding mode 3648 jmp .LOP_FLOAT_TO_INT_continue 3649 3650 3651/* ------------------------------ */ 3652 .balign 64 3653.L_OP_FLOAT_TO_LONG: /* 0x88 */ 3654/* File: x86/OP_FLOAT_TO_LONG.S */ 3655/* File: x86/cvtfp_int.S */ 3656/* On fp to int conversions, Java requires that 3657 * if the result > maxint, it should be clamped to maxint. If it is less 3658 * than minint, it should be clamped to minint. If it is a nan, the result 3659 * should be zero. Further, the rounding mode is to truncate. This model 3660 * differs from what is delivered normally via the x86 fpu, so we have 3661 * to play some games. 3662 */ 3663 /* float/double to int/long vA, vB */ 3664 movzbl rINSTbl,%ecx # ecx<- A+ 3665 sarl $4,rINST # rINST<- B 3666 .if 0 3667 fldl (rFP,rINST,4) # %st0<- vB 3668 .else 3669 flds (rFP,rINST,4) # %st0<- vB 3670 .endif 3671 ftst 3672 fnstcw LOCAL0_OFFSET(%ebp) # remember original rounding mode 3673 movzwl LOCAL0_OFFSET(%ebp),%eax 3674 movb $0xc,%ah 3675 movw %ax,LOCAL0_OFFSET+2(%ebp) 3676 fldcw LOCAL0_OFFSET+2(%ebp) # set "to zero" rounding mode 3677 FETCH_INST_OPCODE 1 %edx 3678 andb $0xf,%cl # ecx<- A 3679 .if 1 3680 fistpll (rFP,%ecx,4) # convert and store 3681 .else 3682 fistpl (rFP,%ecx,4) # convert and store 3683 .endif 3684 fldcw LOCAL0_OFFSET(%ebp) # restore previous rounding mode 3685 jmp .LOP_FLOAT_TO_LONG_continue 3686 3687 3688/* ------------------------------ */ 3689 .balign 64 3690.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */ 3691/* File: x86/OP_FLOAT_TO_DOUBLE.S */ 3692/* File: x86/fpcvt.S */ 3693 /* 3694 * Generic 32-bit FP conversion operation. 3695 */ 3696 /* unop vA, vB */ 3697 movzbl rINSTbl,%ecx # ecx<- A+ 3698 sarl $4,rINST # rINST<- B 3699 flds (rFP,rINST,4) # %st0<- vB 3700 andb $0xf,%cl # ecx<- A 3701 FETCH_INST_OPCODE 1 %edx 3702 ADVANCE_PC 1 3703 3704 fstpl (rFP,%ecx,4) # vA<- %st0 3705 GOTO_NEXT_R %edx 3706 3707 3708/* ------------------------------ */ 3709 .balign 64 3710.L_OP_DOUBLE_TO_INT: /* 0x8a */ 3711/* File: x86/OP_DOUBLE_TO_INT.S */ 3712/* File: x86/cvtfp_int.S */ 3713/* On fp to int conversions, Java requires that 3714 * if the result > maxint, it should be clamped to maxint. If it is less 3715 * than minint, it should be clamped to minint. If it is a nan, the result 3716 * should be zero. Further, the rounding mode is to truncate. This model 3717 * differs from what is delivered normally via the x86 fpu, so we have 3718 * to play some games. 3719 */ 3720 /* float/double to int/long vA, vB */ 3721 movzbl rINSTbl,%ecx # ecx<- A+ 3722 sarl $4,rINST # rINST<- B 3723 .if 1 3724 fldl (rFP,rINST,4) # %st0<- vB 3725 .else 3726 flds (rFP,rINST,4) # %st0<- vB 3727 .endif 3728 ftst 3729 fnstcw LOCAL0_OFFSET(%ebp) # remember original rounding mode 3730 movzwl LOCAL0_OFFSET(%ebp),%eax 3731 movb $0xc,%ah 3732 movw %ax,LOCAL0_OFFSET+2(%ebp) 3733 fldcw LOCAL0_OFFSET+2(%ebp) # set "to zero" rounding mode 3734 FETCH_INST_OPCODE 1 %edx 3735 andb $0xf,%cl # ecx<- A 3736 .if 0 3737 fistpll (rFP,%ecx,4) # convert and store 3738 .else 3739 fistpl (rFP,%ecx,4) # convert and store 3740 .endif 3741 fldcw LOCAL0_OFFSET(%ebp) # restore previous rounding mode 3742 jmp .LOP_DOUBLE_TO_INT_continue 3743 3744 3745/* ------------------------------ */ 3746 .balign 64 3747.L_OP_DOUBLE_TO_LONG: /* 0x8b */ 3748/* File: x86/OP_DOUBLE_TO_LONG.S */ 3749/* File: x86/cvtfp_int.S */ 3750/* On fp to int conversions, Java requires that 3751 * if the result > maxint, it should be clamped to maxint. If it is less 3752 * than minint, it should be clamped to minint. If it is a nan, the result 3753 * should be zero. Further, the rounding mode is to truncate. This model 3754 * differs from what is delivered normally via the x86 fpu, so we have 3755 * to play some games. 3756 */ 3757 /* float/double to int/long vA, vB */ 3758 movzbl rINSTbl,%ecx # ecx<- A+ 3759 sarl $4,rINST # rINST<- B 3760 .if 1 3761 fldl (rFP,rINST,4) # %st0<- vB 3762 .else 3763 flds (rFP,rINST,4) # %st0<- vB 3764 .endif 3765 ftst 3766 fnstcw LOCAL0_OFFSET(%ebp) # remember original rounding mode 3767 movzwl LOCAL0_OFFSET(%ebp),%eax 3768 movb $0xc,%ah 3769 movw %ax,LOCAL0_OFFSET+2(%ebp) 3770 fldcw LOCAL0_OFFSET+2(%ebp) # set "to zero" rounding mode 3771 FETCH_INST_OPCODE 1 %edx 3772 andb $0xf,%cl # ecx<- A 3773 .if 1 3774 fistpll (rFP,%ecx,4) # convert and store 3775 .else 3776 fistpl (rFP,%ecx,4) # convert and store 3777 .endif 3778 fldcw LOCAL0_OFFSET(%ebp) # restore previous rounding mode 3779 jmp .LOP_DOUBLE_TO_LONG_continue 3780 3781 3782/* ------------------------------ */ 3783 .balign 64 3784.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */ 3785/* File: x86/OP_DOUBLE_TO_FLOAT.S */ 3786/* File: x86/fpcvt.S */ 3787 /* 3788 * Generic 32-bit FP conversion operation. 3789 */ 3790 /* unop vA, vB */ 3791 movzbl rINSTbl,%ecx # ecx<- A+ 3792 sarl $4,rINST # rINST<- B 3793 fldl (rFP,rINST,4) # %st0<- vB 3794 andb $0xf,%cl # ecx<- A 3795 FETCH_INST_OPCODE 1 %edx 3796 ADVANCE_PC 1 3797 3798 fstps (rFP,%ecx,4) # vA<- %st0 3799 GOTO_NEXT_R %edx 3800 3801 3802/* ------------------------------ */ 3803 .balign 64 3804.L_OP_INT_TO_BYTE: /* 0x8d */ 3805/* File: x86/OP_INT_TO_BYTE.S */ 3806/* File: x86/unop.S */ 3807 /* 3808 * Generic 32-bit unary operation. Provide an "instr" line that 3809 * specifies an instruction that performs "result = op eax". 3810 */ 3811 /* unop vA, vB */ 3812 movzbl rINSTbl,%ecx # ecx<- A+ 3813 sarl $4,rINST # rINST<- B 3814 GET_VREG_R %eax rINST # eax<- vB 3815 andb $0xf,%cl # ecx<- A 3816 FETCH_INST_OPCODE 1 %edx 3817 ADVANCE_PC 1 3818 3819 3820 movsbl %al,%eax 3821 SET_VREG %eax %ecx 3822 GOTO_NEXT_R %edx 3823 3824 3825/* ------------------------------ */ 3826 .balign 64 3827.L_OP_INT_TO_CHAR: /* 0x8e */ 3828/* File: x86/OP_INT_TO_CHAR.S */ 3829/* File: x86/unop.S */ 3830 /* 3831 * Generic 32-bit unary operation. Provide an "instr" line that 3832 * specifies an instruction that performs "result = op eax". 3833 */ 3834 /* unop vA, vB */ 3835 movzbl rINSTbl,%ecx # ecx<- A+ 3836 sarl $4,rINST # rINST<- B 3837 GET_VREG_R %eax rINST # eax<- vB 3838 andb $0xf,%cl # ecx<- A 3839 FETCH_INST_OPCODE 1 %edx 3840 ADVANCE_PC 1 3841 3842 3843 movzwl %ax,%eax 3844 SET_VREG %eax %ecx 3845 GOTO_NEXT_R %edx 3846 3847 3848/* ------------------------------ */ 3849 .balign 64 3850.L_OP_INT_TO_SHORT: /* 0x8f */ 3851/* File: x86/OP_INT_TO_SHORT.S */ 3852/* File: x86/unop.S */ 3853 /* 3854 * Generic 32-bit unary operation. Provide an "instr" line that 3855 * specifies an instruction that performs "result = op eax". 3856 */ 3857 /* unop vA, vB */ 3858 movzbl rINSTbl,%ecx # ecx<- A+ 3859 sarl $4,rINST # rINST<- B 3860 GET_VREG_R %eax rINST # eax<- vB 3861 andb $0xf,%cl # ecx<- A 3862 FETCH_INST_OPCODE 1 %edx 3863 ADVANCE_PC 1 3864 3865 3866 movswl %ax,%eax 3867 SET_VREG %eax %ecx 3868 GOTO_NEXT_R %edx 3869 3870 3871/* ------------------------------ */ 3872 .balign 64 3873.L_OP_ADD_INT: /* 0x90 */ 3874/* File: x86/OP_ADD_INT.S */ 3875/* File: x86/binop.S */ 3876 /* 3877 * Generic 32-bit binary operation. Provide an "instr" line that 3878 * specifies an instruction that performs "result = eax op (rFP,%ecx,4)". 3879 * This could be an x86 instruction or a function call. (If the result 3880 * comes back in a register other than eax, you can override "result".) 3881 * 3882 * For: add-int, sub-int, and-int, or-int, 3883 * xor-int, shl-int, shr-int, ushr-int 3884 */ 3885 /* binop vAA, vBB, vCC */ 3886 movzbl 2(rPC),%eax # eax<- BB 3887 movzbl 3(rPC),%ecx # ecx<- CC 3888 GET_VREG_R %eax %eax # eax<- vBB 3889 addl (rFP,%ecx,4),%eax # ex: addl (rFP,%ecx,4),%eax 3890 FETCH_INST_OPCODE 2 %edx 3891 ADVANCE_PC 2 3892 SET_VREG %eax rINST 3893 GOTO_NEXT_R %edx 3894 3895 3896/* ------------------------------ */ 3897 .balign 64 3898.L_OP_SUB_INT: /* 0x91 */ 3899/* File: x86/OP_SUB_INT.S */ 3900/* File: x86/binop.S */ 3901 /* 3902 * Generic 32-bit binary operation. Provide an "instr" line that 3903 * specifies an instruction that performs "result = eax op (rFP,%ecx,4)". 3904 * This could be an x86 instruction or a function call. (If the result 3905 * comes back in a register other than eax, you can override "result".) 3906 * 3907 * For: add-int, sub-int, and-int, or-int, 3908 * xor-int, shl-int, shr-int, ushr-int 3909 */ 3910 /* binop vAA, vBB, vCC */ 3911 movzbl 2(rPC),%eax # eax<- BB 3912 movzbl 3(rPC),%ecx # ecx<- CC 3913 GET_VREG_R %eax %eax # eax<- vBB 3914 subl (rFP,%ecx,4),%eax # ex: addl (rFP,%ecx,4),%eax 3915 FETCH_INST_OPCODE 2 %edx 3916 ADVANCE_PC 2 3917 SET_VREG %eax rINST 3918 GOTO_NEXT_R %edx 3919 3920 3921/* ------------------------------ */ 3922 .balign 64 3923.L_OP_MUL_INT: /* 0x92 */ 3924/* File: x86/OP_MUL_INT.S */ 3925 /* 3926 * 32-bit binary multiplication. 3927 */ 3928 /* mul vAA, vBB, vCC */ 3929 movzbl 2(rPC),%eax # eax<- BB 3930 movzbl 3(rPC),%ecx # ecx<- CC 3931 GET_VREG_R %eax %eax # eax<- vBB 3932 imull (rFP,%ecx,4),%eax # trashes edx 3933 FETCH_INST_OPCODE 2 %edx 3934 ADVANCE_PC 2 3935 SET_VREG %eax rINST 3936 GOTO_NEXT_R %edx 3937 3938/* ------------------------------ */ 3939 .balign 64 3940.L_OP_DIV_INT: /* 0x93 */ 3941/* File: x86/OP_DIV_INT.S */ 3942/* File: x86/bindiv.S */ 3943 3944 /* 3945 * 32-bit binary div/rem operation. Handles special case of op0=minint and 3946 * op1=-1. 3947 */ 3948 /* binop vAA, vBB, vCC */ 3949 movzbl 2(rPC),%eax # eax<- BB 3950 movzbl 3(rPC),%ecx # ecx<- CC 3951 GET_VREG_R %eax %eax # eax<- vBB 3952 GET_VREG_R %ecx %ecx # eax<- vBB 3953 cmpl $0,%ecx 3954 je common_errDivideByZero 3955 cmpl $-1,%ecx 3956 jne .LOP_DIV_INT_continue_div 3957 cmpl $0x80000000,%eax 3958 jne .LOP_DIV_INT_continue_div 3959 movl $0x80000000,%eax 3960 jmp .LOP_DIV_INT_finish_div 3961 3962 3963 3964/* ------------------------------ */ 3965 .balign 64 3966.L_OP_REM_INT: /* 0x94 */ 3967/* File: x86/OP_REM_INT.S */ 3968/* File: x86/bindiv.S */ 3969 3970 /* 3971 * 32-bit binary div/rem operation. Handles special case of op0=minint and 3972 * op1=-1. 3973 */ 3974 /* binop vAA, vBB, vCC */ 3975 movzbl 2(rPC),%eax # eax<- BB 3976 movzbl 3(rPC),%ecx # ecx<- CC 3977 GET_VREG_R %eax %eax # eax<- vBB 3978 GET_VREG_R %ecx %ecx # eax<- vBB 3979 cmpl $0,%ecx 3980 je common_errDivideByZero 3981 cmpl $-1,%ecx 3982 jne .LOP_REM_INT_continue_div 3983 cmpl $0x80000000,%eax 3984 jne .LOP_REM_INT_continue_div 3985 movl $0,%edx 3986 jmp .LOP_REM_INT_finish_div 3987 3988 3989 3990/* ------------------------------ */ 3991 .balign 64 3992.L_OP_AND_INT: /* 0x95 */ 3993/* File: x86/OP_AND_INT.S */ 3994/* File: x86/binop.S */ 3995 /* 3996 * Generic 32-bit binary operation. Provide an "instr" line that 3997 * specifies an instruction that performs "result = eax op (rFP,%ecx,4)". 3998 * This could be an x86 instruction or a function call. (If the result 3999 * comes back in a register other than eax, you can override "result".) 4000 * 4001 * For: add-int, sub-int, and-int, or-int, 4002 * xor-int, shl-int, shr-int, ushr-int 4003 */ 4004 /* binop vAA, vBB, vCC */ 4005 movzbl 2(rPC),%eax # eax<- BB 4006 movzbl 3(rPC),%ecx # ecx<- CC 4007 GET_VREG_R %eax %eax # eax<- vBB 4008 andl (rFP,%ecx,4),%eax # ex: addl (rFP,%ecx,4),%eax 4009 FETCH_INST_OPCODE 2 %edx 4010 ADVANCE_PC 2 4011 SET_VREG %eax rINST 4012 GOTO_NEXT_R %edx 4013 4014 4015/* ------------------------------ */ 4016 .balign 64 4017.L_OP_OR_INT: /* 0x96 */ 4018/* File: x86/OP_OR_INT.S */ 4019/* File: x86/binop.S */ 4020 /* 4021 * Generic 32-bit binary operation. Provide an "instr" line that 4022 * specifies an instruction that performs "result = eax op (rFP,%ecx,4)". 4023 * This could be an x86 instruction or a function call. (If the result 4024 * comes back in a register other than eax, you can override "result".) 4025 * 4026 * For: add-int, sub-int, and-int, or-int, 4027 * xor-int, shl-int, shr-int, ushr-int 4028 */ 4029 /* binop vAA, vBB, vCC */ 4030 movzbl 2(rPC),%eax # eax<- BB 4031 movzbl 3(rPC),%ecx # ecx<- CC 4032 GET_VREG_R %eax %eax # eax<- vBB 4033 orl (rFP,%ecx,4),%eax # ex: addl (rFP,%ecx,4),%eax 4034 FETCH_INST_OPCODE 2 %edx 4035 ADVANCE_PC 2 4036 SET_VREG %eax rINST 4037 GOTO_NEXT_R %edx 4038 4039 4040/* ------------------------------ */ 4041 .balign 64 4042.L_OP_XOR_INT: /* 0x97 */ 4043/* File: x86/OP_XOR_INT.S */ 4044/* File: x86/binop.S */ 4045 /* 4046 * Generic 32-bit binary operation. Provide an "instr" line that 4047 * specifies an instruction that performs "result = eax op (rFP,%ecx,4)". 4048 * This could be an x86 instruction or a function call. (If the result 4049 * comes back in a register other than eax, you can override "result".) 4050 * 4051 * For: add-int, sub-int, and-int, or-int, 4052 * xor-int, shl-int, shr-int, ushr-int 4053 */ 4054 /* binop vAA, vBB, vCC */ 4055 movzbl 2(rPC),%eax # eax<- BB 4056 movzbl 3(rPC),%ecx # ecx<- CC 4057 GET_VREG_R %eax %eax # eax<- vBB 4058 xorl (rFP,%ecx,4),%eax # ex: addl (rFP,%ecx,4),%eax 4059 FETCH_INST_OPCODE 2 %edx 4060 ADVANCE_PC 2 4061 SET_VREG %eax rINST 4062 GOTO_NEXT_R %edx 4063 4064 4065/* ------------------------------ */ 4066 .balign 64 4067.L_OP_SHL_INT: /* 0x98 */ 4068/* File: x86/OP_SHL_INT.S */ 4069/* File: x86/binop1.S */ 4070 /* 4071 * Generic 32-bit binary operation in which both operands loaded to 4072 * registers (op0 in eax, op1 in ecx). 4073 */ 4074 /* binop vAA, vBB, vCC */ 4075 movzbl 2(rPC),%eax # eax<- BB 4076 movzbl 3(rPC),%ecx # ecx<- CC 4077 GET_VREG_R %eax %eax # eax<- vBB 4078 GET_VREG_R %ecx %ecx # eax<- vBB 4079 sall %cl,%eax # ex: addl %ecx,%eax 4080 FETCH_INST_OPCODE 2 %edx 4081 ADVANCE_PC 2 4082 SET_VREG %eax rINST 4083 GOTO_NEXT_R %edx 4084 4085 4086/* ------------------------------ */ 4087 .balign 64 4088.L_OP_SHR_INT: /* 0x99 */ 4089/* File: x86/OP_SHR_INT.S */ 4090/* File: x86/binop1.S */ 4091 /* 4092 * Generic 32-bit binary operation in which both operands loaded to 4093 * registers (op0 in eax, op1 in ecx). 4094 */ 4095 /* binop vAA, vBB, vCC */ 4096 movzbl 2(rPC),%eax # eax<- BB 4097 movzbl 3(rPC),%ecx # ecx<- CC 4098 GET_VREG_R %eax %eax # eax<- vBB 4099 GET_VREG_R %ecx %ecx # eax<- vBB 4100 sarl %cl,%eax # ex: addl %ecx,%eax 4101 FETCH_INST_OPCODE 2 %edx 4102 ADVANCE_PC 2 4103 SET_VREG %eax rINST 4104 GOTO_NEXT_R %edx 4105 4106 4107/* ------------------------------ */ 4108 .balign 64 4109.L_OP_USHR_INT: /* 0x9a */ 4110/* File: x86/OP_USHR_INT.S */ 4111/* File: x86/binop1.S */ 4112 /* 4113 * Generic 32-bit binary operation in which both operands loaded to 4114 * registers (op0 in eax, op1 in ecx). 4115 */ 4116 /* binop vAA, vBB, vCC */ 4117 movzbl 2(rPC),%eax # eax<- BB 4118 movzbl 3(rPC),%ecx # ecx<- CC 4119 GET_VREG_R %eax %eax # eax<- vBB 4120 GET_VREG_R %ecx %ecx # eax<- vBB 4121 shrl %cl,%eax # ex: addl %ecx,%eax 4122 FETCH_INST_OPCODE 2 %edx 4123 ADVANCE_PC 2 4124 SET_VREG %eax rINST 4125 GOTO_NEXT_R %edx 4126 4127 4128/* ------------------------------ */ 4129 .balign 64 4130.L_OP_ADD_LONG: /* 0x9b */ 4131/* File: x86/OP_ADD_LONG.S */ 4132/* File: x86/binopWide.S */ 4133 /* 4134 * Generic 64-bit binary operation. 4135 */ 4136 /* binop vAA, vBB, vCC */ 4137 4138 movzbl 2(rPC),%eax # eax<- BB 4139 movzbl 3(rPC),%ecx # ecx<- CC 4140 GET_VREG_WORD %edx %eax 0 # edx<- v[BB+0] 4141 GET_VREG_WORD %eax %eax 1 # eax<- v[BB+1] 4142 addl (rFP,%ecx,4),%edx # ex: addl (rFP,%ecx,4),%edx 4143 adcl 4(rFP,%ecx,4),%eax # ex: adcl 4(rFP,%ecx,4),%eax 4144 SET_VREG_WORD %edx rINST 0 # v[AA+0] <- edx 4145 FETCH_INST_OPCODE 2 %edx 4146 SET_VREG_WORD %eax rINST 1 # v[AA+1] <- eax 4147 ADVANCE_PC 2 4148 GOTO_NEXT_R %edx 4149 4150 4151/* ------------------------------ */ 4152 .balign 64 4153.L_OP_SUB_LONG: /* 0x9c */ 4154/* File: x86/OP_SUB_LONG.S */ 4155/* File: x86/binopWide.S */ 4156 /* 4157 * Generic 64-bit binary operation. 4158 */ 4159 /* binop vAA, vBB, vCC */ 4160 4161 movzbl 2(rPC),%eax # eax<- BB 4162 movzbl 3(rPC),%ecx # ecx<- CC 4163 GET_VREG_WORD %edx %eax 0 # edx<- v[BB+0] 4164 GET_VREG_WORD %eax %eax 1 # eax<- v[BB+1] 4165 subl (rFP,%ecx,4),%edx # ex: addl (rFP,%ecx,4),%edx 4166 sbbl 4(rFP,%ecx,4),%eax # ex: adcl 4(rFP,%ecx,4),%eax 4167 SET_VREG_WORD %edx rINST 0 # v[AA+0] <- edx 4168 FETCH_INST_OPCODE 2 %edx 4169 SET_VREG_WORD %eax rINST 1 # v[AA+1] <- eax 4170 ADVANCE_PC 2 4171 GOTO_NEXT_R %edx 4172 4173 4174/* ------------------------------ */ 4175 .balign 64 4176.L_OP_MUL_LONG: /* 0x9d */ 4177/* File: x86/OP_MUL_LONG.S */ 4178 /* 4179 * Signed 64-bit integer multiply. 4180 * 4181 * We could definately use more free registers for 4182 * this code. We spill rINSTw (ebx), 4183 * giving us eax, ebc, ecx and edx as computational 4184 * temps. On top of that, we'll spill edi (rFP) 4185 * for use as the vB pointer and esi (rPC) for use 4186 * as the vC pointer. Yuck. 4187 */ 4188 /* mul-long vAA, vBB, vCC */ 4189 movzbl 2(rPC),%eax # eax<- B 4190 movzbl 3(rPC),%ecx # ecx<- C 4191 SPILL_TMP2(%esi) # save Dalvik PC 4192 SPILL(rFP) 4193 SPILL(rINST) 4194 leal (rFP,%eax,4),%esi # esi<- &v[B] 4195 leal (rFP,%ecx,4),rFP # rFP<- &v[C] 4196 movl 4(%esi),%ecx # ecx<- Bmsw 4197 imull (rFP),%ecx # ecx<- (Bmsw*Clsw) 4198 movl 4(rFP),%eax # eax<- Cmsw 4199 imull (%esi),%eax # eax<- (Cmsw*Blsw) 4200 addl %eax,%ecx # ecx<- (Bmsw*Clsw)+(Cmsw*Blsw) 4201 movl (rFP),%eax # eax<- Clsw 4202 mull (%esi) # eax<- (Clsw*Alsw) 4203 UNSPILL(rINST) 4204 UNSPILL(rFP) 4205 jmp .LOP_MUL_LONG_continue 4206 4207/* ------------------------------ */ 4208 .balign 64 4209.L_OP_DIV_LONG: /* 0x9e */ 4210/* File: x86/OP_DIV_LONG.S */ 4211 /* div vAA, vBB, vCC */ 4212 movzbl 3(rPC),%eax # eax<- CC 4213 movzbl 2(rPC),%ecx # ecx<- BB 4214 GET_VREG_WORD %edx %eax 0 4215 GET_VREG_WORD %eax %eax 1 4216 movl %edx,OUT_ARG2(%esp) 4217 testl %eax,%eax 4218 je .LOP_DIV_LONG_check_zero 4219 cmpl $-1,%eax 4220 je .LOP_DIV_LONG_check_neg1 4221.LOP_DIV_LONG_notSpecial: 4222 GET_VREG_WORD %edx %ecx 0 4223 GET_VREG_WORD %ecx %ecx 1 4224.LOP_DIV_LONG_notSpecial1: 4225 movl %eax,OUT_ARG3(%esp) 4226 movl %edx,OUT_ARG0(%esp) 4227 movl %ecx,OUT_ARG1(%esp) 4228 jmp .LOP_DIV_LONG_continue 4229 4230/* ------------------------------ */ 4231 .balign 64 4232.L_OP_REM_LONG: /* 0x9f */ 4233/* File: x86/OP_REM_LONG.S */ 4234/* File: x86/OP_DIV_LONG.S */ 4235 /* div vAA, vBB, vCC */ 4236 movzbl 3(rPC),%eax # eax<- CC 4237 movzbl 2(rPC),%ecx # ecx<- BB 4238 GET_VREG_WORD %edx %eax 0 4239 GET_VREG_WORD %eax %eax 1 4240 movl %edx,OUT_ARG2(%esp) 4241 testl %eax,%eax 4242 je .LOP_REM_LONG_check_zero 4243 cmpl $-1,%eax 4244 je .LOP_REM_LONG_check_neg1 4245.LOP_REM_LONG_notSpecial: 4246 GET_VREG_WORD %edx %ecx 0 4247 GET_VREG_WORD %ecx %ecx 1 4248.LOP_REM_LONG_notSpecial1: 4249 movl %eax,OUT_ARG3(%esp) 4250 movl %edx,OUT_ARG0(%esp) 4251 movl %ecx,OUT_ARG1(%esp) 4252 jmp .LOP_REM_LONG_continue 4253 4254 4255/* ------------------------------ */ 4256 .balign 64 4257.L_OP_AND_LONG: /* 0xa0 */ 4258/* File: x86/OP_AND_LONG.S */ 4259/* File: x86/binopWide.S */ 4260 /* 4261 * Generic 64-bit binary operation. 4262 */ 4263 /* binop vAA, vBB, vCC */ 4264 4265 movzbl 2(rPC),%eax # eax<- BB 4266 movzbl 3(rPC),%ecx # ecx<- CC 4267 GET_VREG_WORD %edx %eax 0 # edx<- v[BB+0] 4268 GET_VREG_WORD %eax %eax 1 # eax<- v[BB+1] 4269 andl (rFP,%ecx,4),%edx # ex: addl (rFP,%ecx,4),%edx 4270 andl 4(rFP,%ecx,4),%eax # ex: adcl 4(rFP,%ecx,4),%eax 4271 SET_VREG_WORD %edx rINST 0 # v[AA+0] <- edx 4272 FETCH_INST_OPCODE 2 %edx 4273 SET_VREG_WORD %eax rINST 1 # v[AA+1] <- eax 4274 ADVANCE_PC 2 4275 GOTO_NEXT_R %edx 4276 4277 4278/* ------------------------------ */ 4279 .balign 64 4280.L_OP_OR_LONG: /* 0xa1 */ 4281/* File: x86/OP_OR_LONG.S */ 4282/* File: x86/binopWide.S */ 4283 /* 4284 * Generic 64-bit binary operation. 4285 */ 4286 /* binop vAA, vBB, vCC */ 4287 4288 movzbl 2(rPC),%eax # eax<- BB 4289 movzbl 3(rPC),%ecx # ecx<- CC 4290 GET_VREG_WORD %edx %eax 0 # edx<- v[BB+0] 4291 GET_VREG_WORD %eax %eax 1 # eax<- v[BB+1] 4292 orl (rFP,%ecx,4),%edx # ex: addl (rFP,%ecx,4),%edx 4293 orl 4(rFP,%ecx,4),%eax # ex: adcl 4(rFP,%ecx,4),%eax 4294 SET_VREG_WORD %edx rINST 0 # v[AA+0] <- edx 4295 FETCH_INST_OPCODE 2 %edx 4296 SET_VREG_WORD %eax rINST 1 # v[AA+1] <- eax 4297 ADVANCE_PC 2 4298 GOTO_NEXT_R %edx 4299 4300 4301/* ------------------------------ */ 4302 .balign 64 4303.L_OP_XOR_LONG: /* 0xa2 */ 4304/* File: x86/OP_XOR_LONG.S */ 4305/* File: x86/binopWide.S */ 4306 /* 4307 * Generic 64-bit binary operation. 4308 */ 4309 /* binop vAA, vBB, vCC */ 4310 4311 movzbl 2(rPC),%eax # eax<- BB 4312 movzbl 3(rPC),%ecx # ecx<- CC 4313 GET_VREG_WORD %edx %eax 0 # edx<- v[BB+0] 4314 GET_VREG_WORD %eax %eax 1 # eax<- v[BB+1] 4315 xorl (rFP,%ecx,4),%edx # ex: addl (rFP,%ecx,4),%edx 4316 xorl 4(rFP,%ecx,4),%eax # ex: adcl 4(rFP,%ecx,4),%eax 4317 SET_VREG_WORD %edx rINST 0 # v[AA+0] <- edx 4318 FETCH_INST_OPCODE 2 %edx 4319 SET_VREG_WORD %eax rINST 1 # v[AA+1] <- eax 4320 ADVANCE_PC 2 4321 GOTO_NEXT_R %edx 4322 4323 4324/* ------------------------------ */ 4325 .balign 64 4326.L_OP_SHL_LONG: /* 0xa3 */ 4327/* File: x86/OP_SHL_LONG.S */ 4328 /* 4329 * Long integer shift. This is different from the generic 32/64-bit 4330 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4331 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4332 * 6 bits of the shift distance. x86 shifts automatically mask off 4333 * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31 4334 * case specially. 4335 */ 4336 /* shl-long vAA, vBB, vCC */ 4337 /* ecx gets shift count */ 4338 /* Need to spill edx */ 4339 /* rINSTw gets AA */ 4340 movzbl 2(rPC),%eax # eax<- BB 4341 movzbl 3(rPC),%ecx # ecx<- CC 4342 GET_VREG_WORD %edx %eax 1 # ecx<- v[BB+1] 4343 GET_VREG_R %ecx %ecx # ecx<- vCC 4344 GET_VREG_WORD %eax %eax 0 # eax<- v[BB+0] 4345 shldl %eax,%edx 4346 sall %cl,%eax 4347 testb $32,%cl 4348 je 2f 4349 movl %eax,%edx 4350 xorl %eax,%eax 43512: 4352 SET_VREG_WORD %edx rINST 1 # v[AA+1]<- %edx 4353 FETCH_INST_OPCODE 2 %edx 4354 jmp .LOP_SHL_LONG_finish 4355 4356/* ------------------------------ */ 4357 .balign 64 4358.L_OP_SHR_LONG: /* 0xa4 */ 4359/* File: x86/OP_SHR_LONG.S */ 4360 /* 4361 * Long integer shift. This is different from the generic 32/64-bit 4362 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4363 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4364 * 6 bits of the shift distance. x86 shifts automatically mask off 4365 * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31 4366 * case specially. 4367 */ 4368 /* shr-long vAA, vBB, vCC */ 4369 /* ecx gets shift count */ 4370 /* Need to spill edx */ 4371 /* rINSTw gets AA */ 4372 movzbl 2(rPC),%eax # eax<- BB 4373 movzbl 3(rPC),%ecx # ecx<- CC 4374 GET_VREG_WORD %edx %eax 1 # edx<- v[BB+1] 4375 GET_VREG_R %ecx %ecx # ecx<- vCC 4376 GET_VREG_WORD %eax %eax 0 # eax<- v[BB+0] 4377 shrdl %edx,%eax 4378 sarl %cl,%edx 4379 testb $32,%cl 4380 je 2f 4381 movl %edx,%eax 4382 sarl $31,%edx 43832: 4384 SET_VREG_WORD %edx rINST 1 # v[AA+1]<- edx 4385 FETCH_INST_OPCODE 2 %edx 4386 jmp .LOP_SHR_LONG_finish 4387 4388/* ------------------------------ */ 4389 .balign 64 4390.L_OP_USHR_LONG: /* 0xa5 */ 4391/* File: x86/OP_USHR_LONG.S */ 4392 /* 4393 * Long integer shift. This is different from the generic 32/64-bit 4394 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4395 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4396 * 6 bits of the shift distance. x86 shifts automatically mask off 4397 * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31 4398 * case specially. 4399 */ 4400 /* shr-long vAA, vBB, vCC */ 4401 /* ecx gets shift count */ 4402 /* Need to spill edx */ 4403 /* rINSTw gets AA */ 4404 movzbl 2(rPC),%eax # eax<- BB 4405 movzbl 3(rPC),%ecx # ecx<- CC 4406 GET_VREG_WORD %edx %eax 1 # edx<- v[BB+1] 4407 GET_VREG_R %ecx %ecx # ecx<- vCC 4408 GET_VREG_WORD %eax %eax 0 # eax<- v[BB+0] 4409 shrdl %edx,%eax 4410 shrl %cl,%edx 4411 testb $32,%cl 4412 je 2f 4413 movl %edx,%eax 4414 xorl %edx,%edx 44152: 4416 SET_VREG_WORD %edx rINST 1 # v[AA+1]<- edx 4417 FETCH_INST_OPCODE 2 %edx 4418 jmp .LOP_USHR_LONG_finish 4419 4420/* ------------------------------ */ 4421 .balign 64 4422.L_OP_ADD_FLOAT: /* 0xa6 */ 4423/* File: x86/OP_ADD_FLOAT.S */ 4424/* File: x86/binflop.S */ 4425 /* 4426 * Generic 32-bit binary float operation. 4427 * 4428 * For: add-fp, sub-fp, mul-fp, div-fp 4429 */ 4430 /* binop vAA, vBB, vCC */ 4431 movzbl 2(rPC),%eax # eax<- CC 4432 movzbl 3(rPC),%ecx # ecx<- BB 4433 flds (rFP,%eax,4) # vCC to fp stack 4434 fadds (rFP,%ecx,4) # ex: faddp 4435 FETCH_INST_OPCODE 2 %edx 4436 ADVANCE_PC 2 4437 fstps (rFP,rINST,4) # %st to vAA 4438 GOTO_NEXT_R %edx 4439 4440 4441/* ------------------------------ */ 4442 .balign 64 4443.L_OP_SUB_FLOAT: /* 0xa7 */ 4444/* File: x86/OP_SUB_FLOAT.S */ 4445/* File: x86/binflop.S */ 4446 /* 4447 * Generic 32-bit binary float operation. 4448 * 4449 * For: add-fp, sub-fp, mul-fp, div-fp 4450 */ 4451 /* binop vAA, vBB, vCC */ 4452 movzbl 2(rPC),%eax # eax<- CC 4453 movzbl 3(rPC),%ecx # ecx<- BB 4454 flds (rFP,%eax,4) # vCC to fp stack 4455 fsubs (rFP,%ecx,4) # ex: faddp 4456 FETCH_INST_OPCODE 2 %edx 4457 ADVANCE_PC 2 4458 fstps (rFP,rINST,4) # %st to vAA 4459 GOTO_NEXT_R %edx 4460 4461 4462/* ------------------------------ */ 4463 .balign 64 4464.L_OP_MUL_FLOAT: /* 0xa8 */ 4465/* File: x86/OP_MUL_FLOAT.S */ 4466/* File: x86/binflop.S */ 4467 /* 4468 * Generic 32-bit binary float operation. 4469 * 4470 * For: add-fp, sub-fp, mul-fp, div-fp 4471 */ 4472 /* binop vAA, vBB, vCC */ 4473 movzbl 2(rPC),%eax # eax<- CC 4474 movzbl 3(rPC),%ecx # ecx<- BB 4475 flds (rFP,%eax,4) # vCC to fp stack 4476 fmuls (rFP,%ecx,4) # ex: faddp 4477 FETCH_INST_OPCODE 2 %edx 4478 ADVANCE_PC 2 4479 fstps (rFP,rINST,4) # %st to vAA 4480 GOTO_NEXT_R %edx 4481 4482 4483/* ------------------------------ */ 4484 .balign 64 4485.L_OP_DIV_FLOAT: /* 0xa9 */ 4486/* File: x86/OP_DIV_FLOAT.S */ 4487/* File: x86/binflop.S */ 4488 /* 4489 * Generic 32-bit binary float operation. 4490 * 4491 * For: add-fp, sub-fp, mul-fp, div-fp 4492 */ 4493 /* binop vAA, vBB, vCC */ 4494 movzbl 2(rPC),%eax # eax<- CC 4495 movzbl 3(rPC),%ecx # ecx<- BB 4496 flds (rFP,%eax,4) # vCC to fp stack 4497 fdivs (rFP,%ecx,4) # ex: faddp 4498 FETCH_INST_OPCODE 2 %edx 4499 ADVANCE_PC 2 4500 fstps (rFP,rINST,4) # %st to vAA 4501 GOTO_NEXT_R %edx 4502 4503 4504/* ------------------------------ */ 4505 .balign 64 4506.L_OP_REM_FLOAT: /* 0xaa */ 4507/* File: x86/OP_REM_FLOAT.S */ 4508 /* rem_float vAA, vBB, vCC */ 4509 movzbl 3(rPC),%ecx # ecx<- BB 4510 movzbl 2(rPC),%eax # eax<- CC 4511 flds (rFP,%ecx,4) # vCC to fp stack 4512 flds (rFP,%eax,4) # vCC to fp stack 4513 movzbl rINSTbl,%ecx # ecx<- AA 4514 FETCH_INST_OPCODE 2 %edx 45151: 4516 fprem 4517 fstsw %ax 4518 sahf 4519 jp 1b 4520 fstp %st(1) 4521 ADVANCE_PC 2 4522 fstps (rFP,%ecx,4) # %st to vAA 4523 GOTO_NEXT_R %edx 4524 4525/* ------------------------------ */ 4526 .balign 64 4527.L_OP_ADD_DOUBLE: /* 0xab */ 4528/* File: x86/OP_ADD_DOUBLE.S */ 4529/* File: x86/binflop.S */ 4530 /* 4531 * Generic 32-bit binary float operation. 4532 * 4533 * For: add-fp, sub-fp, mul-fp, div-fp 4534 */ 4535 /* binop vAA, vBB, vCC */ 4536 movzbl 2(rPC),%eax # eax<- CC 4537 movzbl 3(rPC),%ecx # ecx<- BB 4538 fldl (rFP,%eax,4) # vCC to fp stack 4539 faddl (rFP,%ecx,4) # ex: faddp 4540 FETCH_INST_OPCODE 2 %edx 4541 ADVANCE_PC 2 4542 fstpl (rFP,rINST,4) # %st to vAA 4543 GOTO_NEXT_R %edx 4544 4545 4546/* ------------------------------ */ 4547 .balign 64 4548.L_OP_SUB_DOUBLE: /* 0xac */ 4549/* File: x86/OP_SUB_DOUBLE.S */ 4550/* File: x86/binflop.S */ 4551 /* 4552 * Generic 32-bit binary float operation. 4553 * 4554 * For: add-fp, sub-fp, mul-fp, div-fp 4555 */ 4556 /* binop vAA, vBB, vCC */ 4557 movzbl 2(rPC),%eax # eax<- CC 4558 movzbl 3(rPC),%ecx # ecx<- BB 4559 fldl (rFP,%eax,4) # vCC to fp stack 4560 fsubl (rFP,%ecx,4) # ex: faddp 4561 FETCH_INST_OPCODE 2 %edx 4562 ADVANCE_PC 2 4563 fstpl (rFP,rINST,4) # %st to vAA 4564 GOTO_NEXT_R %edx 4565 4566 4567/* ------------------------------ */ 4568 .balign 64 4569.L_OP_MUL_DOUBLE: /* 0xad */ 4570/* File: x86/OP_MUL_DOUBLE.S */ 4571/* File: x86/binflop.S */ 4572 /* 4573 * Generic 32-bit binary float operation. 4574 * 4575 * For: add-fp, sub-fp, mul-fp, div-fp 4576 */ 4577 /* binop vAA, vBB, vCC */ 4578 movzbl 2(rPC),%eax # eax<- CC 4579 movzbl 3(rPC),%ecx # ecx<- BB 4580 fldl (rFP,%eax,4) # vCC to fp stack 4581 fmull (rFP,%ecx,4) # ex: faddp 4582 FETCH_INST_OPCODE 2 %edx 4583 ADVANCE_PC 2 4584 fstpl (rFP,rINST,4) # %st to vAA 4585 GOTO_NEXT_R %edx 4586 4587 4588/* ------------------------------ */ 4589 .balign 64 4590.L_OP_DIV_DOUBLE: /* 0xae */ 4591/* File: x86/OP_DIV_DOUBLE.S */ 4592/* File: x86/binflop.S */ 4593 /* 4594 * Generic 32-bit binary float operation. 4595 * 4596 * For: add-fp, sub-fp, mul-fp, div-fp 4597 */ 4598 /* binop vAA, vBB, vCC */ 4599 movzbl 2(rPC),%eax # eax<- CC 4600 movzbl 3(rPC),%ecx # ecx<- BB 4601 fldl (rFP,%eax,4) # vCC to fp stack 4602 fdivl (rFP,%ecx,4) # ex: faddp 4603 FETCH_INST_OPCODE 2 %edx 4604 ADVANCE_PC 2 4605 fstpl (rFP,rINST,4) # %st to vAA 4606 GOTO_NEXT_R %edx 4607 4608 4609/* ------------------------------ */ 4610 .balign 64 4611.L_OP_REM_DOUBLE: /* 0xaf */ 4612/* File: x86/OP_REM_DOUBLE.S */ 4613 /* rem_float vAA, vBB, vCC */ 4614 movzbl 3(rPC),%ecx # ecx<- BB 4615 movzbl 2(rPC),%eax # eax<- CC 4616 fldl (rFP,%ecx,4) # vCC to fp stack 4617 fldl (rFP,%eax,4) # vCC to fp stack 4618 movzbl rINSTbl,%ecx # ecx<- AA 4619 FETCH_INST_OPCODE 2 %edx 46201: 4621 fprem 4622 fstsw %ax 4623 sahf 4624 jp 1b 4625 fstp %st(1) 4626 ADVANCE_PC 2 4627 fstpl (rFP,%ecx,4) # %st to vAA 4628 GOTO_NEXT_R %edx 4629 4630/* ------------------------------ */ 4631 .balign 64 4632.L_OP_ADD_INT_2ADDR: /* 0xb0 */ 4633/* File: x86/OP_ADD_INT_2ADDR.S */ 4634/* File: x86/binop2addr.S */ 4635 /* 4636 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 4637 * that specifies an instruction that performs "result = r0 op r1". 4638 * This could be an ARM instruction or a function call. (If the result 4639 * comes back in a register other than r0, you can override "result".) 4640 * 4641 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4642 * vCC (r1). Useful for integer division and modulus. 4643 * 4644 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 4645 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 4646 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 4647 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 4648 */ 4649 /* binop/2addr vA, vB */ 4650 movzx rINSTbl,%ecx # ecx<- A+ 4651 sarl $4,rINST # rINST<- B 4652 GET_VREG_R %eax rINST # eax<- vB 4653 FETCH_INST_OPCODE 1 %edx 4654 andb $0xf,%cl # ecx<- A 4655 addl %eax,(rFP,%ecx,4) # for ex: addl %eax,(rFP,%ecx,4) 4656 ADVANCE_PC 1 4657 GOTO_NEXT_R %edx 4658 4659 4660/* ------------------------------ */ 4661 .balign 64 4662.L_OP_SUB_INT_2ADDR: /* 0xb1 */ 4663/* File: x86/OP_SUB_INT_2ADDR.S */ 4664/* File: x86/binop2addr.S */ 4665 /* 4666 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 4667 * that specifies an instruction that performs "result = r0 op r1". 4668 * This could be an ARM instruction or a function call. (If the result 4669 * comes back in a register other than r0, you can override "result".) 4670 * 4671 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4672 * vCC (r1). Useful for integer division and modulus. 4673 * 4674 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 4675 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 4676 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 4677 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 4678 */ 4679 /* binop/2addr vA, vB */ 4680 movzx rINSTbl,%ecx # ecx<- A+ 4681 sarl $4,rINST # rINST<- B 4682 GET_VREG_R %eax rINST # eax<- vB 4683 FETCH_INST_OPCODE 1 %edx 4684 andb $0xf,%cl # ecx<- A 4685 subl %eax,(rFP,%ecx,4) # for ex: addl %eax,(rFP,%ecx,4) 4686 ADVANCE_PC 1 4687 GOTO_NEXT_R %edx 4688 4689 4690/* ------------------------------ */ 4691 .balign 64 4692.L_OP_MUL_INT_2ADDR: /* 0xb2 */ 4693/* File: x86/OP_MUL_INT_2ADDR.S */ 4694 /* mul vA, vB */ 4695 movzx rINSTbl,%ecx # ecx<- A+ 4696 sarl $4,rINST # rINST<- B 4697 GET_VREG_R %eax rINST # eax<- vB 4698 andb $0xf,%cl # ecx<- A 4699 imull (rFP,%ecx,4),%eax 4700 FETCH_INST_OPCODE 1 %edx 4701 SET_VREG %eax %ecx 4702 ADVANCE_PC 1 4703 GOTO_NEXT_R %edx 4704 4705/* ------------------------------ */ 4706 .balign 64 4707.L_OP_DIV_INT_2ADDR: /* 0xb3 */ 4708/* File: x86/OP_DIV_INT_2ADDR.S */ 4709/* File: x86/bindiv2addr.S */ 4710 /* 4711 * 32-bit binary div/rem operation. Handles special case of op0=minint and 4712 * op1=-1. 4713 */ 4714 /* div/rem/2addr vA, vB */ 4715 movzx rINSTbl,%ecx # eax<- BA 4716 sarl $4,%ecx # ecx<- B 4717 GET_VREG_R %ecx %ecx # eax<- vBB 4718 andb $0xf,rINSTbl # rINST<- A 4719 GET_VREG_R %eax rINST # eax<- vBB 4720 cmpl $0,%ecx 4721 je common_errDivideByZero 4722 cmpl $-1,%ecx 4723 jne .LOP_DIV_INT_2ADDR_continue_div2addr 4724 cmpl $0x80000000,%eax 4725 jne .LOP_DIV_INT_2ADDR_continue_div2addr 4726 movl $0x80000000,%eax 4727 jmp .LOP_DIV_INT_2ADDR_finish_div2addr 4728 4729 4730 4731/* ------------------------------ */ 4732 .balign 64 4733.L_OP_REM_INT_2ADDR: /* 0xb4 */ 4734/* File: x86/OP_REM_INT_2ADDR.S */ 4735/* File: x86/bindiv2addr.S */ 4736 /* 4737 * 32-bit binary div/rem operation. Handles special case of op0=minint and 4738 * op1=-1. 4739 */ 4740 /* div/rem/2addr vA, vB */ 4741 movzx rINSTbl,%ecx # eax<- BA 4742 sarl $4,%ecx # ecx<- B 4743 GET_VREG_R %ecx %ecx # eax<- vBB 4744 andb $0xf,rINSTbl # rINST<- A 4745 GET_VREG_R %eax rINST # eax<- vBB 4746 cmpl $0,%ecx 4747 je common_errDivideByZero 4748 cmpl $-1,%ecx 4749 jne .LOP_REM_INT_2ADDR_continue_div2addr 4750 cmpl $0x80000000,%eax 4751 jne .LOP_REM_INT_2ADDR_continue_div2addr 4752 movl $0,%edx 4753 jmp .LOP_REM_INT_2ADDR_finish_div2addr 4754 4755 4756 4757/* ------------------------------ */ 4758 .balign 64 4759.L_OP_AND_INT_2ADDR: /* 0xb5 */ 4760/* File: x86/OP_AND_INT_2ADDR.S */ 4761/* File: x86/binop2addr.S */ 4762 /* 4763 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 4764 * that specifies an instruction that performs "result = r0 op r1". 4765 * This could be an ARM instruction or a function call. (If the result 4766 * comes back in a register other than r0, you can override "result".) 4767 * 4768 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4769 * vCC (r1). Useful for integer division and modulus. 4770 * 4771 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 4772 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 4773 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 4774 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 4775 */ 4776 /* binop/2addr vA, vB */ 4777 movzx rINSTbl,%ecx # ecx<- A+ 4778 sarl $4,rINST # rINST<- B 4779 GET_VREG_R %eax rINST # eax<- vB 4780 FETCH_INST_OPCODE 1 %edx 4781 andb $0xf,%cl # ecx<- A 4782 andl %eax,(rFP,%ecx,4) # for ex: addl %eax,(rFP,%ecx,4) 4783 ADVANCE_PC 1 4784 GOTO_NEXT_R %edx 4785 4786 4787/* ------------------------------ */ 4788 .balign 64 4789.L_OP_OR_INT_2ADDR: /* 0xb6 */ 4790/* File: x86/OP_OR_INT_2ADDR.S */ 4791/* File: x86/binop2addr.S */ 4792 /* 4793 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 4794 * that specifies an instruction that performs "result = r0 op r1". 4795 * This could be an ARM instruction or a function call. (If the result 4796 * comes back in a register other than r0, you can override "result".) 4797 * 4798 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4799 * vCC (r1). Useful for integer division and modulus. 4800 * 4801 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 4802 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 4803 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 4804 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 4805 */ 4806 /* binop/2addr vA, vB */ 4807 movzx rINSTbl,%ecx # ecx<- A+ 4808 sarl $4,rINST # rINST<- B 4809 GET_VREG_R %eax rINST # eax<- vB 4810 FETCH_INST_OPCODE 1 %edx 4811 andb $0xf,%cl # ecx<- A 4812 orl %eax,(rFP,%ecx,4) # for ex: addl %eax,(rFP,%ecx,4) 4813 ADVANCE_PC 1 4814 GOTO_NEXT_R %edx 4815 4816 4817/* ------------------------------ */ 4818 .balign 64 4819.L_OP_XOR_INT_2ADDR: /* 0xb7 */ 4820/* File: x86/OP_XOR_INT_2ADDR.S */ 4821/* File: x86/binop2addr.S */ 4822 /* 4823 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 4824 * that specifies an instruction that performs "result = r0 op r1". 4825 * This could be an ARM instruction or a function call. (If the result 4826 * comes back in a register other than r0, you can override "result".) 4827 * 4828 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4829 * vCC (r1). Useful for integer division and modulus. 4830 * 4831 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 4832 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 4833 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 4834 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 4835 */ 4836 /* binop/2addr vA, vB */ 4837 movzx rINSTbl,%ecx # ecx<- A+ 4838 sarl $4,rINST # rINST<- B 4839 GET_VREG_R %eax rINST # eax<- vB 4840 FETCH_INST_OPCODE 1 %edx 4841 andb $0xf,%cl # ecx<- A 4842 xorl %eax,(rFP,%ecx,4) # for ex: addl %eax,(rFP,%ecx,4) 4843 ADVANCE_PC 1 4844 GOTO_NEXT_R %edx 4845 4846 4847/* ------------------------------ */ 4848 .balign 64 4849.L_OP_SHL_INT_2ADDR: /* 0xb8 */ 4850/* File: x86/OP_SHL_INT_2ADDR.S */ 4851/* File: x86/shop2addr.S */ 4852 /* 4853 * Generic 32-bit "shift/2addr" operation. 4854 */ 4855 /* shift/2addr vA, vB */ 4856 movzx rINSTbl,%ecx # eax<- BA 4857 sarl $4,%ecx # ecx<- B 4858 GET_VREG_R %ecx %ecx # eax<- vBB 4859 andb $0xf,rINSTbl # rINST<- A 4860 GET_VREG_R %eax rINST # eax<- vAA 4861 sall %cl,%eax # ex: sarl %cl,%eax 4862 FETCH_INST_OPCODE 1 %edx 4863 SET_VREG %eax rINST 4864 ADVANCE_PC 1 4865 GOTO_NEXT_R %edx 4866 4867 4868/* ------------------------------ */ 4869 .balign 64 4870.L_OP_SHR_INT_2ADDR: /* 0xb9 */ 4871/* File: x86/OP_SHR_INT_2ADDR.S */ 4872/* File: x86/shop2addr.S */ 4873 /* 4874 * Generic 32-bit "shift/2addr" operation. 4875 */ 4876 /* shift/2addr vA, vB */ 4877 movzx rINSTbl,%ecx # eax<- BA 4878 sarl $4,%ecx # ecx<- B 4879 GET_VREG_R %ecx %ecx # eax<- vBB 4880 andb $0xf,rINSTbl # rINST<- A 4881 GET_VREG_R %eax rINST # eax<- vAA 4882 sarl %cl,%eax # ex: sarl %cl,%eax 4883 FETCH_INST_OPCODE 1 %edx 4884 SET_VREG %eax rINST 4885 ADVANCE_PC 1 4886 GOTO_NEXT_R %edx 4887 4888 4889/* ------------------------------ */ 4890 .balign 64 4891.L_OP_USHR_INT_2ADDR: /* 0xba */ 4892/* File: x86/OP_USHR_INT_2ADDR.S */ 4893/* File: x86/shop2addr.S */ 4894 /* 4895 * Generic 32-bit "shift/2addr" operation. 4896 */ 4897 /* shift/2addr vA, vB */ 4898 movzx rINSTbl,%ecx # eax<- BA 4899 sarl $4,%ecx # ecx<- B 4900 GET_VREG_R %ecx %ecx # eax<- vBB 4901 andb $0xf,rINSTbl # rINST<- A 4902 GET_VREG_R %eax rINST # eax<- vAA 4903 shrl %cl,%eax # ex: sarl %cl,%eax 4904 FETCH_INST_OPCODE 1 %edx 4905 SET_VREG %eax rINST 4906 ADVANCE_PC 1 4907 GOTO_NEXT_R %edx 4908 4909 4910/* ------------------------------ */ 4911 .balign 64 4912.L_OP_ADD_LONG_2ADDR: /* 0xbb */ 4913/* File: x86/OP_ADD_LONG_2ADDR.S */ 4914/* File: x86/binopWide2addr.S */ 4915 /* 4916 * Generic 64-bit binary operation. 4917 */ 4918 /* binop/2addr vA, vB */ 4919 movzbl rINSTbl,%ecx # ecx<- BA 4920 sarl $4,%ecx # ecx<- B 4921 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 4922 GET_VREG_WORD %ecx %ecx 1 # eax<- v[B+1] 4923 andb $0xF,rINSTbl # rINST<- A 4924 addl %eax,(rFP,rINST,4) # example: addl %eax,(rFP,rINST,4) 4925 adcl %ecx,4(rFP,rINST,4) # example: adcl %ecx,4(rFP,rINST,4) 4926 FETCH_INST_OPCODE 1 %edx 4927 ADVANCE_PC 1 4928 GOTO_NEXT_R %edx 4929 4930 4931/* ------------------------------ */ 4932 .balign 64 4933.L_OP_SUB_LONG_2ADDR: /* 0xbc */ 4934/* File: x86/OP_SUB_LONG_2ADDR.S */ 4935/* File: x86/binopWide2addr.S */ 4936 /* 4937 * Generic 64-bit binary operation. 4938 */ 4939 /* binop/2addr vA, vB */ 4940 movzbl rINSTbl,%ecx # ecx<- BA 4941 sarl $4,%ecx # ecx<- B 4942 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 4943 GET_VREG_WORD %ecx %ecx 1 # eax<- v[B+1] 4944 andb $0xF,rINSTbl # rINST<- A 4945 subl %eax,(rFP,rINST,4) # example: addl %eax,(rFP,rINST,4) 4946 sbbl %ecx,4(rFP,rINST,4) # example: adcl %ecx,4(rFP,rINST,4) 4947 FETCH_INST_OPCODE 1 %edx 4948 ADVANCE_PC 1 4949 GOTO_NEXT_R %edx 4950 4951 4952/* ------------------------------ */ 4953 .balign 64 4954.L_OP_MUL_LONG_2ADDR: /* 0xbd */ 4955/* File: x86/OP_MUL_LONG_2ADDR.S */ 4956 /* 4957 * Signed 64-bit integer multiply, 2-addr version 4958 * 4959 * We could definately use more free registers for 4960 * this code. We must spill %edx (edx) because it 4961 * is used by imul. We'll also spill rINST (ebx), 4962 * giving us eax, ebc, ecx and edx as computational 4963 * temps. On top of that, we'll spill %esi (edi) 4964 * for use as the vA pointer and rFP (esi) for use 4965 * as the vB pointer. Yuck. 4966 */ 4967 /* mul-long/2addr vA, vB */ 4968 movzbl rINSTbl,%eax # eax<- BA 4969 andb $0xf,%al # eax<- A 4970 sarl $4,rINST # rINST<- B 4971 SPILL_TMP2(%esi) 4972 SPILL(rFP) 4973 leal (rFP,%eax,4),%esi # %esi<- &v[A] 4974 leal (rFP,rINST,4),rFP # rFP<- &v[B] 4975 movl 4(%esi),%ecx # ecx<- Amsw 4976 imull (rFP),%ecx # ecx<- (Amsw*Blsw) 4977 movl 4(rFP),%eax # eax<- Bmsw 4978 imull (%esi),%eax # eax<- (Bmsw*Alsw) 4979 addl %eax,%ecx # ecx<- (Amsw*Blsw)+(Bmsw*Alsw) 4980 movl (rFP),%eax # eax<- Blsw 4981 mull (%esi) # eax<- (Blsw*Alsw) 4982 jmp .LOP_MUL_LONG_2ADDR_continue 4983 4984/* ------------------------------ */ 4985 .balign 64 4986.L_OP_DIV_LONG_2ADDR: /* 0xbe */ 4987/* File: x86/OP_DIV_LONG_2ADDR.S */ 4988 /* div/2addr vA, vB */ 4989 movzbl rINSTbl,%eax 4990 shrl $4,%eax # eax<- B 4991 andb $0xf,rINSTbl # rINST<- A 4992 GET_VREG_WORD %edx %eax 0 4993 GET_VREG_WORD %eax %eax 1 4994 movl %edx,OUT_ARG2(%esp) 4995 testl %eax,%eax 4996 je .LOP_DIV_LONG_2ADDR_check_zero 4997 cmpl $-1,%eax 4998 je .LOP_DIV_LONG_2ADDR_check_neg1 4999.LOP_DIV_LONG_2ADDR_notSpecial: 5000 GET_VREG_WORD %edx rINST 0 5001 GET_VREG_WORD %ecx rINST 1 5002.LOP_DIV_LONG_2ADDR_notSpecial1: 5003 jmp .LOP_DIV_LONG_2ADDR_continue 5004 5005/* ------------------------------ */ 5006 .balign 64 5007.L_OP_REM_LONG_2ADDR: /* 0xbf */ 5008/* File: x86/OP_REM_LONG_2ADDR.S */ 5009/* File: x86/OP_DIV_LONG_2ADDR.S */ 5010 /* div/2addr vA, vB */ 5011 movzbl rINSTbl,%eax 5012 shrl $4,%eax # eax<- B 5013 andb $0xf,rINSTbl # rINST<- A 5014 GET_VREG_WORD %edx %eax 0 5015 GET_VREG_WORD %eax %eax 1 5016 movl %edx,OUT_ARG2(%esp) 5017 testl %eax,%eax 5018 je .LOP_REM_LONG_2ADDR_check_zero 5019 cmpl $-1,%eax 5020 je .LOP_REM_LONG_2ADDR_check_neg1 5021.LOP_REM_LONG_2ADDR_notSpecial: 5022 GET_VREG_WORD %edx rINST 0 5023 GET_VREG_WORD %ecx rINST 1 5024.LOP_REM_LONG_2ADDR_notSpecial1: 5025 jmp .LOP_REM_LONG_2ADDR_continue 5026 5027 5028/* ------------------------------ */ 5029 .balign 64 5030.L_OP_AND_LONG_2ADDR: /* 0xc0 */ 5031/* File: x86/OP_AND_LONG_2ADDR.S */ 5032/* File: x86/binopWide2addr.S */ 5033 /* 5034 * Generic 64-bit binary operation. 5035 */ 5036 /* binop/2addr vA, vB */ 5037 movzbl rINSTbl,%ecx # ecx<- BA 5038 sarl $4,%ecx # ecx<- B 5039 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 5040 GET_VREG_WORD %ecx %ecx 1 # eax<- v[B+1] 5041 andb $0xF,rINSTbl # rINST<- A 5042 andl %eax,(rFP,rINST,4) # example: addl %eax,(rFP,rINST,4) 5043 andl %ecx,4(rFP,rINST,4) # example: adcl %ecx,4(rFP,rINST,4) 5044 FETCH_INST_OPCODE 1 %edx 5045 ADVANCE_PC 1 5046 GOTO_NEXT_R %edx 5047 5048 5049/* ------------------------------ */ 5050 .balign 64 5051.L_OP_OR_LONG_2ADDR: /* 0xc1 */ 5052/* File: x86/OP_OR_LONG_2ADDR.S */ 5053/* File: x86/binopWide2addr.S */ 5054 /* 5055 * Generic 64-bit binary operation. 5056 */ 5057 /* binop/2addr vA, vB */ 5058 movzbl rINSTbl,%ecx # ecx<- BA 5059 sarl $4,%ecx # ecx<- B 5060 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 5061 GET_VREG_WORD %ecx %ecx 1 # eax<- v[B+1] 5062 andb $0xF,rINSTbl # rINST<- A 5063 orl %eax,(rFP,rINST,4) # example: addl %eax,(rFP,rINST,4) 5064 orl %ecx,4(rFP,rINST,4) # example: adcl %ecx,4(rFP,rINST,4) 5065 FETCH_INST_OPCODE 1 %edx 5066 ADVANCE_PC 1 5067 GOTO_NEXT_R %edx 5068 5069 5070/* ------------------------------ */ 5071 .balign 64 5072.L_OP_XOR_LONG_2ADDR: /* 0xc2 */ 5073/* File: x86/OP_XOR_LONG_2ADDR.S */ 5074/* File: x86/binopWide2addr.S */ 5075 /* 5076 * Generic 64-bit binary operation. 5077 */ 5078 /* binop/2addr vA, vB */ 5079 movzbl rINSTbl,%ecx # ecx<- BA 5080 sarl $4,%ecx # ecx<- B 5081 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 5082 GET_VREG_WORD %ecx %ecx 1 # eax<- v[B+1] 5083 andb $0xF,rINSTbl # rINST<- A 5084 xorl %eax,(rFP,rINST,4) # example: addl %eax,(rFP,rINST,4) 5085 xorl %ecx,4(rFP,rINST,4) # example: adcl %ecx,4(rFP,rINST,4) 5086 FETCH_INST_OPCODE 1 %edx 5087 ADVANCE_PC 1 5088 GOTO_NEXT_R %edx 5089 5090 5091/* ------------------------------ */ 5092 .balign 64 5093.L_OP_SHL_LONG_2ADDR: /* 0xc3 */ 5094/* File: x86/OP_SHL_LONG_2ADDR.S */ 5095 /* 5096 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5097 * 32-bit shift distance. 5098 */ 5099 /* shl-long/2addr vA, vB */ 5100 /* ecx gets shift count */ 5101 /* Need to spill edx */ 5102 /* rINSTw gets AA */ 5103 movzbl rINSTbl,%ecx # ecx<- BA 5104 andb $0xf,rINSTbl # rINST<- A 5105 GET_VREG_WORD %eax rINST 0 # eax<- v[AA+0] 5106 sarl $4,%ecx # ecx<- B 5107 GET_VREG_WORD %edx rINST 1 # edx<- v[AA+1] 5108 GET_VREG_R %ecx %ecx # ecx<- vBB 5109 shldl %eax,%edx 5110 sall %cl,%eax 5111 testb $32,%cl 5112 je 2f 5113 movl %eax,%edx 5114 xorl %eax,%eax 51152: 5116 SET_VREG_WORD %edx rINST 1 # v[AA+1]<- edx 5117 jmp .LOP_SHL_LONG_2ADDR_finish 5118 5119/* ------------------------------ */ 5120 .balign 64 5121.L_OP_SHR_LONG_2ADDR: /* 0xc4 */ 5122/* File: x86/OP_SHR_LONG_2ADDR.S */ 5123 /* 5124 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5125 * 32-bit shift distance. 5126 */ 5127 /* shl-long/2addr vA, vB */ 5128 /* ecx gets shift count */ 5129 /* Need to spill edx */ 5130 /* rINSTw gets AA */ 5131 movzbl rINSTbl,%ecx # ecx<- BA 5132 andb $0xf,rINSTbl # rINST<- A 5133 GET_VREG_WORD %eax rINST 0 # eax<- v[AA+0] 5134 sarl $4,%ecx # ecx<- B 5135 GET_VREG_WORD %edx rINST 1 # edx<- v[AA+1] 5136 GET_VREG_R %ecx %ecx # ecx<- vBB 5137 shrdl %edx,%eax 5138 sarl %cl,%edx 5139 testb $32,%cl 5140 je 2f 5141 movl %edx,%eax 5142 sarl $31,%edx 51432: 5144 SET_VREG_WORD %edx rINST 1 # v[AA+1]<- edx 5145 jmp .LOP_SHR_LONG_2ADDR_finish 5146 5147/* ------------------------------ */ 5148 .balign 64 5149.L_OP_USHR_LONG_2ADDR: /* 0xc5 */ 5150/* File: x86/OP_USHR_LONG_2ADDR.S */ 5151 /* 5152 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5153 * 32-bit shift distance. 5154 */ 5155 /* shl-long/2addr vA, vB */ 5156 /* ecx gets shift count */ 5157 /* Need to spill edx */ 5158 /* rINSTw gets AA */ 5159 movzbl rINSTbl,%ecx # ecx<- BA 5160 andb $0xf,rINSTbl # rINST<- A 5161 GET_VREG_WORD %eax rINST 0 # eax<- v[AA+0] 5162 sarl $4,%ecx # ecx<- B 5163 GET_VREG_WORD %edx rINST 1 # edx<- v[AA+1] 5164 GET_VREG_R %ecx %ecx # ecx<- vBB 5165 shrdl %edx,%eax 5166 shrl %cl,%edx 5167 testb $32,%cl 5168 je 2f 5169 movl %edx,%eax 5170 xorl %edx,%edx 51712: 5172 SET_VREG_WORD %edx rINST 1 # v[AA+1]<- edx 5173 jmp .LOP_USHR_LONG_2ADDR_finish 5174 5175/* ------------------------------ */ 5176 .balign 64 5177.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */ 5178/* File: x86/OP_ADD_FLOAT_2ADDR.S */ 5179/* File: x86/binflop2addr.S */ 5180 /* 5181 * Generic 32-bit binary float operation. 5182 * 5183 * For: add-fp, sub-fp, mul-fp, div-fp 5184 */ 5185 5186 /* binop/2addr vA, vB */ 5187 movzx rINSTbl,%ecx # ecx<- A+ 5188 andb $0xf,%cl # ecx<- A 5189 flds (rFP,%ecx,4) # vAA to fp stack 5190 sarl $4,rINST # rINST<- B 5191 fadds (rFP,rINST,4) # ex: faddp 5192 FETCH_INST_OPCODE 1 %edx 5193 ADVANCE_PC 1 5194 fstps (rFP,%ecx,4) # %st to vA 5195 GOTO_NEXT_R %edx 5196 5197 5198/* ------------------------------ */ 5199 .balign 64 5200.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */ 5201/* File: x86/OP_SUB_FLOAT_2ADDR.S */ 5202/* File: x86/binflop2addr.S */ 5203 /* 5204 * Generic 32-bit binary float operation. 5205 * 5206 * For: add-fp, sub-fp, mul-fp, div-fp 5207 */ 5208 5209 /* binop/2addr vA, vB */ 5210 movzx rINSTbl,%ecx # ecx<- A+ 5211 andb $0xf,%cl # ecx<- A 5212 flds (rFP,%ecx,4) # vAA to fp stack 5213 sarl $4,rINST # rINST<- B 5214 fsubs (rFP,rINST,4) # ex: faddp 5215 FETCH_INST_OPCODE 1 %edx 5216 ADVANCE_PC 1 5217 fstps (rFP,%ecx,4) # %st to vA 5218 GOTO_NEXT_R %edx 5219 5220 5221/* ------------------------------ */ 5222 .balign 64 5223.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */ 5224/* File: x86/OP_MUL_FLOAT_2ADDR.S */ 5225/* File: x86/binflop2addr.S */ 5226 /* 5227 * Generic 32-bit binary float operation. 5228 * 5229 * For: add-fp, sub-fp, mul-fp, div-fp 5230 */ 5231 5232 /* binop/2addr vA, vB */ 5233 movzx rINSTbl,%ecx # ecx<- A+ 5234 andb $0xf,%cl # ecx<- A 5235 flds (rFP,%ecx,4) # vAA to fp stack 5236 sarl $4,rINST # rINST<- B 5237 fmuls (rFP,rINST,4) # ex: faddp 5238 FETCH_INST_OPCODE 1 %edx 5239 ADVANCE_PC 1 5240 fstps (rFP,%ecx,4) # %st to vA 5241 GOTO_NEXT_R %edx 5242 5243 5244/* ------------------------------ */ 5245 .balign 64 5246.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */ 5247/* File: x86/OP_DIV_FLOAT_2ADDR.S */ 5248/* File: x86/binflop2addr.S */ 5249 /* 5250 * Generic 32-bit binary float operation. 5251 * 5252 * For: add-fp, sub-fp, mul-fp, div-fp 5253 */ 5254 5255 /* binop/2addr vA, vB */ 5256 movzx rINSTbl,%ecx # ecx<- A+ 5257 andb $0xf,%cl # ecx<- A 5258 flds (rFP,%ecx,4) # vAA to fp stack 5259 sarl $4,rINST # rINST<- B 5260 fdivs (rFP,rINST,4) # ex: faddp 5261 FETCH_INST_OPCODE 1 %edx 5262 ADVANCE_PC 1 5263 fstps (rFP,%ecx,4) # %st to vA 5264 GOTO_NEXT_R %edx 5265 5266 5267/* ------------------------------ */ 5268 .balign 64 5269.L_OP_REM_FLOAT_2ADDR: /* 0xca */ 5270/* File: x86/OP_REM_FLOAT_2ADDR.S */ 5271 /* rem_float/2addr vA, vB */ 5272 movzx rINSTbl,%ecx # ecx<- A+ 5273 sarl $4,rINST # rINST<- B 5274 flds (rFP,rINST,4) # vBB to fp stack 5275 andb $0xf,%cl # ecx<- A 5276 flds (rFP,%ecx,4) # vAA to fp stack 5277 FETCH_INST_OPCODE 1 %edx 52781: 5279 fprem 5280 fstsw %ax 5281 sahf 5282 jp 1b 5283 fstp %st(1) 5284 ADVANCE_PC 1 5285 fstps (rFP,%ecx,4) # %st to vA 5286 GOTO_NEXT_R %edx 5287 5288/* ------------------------------ */ 5289 .balign 64 5290.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */ 5291/* File: x86/OP_ADD_DOUBLE_2ADDR.S */ 5292/* File: x86/binflop2addr.S */ 5293 /* 5294 * Generic 32-bit binary float operation. 5295 * 5296 * For: add-fp, sub-fp, mul-fp, div-fp 5297 */ 5298 5299 /* binop/2addr vA, vB */ 5300 movzx rINSTbl,%ecx # ecx<- A+ 5301 andb $0xf,%cl # ecx<- A 5302 fldl (rFP,%ecx,4) # vAA to fp stack 5303 sarl $4,rINST # rINST<- B 5304 faddl (rFP,rINST,4) # ex: faddp 5305 FETCH_INST_OPCODE 1 %edx 5306 ADVANCE_PC 1 5307 fstpl (rFP,%ecx,4) # %st to vA 5308 GOTO_NEXT_R %edx 5309 5310 5311/* ------------------------------ */ 5312 .balign 64 5313.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */ 5314/* File: x86/OP_SUB_DOUBLE_2ADDR.S */ 5315/* File: x86/binflop2addr.S */ 5316 /* 5317 * Generic 32-bit binary float operation. 5318 * 5319 * For: add-fp, sub-fp, mul-fp, div-fp 5320 */ 5321 5322 /* binop/2addr vA, vB */ 5323 movzx rINSTbl,%ecx # ecx<- A+ 5324 andb $0xf,%cl # ecx<- A 5325 fldl (rFP,%ecx,4) # vAA to fp stack 5326 sarl $4,rINST # rINST<- B 5327 fsubl (rFP,rINST,4) # ex: faddp 5328 FETCH_INST_OPCODE 1 %edx 5329 ADVANCE_PC 1 5330 fstpl (rFP,%ecx,4) # %st to vA 5331 GOTO_NEXT_R %edx 5332 5333 5334/* ------------------------------ */ 5335 .balign 64 5336.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */ 5337/* File: x86/OP_MUL_DOUBLE_2ADDR.S */ 5338/* File: x86/binflop2addr.S */ 5339 /* 5340 * Generic 32-bit binary float operation. 5341 * 5342 * For: add-fp, sub-fp, mul-fp, div-fp 5343 */ 5344 5345 /* binop/2addr vA, vB */ 5346 movzx rINSTbl,%ecx # ecx<- A+ 5347 andb $0xf,%cl # ecx<- A 5348 fldl (rFP,%ecx,4) # vAA to fp stack 5349 sarl $4,rINST # rINST<- B 5350 fmull (rFP,rINST,4) # ex: faddp 5351 FETCH_INST_OPCODE 1 %edx 5352 ADVANCE_PC 1 5353 fstpl (rFP,%ecx,4) # %st to vA 5354 GOTO_NEXT_R %edx 5355 5356 5357/* ------------------------------ */ 5358 .balign 64 5359.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */ 5360/* File: x86/OP_DIV_DOUBLE_2ADDR.S */ 5361/* File: x86/binflop2addr.S */ 5362 /* 5363 * Generic 32-bit binary float operation. 5364 * 5365 * For: add-fp, sub-fp, mul-fp, div-fp 5366 */ 5367 5368 /* binop/2addr vA, vB */ 5369 movzx rINSTbl,%ecx # ecx<- A+ 5370 andb $0xf,%cl # ecx<- A 5371 fldl (rFP,%ecx,4) # vAA to fp stack 5372 sarl $4,rINST # rINST<- B 5373 fdivl (rFP,rINST,4) # ex: faddp 5374 FETCH_INST_OPCODE 1 %edx 5375 ADVANCE_PC 1 5376 fstpl (rFP,%ecx,4) # %st to vA 5377 GOTO_NEXT_R %edx 5378 5379 5380/* ------------------------------ */ 5381 .balign 64 5382.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */ 5383/* File: x86/OP_REM_DOUBLE_2ADDR.S */ 5384 /* rem_float/2addr vA, vB */ 5385 movzx rINSTbl,%ecx # ecx<- A+ 5386 sarl $4,rINST # rINST<- B 5387 fldl (rFP,rINST,4) # vBB to fp stack 5388 andb $0xf,%cl # ecx<- A 5389 fldl (rFP,%ecx,4) # vAA to fp stack 5390 FETCH_INST_OPCODE 1 %edx 53911: 5392 fprem 5393 fstsw %ax 5394 sahf 5395 jp 1b 5396 fstp %st(1) 5397 ADVANCE_PC 1 5398 fstpl (rFP,%ecx,4) # %st to vA 5399 GOTO_NEXT_R %edx 5400 5401/* ------------------------------ */ 5402 .balign 64 5403.L_OP_ADD_INT_LIT16: /* 0xd0 */ 5404/* File: x86/OP_ADD_INT_LIT16.S */ 5405/* File: x86/binopLit16.S */ 5406 /* 5407 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 5408 * that specifies an instruction that performs "result = eax op ecx". 5409 * This could be an x86 instruction or a function call. (If the result 5410 * comes back in a register other than eax, you can override "result".) 5411 * 5412 * For: add-int/lit16, rsub-int, 5413 * and-int/lit16, or-int/lit16, xor-int/lit16 5414 */ 5415 /* binop/lit16 vA, vB, #+CCCC */ 5416 movzbl rINSTbl,%eax # eax<- 000000BA 5417 sarl $4,%eax # eax<- B 5418 GET_VREG_R %eax %eax # eax<- vB 5419 movswl 2(rPC),%ecx # ecx<- ssssCCCC 5420 andb $0xf,rINSTbl # rINST<- A 5421 addl %ecx,%eax # for example: addl %ecx, %eax 5422 SET_VREG %eax rINST 5423 FETCH_INST_OPCODE 2 %edx 5424 ADVANCE_PC 2 5425 GOTO_NEXT_R %edx 5426 5427 5428/* ------------------------------ */ 5429 .balign 64 5430.L_OP_RSUB_INT: /* 0xd1 */ 5431/* File: x86/OP_RSUB_INT.S */ 5432/* File: x86/binopLit16.S */ 5433 /* 5434 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 5435 * that specifies an instruction that performs "result = eax op ecx". 5436 * This could be an x86 instruction or a function call. (If the result 5437 * comes back in a register other than eax, you can override "result".) 5438 * 5439 * For: add-int/lit16, rsub-int, 5440 * and-int/lit16, or-int/lit16, xor-int/lit16 5441 */ 5442 /* binop/lit16 vA, vB, #+CCCC */ 5443 movzbl rINSTbl,%eax # eax<- 000000BA 5444 sarl $4,%eax # eax<- B 5445 GET_VREG_R %eax %eax # eax<- vB 5446 movswl 2(rPC),%ecx # ecx<- ssssCCCC 5447 andb $0xf,rINSTbl # rINST<- A 5448 subl %eax,%ecx # for example: addl %ecx, %eax 5449 SET_VREG %ecx rINST 5450 FETCH_INST_OPCODE 2 %edx 5451 ADVANCE_PC 2 5452 GOTO_NEXT_R %edx 5453 5454 5455/* ------------------------------ */ 5456 .balign 64 5457.L_OP_MUL_INT_LIT16: /* 0xd2 */ 5458/* File: x86/OP_MUL_INT_LIT16.S */ 5459 /* mul/lit16 vA, vB, #+CCCC */ 5460 /* Need A in rINST, ssssCCCC in ecx, vB in eax */ 5461 movzbl rINSTbl,%eax # eax<- 000000BA 5462 sarl $4,%eax # eax<- B 5463 GET_VREG_R %eax %eax # eax<- vB 5464 movswl 2(rPC),%ecx # ecx<- ssssCCCC 5465 andb $0xf,rINSTbl # rINST<- A 5466 imull %ecx,%eax # trashes edx 5467 FETCH_INST_OPCODE 2 %edx 5468 ADVANCE_PC 2 5469 SET_VREG %eax rINST 5470 GOTO_NEXT_R %edx 5471 5472/* ------------------------------ */ 5473 .balign 64 5474.L_OP_DIV_INT_LIT16: /* 0xd3 */ 5475/* File: x86/OP_DIV_INT_LIT16.S */ 5476/* File: x86/bindivLit16.S */ 5477 /* 5478 * 32-bit binary div/rem operation. Handles special case of op0=minint and 5479 * op1=-1. 5480 */ 5481 /* div/rem/lit16 vA, vB, #+CCCC */ 5482 /* Need A in rINST, ssssCCCC in ecx, vB in eax */ 5483 movzbl rINSTbl,%eax # eax<- 000000BA 5484 sarl $4,%eax # eax<- B 5485 GET_VREG_R %eax %eax # eax<- vB 5486 movswl 2(rPC),%ecx # ecx<- ssssCCCC 5487 andb $0xf,rINSTbl # rINST<- A 5488 cmpl $0,%ecx 5489 je common_errDivideByZero 5490 cmpl $-1,%ecx 5491 jne .LOP_DIV_INT_LIT16_continue_div 5492 cmpl $0x80000000,%eax 5493 jne .LOP_DIV_INT_LIT16_continue_div 5494 movl $0x80000000,%eax 5495 jmp .LOP_DIV_INT_LIT16_finish_div 5496 5497 5498 5499/* ------------------------------ */ 5500 .balign 64 5501.L_OP_REM_INT_LIT16: /* 0xd4 */ 5502/* File: x86/OP_REM_INT_LIT16.S */ 5503/* File: x86/bindivLit16.S */ 5504 /* 5505 * 32-bit binary div/rem operation. Handles special case of op0=minint and 5506 * op1=-1. 5507 */ 5508 /* div/rem/lit16 vA, vB, #+CCCC */ 5509 /* Need A in rINST, ssssCCCC in ecx, vB in eax */ 5510 movzbl rINSTbl,%eax # eax<- 000000BA 5511 sarl $4,%eax # eax<- B 5512 GET_VREG_R %eax %eax # eax<- vB 5513 movswl 2(rPC),%ecx # ecx<- ssssCCCC 5514 andb $0xf,rINSTbl # rINST<- A 5515 cmpl $0,%ecx 5516 je common_errDivideByZero 5517 cmpl $-1,%ecx 5518 jne .LOP_REM_INT_LIT16_continue_div 5519 cmpl $0x80000000,%eax 5520 jne .LOP_REM_INT_LIT16_continue_div 5521 movl $0,%edx 5522 jmp .LOP_REM_INT_LIT16_finish_div 5523 5524 5525 5526/* ------------------------------ */ 5527 .balign 64 5528.L_OP_AND_INT_LIT16: /* 0xd5 */ 5529/* File: x86/OP_AND_INT_LIT16.S */ 5530/* File: x86/binopLit16.S */ 5531 /* 5532 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 5533 * that specifies an instruction that performs "result = eax op ecx". 5534 * This could be an x86 instruction or a function call. (If the result 5535 * comes back in a register other than eax, you can override "result".) 5536 * 5537 * For: add-int/lit16, rsub-int, 5538 * and-int/lit16, or-int/lit16, xor-int/lit16 5539 */ 5540 /* binop/lit16 vA, vB, #+CCCC */ 5541 movzbl rINSTbl,%eax # eax<- 000000BA 5542 sarl $4,%eax # eax<- B 5543 GET_VREG_R %eax %eax # eax<- vB 5544 movswl 2(rPC),%ecx # ecx<- ssssCCCC 5545 andb $0xf,rINSTbl # rINST<- A 5546 andl %ecx,%eax # for example: addl %ecx, %eax 5547 SET_VREG %eax rINST 5548 FETCH_INST_OPCODE 2 %edx 5549 ADVANCE_PC 2 5550 GOTO_NEXT_R %edx 5551 5552 5553/* ------------------------------ */ 5554 .balign 64 5555.L_OP_OR_INT_LIT16: /* 0xd6 */ 5556/* File: x86/OP_OR_INT_LIT16.S */ 5557/* File: x86/binopLit16.S */ 5558 /* 5559 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 5560 * that specifies an instruction that performs "result = eax op ecx". 5561 * This could be an x86 instruction or a function call. (If the result 5562 * comes back in a register other than eax, you can override "result".) 5563 * 5564 * For: add-int/lit16, rsub-int, 5565 * and-int/lit16, or-int/lit16, xor-int/lit16 5566 */ 5567 /* binop/lit16 vA, vB, #+CCCC */ 5568 movzbl rINSTbl,%eax # eax<- 000000BA 5569 sarl $4,%eax # eax<- B 5570 GET_VREG_R %eax %eax # eax<- vB 5571 movswl 2(rPC),%ecx # ecx<- ssssCCCC 5572 andb $0xf,rINSTbl # rINST<- A 5573 orl %ecx,%eax # for example: addl %ecx, %eax 5574 SET_VREG %eax rINST 5575 FETCH_INST_OPCODE 2 %edx 5576 ADVANCE_PC 2 5577 GOTO_NEXT_R %edx 5578 5579 5580/* ------------------------------ */ 5581 .balign 64 5582.L_OP_XOR_INT_LIT16: /* 0xd7 */ 5583/* File: x86/OP_XOR_INT_LIT16.S */ 5584/* File: x86/binopLit16.S */ 5585 /* 5586 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 5587 * that specifies an instruction that performs "result = eax op ecx". 5588 * This could be an x86 instruction or a function call. (If the result 5589 * comes back in a register other than eax, you can override "result".) 5590 * 5591 * For: add-int/lit16, rsub-int, 5592 * and-int/lit16, or-int/lit16, xor-int/lit16 5593 */ 5594 /* binop/lit16 vA, vB, #+CCCC */ 5595 movzbl rINSTbl,%eax # eax<- 000000BA 5596 sarl $4,%eax # eax<- B 5597 GET_VREG_R %eax %eax # eax<- vB 5598 movswl 2(rPC),%ecx # ecx<- ssssCCCC 5599 andb $0xf,rINSTbl # rINST<- A 5600 xor %ecx,%eax # for example: addl %ecx, %eax 5601 SET_VREG %eax rINST 5602 FETCH_INST_OPCODE 2 %edx 5603 ADVANCE_PC 2 5604 GOTO_NEXT_R %edx 5605 5606 5607/* ------------------------------ */ 5608 .balign 64 5609.L_OP_ADD_INT_LIT8: /* 0xd8 */ 5610/* File: x86/OP_ADD_INT_LIT8.S */ 5611/* File: x86/binopLit8.S */ 5612 /* 5613 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 5614 * that specifies an instruction that performs "result = eax op ecx". 5615 * This could be an x86 instruction or a function call. (If the result 5616 * comes back in a register other than r0, you can override "result".) 5617 * 5618 * For: add-int/lit8, rsub-int/lit8 5619 * and-int/lit8, or-int/lit8, xor-int/lit8, 5620 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 5621 */ 5622 /* binop/lit8 vAA, vBB, #+CC */ 5623 movzbl 2(rPC),%eax # eax<- BB 5624 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5625 GET_VREG_R %eax %eax # eax<- rBB 5626 addl %ecx,%eax # ex: addl %ecx,%eax 5627 FETCH_INST_OPCODE 2 %edx 5628 SET_VREG %eax rINST 5629 ADVANCE_PC 2 5630 GOTO_NEXT_R %edx 5631 5632 5633/* ------------------------------ */ 5634 .balign 64 5635.L_OP_RSUB_INT_LIT8: /* 0xd9 */ 5636/* File: x86/OP_RSUB_INT_LIT8.S */ 5637/* File: x86/binopLit8.S */ 5638 /* 5639 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 5640 * that specifies an instruction that performs "result = eax op ecx". 5641 * This could be an x86 instruction or a function call. (If the result 5642 * comes back in a register other than r0, you can override "result".) 5643 * 5644 * For: add-int/lit8, rsub-int/lit8 5645 * and-int/lit8, or-int/lit8, xor-int/lit8, 5646 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 5647 */ 5648 /* binop/lit8 vAA, vBB, #+CC */ 5649 movzbl 2(rPC),%eax # eax<- BB 5650 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5651 GET_VREG_R %eax %eax # eax<- rBB 5652 subl %eax,%ecx # ex: addl %ecx,%eax 5653 FETCH_INST_OPCODE 2 %edx 5654 SET_VREG %ecx rINST 5655 ADVANCE_PC 2 5656 GOTO_NEXT_R %edx 5657 5658 5659/* ------------------------------ */ 5660 .balign 64 5661.L_OP_MUL_INT_LIT8: /* 0xda */ 5662/* File: x86/OP_MUL_INT_LIT8.S */ 5663 /* mul/lit8 vAA, vBB, #+CC */ 5664 movzbl 2(rPC),%eax # eax<- BB 5665 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5666 GET_VREG_R %eax %eax # eax<- rBB 5667 imull %ecx,%eax # trashes edx 5668 FETCH_INST_OPCODE 2 %edx 5669 ADVANCE_PC 2 5670 SET_VREG %eax rINST 5671 GOTO_NEXT_R %edx 5672 5673/* ------------------------------ */ 5674 .balign 64 5675.L_OP_DIV_INT_LIT8: /* 0xdb */ 5676/* File: x86/OP_DIV_INT_LIT8.S */ 5677/* File: x86/bindivLit8.S */ 5678 /* 5679 * 32-bit div/rem "lit8" binary operation. Handles special case of 5680 * op0=minint & op1=-1 5681 */ 5682 /* div/rem/lit8 vAA, vBB, #+CC */ 5683 movzbl 2(rPC),%eax # eax<- BB 5684 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5685 GET_VREG_R %eax %eax # eax<- rBB 5686 cmpl $0,%ecx 5687 je common_errDivideByZero 5688 cmpl $0x80000000,%eax 5689 jne .LOP_DIV_INT_LIT8_continue_div 5690 cmpl $-1,%ecx 5691 jne .LOP_DIV_INT_LIT8_continue_div 5692 movl $0x80000000,%eax 5693 jmp .LOP_DIV_INT_LIT8_finish_div 5694 5695 5696 5697/* ------------------------------ */ 5698 .balign 64 5699.L_OP_REM_INT_LIT8: /* 0xdc */ 5700/* File: x86/OP_REM_INT_LIT8.S */ 5701/* File: x86/bindivLit8.S */ 5702 /* 5703 * 32-bit div/rem "lit8" binary operation. Handles special case of 5704 * op0=minint & op1=-1 5705 */ 5706 /* div/rem/lit8 vAA, vBB, #+CC */ 5707 movzbl 2(rPC),%eax # eax<- BB 5708 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5709 GET_VREG_R %eax %eax # eax<- rBB 5710 cmpl $0,%ecx 5711 je common_errDivideByZero 5712 cmpl $0x80000000,%eax 5713 jne .LOP_REM_INT_LIT8_continue_div 5714 cmpl $-1,%ecx 5715 jne .LOP_REM_INT_LIT8_continue_div 5716 movl $0,%edx 5717 jmp .LOP_REM_INT_LIT8_finish_div 5718 5719 5720 5721/* ------------------------------ */ 5722 .balign 64 5723.L_OP_AND_INT_LIT8: /* 0xdd */ 5724/* File: x86/OP_AND_INT_LIT8.S */ 5725/* File: x86/binopLit8.S */ 5726 /* 5727 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 5728 * that specifies an instruction that performs "result = eax op ecx". 5729 * This could be an x86 instruction or a function call. (If the result 5730 * comes back in a register other than r0, you can override "result".) 5731 * 5732 * For: add-int/lit8, rsub-int/lit8 5733 * and-int/lit8, or-int/lit8, xor-int/lit8, 5734 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 5735 */ 5736 /* binop/lit8 vAA, vBB, #+CC */ 5737 movzbl 2(rPC),%eax # eax<- BB 5738 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5739 GET_VREG_R %eax %eax # eax<- rBB 5740 andl %ecx,%eax # ex: addl %ecx,%eax 5741 FETCH_INST_OPCODE 2 %edx 5742 SET_VREG %eax rINST 5743 ADVANCE_PC 2 5744 GOTO_NEXT_R %edx 5745 5746 5747/* ------------------------------ */ 5748 .balign 64 5749.L_OP_OR_INT_LIT8: /* 0xde */ 5750/* File: x86/OP_OR_INT_LIT8.S */ 5751/* File: x86/binopLit8.S */ 5752 /* 5753 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 5754 * that specifies an instruction that performs "result = eax op ecx". 5755 * This could be an x86 instruction or a function call. (If the result 5756 * comes back in a register other than r0, you can override "result".) 5757 * 5758 * For: add-int/lit8, rsub-int/lit8 5759 * and-int/lit8, or-int/lit8, xor-int/lit8, 5760 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 5761 */ 5762 /* binop/lit8 vAA, vBB, #+CC */ 5763 movzbl 2(rPC),%eax # eax<- BB 5764 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5765 GET_VREG_R %eax %eax # eax<- rBB 5766 orl %ecx,%eax # ex: addl %ecx,%eax 5767 FETCH_INST_OPCODE 2 %edx 5768 SET_VREG %eax rINST 5769 ADVANCE_PC 2 5770 GOTO_NEXT_R %edx 5771 5772 5773/* ------------------------------ */ 5774 .balign 64 5775.L_OP_XOR_INT_LIT8: /* 0xdf */ 5776/* File: x86/OP_XOR_INT_LIT8.S */ 5777/* File: x86/binopLit8.S */ 5778 /* 5779 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 5780 * that specifies an instruction that performs "result = eax op ecx". 5781 * This could be an x86 instruction or a function call. (If the result 5782 * comes back in a register other than r0, you can override "result".) 5783 * 5784 * For: add-int/lit8, rsub-int/lit8 5785 * and-int/lit8, or-int/lit8, xor-int/lit8, 5786 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 5787 */ 5788 /* binop/lit8 vAA, vBB, #+CC */ 5789 movzbl 2(rPC),%eax # eax<- BB 5790 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5791 GET_VREG_R %eax %eax # eax<- rBB 5792 xor %ecx,%eax # ex: addl %ecx,%eax 5793 FETCH_INST_OPCODE 2 %edx 5794 SET_VREG %eax rINST 5795 ADVANCE_PC 2 5796 GOTO_NEXT_R %edx 5797 5798 5799/* ------------------------------ */ 5800 .balign 64 5801.L_OP_SHL_INT_LIT8: /* 0xe0 */ 5802/* File: x86/OP_SHL_INT_LIT8.S */ 5803/* File: x86/binopLit8.S */ 5804 /* 5805 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 5806 * that specifies an instruction that performs "result = eax op ecx". 5807 * This could be an x86 instruction or a function call. (If the result 5808 * comes back in a register other than r0, you can override "result".) 5809 * 5810 * For: add-int/lit8, rsub-int/lit8 5811 * and-int/lit8, or-int/lit8, xor-int/lit8, 5812 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 5813 */ 5814 /* binop/lit8 vAA, vBB, #+CC */ 5815 movzbl 2(rPC),%eax # eax<- BB 5816 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5817 GET_VREG_R %eax %eax # eax<- rBB 5818 sall %cl,%eax # ex: addl %ecx,%eax 5819 FETCH_INST_OPCODE 2 %edx 5820 SET_VREG %eax rINST 5821 ADVANCE_PC 2 5822 GOTO_NEXT_R %edx 5823 5824 5825/* ------------------------------ */ 5826 .balign 64 5827.L_OP_SHR_INT_LIT8: /* 0xe1 */ 5828/* File: x86/OP_SHR_INT_LIT8.S */ 5829/* File: x86/binopLit8.S */ 5830 /* 5831 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 5832 * that specifies an instruction that performs "result = eax op ecx". 5833 * This could be an x86 instruction or a function call. (If the result 5834 * comes back in a register other than r0, you can override "result".) 5835 * 5836 * For: add-int/lit8, rsub-int/lit8 5837 * and-int/lit8, or-int/lit8, xor-int/lit8, 5838 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 5839 */ 5840 /* binop/lit8 vAA, vBB, #+CC */ 5841 movzbl 2(rPC),%eax # eax<- BB 5842 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5843 GET_VREG_R %eax %eax # eax<- rBB 5844 sarl %cl,%eax # ex: addl %ecx,%eax 5845 FETCH_INST_OPCODE 2 %edx 5846 SET_VREG %eax rINST 5847 ADVANCE_PC 2 5848 GOTO_NEXT_R %edx 5849 5850 5851/* ------------------------------ */ 5852 .balign 64 5853.L_OP_USHR_INT_LIT8: /* 0xe2 */ 5854/* File: x86/OP_USHR_INT_LIT8.S */ 5855/* File: x86/binopLit8.S */ 5856 /* 5857 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 5858 * that specifies an instruction that performs "result = eax op ecx". 5859 * This could be an x86 instruction or a function call. (If the result 5860 * comes back in a register other than r0, you can override "result".) 5861 * 5862 * For: add-int/lit8, rsub-int/lit8 5863 * and-int/lit8, or-int/lit8, xor-int/lit8, 5864 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 5865 */ 5866 /* binop/lit8 vAA, vBB, #+CC */ 5867 movzbl 2(rPC),%eax # eax<- BB 5868 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5869 GET_VREG_R %eax %eax # eax<- rBB 5870 shrl %cl,%eax # ex: addl %ecx,%eax 5871 FETCH_INST_OPCODE 2 %edx 5872 SET_VREG %eax rINST 5873 ADVANCE_PC 2 5874 GOTO_NEXT_R %edx 5875 5876 5877/* ------------------------------ */ 5878 .balign 64 5879.L_OP_IGET_VOLATILE: /* 0xe3 */ 5880/* File: x86/OP_IGET_VOLATILE.S */ 5881/* File: x86/OP_IGET.S */ 5882 /* 5883 * General 32-bit instance field get. 5884 * 5885 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 5886 */ 5887 /* op vA, vB, field@CCCC */ 5888 movl rSELF,%ecx 5889 movzwl 2(rPC),%edx # edx<- 0000CCCC 5890 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 5891 movzbl rINSTbl,%ecx # ecx<- BA 5892 sarl $4,%ecx # ecx<- B 5893 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 5894 andb $0xf,rINSTbl # rINST<- A 5895 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 5896 movl (%eax,%edx,4),%eax # resolved entry 5897 testl %eax,%eax # is resolved entry null? 5898 jne .LOP_IGET_VOLATILE_finish # no, already resolved 5899 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 5900 movl rSELF,%edx 5901 jmp .LOP_IGET_VOLATILE_resolve 5902 5903 5904/* ------------------------------ */ 5905 .balign 64 5906.L_OP_IPUT_VOLATILE: /* 0xe4 */ 5907/* File: x86/OP_IPUT_VOLATILE.S */ 5908/* File: x86/OP_IPUT.S */ 5909 5910 /* 5911 * General 32-bit instance field put. 5912 * 5913 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 5914 */ 5915 /* op vA, vB, field@CCCC */ 5916 movl rSELF,%ecx 5917 movzwl 2(rPC),%edx # %edx<- 0000CCCC 5918 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 5919 movzbl rINSTbl,%ecx # ecx<- BA 5920 sarl $4,%ecx # ecx<- B 5921 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 5922 andb $0xf,rINSTbl # rINST<- A 5923 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 5924 movl (%eax,%edx,4),%eax # resolved entry 5925 testl %eax,%eax # is resolved entry null? 5926 jne .LOP_IPUT_VOLATILE_finish # no, already resolved 5927 movl %edx,OUT_ARG1(%esp) 5928 movl rSELF,%edx 5929 jmp .LOP_IPUT_VOLATILE_resolve 5930 5931 5932/* ------------------------------ */ 5933 .balign 64 5934.L_OP_SGET_VOLATILE: /* 0xe5 */ 5935/* File: x86/OP_SGET_VOLATILE.S */ 5936/* File: x86/OP_SGET.S */ 5937 /* 5938 * General 32-bit SGET handler. 5939 * 5940 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 5941 */ 5942 /* op vAA, field@BBBB */ 5943 movl rSELF,%ecx 5944 movzwl 2(rPC),%eax # eax<- field ref BBBB 5945 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 5946 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 5947 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 5948 testl %eax,%eax # resolved entry null? 5949 je .LOP_SGET_VOLATILE_resolve # if not, make it so 5950.LOP_SGET_VOLATILE_finish: # field ptr in eax 5951 movl offStaticField_value(%eax),%eax 5952 FETCH_INST_OPCODE 2 %edx 5953 ADVANCE_PC 2 5954 SET_VREG %eax rINST 5955 GOTO_NEXT_R %edx 5956 5957 5958/* ------------------------------ */ 5959 .balign 64 5960.L_OP_SPUT_VOLATILE: /* 0xe6 */ 5961/* File: x86/OP_SPUT_VOLATILE.S */ 5962/* File: x86/OP_SPUT.S */ 5963 /* 5964 * General 32-bit SPUT handler. 5965 * 5966 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 5967 */ 5968 /* op vAA, field@BBBB */ 5969 movl rSELF,%ecx 5970 movzwl 2(rPC),%eax # eax<- field ref BBBB 5971 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 5972 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 5973 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 5974 testl %eax,%eax # resolved entry null? 5975 je .LOP_SPUT_VOLATILE_resolve # if not, make it so 5976.LOP_SPUT_VOLATILE_finish: # field ptr in eax 5977 GET_VREG_R %ecx rINST 5978 FETCH_INST_OPCODE 2 %edx 5979 ADVANCE_PC 2 5980 movl %ecx,offStaticField_value(%eax) 5981 GOTO_NEXT_R %edx 5982 5983 5984/* ------------------------------ */ 5985 .balign 64 5986.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */ 5987/* File: x86/OP_IGET_OBJECT_VOLATILE.S */ 5988/* File: x86/OP_IGET.S */ 5989 /* 5990 * General 32-bit instance field get. 5991 * 5992 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 5993 */ 5994 /* op vA, vB, field@CCCC */ 5995 movl rSELF,%ecx 5996 movzwl 2(rPC),%edx # edx<- 0000CCCC 5997 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 5998 movzbl rINSTbl,%ecx # ecx<- BA 5999 sarl $4,%ecx # ecx<- B 6000 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6001 andb $0xf,rINSTbl # rINST<- A 6002 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 6003 movl (%eax,%edx,4),%eax # resolved entry 6004 testl %eax,%eax # is resolved entry null? 6005 jne .LOP_IGET_OBJECT_VOLATILE_finish # no, already resolved 6006 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 6007 movl rSELF,%edx 6008 jmp .LOP_IGET_OBJECT_VOLATILE_resolve 6009 6010 6011/* ------------------------------ */ 6012 .balign 64 6013.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */ 6014 /* (stub) */ 6015 SAVE_PC_FP_TO_SELF %ecx # leaves rSELF in %ecx 6016 movl %ecx,OUT_ARG0(%esp) # self is first arg to function 6017 call dvmMterp_OP_IGET_WIDE_VOLATILE # do the real work 6018 mov rSELF,%ecx 6019 LOAD_PC_FP_FROM_SELF # retrieve updated values 6020 FETCH_INST 6021 GOTO_NEXT 6022/* ------------------------------ */ 6023 .balign 64 6024.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */ 6025 /* (stub) */ 6026 SAVE_PC_FP_TO_SELF %ecx # leaves rSELF in %ecx 6027 movl %ecx,OUT_ARG0(%esp) # self is first arg to function 6028 call dvmMterp_OP_IPUT_WIDE_VOLATILE # do the real work 6029 mov rSELF,%ecx 6030 LOAD_PC_FP_FROM_SELF # retrieve updated values 6031 FETCH_INST 6032 GOTO_NEXT 6033/* ------------------------------ */ 6034 .balign 64 6035.L_OP_SGET_WIDE_VOLATILE: /* 0xea */ 6036 /* (stub) */ 6037 SAVE_PC_FP_TO_SELF %ecx # leaves rSELF in %ecx 6038 movl %ecx,OUT_ARG0(%esp) # self is first arg to function 6039 call dvmMterp_OP_SGET_WIDE_VOLATILE # do the real work 6040 mov rSELF,%ecx 6041 LOAD_PC_FP_FROM_SELF # retrieve updated values 6042 FETCH_INST 6043 GOTO_NEXT 6044/* ------------------------------ */ 6045 .balign 64 6046.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */ 6047 /* (stub) */ 6048 SAVE_PC_FP_TO_SELF %ecx # leaves rSELF in %ecx 6049 movl %ecx,OUT_ARG0(%esp) # self is first arg to function 6050 call dvmMterp_OP_SPUT_WIDE_VOLATILE # do the real work 6051 mov rSELF,%ecx 6052 LOAD_PC_FP_FROM_SELF # retrieve updated values 6053 FETCH_INST 6054 GOTO_NEXT 6055/* ------------------------------ */ 6056 .balign 64 6057.L_OP_BREAKPOINT: /* 0xec */ 6058/* File: x86/OP_BREAKPOINT.S */ 6059/* File: x86/unused.S */ 6060 jmp common_abort 6061 6062 6063/* ------------------------------ */ 6064 .balign 64 6065.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */ 6066/* File: x86/OP_THROW_VERIFICATION_ERROR.S */ 6067 /* 6068 * Handle a throw-verification-error instruction. This throws an 6069 * exception for an error discovered during verification. The 6070 * exception is indicated by AA, with some detail provided by BBBB. 6071 */ 6072 /* op AA, ref@BBBB */ 6073 movl rSELF,%ecx 6074 movzwl 2(rPC),%eax # eax<- BBBB 6075 movl offThread_method(%ecx),%ecx # ecx<- self->method 6076 EXPORT_PC 6077 movl %eax,OUT_ARG2(%esp) # arg2<- BBBB 6078 movl rINST,OUT_ARG1(%esp) # arg1<- AA 6079 movl %ecx,OUT_ARG0(%esp) # arg0<- method 6080 call dvmThrowVerificationError # call(method, kind, ref) 6081 jmp common_exceptionThrown # handle exception 6082 6083/* ------------------------------ */ 6084 .balign 64 6085.L_OP_EXECUTE_INLINE: /* 0xee */ 6086/* File: x86/OP_EXECUTE_INLINE.S */ 6087 /* 6088 * Execute a "native inline" instruction. 6089 * 6090 * We will be calling through a function table: 6091 * 6092 * (*gDvmInlineOpsTable[opIndex].func)(arg0, arg1, arg2, arg3, pResult) 6093 * 6094 * Ignores argument count - always loads 4. 6095 * 6096 */ 6097 /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */ 6098 movl rSELF,%ecx 6099 EXPORT_PC 6100 movzwl 2(rPC),%eax # eax<- BBBB 6101 leal offThread_retval(%ecx),%ecx # ecx<- & self->retval 6102 movl %ecx,OUT_ARG4(%esp) 6103 call .LOP_EXECUTE_INLINE_continue # make call; will return after 6104 testl %eax,%eax # successful? 6105 FETCH_INST_OPCODE 3 %edx 6106 je common_exceptionThrown # no, handle exception 6107 ADVANCE_PC 3 6108 GOTO_NEXT_R %edx 6109 6110/* ------------------------------ */ 6111 .balign 64 6112.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */ 6113 /* (stub) */ 6114 SAVE_PC_FP_TO_SELF %ecx # leaves rSELF in %ecx 6115 movl %ecx,OUT_ARG0(%esp) # self is first arg to function 6116 call dvmMterp_OP_EXECUTE_INLINE_RANGE # do the real work 6117 mov rSELF,%ecx 6118 LOAD_PC_FP_FROM_SELF # retrieve updated values 6119 FETCH_INST 6120 GOTO_NEXT 6121/* ------------------------------ */ 6122 .balign 64 6123.L_OP_INVOKE_OBJECT_INIT: /* 0xf0 */ 6124 /* (stub) */ 6125 SAVE_PC_FP_TO_SELF %ecx # leaves rSELF in %ecx 6126 movl %ecx,OUT_ARG0(%esp) # self is first arg to function 6127 call dvmMterp_OP_INVOKE_OBJECT_INIT # do the real work 6128 mov rSELF,%ecx 6129 LOAD_PC_FP_FROM_SELF # retrieve updated values 6130 FETCH_INST 6131 GOTO_NEXT 6132/* ------------------------------ */ 6133 .balign 64 6134.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */ 6135 /* (stub) */ 6136 SAVE_PC_FP_TO_SELF %ecx # leaves rSELF in %ecx 6137 movl %ecx,OUT_ARG0(%esp) # self is first arg to function 6138 call dvmMterp_OP_RETURN_VOID_BARRIER # do the real work 6139 mov rSELF,%ecx 6140 LOAD_PC_FP_FROM_SELF # retrieve updated values 6141 FETCH_INST 6142 GOTO_NEXT 6143/* ------------------------------ */ 6144 .balign 64 6145.L_OP_IGET_QUICK: /* 0xf2 */ 6146/* File: x86/OP_IGET_QUICK.S */ 6147 /* For: iget-quick, iget-object-quick */ 6148 /* op vA, vB, offset@CCCC */ 6149 movzbl rINSTbl,%ecx # ecx<- BA 6150 sarl $4,%ecx # ecx<- B 6151 GET_VREG_R %ecx %ecx # vB (object we're operating on) 6152 movzwl 2(rPC),%eax # eax<- field byte offset 6153 cmpl $0,%ecx # is object null? 6154 je common_errNullObject 6155 movl (%ecx,%eax,1),%eax 6156 FETCH_INST_OPCODE 2 %edx 6157 ADVANCE_PC 2 6158 andb $0xf,rINSTbl # rINST<- A 6159 SET_VREG %eax rINST # fp[A]<- result 6160 GOTO_NEXT_R %edx 6161 6162/* ------------------------------ */ 6163 .balign 64 6164.L_OP_IGET_WIDE_QUICK: /* 0xf3 */ 6165/* File: x86/OP_IGET_WIDE_QUICK.S */ 6166 /* For: iget-wide-quick */ 6167 /* op vA, vB, offset@CCCC */ 6168 movzbl rINSTbl,%ecx # ecx<- BA 6169 sarl $4,%ecx # ecx<- B 6170 GET_VREG_R %ecx %ecx # vB (object we're operating on) 6171 movzwl 2(rPC),%eax # eax<- field byte offset 6172 cmpl $0,%ecx # is object null? 6173 je common_errNullObject 6174 leal (%ecx,%eax,1),%eax # eax<- address of 64-bit source 6175 movl (%eax),%ecx # ecx<- lsw 6176 movl 4(%eax),%eax # eax<- msw 6177 andb $0xf,rINSTbl # rINST<- A 6178 FETCH_INST_OPCODE 2 %edx 6179 SET_VREG_WORD %ecx rINST 0 # v[A+0]<- lsw 6180 SET_VREG_WORD %eax rINST 1 # v[A+1]<- msw 6181 ADVANCE_PC 2 6182 GOTO_NEXT_R %edx 6183 6184/* ------------------------------ */ 6185 .balign 64 6186.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */ 6187/* File: x86/OP_IGET_OBJECT_QUICK.S */ 6188/* File: x86/OP_IGET_QUICK.S */ 6189 /* For: iget-quick, iget-object-quick */ 6190 /* op vA, vB, offset@CCCC */ 6191 movzbl rINSTbl,%ecx # ecx<- BA 6192 sarl $4,%ecx # ecx<- B 6193 GET_VREG_R %ecx %ecx # vB (object we're operating on) 6194 movzwl 2(rPC),%eax # eax<- field byte offset 6195 cmpl $0,%ecx # is object null? 6196 je common_errNullObject 6197 movl (%ecx,%eax,1),%eax 6198 FETCH_INST_OPCODE 2 %edx 6199 ADVANCE_PC 2 6200 andb $0xf,rINSTbl # rINST<- A 6201 SET_VREG %eax rINST # fp[A]<- result 6202 GOTO_NEXT_R %edx 6203 6204 6205/* ------------------------------ */ 6206 .balign 64 6207.L_OP_IPUT_QUICK: /* 0xf5 */ 6208/* File: x86/OP_IPUT_QUICK.S */ 6209 /* For: iput-quick */ 6210 /* op vA, vB, offset@CCCC */ 6211 movzbl rINSTbl,%ecx # ecx<- BA 6212 sarl $4,%ecx # ecx<- B 6213 GET_VREG_R %ecx %ecx # vB (object we're operating on) 6214 andb $0xf,rINSTbl # rINST<- A 6215 GET_VREG_R rINST,rINST # rINST<- v[A] 6216 movzwl 2(rPC),%eax # eax<- field byte offset 6217 testl %ecx,%ecx # is object null? 6218 FETCH_INST_OPCODE 2 %edx 6219 je common_errNullObject 6220 movl rINST,(%ecx,%eax,1) 6221 ADVANCE_PC 2 6222 GOTO_NEXT_R %edx 6223 6224/* ------------------------------ */ 6225 .balign 64 6226.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */ 6227/* File: x86/OP_IPUT_WIDE_QUICK.S */ 6228 /* For: iput-wide-quick */ 6229 /* op vA, vB, offset@CCCC */ 6230 movzbl rINSTbl,%ecx # ecx<- BA 6231 sarl $4,%ecx # ecx<- B 6232 GET_VREG_R %ecx %ecx # vB (object we're operating on) 6233 movzwl 2(rPC),%eax # eax<- field byte offset 6234 testl %ecx,%ecx # is object null? 6235 je common_errNullObject 6236 leal (%ecx,%eax,1),%ecx # ecx<- Address of 64-bit target 6237 andb $0xf,rINSTbl # rINST<- A 6238 GET_VREG_WORD %eax rINST 0 # eax<- lsw 6239 GET_VREG_WORD rINST rINST 1 # rINST<- msw 6240 FETCH_INST_OPCODE 2 %edx 6241 movl %eax,(%ecx) 6242 movl rINST,4(%ecx) 6243 ADVANCE_PC 2 6244 GOTO_NEXT_R %edx 6245 6246/* ------------------------------ */ 6247 .balign 64 6248.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */ 6249/* File: x86/OP_IPUT_OBJECT_QUICK.S */ 6250 /* For: iput-object-quick */ 6251 /* op vA, vB, offset@CCCC */ 6252 movzbl rINSTbl,%ecx # ecx<- BA 6253 sarl $4,%ecx # ecx<- B 6254 GET_VREG_R %ecx %ecx # vB (object we're operating on) 6255 andb $0xf,rINSTbl # rINST<- A 6256 GET_VREG_R rINST rINST # rINST<- v[A] 6257 movzwl 2(rPC),%eax # eax<- field byte offset 6258 testl %ecx,%ecx # is object null? 6259 je common_errNullObject 6260 movl rINST,(%ecx,%eax,1) 6261 movl rSELF,%eax 6262 jmp .LOP_IPUT_OBJECT_QUICK_finish 6263 6264/* ------------------------------ */ 6265 .balign 64 6266.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */ 6267/* File: x86/OP_INVOKE_VIRTUAL_QUICK.S */ 6268 /* 6269 * Handle an optimized virtual method call. 6270 * 6271 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 6272 */ 6273 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 6274 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 6275 movzwl 4(rPC),%eax # eax<- FEDC or CCCC 6276 movzwl 2(rPC),%ecx # ecx<- BBBB 6277 .if (!0) 6278 andl $0xf,%eax # eax<- C (or stays CCCC) 6279 .endif 6280 GET_VREG_R %eax %eax # eax<- vC ("this" ptr) 6281 testl %eax,%eax # null? 6282 je common_errNullObject # yep, throw exception 6283 movl offObject_clazz(%eax),%eax # eax<- thisPtr->clazz 6284 movl offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable 6285 EXPORT_PC # might throw later - get ready 6286 movl (%eax,%ecx,4),%eax # eax<- vtable[BBBB] 6287 jmp common_invokeMethodNoRange 6288 6289/* ------------------------------ */ 6290 .balign 64 6291.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */ 6292/* File: x86/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */ 6293/* File: x86/OP_INVOKE_VIRTUAL_QUICK.S */ 6294 /* 6295 * Handle an optimized virtual method call. 6296 * 6297 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 6298 */ 6299 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 6300 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 6301 movzwl 4(rPC),%eax # eax<- FEDC or CCCC 6302 movzwl 2(rPC),%ecx # ecx<- BBBB 6303 .if (!1) 6304 andl $0xf,%eax # eax<- C (or stays CCCC) 6305 .endif 6306 GET_VREG_R %eax %eax # eax<- vC ("this" ptr) 6307 testl %eax,%eax # null? 6308 je common_errNullObject # yep, throw exception 6309 movl offObject_clazz(%eax),%eax # eax<- thisPtr->clazz 6310 movl offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable 6311 EXPORT_PC # might throw later - get ready 6312 movl (%eax,%ecx,4),%eax # eax<- vtable[BBBB] 6313 jmp common_invokeMethodRange 6314 6315 6316/* ------------------------------ */ 6317 .balign 64 6318.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */ 6319/* File: x86/OP_INVOKE_SUPER_QUICK.S */ 6320 /* 6321 * Handle an optimized "super" method call. 6322 * 6323 * for: [opt] invoke-super-quick, invoke-super-quick/range 6324 */ 6325 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 6326 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 6327 movl rSELF,%ecx 6328 movzwl 4(rPC),%eax # eax<- GFED or CCCC 6329 movl offThread_method(%ecx),%ecx # ecx<- current method 6330 .if (!0) 6331 andl $0xf,%eax # eax<- D (or stays CCCC) 6332 .endif 6333 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 6334 GET_VREG_R %eax %eax # eax<- "this" 6335 movl offClassObject_super(%ecx),%ecx # ecx<- method->clazz->super 6336 testl %eax,%eax # null "this"? 6337 je common_errNullObject # "this" is null, throw exception 6338 movzwl 2(rPC),%eax # eax<- BBBB 6339 movl offClassObject_vtable(%ecx),%ecx # ecx<- vtable 6340 EXPORT_PC 6341 movl (%ecx,%eax,4),%eax # eax<- super->vtable[BBBB] 6342 jmp common_invokeMethodNoRange 6343 6344/* ------------------------------ */ 6345 .balign 64 6346.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */ 6347/* File: x86/OP_INVOKE_SUPER_QUICK_RANGE.S */ 6348/* File: x86/OP_INVOKE_SUPER_QUICK.S */ 6349 /* 6350 * Handle an optimized "super" method call. 6351 * 6352 * for: [opt] invoke-super-quick, invoke-super-quick/range 6353 */ 6354 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 6355 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 6356 movl rSELF,%ecx 6357 movzwl 4(rPC),%eax # eax<- GFED or CCCC 6358 movl offThread_method(%ecx),%ecx # ecx<- current method 6359 .if (!1) 6360 andl $0xf,%eax # eax<- D (or stays CCCC) 6361 .endif 6362 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 6363 GET_VREG_R %eax %eax # eax<- "this" 6364 movl offClassObject_super(%ecx),%ecx # ecx<- method->clazz->super 6365 testl %eax,%eax # null "this"? 6366 je common_errNullObject # "this" is null, throw exception 6367 movzwl 2(rPC),%eax # eax<- BBBB 6368 movl offClassObject_vtable(%ecx),%ecx # ecx<- vtable 6369 EXPORT_PC 6370 movl (%ecx,%eax,4),%eax # eax<- super->vtable[BBBB] 6371 jmp common_invokeMethodRange 6372 6373 6374/* ------------------------------ */ 6375 .balign 64 6376.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */ 6377/* File: x86/OP_IPUT_OBJECT_VOLATILE.S */ 6378/* File: x86/OP_IPUT_OBJECT.S */ 6379 /* 6380 * Object field put. 6381 * 6382 * for: iput-object 6383 */ 6384 /* op vA, vB, field@CCCC */ 6385 movl rSELF,%ecx 6386 movzwl 2(rPC),%edx # edx<- 0000CCCC 6387 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 6388 movzbl rINSTbl,%ecx # ecx<- BA 6389 sarl $4,%ecx # ecx<- B 6390 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6391 andb $0xf,rINSTbl # rINST<- A 6392 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 6393 movl (%eax,%edx,4),%eax # resolved entry 6394 testl %eax,%eax # is resolved entry null? 6395 jne .LOP_IPUT_OBJECT_VOLATILE_finish # no, already resolved 6396 movl %edx,OUT_ARG1(%esp) 6397 movl rSELF,%edx 6398 jmp .LOP_IPUT_OBJECT_VOLATILE_resolve 6399 6400 6401/* ------------------------------ */ 6402 .balign 64 6403.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */ 6404/* File: x86/OP_SGET_OBJECT_VOLATILE.S */ 6405/* File: x86/OP_SGET.S */ 6406 /* 6407 * General 32-bit SGET handler. 6408 * 6409 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 6410 */ 6411 /* op vAA, field@BBBB */ 6412 movl rSELF,%ecx 6413 movzwl 2(rPC),%eax # eax<- field ref BBBB 6414 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 6415 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 6416 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 6417 testl %eax,%eax # resolved entry null? 6418 je .LOP_SGET_OBJECT_VOLATILE_resolve # if not, make it so 6419.LOP_SGET_OBJECT_VOLATILE_finish: # field ptr in eax 6420 movl offStaticField_value(%eax),%eax 6421 FETCH_INST_OPCODE 2 %edx 6422 ADVANCE_PC 2 6423 SET_VREG %eax rINST 6424 GOTO_NEXT_R %edx 6425 6426 6427/* ------------------------------ */ 6428 .balign 64 6429.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */ 6430/* File: x86/OP_SPUT_OBJECT_VOLATILE.S */ 6431/* File: x86/OP_SPUT_OBJECT.S */ 6432 /* 6433 * SPUT object handler. 6434 */ 6435 /* op vAA, field@BBBB */ 6436 movl rSELF,%ecx 6437 movzwl 2(rPC),%eax # eax<- field ref BBBB 6438 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 6439 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 6440 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField 6441 testl %eax,%eax # resolved entry null? 6442 je .LOP_SPUT_OBJECT_VOLATILE_resolve # if not, make it so 6443.LOP_SPUT_OBJECT_VOLATILE_finish: # field ptr in eax 6444 movzbl rINSTbl,%ecx # ecx<- AA 6445 GET_VREG_R %ecx %ecx 6446 jmp .LOP_SPUT_OBJECT_VOLATILE_continue 6447 6448 6449/* ------------------------------ */ 6450 .balign 64 6451.L_OP_DISPATCH_FF: /* 0xff */ 6452/* File: x86/OP_DISPATCH_FF.S */ 6453 leal 256(rINST),%edx 6454 GOTO_NEXT_JUMBO_R %edx 6455 6456/* ------------------------------ */ 6457 .balign 64 6458.L_OP_CONST_CLASS_JUMBO: /* 0x100 */ 6459/* File: x86/OP_CONST_CLASS_JUMBO.S */ 6460 /* const-class/jumbo vBBBB, Class@AAAAAAAA */ 6461 movl rSELF,%ecx 6462 movl 2(rPC),%eax # eax<- AAAAAAAA 6463 movl offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex 6464 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- dvmDex->pResClasses 6465 movl (%ecx,%eax,4),%eax # eax<- rResClasses[AAAAAAAA] 6466 FETCH_INST_OPCODE 4 %edx 6467 testl %eax,%eax # resolved yet? 6468 je .LOP_CONST_CLASS_JUMBO_resolve 6469 SET_VREG %eax rINST # vBBBB<- rResClasses[AAAAAAAA] 6470 ADVANCE_PC 4 6471 GOTO_NEXT_R %edx 6472 6473/* ------------------------------ */ 6474 .balign 64 6475.L_OP_CHECK_CAST_JUMBO: /* 0x101 */ 6476/* File: x86/OP_CHECK_CAST_JUMBO.S */ 6477 /* 6478 * Check to see if a cast from one class to another is allowed. 6479 */ 6480 /* check-cast/jumbo vBBBB, class@AAAAAAAA */ 6481 movl rSELF,%ecx 6482 GET_VREG_R rINST,rINST # rINST<- vBBBB (object) 6483 movl 2(rPC),%eax # eax<- AAAAAAAA 6484 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 6485 testl rINST,rINST # is oject null? 6486 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 6487 je .LOP_CHECK_CAST_JUMBO_okay # null obj, cast always succeeds 6488 movl (%ecx,%eax,4),%eax # eax<- resolved class 6489 movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz 6490 testl %eax,%eax # have we resolved this before? 6491 je .LOP_CHECK_CAST_JUMBO_resolve # no, go do it now 6492.LOP_CHECK_CAST_JUMBO_resolved: 6493 cmpl %eax,%ecx # same class (trivial success)? 6494 jne .LOP_CHECK_CAST_JUMBO_fullcheck # no, do full check 6495.LOP_CHECK_CAST_JUMBO_okay: 6496 FETCH_INST_OPCODE 4 %edx 6497 ADVANCE_PC 4 6498 GOTO_NEXT_R %edx 6499 6500/* ------------------------------ */ 6501 .balign 64 6502.L_OP_INSTANCE_OF_JUMBO: /* 0x102 */ 6503/* File: x86/OP_INSTANCE_OF_JUMBO.S */ 6504 /* 6505 * Check to see if an object reference is an instance of a class. 6506 * 6507 * Most common situation is a non-null object, being compared against 6508 * an already-resolved class. 6509 */ 6510 /* instance-of/jumbo vBBBB, vCCCC, class@AAAAAAAA */ 6511 movzwl 8(rPC),%eax # eax<- CCCC 6512 GET_VREG_R %eax %eax # eax<- vCCCC (obj) 6513 movl rSELF,%ecx 6514 testl %eax,%eax # object null? 6515 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 6516 je .LOP_INSTANCE_OF_JUMBO_store # null obj, not instance, store it 6517 movl 2(rPC),%edx # edx<- AAAAAAAA 6518 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 6519 movl (%ecx,%edx,4),%ecx # ecx<- resolved class 6520 movl offObject_clazz(%eax),%eax # eax<- obj->clazz 6521 testl %ecx,%ecx # have we resolved this before? 6522 je .LOP_INSTANCE_OF_JUMBO_resolve # not resolved, do it now 6523.LOP_INSTANCE_OF_JUMBO_resolved: # eax<- obj->clazz, ecx<- resolved class 6524 cmpl %eax,%ecx # same class (trivial success)? 6525 je .LOP_INSTANCE_OF_JUMBO_trivial # yes, trivial finish 6526 jmp .LOP_INSTANCE_OF_JUMBO_fullcheck # no, do full check 6527 6528/* ------------------------------ */ 6529 .balign 64 6530.L_OP_NEW_INSTANCE_JUMBO: /* 0x103 */ 6531/* File: x86/OP_NEW_INSTANCE_JUMBO.S */ 6532 /* 6533 * Create a new instance of a class. 6534 */ 6535 /* new-instance/jumbo vBBBB, class@AAAAAAAA */ 6536 movl rSELF,%ecx 6537 movl 2(rPC),%eax # eax<- AAAAAAAA 6538 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 6539 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 6540 EXPORT_PC 6541 movl (%ecx,%eax,4),%ecx # ecx<- resolved class 6542 testl %ecx,%ecx # resolved? 6543 je .LOP_NEW_INSTANCE_JUMBO_resolve # no, go do it 6544.LOP_NEW_INSTANCE_JUMBO_resolved: # on entry, ecx<- class 6545 cmpb $CLASS_INITIALIZED,offClassObject_status(%ecx) 6546 je .LOP_NEW_INSTANCE_JUMBO_initialized 6547 jmp .LOP_NEW_INSTANCE_JUMBO_needinit 6548 6549/* ------------------------------ */ 6550 .balign 64 6551.L_OP_NEW_ARRAY_JUMBO: /* 0x104 */ 6552/* File: x86/OP_NEW_ARRAY_JUMBO.S */ 6553 /* 6554 * Allocate an array of objects, specified with the array class 6555 * and a count. 6556 * 6557 * The verifier guarantees that this is an array class, so we don't 6558 * check for it here. 6559 */ 6560 /* new-array/jumbo vBBBB, vCCCC, class@AAAAAAAA */ 6561 movl rSELF,%ecx 6562 EXPORT_PC 6563 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 6564 movl 2(rPC),%eax # eax<- AAAAAAAA 6565 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 6566 movl (%ecx,%eax,4),%ecx # ecx<- resolved class 6567 movzwl 8(rPC),%eax # eax<- CCCC 6568 GET_VREG_R %eax %eax # eax<- vCCCC (array length) 6569 testl %eax,%eax 6570 js common_errNegativeArraySize # bail 6571 testl %ecx,%ecx # already resolved? 6572 jne .LOP_NEW_ARRAY_JUMBO_finish # yes, fast path 6573 jmp .LOP_NEW_ARRAY_JUMBO_resolve # resolve now 6574 6575/* ------------------------------ */ 6576 .balign 64 6577.L_OP_FILLED_NEW_ARRAY_JUMBO: /* 0x105 */ 6578/* File: x86/OP_FILLED_NEW_ARRAY_JUMBO.S */ 6579 /* 6580 * Create a new array with elements filled from registers. 6581 */ 6582 /* filled-new-array/jumbo {vCCCC..v(CCCC+BBBB-1)}, type@AAAAAAAA */ 6583 movl rSELF,%eax 6584 movl offThread_methodClassDex(%eax),%eax # eax<- pDvmDex 6585 movl 2(rPC),%ecx # ecx<- AAAAAAAA 6586 movl offDvmDex_pResClasses(%eax),%eax # eax<- pDvmDex->pResClasses 6587 movl (%eax,%ecx,4),%eax # eax<- resolved class 6588 EXPORT_PC 6589 testl %eax,%eax # already resolved? 6590 jne .LOP_FILLED_NEW_ARRAY_JUMBO_continue # yes, continue 6591 # less frequent path, so we'll redo some work 6592 movl rSELF,%eax 6593 movl $0,OUT_ARG2(%esp) # arg2<- false 6594 movl %ecx,OUT_ARG1(%esp) # arg1<- AAAAAAAA 6595 movl offThread_method(%eax),%eax # eax<- self->method 6596 jmp .LOP_FILLED_NEW_ARRAY_JUMBO_more 6597 6598/* ------------------------------ */ 6599 .balign 64 6600.L_OP_IGET_JUMBO: /* 0x106 */ 6601/* File: x86/OP_IGET_JUMBO.S */ 6602 /* 6603 * Jumbo 32-bit instance field get. 6604 * 6605 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 6606 * iget-char/jumbo, iget-short/jumbo 6607 */ 6608 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6609 movl rSELF,%ecx 6610 movl 2(rPC),%edx # edx<- AAAAAAAA 6611 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 6612 movzwl 8(rPC),%ecx # ecx<- CCCC 6613 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6614 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6615 movl (%eax,%edx,4),%eax # resolved entry 6616 testl %eax,%eax # is resolved entry null? 6617 jne .LOP_IGET_JUMBO_finish # no, already resolved 6618 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 6619 movl rSELF,%edx 6620 jmp .LOP_IGET_JUMBO_resolve 6621 6622/* ------------------------------ */ 6623 .balign 64 6624.L_OP_IGET_WIDE_JUMBO: /* 0x107 */ 6625/* File: x86/OP_IGET_WIDE_JUMBO.S */ 6626 /* 6627 * Jumbo 64-bit instance field get. 6628 */ 6629 /* iget-wide/jumbo vBBBB, vCCCC, field@AAAA */ 6630 movl rSELF,%ecx 6631 movl 2(rPC),%edx # edx<- AAAAAAAA 6632 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 6633 movzwl 8(rPC),%ecx # ecx<- CCCC 6634 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6635 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6636 movl (%eax,%edx,4),%eax # resolved entry 6637 testl %eax,%eax # is resolved entry null? 6638 jne .LOP_IGET_WIDE_JUMBO_finish # no, already resolved 6639 movl %edx,OUT_ARG1(%esp) # for dvmResolveInstField 6640 movl rSELF,%edx 6641 jmp .LOP_IGET_WIDE_JUMBO_resolve 6642 6643/* ------------------------------ */ 6644 .balign 64 6645.L_OP_IGET_OBJECT_JUMBO: /* 0x108 */ 6646/* File: x86/OP_IGET_OBJECT_JUMBO.S */ 6647/* File: x86/OP_IGET_JUMBO.S */ 6648 /* 6649 * Jumbo 32-bit instance field get. 6650 * 6651 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 6652 * iget-char/jumbo, iget-short/jumbo 6653 */ 6654 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6655 movl rSELF,%ecx 6656 movl 2(rPC),%edx # edx<- AAAAAAAA 6657 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 6658 movzwl 8(rPC),%ecx # ecx<- CCCC 6659 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6660 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6661 movl (%eax,%edx,4),%eax # resolved entry 6662 testl %eax,%eax # is resolved entry null? 6663 jne .LOP_IGET_OBJECT_JUMBO_finish # no, already resolved 6664 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 6665 movl rSELF,%edx 6666 jmp .LOP_IGET_OBJECT_JUMBO_resolve 6667 6668 6669/* ------------------------------ */ 6670 .balign 64 6671.L_OP_IGET_BOOLEAN_JUMBO: /* 0x109 */ 6672/* File: x86/OP_IGET_BOOLEAN_JUMBO.S */ 6673/* File: x86/OP_IGET_JUMBO.S */ 6674 /* 6675 * Jumbo 32-bit instance field get. 6676 * 6677 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 6678 * iget-char/jumbo, iget-short/jumbo 6679 */ 6680 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6681 movl rSELF,%ecx 6682 movl 2(rPC),%edx # edx<- AAAAAAAA 6683 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 6684 movzwl 8(rPC),%ecx # ecx<- CCCC 6685 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6686 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6687 movl (%eax,%edx,4),%eax # resolved entry 6688 testl %eax,%eax # is resolved entry null? 6689 jne .LOP_IGET_BOOLEAN_JUMBO_finish # no, already resolved 6690 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 6691 movl rSELF,%edx 6692 jmp .LOP_IGET_BOOLEAN_JUMBO_resolve 6693 6694 6695/* ------------------------------ */ 6696 .balign 64 6697.L_OP_IGET_BYTE_JUMBO: /* 0x10a */ 6698/* File: x86/OP_IGET_BYTE_JUMBO.S */ 6699/* File: x86/OP_IGET_JUMBO.S */ 6700 /* 6701 * Jumbo 32-bit instance field get. 6702 * 6703 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 6704 * iget-char/jumbo, iget-short/jumbo 6705 */ 6706 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6707 movl rSELF,%ecx 6708 movl 2(rPC),%edx # edx<- AAAAAAAA 6709 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 6710 movzwl 8(rPC),%ecx # ecx<- CCCC 6711 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6712 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6713 movl (%eax,%edx,4),%eax # resolved entry 6714 testl %eax,%eax # is resolved entry null? 6715 jne .LOP_IGET_BYTE_JUMBO_finish # no, already resolved 6716 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 6717 movl rSELF,%edx 6718 jmp .LOP_IGET_BYTE_JUMBO_resolve 6719 6720 6721/* ------------------------------ */ 6722 .balign 64 6723.L_OP_IGET_CHAR_JUMBO: /* 0x10b */ 6724/* File: x86/OP_IGET_CHAR_JUMBO.S */ 6725/* File: x86/OP_IGET_JUMBO.S */ 6726 /* 6727 * Jumbo 32-bit instance field get. 6728 * 6729 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 6730 * iget-char/jumbo, iget-short/jumbo 6731 */ 6732 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6733 movl rSELF,%ecx 6734 movl 2(rPC),%edx # edx<- AAAAAAAA 6735 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 6736 movzwl 8(rPC),%ecx # ecx<- CCCC 6737 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6738 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6739 movl (%eax,%edx,4),%eax # resolved entry 6740 testl %eax,%eax # is resolved entry null? 6741 jne .LOP_IGET_CHAR_JUMBO_finish # no, already resolved 6742 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 6743 movl rSELF,%edx 6744 jmp .LOP_IGET_CHAR_JUMBO_resolve 6745 6746 6747/* ------------------------------ */ 6748 .balign 64 6749.L_OP_IGET_SHORT_JUMBO: /* 0x10c */ 6750/* File: x86/OP_IGET_SHORT_JUMBO.S */ 6751/* File: x86/OP_IGET_JUMBO.S */ 6752 /* 6753 * Jumbo 32-bit instance field get. 6754 * 6755 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 6756 * iget-char/jumbo, iget-short/jumbo 6757 */ 6758 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6759 movl rSELF,%ecx 6760 movl 2(rPC),%edx # edx<- AAAAAAAA 6761 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 6762 movzwl 8(rPC),%ecx # ecx<- CCCC 6763 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6764 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6765 movl (%eax,%edx,4),%eax # resolved entry 6766 testl %eax,%eax # is resolved entry null? 6767 jne .LOP_IGET_SHORT_JUMBO_finish # no, already resolved 6768 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 6769 movl rSELF,%edx 6770 jmp .LOP_IGET_SHORT_JUMBO_resolve 6771 6772 6773/* ------------------------------ */ 6774 .balign 64 6775.L_OP_IPUT_JUMBO: /* 0x10d */ 6776/* File: x86/OP_IPUT_JUMBO.S */ 6777 /* 6778 * Jumbo 32-bit instance field put. 6779 * 6780 * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo, 6781 iput-char/jumbo, iput-short/jumbo 6782 */ 6783 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6784 movl rSELF,%ecx 6785 movl 2(rPC),%edx # edx<- AAAAAAAA 6786 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 6787 movzwl 8(rPC),%ecx # ecx<- CCCC 6788 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6789 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6790 movl (%eax,%edx,4),%eax # resolved entry 6791 testl %eax,%eax # is resolved entry null? 6792 jne .LOP_IPUT_JUMBO_finish # no, already resolved 6793 movl %edx,OUT_ARG1(%esp) 6794 movl rSELF,%edx 6795 jmp .LOP_IPUT_JUMBO_resolve 6796 6797/* ------------------------------ */ 6798 .balign 64 6799.L_OP_IPUT_WIDE_JUMBO: /* 0x10e */ 6800/* File: x86/OP_IPUT_WIDE_JUMBO.S */ 6801 /* 6802 * Jumbo 64-bit instance field put. 6803 */ 6804 /* iput-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */ 6805 movl rSELF,%ecx 6806 movl 2(rPC),%edx # edx<- AAAAAAAA 6807 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 6808 movzwl 8(rPC),%ecx # ecx<- CCCC 6809 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6810 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6811 movl (%eax,%edx,4),%eax # resolved entry 6812 testl %eax,%eax # is resolved entry null? 6813 jne .LOP_IPUT_WIDE_JUMBO_finish # no, already resolved 6814 movl %edx,OUT_ARG1(%esp) 6815 movl rSELF,%edx 6816 jmp .LOP_IPUT_WIDE_JUMBO_resolve 6817 6818/* ------------------------------ */ 6819 .balign 64 6820.L_OP_IPUT_OBJECT_JUMBO: /* 0x10f */ 6821/* File: x86/OP_IPUT_OBJECT_JUMBO.S */ 6822 /* 6823 * Jumbo object field put. 6824 */ 6825 /* iput-object/jumbo vBBBB, vCCCC, field@AAAAAAAA */ 6826 movl rSELF,%ecx 6827 movl 2(rPC),%edx # edx<- AAAAAAAA 6828 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 6829 movzwl 8(rPC),%ecx # ecx<- CCCC 6830 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6831 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6832 movl (%eax,%edx,4),%eax # resolved entry 6833 testl %eax,%eax # is resolved entry null? 6834 jne .LOP_IPUT_OBJECT_JUMBO_finish # no, already resolved 6835 movl %edx,OUT_ARG1(%esp) 6836 movl rSELF,%edx 6837 jmp .LOP_IPUT_OBJECT_JUMBO_resolve 6838 6839/* ------------------------------ */ 6840 .balign 64 6841.L_OP_IPUT_BOOLEAN_JUMBO: /* 0x110 */ 6842/* File: x86/OP_IPUT_BOOLEAN_JUMBO.S */ 6843/* File: x86/OP_IPUT_JUMBO.S */ 6844 /* 6845 * Jumbo 32-bit instance field put. 6846 * 6847 * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo, 6848 iput-char/jumbo, iput-short/jumbo 6849 */ 6850 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6851 movl rSELF,%ecx 6852 movl 2(rPC),%edx # edx<- AAAAAAAA 6853 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 6854 movzwl 8(rPC),%ecx # ecx<- CCCC 6855 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6856 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6857 movl (%eax,%edx,4),%eax # resolved entry 6858 testl %eax,%eax # is resolved entry null? 6859 jne .LOP_IPUT_BOOLEAN_JUMBO_finish # no, already resolved 6860 movl %edx,OUT_ARG1(%esp) 6861 movl rSELF,%edx 6862 jmp .LOP_IPUT_BOOLEAN_JUMBO_resolve 6863 6864 6865/* ------------------------------ */ 6866 .balign 64 6867.L_OP_IPUT_BYTE_JUMBO: /* 0x111 */ 6868/* File: x86/OP_IPUT_BYTE_JUMBO.S */ 6869/* File: x86/OP_IPUT_JUMBO.S */ 6870 /* 6871 * Jumbo 32-bit instance field put. 6872 * 6873 * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo, 6874 iput-char/jumbo, iput-short/jumbo 6875 */ 6876 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6877 movl rSELF,%ecx 6878 movl 2(rPC),%edx # edx<- AAAAAAAA 6879 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 6880 movzwl 8(rPC),%ecx # ecx<- CCCC 6881 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6882 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6883 movl (%eax,%edx,4),%eax # resolved entry 6884 testl %eax,%eax # is resolved entry null? 6885 jne .LOP_IPUT_BYTE_JUMBO_finish # no, already resolved 6886 movl %edx,OUT_ARG1(%esp) 6887 movl rSELF,%edx 6888 jmp .LOP_IPUT_BYTE_JUMBO_resolve 6889 6890 6891/* ------------------------------ */ 6892 .balign 64 6893.L_OP_IPUT_CHAR_JUMBO: /* 0x112 */ 6894/* File: x86/OP_IPUT_CHAR_JUMBO.S */ 6895/* File: x86/OP_IPUT_JUMBO.S */ 6896 /* 6897 * Jumbo 32-bit instance field put. 6898 * 6899 * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo, 6900 iput-char/jumbo, iput-short/jumbo 6901 */ 6902 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6903 movl rSELF,%ecx 6904 movl 2(rPC),%edx # edx<- AAAAAAAA 6905 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 6906 movzwl 8(rPC),%ecx # ecx<- CCCC 6907 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6908 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6909 movl (%eax,%edx,4),%eax # resolved entry 6910 testl %eax,%eax # is resolved entry null? 6911 jne .LOP_IPUT_CHAR_JUMBO_finish # no, already resolved 6912 movl %edx,OUT_ARG1(%esp) 6913 movl rSELF,%edx 6914 jmp .LOP_IPUT_CHAR_JUMBO_resolve 6915 6916 6917/* ------------------------------ */ 6918 .balign 64 6919.L_OP_IPUT_SHORT_JUMBO: /* 0x113 */ 6920/* File: x86/OP_IPUT_SHORT_JUMBO.S */ 6921/* File: x86/OP_IPUT_JUMBO.S */ 6922 /* 6923 * Jumbo 32-bit instance field put. 6924 * 6925 * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo, 6926 iput-char/jumbo, iput-short/jumbo 6927 */ 6928 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6929 movl rSELF,%ecx 6930 movl 2(rPC),%edx # edx<- AAAAAAAA 6931 movl offThread_methodClassDex(%ecx),%eax # eax<- DvmDex 6932 movzwl 8(rPC),%ecx # ecx<- CCCC 6933 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6934 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6935 movl (%eax,%edx,4),%eax # resolved entry 6936 testl %eax,%eax # is resolved entry null? 6937 jne .LOP_IPUT_SHORT_JUMBO_finish # no, already resolved 6938 movl %edx,OUT_ARG1(%esp) 6939 movl rSELF,%edx 6940 jmp .LOP_IPUT_SHORT_JUMBO_resolve 6941 6942 6943/* ------------------------------ */ 6944 .balign 64 6945.L_OP_SGET_JUMBO: /* 0x114 */ 6946/* File: x86/OP_SGET_JUMBO.S */ 6947 /* 6948 * Jumbo 32-bit SGET handler. 6949 * 6950 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 6951 * sget-char/jumbo, sget-short/jumbo 6952 */ 6953 /* exop vBBBB, field@AAAAAAAA */ 6954 movl rSELF,%ecx 6955 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 6956 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 6957 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 6958 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 6959 testl %eax,%eax # resolved entry null? 6960 je .LOP_SGET_JUMBO_resolve # if not, make it so 6961.LOP_SGET_JUMBO_finish: # field ptr in eax 6962 movl offStaticField_value(%eax),%eax 6963 FETCH_INST_OPCODE 4 %edx 6964 ADVANCE_PC 4 6965 SET_VREG %eax rINST 6966 GOTO_NEXT_R %edx 6967 6968/* ------------------------------ */ 6969 .balign 64 6970.L_OP_SGET_WIDE_JUMBO: /* 0x115 */ 6971/* File: x86/OP_SGET_WIDE_JUMBO.S */ 6972 /* 6973 * Jumbo 64-bit SGET handler. 6974 * 6975 */ 6976 /* sget-wide/jumbo vBBBB, field@AAAAAAAA */ 6977 movl rSELF,%ecx 6978 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 6979 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 6980 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 6981 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 6982 testl %eax,%eax # resolved entry null? 6983 je .LOP_SGET_WIDE_JUMBO_resolve # if not, make it so 6984.LOP_SGET_WIDE_JUMBO_finish: # field ptr in eax 6985 movl offStaticField_value(%eax),%ecx # ecx<- lsw 6986 movl 4+offStaticField_value(%eax),%eax # eax<- msw 6987 FETCH_INST_OPCODE 2 %edx 6988 ADVANCE_PC 2 6989 SET_VREG_WORD %ecx rINST 0 6990 SET_VREG_WORD %eax rINST 1 6991 GOTO_NEXT_R %edx 6992 6993/* ------------------------------ */ 6994 .balign 64 6995.L_OP_SGET_OBJECT_JUMBO: /* 0x116 */ 6996/* File: x86/OP_SGET_OBJECT_JUMBO.S */ 6997/* File: x86/OP_SGET_JUMBO.S */ 6998 /* 6999 * Jumbo 32-bit SGET handler. 7000 * 7001 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 7002 * sget-char/jumbo, sget-short/jumbo 7003 */ 7004 /* exop vBBBB, field@AAAAAAAA */ 7005 movl rSELF,%ecx 7006 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7007 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7008 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7009 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7010 testl %eax,%eax # resolved entry null? 7011 je .LOP_SGET_OBJECT_JUMBO_resolve # if not, make it so 7012.LOP_SGET_OBJECT_JUMBO_finish: # field ptr in eax 7013 movl offStaticField_value(%eax),%eax 7014 FETCH_INST_OPCODE 4 %edx 7015 ADVANCE_PC 4 7016 SET_VREG %eax rINST 7017 GOTO_NEXT_R %edx 7018 7019 7020/* ------------------------------ */ 7021 .balign 64 7022.L_OP_SGET_BOOLEAN_JUMBO: /* 0x117 */ 7023/* File: x86/OP_SGET_BOOLEAN_JUMBO.S */ 7024/* File: x86/OP_SGET_JUMBO.S */ 7025 /* 7026 * Jumbo 32-bit SGET handler. 7027 * 7028 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 7029 * sget-char/jumbo, sget-short/jumbo 7030 */ 7031 /* exop vBBBB, field@AAAAAAAA */ 7032 movl rSELF,%ecx 7033 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7034 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7035 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7036 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7037 testl %eax,%eax # resolved entry null? 7038 je .LOP_SGET_BOOLEAN_JUMBO_resolve # if not, make it so 7039.LOP_SGET_BOOLEAN_JUMBO_finish: # field ptr in eax 7040 movl offStaticField_value(%eax),%eax 7041 FETCH_INST_OPCODE 4 %edx 7042 ADVANCE_PC 4 7043 SET_VREG %eax rINST 7044 GOTO_NEXT_R %edx 7045 7046 7047/* ------------------------------ */ 7048 .balign 64 7049.L_OP_SGET_BYTE_JUMBO: /* 0x118 */ 7050/* File: x86/OP_SGET_BYTE_JUMBO.S */ 7051/* File: x86/OP_SGET_JUMBO.S */ 7052 /* 7053 * Jumbo 32-bit SGET handler. 7054 * 7055 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 7056 * sget-char/jumbo, sget-short/jumbo 7057 */ 7058 /* exop vBBBB, field@AAAAAAAA */ 7059 movl rSELF,%ecx 7060 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7061 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7062 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7063 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7064 testl %eax,%eax # resolved entry null? 7065 je .LOP_SGET_BYTE_JUMBO_resolve # if not, make it so 7066.LOP_SGET_BYTE_JUMBO_finish: # field ptr in eax 7067 movl offStaticField_value(%eax),%eax 7068 FETCH_INST_OPCODE 4 %edx 7069 ADVANCE_PC 4 7070 SET_VREG %eax rINST 7071 GOTO_NEXT_R %edx 7072 7073 7074/* ------------------------------ */ 7075 .balign 64 7076.L_OP_SGET_CHAR_JUMBO: /* 0x119 */ 7077/* File: x86/OP_SGET_CHAR_JUMBO.S */ 7078/* File: x86/OP_SGET_JUMBO.S */ 7079 /* 7080 * Jumbo 32-bit SGET handler. 7081 * 7082 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 7083 * sget-char/jumbo, sget-short/jumbo 7084 */ 7085 /* exop vBBBB, field@AAAAAAAA */ 7086 movl rSELF,%ecx 7087 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7088 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7089 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7090 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7091 testl %eax,%eax # resolved entry null? 7092 je .LOP_SGET_CHAR_JUMBO_resolve # if not, make it so 7093.LOP_SGET_CHAR_JUMBO_finish: # field ptr in eax 7094 movl offStaticField_value(%eax),%eax 7095 FETCH_INST_OPCODE 4 %edx 7096 ADVANCE_PC 4 7097 SET_VREG %eax rINST 7098 GOTO_NEXT_R %edx 7099 7100 7101/* ------------------------------ */ 7102 .balign 64 7103.L_OP_SGET_SHORT_JUMBO: /* 0x11a */ 7104/* File: x86/OP_SGET_SHORT_JUMBO.S */ 7105/* File: x86/OP_SGET_JUMBO.S */ 7106 /* 7107 * Jumbo 32-bit SGET handler. 7108 * 7109 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 7110 * sget-char/jumbo, sget-short/jumbo 7111 */ 7112 /* exop vBBBB, field@AAAAAAAA */ 7113 movl rSELF,%ecx 7114 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7115 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7116 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7117 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7118 testl %eax,%eax # resolved entry null? 7119 je .LOP_SGET_SHORT_JUMBO_resolve # if not, make it so 7120.LOP_SGET_SHORT_JUMBO_finish: # field ptr in eax 7121 movl offStaticField_value(%eax),%eax 7122 FETCH_INST_OPCODE 4 %edx 7123 ADVANCE_PC 4 7124 SET_VREG %eax rINST 7125 GOTO_NEXT_R %edx 7126 7127 7128/* ------------------------------ */ 7129 .balign 64 7130.L_OP_SPUT_JUMBO: /* 0x11b */ 7131/* File: x86/OP_SPUT_JUMBO.S */ 7132 /* 7133 * Jumbo 32-bit SPUT handler. 7134 * 7135 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 7136 * sput-short/jumbo 7137 */ 7138 /* exop vBBBB, field@AAAAAAAA */ 7139 movl rSELF,%ecx 7140 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7141 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7142 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7143 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7144 testl %eax,%eax # resolved entry null? 7145 je .LOP_SPUT_JUMBO_resolve # if not, make it so 7146.LOP_SPUT_JUMBO_finish: # field ptr in eax 7147 GET_VREG_R %ecx rINST 7148 FETCH_INST_OPCODE 4 %edx 7149 ADVANCE_PC 4 7150 movl %ecx,offStaticField_value(%eax) 7151 GOTO_NEXT_R %edx 7152 7153/* ------------------------------ */ 7154 .balign 64 7155.L_OP_SPUT_WIDE_JUMBO: /* 0x11c */ 7156/* File: x86/OP_SPUT_WIDE_JUMBO.S */ 7157 /* 7158 * Jumbo 64-bit SPUT handler. 7159 */ 7160 /* sput-wide/jumbo vBBBB, field@AAAAAAAA */ 7161 movl rSELF,%ecx 7162 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7163 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7164 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7165 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7166 testl %eax,%eax # resolved entry null? 7167 je .LOP_SPUT_WIDE_JUMBO_resolve # if not, make it so 7168.LOP_SPUT_WIDE_JUMBO_finish: # field ptr in eax 7169 GET_VREG_WORD %ecx rINST 0 # ecx<- lsw 7170 GET_VREG_WORD rINST rINST 1 # rINST<- msw 7171 FETCH_INST_OPCODE 4 %edx 7172 ADVANCE_PC 4 7173 movl %ecx,offStaticField_value(%eax) 7174 movl rINST,4+offStaticField_value(%eax) 7175 GOTO_NEXT_R %edx 7176 7177/* ------------------------------ */ 7178 .balign 64 7179.L_OP_SPUT_OBJECT_JUMBO: /* 0x11d */ 7180/* File: x86/OP_SPUT_OBJECT_JUMBO.S */ 7181 /* 7182 * Jumbo SPUT object handler. 7183 */ 7184 /* sput-object/jumbo vBBBB, field@AAAAAAAA */ 7185 movl rSELF,%ecx 7186 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7187 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7188 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7189 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField 7190 testl %eax,%eax # resolved entry null? 7191 je .LOP_SPUT_OBJECT_JUMBO_resolve # if not, make it so 7192.LOP_SPUT_OBJECT_JUMBO_finish: # field ptr in eax 7193 GET_VREG_R %ecx rINST 7194 jmp .LOP_SPUT_OBJECT_JUMBO_continue 7195 7196/* ------------------------------ */ 7197 .balign 64 7198.L_OP_SPUT_BOOLEAN_JUMBO: /* 0x11e */ 7199/* File: x86/OP_SPUT_BOOLEAN_JUMBO.S */ 7200/* File: x86/OP_SPUT_JUMBO.S */ 7201 /* 7202 * Jumbo 32-bit SPUT handler. 7203 * 7204 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 7205 * sput-short/jumbo 7206 */ 7207 /* exop vBBBB, field@AAAAAAAA */ 7208 movl rSELF,%ecx 7209 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7210 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7211 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7212 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7213 testl %eax,%eax # resolved entry null? 7214 je .LOP_SPUT_BOOLEAN_JUMBO_resolve # if not, make it so 7215.LOP_SPUT_BOOLEAN_JUMBO_finish: # field ptr in eax 7216 GET_VREG_R %ecx rINST 7217 FETCH_INST_OPCODE 4 %edx 7218 ADVANCE_PC 4 7219 movl %ecx,offStaticField_value(%eax) 7220 GOTO_NEXT_R %edx 7221 7222 7223/* ------------------------------ */ 7224 .balign 64 7225.L_OP_SPUT_BYTE_JUMBO: /* 0x11f */ 7226/* File: x86/OP_SPUT_BYTE_JUMBO.S */ 7227/* File: x86/OP_SPUT_JUMBO.S */ 7228 /* 7229 * Jumbo 32-bit SPUT handler. 7230 * 7231 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 7232 * sput-short/jumbo 7233 */ 7234 /* exop vBBBB, field@AAAAAAAA */ 7235 movl rSELF,%ecx 7236 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7237 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7238 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7239 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7240 testl %eax,%eax # resolved entry null? 7241 je .LOP_SPUT_BYTE_JUMBO_resolve # if not, make it so 7242.LOP_SPUT_BYTE_JUMBO_finish: # field ptr in eax 7243 GET_VREG_R %ecx rINST 7244 FETCH_INST_OPCODE 4 %edx 7245 ADVANCE_PC 4 7246 movl %ecx,offStaticField_value(%eax) 7247 GOTO_NEXT_R %edx 7248 7249 7250/* ------------------------------ */ 7251 .balign 64 7252.L_OP_SPUT_CHAR_JUMBO: /* 0x120 */ 7253/* File: x86/OP_SPUT_CHAR_JUMBO.S */ 7254/* File: x86/OP_SPUT_JUMBO.S */ 7255 /* 7256 * Jumbo 32-bit SPUT handler. 7257 * 7258 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 7259 * sput-short/jumbo 7260 */ 7261 /* exop vBBBB, field@AAAAAAAA */ 7262 movl rSELF,%ecx 7263 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7264 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7265 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7266 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7267 testl %eax,%eax # resolved entry null? 7268 je .LOP_SPUT_CHAR_JUMBO_resolve # if not, make it so 7269.LOP_SPUT_CHAR_JUMBO_finish: # field ptr in eax 7270 GET_VREG_R %ecx rINST 7271 FETCH_INST_OPCODE 4 %edx 7272 ADVANCE_PC 4 7273 movl %ecx,offStaticField_value(%eax) 7274 GOTO_NEXT_R %edx 7275 7276 7277/* ------------------------------ */ 7278 .balign 64 7279.L_OP_SPUT_SHORT_JUMBO: /* 0x121 */ 7280/* File: x86/OP_SPUT_SHORT_JUMBO.S */ 7281/* File: x86/OP_SPUT_JUMBO.S */ 7282 /* 7283 * Jumbo 32-bit SPUT handler. 7284 * 7285 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 7286 * sput-short/jumbo 7287 */ 7288 /* exop vBBBB, field@AAAAAAAA */ 7289 movl rSELF,%ecx 7290 movl offThread_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7291 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7292 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7293 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7294 testl %eax,%eax # resolved entry null? 7295 je .LOP_SPUT_SHORT_JUMBO_resolve # if not, make it so 7296.LOP_SPUT_SHORT_JUMBO_finish: # field ptr in eax 7297 GET_VREG_R %ecx rINST 7298 FETCH_INST_OPCODE 4 %edx 7299 ADVANCE_PC 4 7300 movl %ecx,offStaticField_value(%eax) 7301 GOTO_NEXT_R %edx 7302 7303 7304/* ------------------------------ */ 7305 .balign 64 7306.L_OP_INVOKE_VIRTUAL_JUMBO: /* 0x122 */ 7307/* File: x86/OP_INVOKE_VIRTUAL_JUMBO.S */ 7308 /* 7309 * Handle a jumbo virtual method call. 7310 */ 7311 /* invoke-virtual/jumbo vBBBB, {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 7312 movl rSELF,%eax 7313 movl 2(rPC),%ecx # ecx<- AAAAAAAA 7314 movl offThread_methodClassDex(%eax),%eax # eax<- pDvmDex 7315 EXPORT_PC 7316 movl offDvmDex_pResMethods(%eax),%eax # eax<- pDvmDex->pResMethods 7317 movl (%eax,%ecx,4),%eax # eax<- resolved baseMethod 7318 testl %eax,%eax # already resolved? 7319 jne .LOP_INVOKE_VIRTUAL_JUMBO_continue # yes, continue 7320 movl rSELF,%eax 7321 movl %ecx,OUT_ARG1(%esp) # arg1<- ref 7322 movl offThread_method(%eax),%eax # eax<- self->method 7323 jmp .LOP_INVOKE_VIRTUAL_JUMBO_more 7324 7325/* ------------------------------ */ 7326 .balign 64 7327.L_OP_INVOKE_SUPER_JUMBO: /* 0x123 */ 7328/* File: x86/OP_INVOKE_SUPER_JUMBO.S */ 7329 /* 7330 * Handle a jumbo "super" method call. 7331 */ 7332 /* invoke-super/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 7333 movl rSELF,rINST 7334 movl 2(rPC),%eax # eax<- AAAAAAAA 7335 movl offThread_methodClassDex(rINST),%ecx # ecx<- pDvmDex 7336 EXPORT_PC 7337 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 7338 movl (%ecx,%eax,4),%ecx # ecx<- resolved baseMethod 7339 movl offThread_method(rINST),%eax # eax<- method 7340 movzwl 8(rPC),rINST # rINST<- CCCC 7341 GET_VREG_R rINST rINST # rINST<- "this" ptr 7342 testl rINST,rINST # null "this"? 7343 je common_errNullObject # yes, throw 7344 movl offMethod_clazz(%eax),%eax # eax<- method->clazz 7345 testl %ecx,%ecx # already resolved? 7346 jne .LOP_INVOKE_SUPER_JUMBO_continue # yes - go on 7347 jmp .LOP_INVOKE_SUPER_JUMBO_resolve 7348 7349/* ------------------------------ */ 7350 .balign 64 7351.L_OP_INVOKE_DIRECT_JUMBO: /* 0x124 */ 7352/* File: x86/OP_INVOKE_DIRECT_JUMBO.S */ 7353 /* 7354 * Handle a jumbo direct method call. 7355 * 7356 * (We could defer the "is 'this' pointer null" test to the common 7357 * method invocation code, and use a flag to indicate that static 7358 * calls don't count. If we do this as part of copying the arguments 7359 * out we could avoiding loading the first arg twice.) 7360 */ 7361 /* invoke-direct/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 7362 movl rSELF,%ecx 7363 movl 2(rPC),%eax # eax<- AAAAAAAA 7364 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 7365 EXPORT_PC 7366 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 7367 movzwl 8(rPC),%edx # edx<- CCCC 7368 movl (%ecx,%eax,4),%eax # eax<- resolved methodToCall 7369 testl %eax,%eax # already resolved? 7370 GET_VREG_R %ecx %edx # ecx<- "this" ptr 7371 je .LOP_INVOKE_DIRECT_JUMBO_resolve # not resolved, do it now 7372.LOP_INVOKE_DIRECT_JUMBO_finish: 7373 testl %ecx,%ecx # null "this"? 7374 jne common_invokeMethodJumbo # no, continue on 7375 jmp common_errNullObject 7376 7377/* ------------------------------ */ 7378 .balign 64 7379.L_OP_INVOKE_STATIC_JUMBO: /* 0x125 */ 7380/* File: x86/OP_INVOKE_STATIC_JUMBO.S */ 7381 /* 7382 * Handle a jumbo static method call. 7383 */ 7384 /* invoke-static/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 7385 movl rSELF,%ecx 7386 movl 2(rPC),%eax # eax<- AAAAAAAA 7387 movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 7388 EXPORT_PC 7389 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 7390 movl (%ecx,%eax,4),%eax # eax<- resolved methodToCall 7391 testl %eax,%eax 7392 jne common_invokeMethodJumbo 7393 movl rSELF,%ecx 7394 movl offThread_method(%ecx),%ecx # ecx<- self->method 7395 movl 2(rPC),%eax # eax<- AAAAAAAA 7396 movl offMethod_clazz(%ecx),%ecx# ecx<- method->clazz 7397 movl %eax,OUT_ARG1(%esp) # arg1<- AAAAAAAA 7398 movl %ecx,OUT_ARG0(%esp) # arg0<- clazz 7399 jmp .LOP_INVOKE_STATIC_JUMBO_continue 7400 7401/* ------------------------------ */ 7402 .balign 64 7403.L_OP_INVOKE_INTERFACE_JUMBO: /* 0x126 */ 7404/* File: x86/OP_INVOKE_INTERFACE_JUMBO.S */ 7405 /* 7406 * Handle a jumbo interface method call. 7407 */ 7408 /* invoke-interface/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 7409 movzwl 8(rPC),%eax # eax<- CCCC 7410 movl rSELF,%ecx 7411 GET_VREG_R %eax %eax # eax<- "this" 7412 EXPORT_PC 7413 testl %eax,%eax # null this? 7414 je common_errNullObject # yes, fail 7415 movl offObject_clazz(%eax),%eax# eax<- thisPtr->clazz 7416 movl %eax,OUT_ARG0(%esp) # arg0<- class 7417 movl offThread_methodClassDex(%ecx),%eax # eax<- methodClassDex 7418 movl offThread_method(%ecx),%ecx # ecx<- method 7419 movl %eax,OUT_ARG3(%esp) # arg3<- dex 7420 movl 2(rPC),%eax # eax<- AAAAAAAA 7421 movl %ecx,OUT_ARG2(%esp) # arg2<- method 7422 movl %eax,OUT_ARG1(%esp) # arg1<- AAAAAAAA 7423 jmp .LOP_INVOKE_INTERFACE_JUMBO_continue 7424 7425/* ------------------------------ */ 7426 .balign 64 7427.L_OP_UNUSED_27FF: /* 0x127 */ 7428/* File: x86/OP_UNUSED_27FF.S */ 7429/* File: x86/unused.S */ 7430 jmp common_abort 7431 7432 7433/* ------------------------------ */ 7434 .balign 64 7435.L_OP_UNUSED_28FF: /* 0x128 */ 7436/* File: x86/OP_UNUSED_28FF.S */ 7437/* File: x86/unused.S */ 7438 jmp common_abort 7439 7440 7441/* ------------------------------ */ 7442 .balign 64 7443.L_OP_UNUSED_29FF: /* 0x129 */ 7444/* File: x86/OP_UNUSED_29FF.S */ 7445/* File: x86/unused.S */ 7446 jmp common_abort 7447 7448 7449/* ------------------------------ */ 7450 .balign 64 7451.L_OP_UNUSED_2AFF: /* 0x12a */ 7452/* File: x86/OP_UNUSED_2AFF.S */ 7453/* File: x86/unused.S */ 7454 jmp common_abort 7455 7456 7457/* ------------------------------ */ 7458 .balign 64 7459.L_OP_UNUSED_2BFF: /* 0x12b */ 7460/* File: x86/OP_UNUSED_2BFF.S */ 7461/* File: x86/unused.S */ 7462 jmp common_abort 7463 7464 7465/* ------------------------------ */ 7466 .balign 64 7467.L_OP_UNUSED_2CFF: /* 0x12c */ 7468/* File: x86/OP_UNUSED_2CFF.S */ 7469/* File: x86/unused.S */ 7470 jmp common_abort 7471 7472 7473/* ------------------------------ */ 7474 .balign 64 7475.L_OP_UNUSED_2DFF: /* 0x12d */ 7476/* File: x86/OP_UNUSED_2DFF.S */ 7477/* File: x86/unused.S */ 7478 jmp common_abort 7479 7480 7481/* ------------------------------ */ 7482 .balign 64 7483.L_OP_UNUSED_2EFF: /* 0x12e */ 7484/* File: x86/OP_UNUSED_2EFF.S */ 7485/* File: x86/unused.S */ 7486 jmp common_abort 7487 7488 7489/* ------------------------------ */ 7490 .balign 64 7491.L_OP_UNUSED_2FFF: /* 0x12f */ 7492/* File: x86/OP_UNUSED_2FFF.S */ 7493/* File: x86/unused.S */ 7494 jmp common_abort 7495 7496 7497/* ------------------------------ */ 7498 .balign 64 7499.L_OP_UNUSED_30FF: /* 0x130 */ 7500/* File: x86/OP_UNUSED_30FF.S */ 7501/* File: x86/unused.S */ 7502 jmp common_abort 7503 7504 7505/* ------------------------------ */ 7506 .balign 64 7507.L_OP_UNUSED_31FF: /* 0x131 */ 7508/* File: x86/OP_UNUSED_31FF.S */ 7509/* File: x86/unused.S */ 7510 jmp common_abort 7511 7512 7513/* ------------------------------ */ 7514 .balign 64 7515.L_OP_UNUSED_32FF: /* 0x132 */ 7516/* File: x86/OP_UNUSED_32FF.S */ 7517/* File: x86/unused.S */ 7518 jmp common_abort 7519 7520 7521/* ------------------------------ */ 7522 .balign 64 7523.L_OP_UNUSED_33FF: /* 0x133 */ 7524/* File: x86/OP_UNUSED_33FF.S */ 7525/* File: x86/unused.S */ 7526 jmp common_abort 7527 7528 7529/* ------------------------------ */ 7530 .balign 64 7531.L_OP_UNUSED_34FF: /* 0x134 */ 7532/* File: x86/OP_UNUSED_34FF.S */ 7533/* File: x86/unused.S */ 7534 jmp common_abort 7535 7536 7537/* ------------------------------ */ 7538 .balign 64 7539.L_OP_UNUSED_35FF: /* 0x135 */ 7540/* File: x86/OP_UNUSED_35FF.S */ 7541/* File: x86/unused.S */ 7542 jmp common_abort 7543 7544 7545/* ------------------------------ */ 7546 .balign 64 7547.L_OP_UNUSED_36FF: /* 0x136 */ 7548/* File: x86/OP_UNUSED_36FF.S */ 7549/* File: x86/unused.S */ 7550 jmp common_abort 7551 7552 7553/* ------------------------------ */ 7554 .balign 64 7555.L_OP_UNUSED_37FF: /* 0x137 */ 7556/* File: x86/OP_UNUSED_37FF.S */ 7557/* File: x86/unused.S */ 7558 jmp common_abort 7559 7560 7561/* ------------------------------ */ 7562 .balign 64 7563.L_OP_UNUSED_38FF: /* 0x138 */ 7564/* File: x86/OP_UNUSED_38FF.S */ 7565/* File: x86/unused.S */ 7566 jmp common_abort 7567 7568 7569/* ------------------------------ */ 7570 .balign 64 7571.L_OP_UNUSED_39FF: /* 0x139 */ 7572/* File: x86/OP_UNUSED_39FF.S */ 7573/* File: x86/unused.S */ 7574 jmp common_abort 7575 7576 7577/* ------------------------------ */ 7578 .balign 64 7579.L_OP_UNUSED_3AFF: /* 0x13a */ 7580/* File: x86/OP_UNUSED_3AFF.S */ 7581/* File: x86/unused.S */ 7582 jmp common_abort 7583 7584 7585/* ------------------------------ */ 7586 .balign 64 7587.L_OP_UNUSED_3BFF: /* 0x13b */ 7588/* File: x86/OP_UNUSED_3BFF.S */ 7589/* File: x86/unused.S */ 7590 jmp common_abort 7591 7592 7593/* ------------------------------ */ 7594 .balign 64 7595.L_OP_UNUSED_3CFF: /* 0x13c */ 7596/* File: x86/OP_UNUSED_3CFF.S */ 7597/* File: x86/unused.S */ 7598 jmp common_abort 7599 7600 7601/* ------------------------------ */ 7602 .balign 64 7603.L_OP_UNUSED_3DFF: /* 0x13d */ 7604/* File: x86/OP_UNUSED_3DFF.S */ 7605/* File: x86/unused.S */ 7606 jmp common_abort 7607 7608 7609/* ------------------------------ */ 7610 .balign 64 7611.L_OP_UNUSED_3EFF: /* 0x13e */ 7612/* File: x86/OP_UNUSED_3EFF.S */ 7613/* File: x86/unused.S */ 7614 jmp common_abort 7615 7616 7617/* ------------------------------ */ 7618 .balign 64 7619.L_OP_UNUSED_3FFF: /* 0x13f */ 7620/* File: x86/OP_UNUSED_3FFF.S */ 7621/* File: x86/unused.S */ 7622 jmp common_abort 7623 7624 7625/* ------------------------------ */ 7626 .balign 64 7627.L_OP_UNUSED_40FF: /* 0x140 */ 7628/* File: x86/OP_UNUSED_40FF.S */ 7629/* File: x86/unused.S */ 7630 jmp common_abort 7631 7632 7633/* ------------------------------ */ 7634 .balign 64 7635.L_OP_UNUSED_41FF: /* 0x141 */ 7636/* File: x86/OP_UNUSED_41FF.S */ 7637/* File: x86/unused.S */ 7638 jmp common_abort 7639 7640 7641/* ------------------------------ */ 7642 .balign 64 7643.L_OP_UNUSED_42FF: /* 0x142 */ 7644/* File: x86/OP_UNUSED_42FF.S */ 7645/* File: x86/unused.S */ 7646 jmp common_abort 7647 7648 7649/* ------------------------------ */ 7650 .balign 64 7651.L_OP_UNUSED_43FF: /* 0x143 */ 7652/* File: x86/OP_UNUSED_43FF.S */ 7653/* File: x86/unused.S */ 7654 jmp common_abort 7655 7656 7657/* ------------------------------ */ 7658 .balign 64 7659.L_OP_UNUSED_44FF: /* 0x144 */ 7660/* File: x86/OP_UNUSED_44FF.S */ 7661/* File: x86/unused.S */ 7662 jmp common_abort 7663 7664 7665/* ------------------------------ */ 7666 .balign 64 7667.L_OP_UNUSED_45FF: /* 0x145 */ 7668/* File: x86/OP_UNUSED_45FF.S */ 7669/* File: x86/unused.S */ 7670 jmp common_abort 7671 7672 7673/* ------------------------------ */ 7674 .balign 64 7675.L_OP_UNUSED_46FF: /* 0x146 */ 7676/* File: x86/OP_UNUSED_46FF.S */ 7677/* File: x86/unused.S */ 7678 jmp common_abort 7679 7680 7681/* ------------------------------ */ 7682 .balign 64 7683.L_OP_UNUSED_47FF: /* 0x147 */ 7684/* File: x86/OP_UNUSED_47FF.S */ 7685/* File: x86/unused.S */ 7686 jmp common_abort 7687 7688 7689/* ------------------------------ */ 7690 .balign 64 7691.L_OP_UNUSED_48FF: /* 0x148 */ 7692/* File: x86/OP_UNUSED_48FF.S */ 7693/* File: x86/unused.S */ 7694 jmp common_abort 7695 7696 7697/* ------------------------------ */ 7698 .balign 64 7699.L_OP_UNUSED_49FF: /* 0x149 */ 7700/* File: x86/OP_UNUSED_49FF.S */ 7701/* File: x86/unused.S */ 7702 jmp common_abort 7703 7704 7705/* ------------------------------ */ 7706 .balign 64 7707.L_OP_UNUSED_4AFF: /* 0x14a */ 7708/* File: x86/OP_UNUSED_4AFF.S */ 7709/* File: x86/unused.S */ 7710 jmp common_abort 7711 7712 7713/* ------------------------------ */ 7714 .balign 64 7715.L_OP_UNUSED_4BFF: /* 0x14b */ 7716/* File: x86/OP_UNUSED_4BFF.S */ 7717/* File: x86/unused.S */ 7718 jmp common_abort 7719 7720 7721/* ------------------------------ */ 7722 .balign 64 7723.L_OP_UNUSED_4CFF: /* 0x14c */ 7724/* File: x86/OP_UNUSED_4CFF.S */ 7725/* File: x86/unused.S */ 7726 jmp common_abort 7727 7728 7729/* ------------------------------ */ 7730 .balign 64 7731.L_OP_UNUSED_4DFF: /* 0x14d */ 7732/* File: x86/OP_UNUSED_4DFF.S */ 7733/* File: x86/unused.S */ 7734 jmp common_abort 7735 7736 7737/* ------------------------------ */ 7738 .balign 64 7739.L_OP_UNUSED_4EFF: /* 0x14e */ 7740/* File: x86/OP_UNUSED_4EFF.S */ 7741/* File: x86/unused.S */ 7742 jmp common_abort 7743 7744 7745/* ------------------------------ */ 7746 .balign 64 7747.L_OP_UNUSED_4FFF: /* 0x14f */ 7748/* File: x86/OP_UNUSED_4FFF.S */ 7749/* File: x86/unused.S */ 7750 jmp common_abort 7751 7752 7753/* ------------------------------ */ 7754 .balign 64 7755.L_OP_UNUSED_50FF: /* 0x150 */ 7756/* File: x86/OP_UNUSED_50FF.S */ 7757/* File: x86/unused.S */ 7758 jmp common_abort 7759 7760 7761/* ------------------------------ */ 7762 .balign 64 7763.L_OP_UNUSED_51FF: /* 0x151 */ 7764/* File: x86/OP_UNUSED_51FF.S */ 7765/* File: x86/unused.S */ 7766 jmp common_abort 7767 7768 7769/* ------------------------------ */ 7770 .balign 64 7771.L_OP_UNUSED_52FF: /* 0x152 */ 7772/* File: x86/OP_UNUSED_52FF.S */ 7773/* File: x86/unused.S */ 7774 jmp common_abort 7775 7776 7777/* ------------------------------ */ 7778 .balign 64 7779.L_OP_UNUSED_53FF: /* 0x153 */ 7780/* File: x86/OP_UNUSED_53FF.S */ 7781/* File: x86/unused.S */ 7782 jmp common_abort 7783 7784 7785/* ------------------------------ */ 7786 .balign 64 7787.L_OP_UNUSED_54FF: /* 0x154 */ 7788/* File: x86/OP_UNUSED_54FF.S */ 7789/* File: x86/unused.S */ 7790 jmp common_abort 7791 7792 7793/* ------------------------------ */ 7794 .balign 64 7795.L_OP_UNUSED_55FF: /* 0x155 */ 7796/* File: x86/OP_UNUSED_55FF.S */ 7797/* File: x86/unused.S */ 7798 jmp common_abort 7799 7800 7801/* ------------------------------ */ 7802 .balign 64 7803.L_OP_UNUSED_56FF: /* 0x156 */ 7804/* File: x86/OP_UNUSED_56FF.S */ 7805/* File: x86/unused.S */ 7806 jmp common_abort 7807 7808 7809/* ------------------------------ */ 7810 .balign 64 7811.L_OP_UNUSED_57FF: /* 0x157 */ 7812/* File: x86/OP_UNUSED_57FF.S */ 7813/* File: x86/unused.S */ 7814 jmp common_abort 7815 7816 7817/* ------------------------------ */ 7818 .balign 64 7819.L_OP_UNUSED_58FF: /* 0x158 */ 7820/* File: x86/OP_UNUSED_58FF.S */ 7821/* File: x86/unused.S */ 7822 jmp common_abort 7823 7824 7825/* ------------------------------ */ 7826 .balign 64 7827.L_OP_UNUSED_59FF: /* 0x159 */ 7828/* File: x86/OP_UNUSED_59FF.S */ 7829/* File: x86/unused.S */ 7830 jmp common_abort 7831 7832 7833/* ------------------------------ */ 7834 .balign 64 7835.L_OP_UNUSED_5AFF: /* 0x15a */ 7836/* File: x86/OP_UNUSED_5AFF.S */ 7837/* File: x86/unused.S */ 7838 jmp common_abort 7839 7840 7841/* ------------------------------ */ 7842 .balign 64 7843.L_OP_UNUSED_5BFF: /* 0x15b */ 7844/* File: x86/OP_UNUSED_5BFF.S */ 7845/* File: x86/unused.S */ 7846 jmp common_abort 7847 7848 7849/* ------------------------------ */ 7850 .balign 64 7851.L_OP_UNUSED_5CFF: /* 0x15c */ 7852/* File: x86/OP_UNUSED_5CFF.S */ 7853/* File: x86/unused.S */ 7854 jmp common_abort 7855 7856 7857/* ------------------------------ */ 7858 .balign 64 7859.L_OP_UNUSED_5DFF: /* 0x15d */ 7860/* File: x86/OP_UNUSED_5DFF.S */ 7861/* File: x86/unused.S */ 7862 jmp common_abort 7863 7864 7865/* ------------------------------ */ 7866 .balign 64 7867.L_OP_UNUSED_5EFF: /* 0x15e */ 7868/* File: x86/OP_UNUSED_5EFF.S */ 7869/* File: x86/unused.S */ 7870 jmp common_abort 7871 7872 7873/* ------------------------------ */ 7874 .balign 64 7875.L_OP_UNUSED_5FFF: /* 0x15f */ 7876/* File: x86/OP_UNUSED_5FFF.S */ 7877/* File: x86/unused.S */ 7878 jmp common_abort 7879 7880 7881/* ------------------------------ */ 7882 .balign 64 7883.L_OP_UNUSED_60FF: /* 0x160 */ 7884/* File: x86/OP_UNUSED_60FF.S */ 7885/* File: x86/unused.S */ 7886 jmp common_abort 7887 7888 7889/* ------------------------------ */ 7890 .balign 64 7891.L_OP_UNUSED_61FF: /* 0x161 */ 7892/* File: x86/OP_UNUSED_61FF.S */ 7893/* File: x86/unused.S */ 7894 jmp common_abort 7895 7896 7897/* ------------------------------ */ 7898 .balign 64 7899.L_OP_UNUSED_62FF: /* 0x162 */ 7900/* File: x86/OP_UNUSED_62FF.S */ 7901/* File: x86/unused.S */ 7902 jmp common_abort 7903 7904 7905/* ------------------------------ */ 7906 .balign 64 7907.L_OP_UNUSED_63FF: /* 0x163 */ 7908/* File: x86/OP_UNUSED_63FF.S */ 7909/* File: x86/unused.S */ 7910 jmp common_abort 7911 7912 7913/* ------------------------------ */ 7914 .balign 64 7915.L_OP_UNUSED_64FF: /* 0x164 */ 7916/* File: x86/OP_UNUSED_64FF.S */ 7917/* File: x86/unused.S */ 7918 jmp common_abort 7919 7920 7921/* ------------------------------ */ 7922 .balign 64 7923.L_OP_UNUSED_65FF: /* 0x165 */ 7924/* File: x86/OP_UNUSED_65FF.S */ 7925/* File: x86/unused.S */ 7926 jmp common_abort 7927 7928 7929/* ------------------------------ */ 7930 .balign 64 7931.L_OP_UNUSED_66FF: /* 0x166 */ 7932/* File: x86/OP_UNUSED_66FF.S */ 7933/* File: x86/unused.S */ 7934 jmp common_abort 7935 7936 7937/* ------------------------------ */ 7938 .balign 64 7939.L_OP_UNUSED_67FF: /* 0x167 */ 7940/* File: x86/OP_UNUSED_67FF.S */ 7941/* File: x86/unused.S */ 7942 jmp common_abort 7943 7944 7945/* ------------------------------ */ 7946 .balign 64 7947.L_OP_UNUSED_68FF: /* 0x168 */ 7948/* File: x86/OP_UNUSED_68FF.S */ 7949/* File: x86/unused.S */ 7950 jmp common_abort 7951 7952 7953/* ------------------------------ */ 7954 .balign 64 7955.L_OP_UNUSED_69FF: /* 0x169 */ 7956/* File: x86/OP_UNUSED_69FF.S */ 7957/* File: x86/unused.S */ 7958 jmp common_abort 7959 7960 7961/* ------------------------------ */ 7962 .balign 64 7963.L_OP_UNUSED_6AFF: /* 0x16a */ 7964/* File: x86/OP_UNUSED_6AFF.S */ 7965/* File: x86/unused.S */ 7966 jmp common_abort 7967 7968 7969/* ------------------------------ */ 7970 .balign 64 7971.L_OP_UNUSED_6BFF: /* 0x16b */ 7972/* File: x86/OP_UNUSED_6BFF.S */ 7973/* File: x86/unused.S */ 7974 jmp common_abort 7975 7976 7977/* ------------------------------ */ 7978 .balign 64 7979.L_OP_UNUSED_6CFF: /* 0x16c */ 7980/* File: x86/OP_UNUSED_6CFF.S */ 7981/* File: x86/unused.S */ 7982 jmp common_abort 7983 7984 7985/* ------------------------------ */ 7986 .balign 64 7987.L_OP_UNUSED_6DFF: /* 0x16d */ 7988/* File: x86/OP_UNUSED_6DFF.S */ 7989/* File: x86/unused.S */ 7990 jmp common_abort 7991 7992 7993/* ------------------------------ */ 7994 .balign 64 7995.L_OP_UNUSED_6EFF: /* 0x16e */ 7996/* File: x86/OP_UNUSED_6EFF.S */ 7997/* File: x86/unused.S */ 7998 jmp common_abort 7999 8000 8001/* ------------------------------ */ 8002 .balign 64 8003.L_OP_UNUSED_6FFF: /* 0x16f */ 8004/* File: x86/OP_UNUSED_6FFF.S */ 8005/* File: x86/unused.S */ 8006 jmp common_abort 8007 8008 8009/* ------------------------------ */ 8010 .balign 64 8011.L_OP_UNUSED_70FF: /* 0x170 */ 8012/* File: x86/OP_UNUSED_70FF.S */ 8013/* File: x86/unused.S */ 8014 jmp common_abort 8015 8016 8017/* ------------------------------ */ 8018 .balign 64 8019.L_OP_UNUSED_71FF: /* 0x171 */ 8020/* File: x86/OP_UNUSED_71FF.S */ 8021/* File: x86/unused.S */ 8022 jmp common_abort 8023 8024 8025/* ------------------------------ */ 8026 .balign 64 8027.L_OP_UNUSED_72FF: /* 0x172 */ 8028/* File: x86/OP_UNUSED_72FF.S */ 8029/* File: x86/unused.S */ 8030 jmp common_abort 8031 8032 8033/* ------------------------------ */ 8034 .balign 64 8035.L_OP_UNUSED_73FF: /* 0x173 */ 8036/* File: x86/OP_UNUSED_73FF.S */ 8037/* File: x86/unused.S */ 8038 jmp common_abort 8039 8040 8041/* ------------------------------ */ 8042 .balign 64 8043.L_OP_UNUSED_74FF: /* 0x174 */ 8044/* File: x86/OP_UNUSED_74FF.S */ 8045/* File: x86/unused.S */ 8046 jmp common_abort 8047 8048 8049/* ------------------------------ */ 8050 .balign 64 8051.L_OP_UNUSED_75FF: /* 0x175 */ 8052/* File: x86/OP_UNUSED_75FF.S */ 8053/* File: x86/unused.S */ 8054 jmp common_abort 8055 8056 8057/* ------------------------------ */ 8058 .balign 64 8059.L_OP_UNUSED_76FF: /* 0x176 */ 8060/* File: x86/OP_UNUSED_76FF.S */ 8061/* File: x86/unused.S */ 8062 jmp common_abort 8063 8064 8065/* ------------------------------ */ 8066 .balign 64 8067.L_OP_UNUSED_77FF: /* 0x177 */ 8068/* File: x86/OP_UNUSED_77FF.S */ 8069/* File: x86/unused.S */ 8070 jmp common_abort 8071 8072 8073/* ------------------------------ */ 8074 .balign 64 8075.L_OP_UNUSED_78FF: /* 0x178 */ 8076/* File: x86/OP_UNUSED_78FF.S */ 8077/* File: x86/unused.S */ 8078 jmp common_abort 8079 8080 8081/* ------------------------------ */ 8082 .balign 64 8083.L_OP_UNUSED_79FF: /* 0x179 */ 8084/* File: x86/OP_UNUSED_79FF.S */ 8085/* File: x86/unused.S */ 8086 jmp common_abort 8087 8088 8089/* ------------------------------ */ 8090 .balign 64 8091.L_OP_UNUSED_7AFF: /* 0x17a */ 8092/* File: x86/OP_UNUSED_7AFF.S */ 8093/* File: x86/unused.S */ 8094 jmp common_abort 8095 8096 8097/* ------------------------------ */ 8098 .balign 64 8099.L_OP_UNUSED_7BFF: /* 0x17b */ 8100/* File: x86/OP_UNUSED_7BFF.S */ 8101/* File: x86/unused.S */ 8102 jmp common_abort 8103 8104 8105/* ------------------------------ */ 8106 .balign 64 8107.L_OP_UNUSED_7CFF: /* 0x17c */ 8108/* File: x86/OP_UNUSED_7CFF.S */ 8109/* File: x86/unused.S */ 8110 jmp common_abort 8111 8112 8113/* ------------------------------ */ 8114 .balign 64 8115.L_OP_UNUSED_7DFF: /* 0x17d */ 8116/* File: x86/OP_UNUSED_7DFF.S */ 8117/* File: x86/unused.S */ 8118 jmp common_abort 8119 8120 8121/* ------------------------------ */ 8122 .balign 64 8123.L_OP_UNUSED_7EFF: /* 0x17e */ 8124/* File: x86/OP_UNUSED_7EFF.S */ 8125/* File: x86/unused.S */ 8126 jmp common_abort 8127 8128 8129/* ------------------------------ */ 8130 .balign 64 8131.L_OP_UNUSED_7FFF: /* 0x17f */ 8132/* File: x86/OP_UNUSED_7FFF.S */ 8133/* File: x86/unused.S */ 8134 jmp common_abort 8135 8136 8137/* ------------------------------ */ 8138 .balign 64 8139.L_OP_UNUSED_80FF: /* 0x180 */ 8140/* File: x86/OP_UNUSED_80FF.S */ 8141/* File: x86/unused.S */ 8142 jmp common_abort 8143 8144 8145/* ------------------------------ */ 8146 .balign 64 8147.L_OP_UNUSED_81FF: /* 0x181 */ 8148/* File: x86/OP_UNUSED_81FF.S */ 8149/* File: x86/unused.S */ 8150 jmp common_abort 8151 8152 8153/* ------------------------------ */ 8154 .balign 64 8155.L_OP_UNUSED_82FF: /* 0x182 */ 8156/* File: x86/OP_UNUSED_82FF.S */ 8157/* File: x86/unused.S */ 8158 jmp common_abort 8159 8160 8161/* ------------------------------ */ 8162 .balign 64 8163.L_OP_UNUSED_83FF: /* 0x183 */ 8164/* File: x86/OP_UNUSED_83FF.S */ 8165/* File: x86/unused.S */ 8166 jmp common_abort 8167 8168 8169/* ------------------------------ */ 8170 .balign 64 8171.L_OP_UNUSED_84FF: /* 0x184 */ 8172/* File: x86/OP_UNUSED_84FF.S */ 8173/* File: x86/unused.S */ 8174 jmp common_abort 8175 8176 8177/* ------------------------------ */ 8178 .balign 64 8179.L_OP_UNUSED_85FF: /* 0x185 */ 8180/* File: x86/OP_UNUSED_85FF.S */ 8181/* File: x86/unused.S */ 8182 jmp common_abort 8183 8184 8185/* ------------------------------ */ 8186 .balign 64 8187.L_OP_UNUSED_86FF: /* 0x186 */ 8188/* File: x86/OP_UNUSED_86FF.S */ 8189/* File: x86/unused.S */ 8190 jmp common_abort 8191 8192 8193/* ------------------------------ */ 8194 .balign 64 8195.L_OP_UNUSED_87FF: /* 0x187 */ 8196/* File: x86/OP_UNUSED_87FF.S */ 8197/* File: x86/unused.S */ 8198 jmp common_abort 8199 8200 8201/* ------------------------------ */ 8202 .balign 64 8203.L_OP_UNUSED_88FF: /* 0x188 */ 8204/* File: x86/OP_UNUSED_88FF.S */ 8205/* File: x86/unused.S */ 8206 jmp common_abort 8207 8208 8209/* ------------------------------ */ 8210 .balign 64 8211.L_OP_UNUSED_89FF: /* 0x189 */ 8212/* File: x86/OP_UNUSED_89FF.S */ 8213/* File: x86/unused.S */ 8214 jmp common_abort 8215 8216 8217/* ------------------------------ */ 8218 .balign 64 8219.L_OP_UNUSED_8AFF: /* 0x18a */ 8220/* File: x86/OP_UNUSED_8AFF.S */ 8221/* File: x86/unused.S */ 8222 jmp common_abort 8223 8224 8225/* ------------------------------ */ 8226 .balign 64 8227.L_OP_UNUSED_8BFF: /* 0x18b */ 8228/* File: x86/OP_UNUSED_8BFF.S */ 8229/* File: x86/unused.S */ 8230 jmp common_abort 8231 8232 8233/* ------------------------------ */ 8234 .balign 64 8235.L_OP_UNUSED_8CFF: /* 0x18c */ 8236/* File: x86/OP_UNUSED_8CFF.S */ 8237/* File: x86/unused.S */ 8238 jmp common_abort 8239 8240 8241/* ------------------------------ */ 8242 .balign 64 8243.L_OP_UNUSED_8DFF: /* 0x18d */ 8244/* File: x86/OP_UNUSED_8DFF.S */ 8245/* File: x86/unused.S */ 8246 jmp common_abort 8247 8248 8249/* ------------------------------ */ 8250 .balign 64 8251.L_OP_UNUSED_8EFF: /* 0x18e */ 8252/* File: x86/OP_UNUSED_8EFF.S */ 8253/* File: x86/unused.S */ 8254 jmp common_abort 8255 8256 8257/* ------------------------------ */ 8258 .balign 64 8259.L_OP_UNUSED_8FFF: /* 0x18f */ 8260/* File: x86/OP_UNUSED_8FFF.S */ 8261/* File: x86/unused.S */ 8262 jmp common_abort 8263 8264 8265/* ------------------------------ */ 8266 .balign 64 8267.L_OP_UNUSED_90FF: /* 0x190 */ 8268/* File: x86/OP_UNUSED_90FF.S */ 8269/* File: x86/unused.S */ 8270 jmp common_abort 8271 8272 8273/* ------------------------------ */ 8274 .balign 64 8275.L_OP_UNUSED_91FF: /* 0x191 */ 8276/* File: x86/OP_UNUSED_91FF.S */ 8277/* File: x86/unused.S */ 8278 jmp common_abort 8279 8280 8281/* ------------------------------ */ 8282 .balign 64 8283.L_OP_UNUSED_92FF: /* 0x192 */ 8284/* File: x86/OP_UNUSED_92FF.S */ 8285/* File: x86/unused.S */ 8286 jmp common_abort 8287 8288 8289/* ------------------------------ */ 8290 .balign 64 8291.L_OP_UNUSED_93FF: /* 0x193 */ 8292/* File: x86/OP_UNUSED_93FF.S */ 8293/* File: x86/unused.S */ 8294 jmp common_abort 8295 8296 8297/* ------------------------------ */ 8298 .balign 64 8299.L_OP_UNUSED_94FF: /* 0x194 */ 8300/* File: x86/OP_UNUSED_94FF.S */ 8301/* File: x86/unused.S */ 8302 jmp common_abort 8303 8304 8305/* ------------------------------ */ 8306 .balign 64 8307.L_OP_UNUSED_95FF: /* 0x195 */ 8308/* File: x86/OP_UNUSED_95FF.S */ 8309/* File: x86/unused.S */ 8310 jmp common_abort 8311 8312 8313/* ------------------------------ */ 8314 .balign 64 8315.L_OP_UNUSED_96FF: /* 0x196 */ 8316/* File: x86/OP_UNUSED_96FF.S */ 8317/* File: x86/unused.S */ 8318 jmp common_abort 8319 8320 8321/* ------------------------------ */ 8322 .balign 64 8323.L_OP_UNUSED_97FF: /* 0x197 */ 8324/* File: x86/OP_UNUSED_97FF.S */ 8325/* File: x86/unused.S */ 8326 jmp common_abort 8327 8328 8329/* ------------------------------ */ 8330 .balign 64 8331.L_OP_UNUSED_98FF: /* 0x198 */ 8332/* File: x86/OP_UNUSED_98FF.S */ 8333/* File: x86/unused.S */ 8334 jmp common_abort 8335 8336 8337/* ------------------------------ */ 8338 .balign 64 8339.L_OP_UNUSED_99FF: /* 0x199 */ 8340/* File: x86/OP_UNUSED_99FF.S */ 8341/* File: x86/unused.S */ 8342 jmp common_abort 8343 8344 8345/* ------------------------------ */ 8346 .balign 64 8347.L_OP_UNUSED_9AFF: /* 0x19a */ 8348/* File: x86/OP_UNUSED_9AFF.S */ 8349/* File: x86/unused.S */ 8350 jmp common_abort 8351 8352 8353/* ------------------------------ */ 8354 .balign 64 8355.L_OP_UNUSED_9BFF: /* 0x19b */ 8356/* File: x86/OP_UNUSED_9BFF.S */ 8357/* File: x86/unused.S */ 8358 jmp common_abort 8359 8360 8361/* ------------------------------ */ 8362 .balign 64 8363.L_OP_UNUSED_9CFF: /* 0x19c */ 8364/* File: x86/OP_UNUSED_9CFF.S */ 8365/* File: x86/unused.S */ 8366 jmp common_abort 8367 8368 8369/* ------------------------------ */ 8370 .balign 64 8371.L_OP_UNUSED_9DFF: /* 0x19d */ 8372/* File: x86/OP_UNUSED_9DFF.S */ 8373/* File: x86/unused.S */ 8374 jmp common_abort 8375 8376 8377/* ------------------------------ */ 8378 .balign 64 8379.L_OP_UNUSED_9EFF: /* 0x19e */ 8380/* File: x86/OP_UNUSED_9EFF.S */ 8381/* File: x86/unused.S */ 8382 jmp common_abort 8383 8384 8385/* ------------------------------ */ 8386 .balign 64 8387.L_OP_UNUSED_9FFF: /* 0x19f */ 8388/* File: x86/OP_UNUSED_9FFF.S */ 8389/* File: x86/unused.S */ 8390 jmp common_abort 8391 8392 8393/* ------------------------------ */ 8394 .balign 64 8395.L_OP_UNUSED_A0FF: /* 0x1a0 */ 8396/* File: x86/OP_UNUSED_A0FF.S */ 8397/* File: x86/unused.S */ 8398 jmp common_abort 8399 8400 8401/* ------------------------------ */ 8402 .balign 64 8403.L_OP_UNUSED_A1FF: /* 0x1a1 */ 8404/* File: x86/OP_UNUSED_A1FF.S */ 8405/* File: x86/unused.S */ 8406 jmp common_abort 8407 8408 8409/* ------------------------------ */ 8410 .balign 64 8411.L_OP_UNUSED_A2FF: /* 0x1a2 */ 8412/* File: x86/OP_UNUSED_A2FF.S */ 8413/* File: x86/unused.S */ 8414 jmp common_abort 8415 8416 8417/* ------------------------------ */ 8418 .balign 64 8419.L_OP_UNUSED_A3FF: /* 0x1a3 */ 8420/* File: x86/OP_UNUSED_A3FF.S */ 8421/* File: x86/unused.S */ 8422 jmp common_abort 8423 8424 8425/* ------------------------------ */ 8426 .balign 64 8427.L_OP_UNUSED_A4FF: /* 0x1a4 */ 8428/* File: x86/OP_UNUSED_A4FF.S */ 8429/* File: x86/unused.S */ 8430 jmp common_abort 8431 8432 8433/* ------------------------------ */ 8434 .balign 64 8435.L_OP_UNUSED_A5FF: /* 0x1a5 */ 8436/* File: x86/OP_UNUSED_A5FF.S */ 8437/* File: x86/unused.S */ 8438 jmp common_abort 8439 8440 8441/* ------------------------------ */ 8442 .balign 64 8443.L_OP_UNUSED_A6FF: /* 0x1a6 */ 8444/* File: x86/OP_UNUSED_A6FF.S */ 8445/* File: x86/unused.S */ 8446 jmp common_abort 8447 8448 8449/* ------------------------------ */ 8450 .balign 64 8451.L_OP_UNUSED_A7FF: /* 0x1a7 */ 8452/* File: x86/OP_UNUSED_A7FF.S */ 8453/* File: x86/unused.S */ 8454 jmp common_abort 8455 8456 8457/* ------------------------------ */ 8458 .balign 64 8459.L_OP_UNUSED_A8FF: /* 0x1a8 */ 8460/* File: x86/OP_UNUSED_A8FF.S */ 8461/* File: x86/unused.S */ 8462 jmp common_abort 8463 8464 8465/* ------------------------------ */ 8466 .balign 64 8467.L_OP_UNUSED_A9FF: /* 0x1a9 */ 8468/* File: x86/OP_UNUSED_A9FF.S */ 8469/* File: x86/unused.S */ 8470 jmp common_abort 8471 8472 8473/* ------------------------------ */ 8474 .balign 64 8475.L_OP_UNUSED_AAFF: /* 0x1aa */ 8476/* File: x86/OP_UNUSED_AAFF.S */ 8477/* File: x86/unused.S */ 8478 jmp common_abort 8479 8480 8481/* ------------------------------ */ 8482 .balign 64 8483.L_OP_UNUSED_ABFF: /* 0x1ab */ 8484/* File: x86/OP_UNUSED_ABFF.S */ 8485/* File: x86/unused.S */ 8486 jmp common_abort 8487 8488 8489/* ------------------------------ */ 8490 .balign 64 8491.L_OP_UNUSED_ACFF: /* 0x1ac */ 8492/* File: x86/OP_UNUSED_ACFF.S */ 8493/* File: x86/unused.S */ 8494 jmp common_abort 8495 8496 8497/* ------------------------------ */ 8498 .balign 64 8499.L_OP_UNUSED_ADFF: /* 0x1ad */ 8500/* File: x86/OP_UNUSED_ADFF.S */ 8501/* File: x86/unused.S */ 8502 jmp common_abort 8503 8504 8505/* ------------------------------ */ 8506 .balign 64 8507.L_OP_UNUSED_AEFF: /* 0x1ae */ 8508/* File: x86/OP_UNUSED_AEFF.S */ 8509/* File: x86/unused.S */ 8510 jmp common_abort 8511 8512 8513/* ------------------------------ */ 8514 .balign 64 8515.L_OP_UNUSED_AFFF: /* 0x1af */ 8516/* File: x86/OP_UNUSED_AFFF.S */ 8517/* File: x86/unused.S */ 8518 jmp common_abort 8519 8520 8521/* ------------------------------ */ 8522 .balign 64 8523.L_OP_UNUSED_B0FF: /* 0x1b0 */ 8524/* File: x86/OP_UNUSED_B0FF.S */ 8525/* File: x86/unused.S */ 8526 jmp common_abort 8527 8528 8529/* ------------------------------ */ 8530 .balign 64 8531.L_OP_UNUSED_B1FF: /* 0x1b1 */ 8532/* File: x86/OP_UNUSED_B1FF.S */ 8533/* File: x86/unused.S */ 8534 jmp common_abort 8535 8536 8537/* ------------------------------ */ 8538 .balign 64 8539.L_OP_UNUSED_B2FF: /* 0x1b2 */ 8540/* File: x86/OP_UNUSED_B2FF.S */ 8541/* File: x86/unused.S */ 8542 jmp common_abort 8543 8544 8545/* ------------------------------ */ 8546 .balign 64 8547.L_OP_UNUSED_B3FF: /* 0x1b3 */ 8548/* File: x86/OP_UNUSED_B3FF.S */ 8549/* File: x86/unused.S */ 8550 jmp common_abort 8551 8552 8553/* ------------------------------ */ 8554 .balign 64 8555.L_OP_UNUSED_B4FF: /* 0x1b4 */ 8556/* File: x86/OP_UNUSED_B4FF.S */ 8557/* File: x86/unused.S */ 8558 jmp common_abort 8559 8560 8561/* ------------------------------ */ 8562 .balign 64 8563.L_OP_UNUSED_B5FF: /* 0x1b5 */ 8564/* File: x86/OP_UNUSED_B5FF.S */ 8565/* File: x86/unused.S */ 8566 jmp common_abort 8567 8568 8569/* ------------------------------ */ 8570 .balign 64 8571.L_OP_UNUSED_B6FF: /* 0x1b6 */ 8572/* File: x86/OP_UNUSED_B6FF.S */ 8573/* File: x86/unused.S */ 8574 jmp common_abort 8575 8576 8577/* ------------------------------ */ 8578 .balign 64 8579.L_OP_UNUSED_B7FF: /* 0x1b7 */ 8580/* File: x86/OP_UNUSED_B7FF.S */ 8581/* File: x86/unused.S */ 8582 jmp common_abort 8583 8584 8585/* ------------------------------ */ 8586 .balign 64 8587.L_OP_UNUSED_B8FF: /* 0x1b8 */ 8588/* File: x86/OP_UNUSED_B8FF.S */ 8589/* File: x86/unused.S */ 8590 jmp common_abort 8591 8592 8593/* ------------------------------ */ 8594 .balign 64 8595.L_OP_UNUSED_B9FF: /* 0x1b9 */ 8596/* File: x86/OP_UNUSED_B9FF.S */ 8597/* File: x86/unused.S */ 8598 jmp common_abort 8599 8600 8601/* ------------------------------ */ 8602 .balign 64 8603.L_OP_UNUSED_BAFF: /* 0x1ba */ 8604/* File: x86/OP_UNUSED_BAFF.S */ 8605/* File: x86/unused.S */ 8606 jmp common_abort 8607 8608 8609/* ------------------------------ */ 8610 .balign 64 8611.L_OP_UNUSED_BBFF: /* 0x1bb */ 8612/* File: x86/OP_UNUSED_BBFF.S */ 8613/* File: x86/unused.S */ 8614 jmp common_abort 8615 8616 8617/* ------------------------------ */ 8618 .balign 64 8619.L_OP_UNUSED_BCFF: /* 0x1bc */ 8620/* File: x86/OP_UNUSED_BCFF.S */ 8621/* File: x86/unused.S */ 8622 jmp common_abort 8623 8624 8625/* ------------------------------ */ 8626 .balign 64 8627.L_OP_UNUSED_BDFF: /* 0x1bd */ 8628/* File: x86/OP_UNUSED_BDFF.S */ 8629/* File: x86/unused.S */ 8630 jmp common_abort 8631 8632 8633/* ------------------------------ */ 8634 .balign 64 8635.L_OP_UNUSED_BEFF: /* 0x1be */ 8636/* File: x86/OP_UNUSED_BEFF.S */ 8637/* File: x86/unused.S */ 8638 jmp common_abort 8639 8640 8641/* ------------------------------ */ 8642 .balign 64 8643.L_OP_UNUSED_BFFF: /* 0x1bf */ 8644/* File: x86/OP_UNUSED_BFFF.S */ 8645/* File: x86/unused.S */ 8646 jmp common_abort 8647 8648 8649/* ------------------------------ */ 8650 .balign 64 8651.L_OP_UNUSED_C0FF: /* 0x1c0 */ 8652/* File: x86/OP_UNUSED_C0FF.S */ 8653/* File: x86/unused.S */ 8654 jmp common_abort 8655 8656 8657/* ------------------------------ */ 8658 .balign 64 8659.L_OP_UNUSED_C1FF: /* 0x1c1 */ 8660/* File: x86/OP_UNUSED_C1FF.S */ 8661/* File: x86/unused.S */ 8662 jmp common_abort 8663 8664 8665/* ------------------------------ */ 8666 .balign 64 8667.L_OP_UNUSED_C2FF: /* 0x1c2 */ 8668/* File: x86/OP_UNUSED_C2FF.S */ 8669/* File: x86/unused.S */ 8670 jmp common_abort 8671 8672 8673/* ------------------------------ */ 8674 .balign 64 8675.L_OP_UNUSED_C3FF: /* 0x1c3 */ 8676/* File: x86/OP_UNUSED_C3FF.S */ 8677/* File: x86/unused.S */ 8678 jmp common_abort 8679 8680 8681/* ------------------------------ */ 8682 .balign 64 8683.L_OP_UNUSED_C4FF: /* 0x1c4 */ 8684/* File: x86/OP_UNUSED_C4FF.S */ 8685/* File: x86/unused.S */ 8686 jmp common_abort 8687 8688 8689/* ------------------------------ */ 8690 .balign 64 8691.L_OP_UNUSED_C5FF: /* 0x1c5 */ 8692/* File: x86/OP_UNUSED_C5FF.S */ 8693/* File: x86/unused.S */ 8694 jmp common_abort 8695 8696 8697/* ------------------------------ */ 8698 .balign 64 8699.L_OP_UNUSED_C6FF: /* 0x1c6 */ 8700/* File: x86/OP_UNUSED_C6FF.S */ 8701/* File: x86/unused.S */ 8702 jmp common_abort 8703 8704 8705/* ------------------------------ */ 8706 .balign 64 8707.L_OP_UNUSED_C7FF: /* 0x1c7 */ 8708/* File: x86/OP_UNUSED_C7FF.S */ 8709/* File: x86/unused.S */ 8710 jmp common_abort 8711 8712 8713/* ------------------------------ */ 8714 .balign 64 8715.L_OP_UNUSED_C8FF: /* 0x1c8 */ 8716/* File: x86/OP_UNUSED_C8FF.S */ 8717/* File: x86/unused.S */ 8718 jmp common_abort 8719 8720 8721/* ------------------------------ */ 8722 .balign 64 8723.L_OP_UNUSED_C9FF: /* 0x1c9 */ 8724/* File: x86/OP_UNUSED_C9FF.S */ 8725/* File: x86/unused.S */ 8726 jmp common_abort 8727 8728 8729/* ------------------------------ */ 8730 .balign 64 8731.L_OP_UNUSED_CAFF: /* 0x1ca */ 8732/* File: x86/OP_UNUSED_CAFF.S */ 8733/* File: x86/unused.S */ 8734 jmp common_abort 8735 8736 8737/* ------------------------------ */ 8738 .balign 64 8739.L_OP_UNUSED_CBFF: /* 0x1cb */ 8740/* File: x86/OP_UNUSED_CBFF.S */ 8741/* File: x86/unused.S */ 8742 jmp common_abort 8743 8744 8745/* ------------------------------ */ 8746 .balign 64 8747.L_OP_UNUSED_CCFF: /* 0x1cc */ 8748/* File: x86/OP_UNUSED_CCFF.S */ 8749/* File: x86/unused.S */ 8750 jmp common_abort 8751 8752 8753/* ------------------------------ */ 8754 .balign 64 8755.L_OP_UNUSED_CDFF: /* 0x1cd */ 8756/* File: x86/OP_UNUSED_CDFF.S */ 8757/* File: x86/unused.S */ 8758 jmp common_abort 8759 8760 8761/* ------------------------------ */ 8762 .balign 64 8763.L_OP_UNUSED_CEFF: /* 0x1ce */ 8764/* File: x86/OP_UNUSED_CEFF.S */ 8765/* File: x86/unused.S */ 8766 jmp common_abort 8767 8768 8769/* ------------------------------ */ 8770 .balign 64 8771.L_OP_UNUSED_CFFF: /* 0x1cf */ 8772/* File: x86/OP_UNUSED_CFFF.S */ 8773/* File: x86/unused.S */ 8774 jmp common_abort 8775 8776 8777/* ------------------------------ */ 8778 .balign 64 8779.L_OP_UNUSED_D0FF: /* 0x1d0 */ 8780/* File: x86/OP_UNUSED_D0FF.S */ 8781/* File: x86/unused.S */ 8782 jmp common_abort 8783 8784 8785/* ------------------------------ */ 8786 .balign 64 8787.L_OP_UNUSED_D1FF: /* 0x1d1 */ 8788/* File: x86/OP_UNUSED_D1FF.S */ 8789/* File: x86/unused.S */ 8790 jmp common_abort 8791 8792 8793/* ------------------------------ */ 8794 .balign 64 8795.L_OP_UNUSED_D2FF: /* 0x1d2 */ 8796/* File: x86/OP_UNUSED_D2FF.S */ 8797/* File: x86/unused.S */ 8798 jmp common_abort 8799 8800 8801/* ------------------------------ */ 8802 .balign 64 8803.L_OP_UNUSED_D3FF: /* 0x1d3 */ 8804/* File: x86/OP_UNUSED_D3FF.S */ 8805/* File: x86/unused.S */ 8806 jmp common_abort 8807 8808 8809/* ------------------------------ */ 8810 .balign 64 8811.L_OP_UNUSED_D4FF: /* 0x1d4 */ 8812/* File: x86/OP_UNUSED_D4FF.S */ 8813/* File: x86/unused.S */ 8814 jmp common_abort 8815 8816 8817/* ------------------------------ */ 8818 .balign 64 8819.L_OP_UNUSED_D5FF: /* 0x1d5 */ 8820/* File: x86/OP_UNUSED_D5FF.S */ 8821/* File: x86/unused.S */ 8822 jmp common_abort 8823 8824 8825/* ------------------------------ */ 8826 .balign 64 8827.L_OP_UNUSED_D6FF: /* 0x1d6 */ 8828/* File: x86/OP_UNUSED_D6FF.S */ 8829/* File: x86/unused.S */ 8830 jmp common_abort 8831 8832 8833/* ------------------------------ */ 8834 .balign 64 8835.L_OP_UNUSED_D7FF: /* 0x1d7 */ 8836/* File: x86/OP_UNUSED_D7FF.S */ 8837/* File: x86/unused.S */ 8838 jmp common_abort 8839 8840 8841/* ------------------------------ */ 8842 .balign 64 8843.L_OP_UNUSED_D8FF: /* 0x1d8 */ 8844/* File: x86/OP_UNUSED_D8FF.S */ 8845/* File: x86/unused.S */ 8846 jmp common_abort 8847 8848 8849/* ------------------------------ */ 8850 .balign 64 8851.L_OP_UNUSED_D9FF: /* 0x1d9 */ 8852/* File: x86/OP_UNUSED_D9FF.S */ 8853/* File: x86/unused.S */ 8854 jmp common_abort 8855 8856 8857/* ------------------------------ */ 8858 .balign 64 8859.L_OP_UNUSED_DAFF: /* 0x1da */ 8860/* File: x86/OP_UNUSED_DAFF.S */ 8861/* File: x86/unused.S */ 8862 jmp common_abort 8863 8864 8865/* ------------------------------ */ 8866 .balign 64 8867.L_OP_UNUSED_DBFF: /* 0x1db */ 8868/* File: x86/OP_UNUSED_DBFF.S */ 8869/* File: x86/unused.S */ 8870 jmp common_abort 8871 8872 8873/* ------------------------------ */ 8874 .balign 64 8875.L_OP_UNUSED_DCFF: /* 0x1dc */ 8876/* File: x86/OP_UNUSED_DCFF.S */ 8877/* File: x86/unused.S */ 8878 jmp common_abort 8879 8880 8881/* ------------------------------ */ 8882 .balign 64 8883.L_OP_UNUSED_DDFF: /* 0x1dd */ 8884/* File: x86/OP_UNUSED_DDFF.S */ 8885/* File: x86/unused.S */ 8886 jmp common_abort 8887 8888 8889/* ------------------------------ */ 8890 .balign 64 8891.L_OP_UNUSED_DEFF: /* 0x1de */ 8892/* File: x86/OP_UNUSED_DEFF.S */ 8893/* File: x86/unused.S */ 8894 jmp common_abort 8895 8896 8897/* ------------------------------ */ 8898 .balign 64 8899.L_OP_UNUSED_DFFF: /* 0x1df */ 8900/* File: x86/OP_UNUSED_DFFF.S */ 8901/* File: x86/unused.S */ 8902 jmp common_abort 8903 8904 8905/* ------------------------------ */ 8906 .balign 64 8907.L_OP_UNUSED_E0FF: /* 0x1e0 */ 8908/* File: x86/OP_UNUSED_E0FF.S */ 8909/* File: x86/unused.S */ 8910 jmp common_abort 8911 8912 8913/* ------------------------------ */ 8914 .balign 64 8915.L_OP_UNUSED_E1FF: /* 0x1e1 */ 8916/* File: x86/OP_UNUSED_E1FF.S */ 8917/* File: x86/unused.S */ 8918 jmp common_abort 8919 8920 8921/* ------------------------------ */ 8922 .balign 64 8923.L_OP_UNUSED_E2FF: /* 0x1e2 */ 8924/* File: x86/OP_UNUSED_E2FF.S */ 8925/* File: x86/unused.S */ 8926 jmp common_abort 8927 8928 8929/* ------------------------------ */ 8930 .balign 64 8931.L_OP_UNUSED_E3FF: /* 0x1e3 */ 8932/* File: x86/OP_UNUSED_E3FF.S */ 8933/* File: x86/unused.S */ 8934 jmp common_abort 8935 8936 8937/* ------------------------------ */ 8938 .balign 64 8939.L_OP_UNUSED_E4FF: /* 0x1e4 */ 8940/* File: x86/OP_UNUSED_E4FF.S */ 8941/* File: x86/unused.S */ 8942 jmp common_abort 8943 8944 8945/* ------------------------------ */ 8946 .balign 64 8947.L_OP_UNUSED_E5FF: /* 0x1e5 */ 8948/* File: x86/OP_UNUSED_E5FF.S */ 8949/* File: x86/unused.S */ 8950 jmp common_abort 8951 8952 8953/* ------------------------------ */ 8954 .balign 64 8955.L_OP_UNUSED_E6FF: /* 0x1e6 */ 8956/* File: x86/OP_UNUSED_E6FF.S */ 8957/* File: x86/unused.S */ 8958 jmp common_abort 8959 8960 8961/* ------------------------------ */ 8962 .balign 64 8963.L_OP_UNUSED_E7FF: /* 0x1e7 */ 8964/* File: x86/OP_UNUSED_E7FF.S */ 8965/* File: x86/unused.S */ 8966 jmp common_abort 8967 8968 8969/* ------------------------------ */ 8970 .balign 64 8971.L_OP_UNUSED_E8FF: /* 0x1e8 */ 8972/* File: x86/OP_UNUSED_E8FF.S */ 8973/* File: x86/unused.S */ 8974 jmp common_abort 8975 8976 8977/* ------------------------------ */ 8978 .balign 64 8979.L_OP_UNUSED_E9FF: /* 0x1e9 */ 8980/* File: x86/OP_UNUSED_E9FF.S */ 8981/* File: x86/unused.S */ 8982 jmp common_abort 8983 8984 8985/* ------------------------------ */ 8986 .balign 64 8987.L_OP_UNUSED_EAFF: /* 0x1ea */ 8988/* File: x86/OP_UNUSED_EAFF.S */ 8989/* File: x86/unused.S */ 8990 jmp common_abort 8991 8992 8993/* ------------------------------ */ 8994 .balign 64 8995.L_OP_UNUSED_EBFF: /* 0x1eb */ 8996/* File: x86/OP_UNUSED_EBFF.S */ 8997/* File: x86/unused.S */ 8998 jmp common_abort 8999 9000 9001/* ------------------------------ */ 9002 .balign 64 9003.L_OP_UNUSED_ECFF: /* 0x1ec */ 9004/* File: x86/OP_UNUSED_ECFF.S */ 9005/* File: x86/unused.S */ 9006 jmp common_abort 9007 9008 9009/* ------------------------------ */ 9010 .balign 64 9011.L_OP_UNUSED_EDFF: /* 0x1ed */ 9012/* File: x86/OP_UNUSED_EDFF.S */ 9013/* File: x86/unused.S */ 9014 jmp common_abort 9015 9016 9017/* ------------------------------ */ 9018 .balign 64 9019.L_OP_UNUSED_EEFF: /* 0x1ee */ 9020/* File: x86/OP_UNUSED_EEFF.S */ 9021/* File: x86/unused.S */ 9022 jmp common_abort 9023 9024 9025/* ------------------------------ */ 9026 .balign 64 9027.L_OP_UNUSED_EFFF: /* 0x1ef */ 9028/* File: x86/OP_UNUSED_EFFF.S */ 9029/* File: x86/unused.S */ 9030 jmp common_abort 9031 9032 9033/* ------------------------------ */ 9034 .balign 64 9035.L_OP_UNUSED_F0FF: /* 0x1f0 */ 9036/* File: x86/OP_UNUSED_F0FF.S */ 9037/* File: x86/unused.S */ 9038 jmp common_abort 9039 9040 9041/* ------------------------------ */ 9042 .balign 64 9043.L_OP_UNUSED_F1FF: /* 0x1f1 */ 9044/* File: x86/OP_UNUSED_F1FF.S */ 9045/* File: x86/unused.S */ 9046 jmp common_abort 9047 9048 9049/* ------------------------------ */ 9050 .balign 64 9051.L_OP_UNUSED_F2FF: /* 0x1f2 */ 9052/* File: x86/OP_UNUSED_F2FF.S */ 9053/* File: x86/unused.S */ 9054 jmp common_abort 9055 9056 9057/* ------------------------------ */ 9058 .balign 64 9059.L_OP_UNUSED_F3FF: /* 0x1f3 */ 9060/* File: x86/OP_UNUSED_F3FF.S */ 9061/* File: x86/unused.S */ 9062 jmp common_abort 9063 9064 9065/* ------------------------------ */ 9066 .balign 64 9067.L_OP_UNUSED_F4FF: /* 0x1f4 */ 9068/* File: x86/OP_UNUSED_F4FF.S */ 9069/* File: x86/unused.S */ 9070 jmp common_abort 9071 9072 9073/* ------------------------------ */ 9074 .balign 64 9075.L_OP_UNUSED_F5FF: /* 0x1f5 */ 9076/* File: x86/OP_UNUSED_F5FF.S */ 9077/* File: x86/unused.S */ 9078 jmp common_abort 9079 9080 9081/* ------------------------------ */ 9082 .balign 64 9083.L_OP_UNUSED_F6FF: /* 0x1f6 */ 9084/* File: x86/OP_UNUSED_F6FF.S */ 9085/* File: x86/unused.S */ 9086 jmp common_abort 9087 9088 9089/* ------------------------------ */ 9090 .balign 64 9091.L_OP_UNUSED_F7FF: /* 0x1f7 */ 9092/* File: x86/OP_UNUSED_F7FF.S */ 9093/* File: x86/unused.S */ 9094 jmp common_abort 9095 9096 9097/* ------------------------------ */ 9098 .balign 64 9099.L_OP_UNUSED_F8FF: /* 0x1f8 */ 9100/* File: x86/OP_UNUSED_F8FF.S */ 9101/* File: x86/unused.S */ 9102 jmp common_abort 9103 9104 9105/* ------------------------------ */ 9106 .balign 64 9107.L_OP_UNUSED_F9FF: /* 0x1f9 */ 9108/* File: x86/OP_UNUSED_F9FF.S */ 9109/* File: x86/unused.S */ 9110 jmp common_abort 9111 9112 9113/* ------------------------------ */ 9114 .balign 64 9115.L_OP_UNUSED_FAFF: /* 0x1fa */ 9116/* File: x86/OP_UNUSED_FAFF.S */ 9117/* File: x86/unused.S */ 9118 jmp common_abort 9119 9120 9121/* ------------------------------ */ 9122 .balign 64 9123.L_OP_UNUSED_FBFF: /* 0x1fb */ 9124/* File: x86/OP_UNUSED_FBFF.S */ 9125/* File: x86/unused.S */ 9126 jmp common_abort 9127 9128 9129/* ------------------------------ */ 9130 .balign 64 9131.L_OP_UNUSED_FCFF: /* 0x1fc */ 9132/* File: x86/OP_UNUSED_FCFF.S */ 9133/* File: x86/unused.S */ 9134 jmp common_abort 9135 9136 9137/* ------------------------------ */ 9138 .balign 64 9139.L_OP_UNUSED_FDFF: /* 0x1fd */ 9140/* File: x86/OP_UNUSED_FDFF.S */ 9141/* File: x86/unused.S */ 9142 jmp common_abort 9143 9144 9145/* ------------------------------ */ 9146 .balign 64 9147.L_OP_UNUSED_FEFF: /* 0x1fe */ 9148/* File: x86/OP_UNUSED_FEFF.S */ 9149/* File: x86/unused.S */ 9150 jmp common_abort 9151 9152 9153/* ------------------------------ */ 9154 .balign 64 9155.L_OP_THROW_VERIFICATION_ERROR_JUMBO: /* 0x1ff */ 9156/* File: x86/OP_THROW_VERIFICATION_ERROR_JUMBO.S */ 9157 /* 9158 * Handle a jumbo throw-verification-error instruction. This throws an 9159 * exception for an error discovered during verification. The 9160 * exception is indicated by BBBB, with some detail provided by AAAAAAAA. 9161 */ 9162 /* exop BBBB, ref@AAAAAAAA */ 9163 movl rSELF,%ecx 9164 movl 2(rPC),%eax # eax<- AAAAAAAA 9165 movl offThread_method(%ecx),%ecx # ecx<- self->method 9166 EXPORT_PC 9167 movl %eax,OUT_ARG2(%esp) # arg2<- AAAAAAAA 9168 movl rINST,OUT_ARG1(%esp) # arg1<- BBBB 9169 movl %ecx,OUT_ARG0(%esp) # arg0<- method 9170 call dvmThrowVerificationError # call(method, kind, ref) 9171 jmp common_exceptionThrown # handle exception 9172 9173 9174 .balign 64 9175 .size .L_OP_NOP, .-.L_OP_NOP 9176 .global dvmAsmInstructionEnd 9177dvmAsmInstructionEnd: 9178 9179/* 9180 * =========================================================================== 9181 * Sister implementations 9182 * =========================================================================== 9183 */ 9184 .global dvmAsmSisterStart 9185 .type dvmAsmSisterStart, %function 9186 .text 9187 .balign 4 9188dvmAsmSisterStart: 9189 9190/* continuation for OP_CONST_STRING */ 9191 9192/* This is the less common path, so we'll redo some work 9193 here rather than force spills on the common path */ 9194.LOP_CONST_STRING_resolve: 9195 movl rSELF,%eax 9196 movl %ecx,rINST # rINST<- AA 9197 EXPORT_PC 9198 movl offThread_method(%eax),%eax # eax<- self->method 9199 movzwl 2(rPC),%ecx # ecx<- BBBB 9200 movl offMethod_clazz(%eax),%eax 9201 movl %ecx,OUT_ARG1(%esp) 9202 movl %eax,OUT_ARG0(%esp) 9203 call dvmResolveString # go resolve 9204 testl %eax,%eax # failed? 9205 je common_exceptionThrown 9206 SET_VREG %eax rINST 9207 FETCH_INST_OPCODE 2 %edx 9208 ADVANCE_PC 2 9209 GOTO_NEXT_R %edx 9210 9211/* continuation for OP_CONST_STRING_JUMBO */ 9212 9213/* This is the less common path, so we'll redo some work 9214 here rather than force spills on the common path */ 9215.LOP_CONST_STRING_JUMBO_resolve: 9216 movl rSELF,%eax 9217 movl %ecx,rINST # rINST<- AA 9218 EXPORT_PC 9219 movl offThread_method(%eax),%eax # eax<- self->method 9220 movl 2(rPC),%ecx # ecx<- BBBBBBBB 9221 movl offMethod_clazz(%eax),%eax 9222 movl %ecx,OUT_ARG1(%esp) 9223 movl %eax,OUT_ARG0(%esp) 9224 call dvmResolveString # go resolve 9225 testl %eax,%eax # failed? 9226 je common_exceptionThrown 9227 SET_VREG %eax rINST 9228 FETCH_INST_OPCODE 3 %edx 9229 ADVANCE_PC 3 9230 GOTO_NEXT_R %edx 9231 9232/* continuation for OP_CONST_CLASS */ 9233 9234/* This is the less common path, so we'll redo some work 9235 here rather than force spills on the common path */ 9236.LOP_CONST_CLASS_resolve: 9237 movl rSELF,%eax 9238 movl %ecx,rINST # rINST<- AA 9239 EXPORT_PC 9240 movl offThread_method(%eax),%eax # eax<- self->method 9241 movl $1,OUT_ARG2(%esp) # true 9242 movzwl 2(rPC),%ecx # ecx<- BBBB 9243 movl offMethod_clazz(%eax),%eax 9244 movl %ecx,OUT_ARG1(%esp) 9245 movl %eax,OUT_ARG0(%esp) 9246 call dvmResolveClass # go resolve 9247 testl %eax,%eax # failed? 9248 je common_exceptionThrown 9249 SET_VREG %eax rINST 9250 FETCH_INST_OPCODE 2 %edx 9251 ADVANCE_PC 2 9252 GOTO_NEXT_R %edx 9253 9254/* continuation for OP_MONITOR_ENTER */ 9255 9256.LOP_MONITOR_ENTER_continue: 9257 movl %ecx,OUT_ARG0(%esp) 9258 movl %eax,OUT_ARG1(%esp) 9259 call dvmLockObject # dvmLockObject(self,object) 9260 ADVANCE_PC 1 9261 GOTO_NEXT 9262 9263/* continuation for OP_MONITOR_EXIT */ 9264 9265.LOP_MONITOR_EXIT_continue: 9266 call dvmUnlockObject # unlock(self,obj) 9267 FETCH_INST_OPCODE 1 %edx 9268 testl %eax,%eax # success? 9269 ADVANCE_PC 1 9270 je common_exceptionThrown # no, exception pending 9271 GOTO_NEXT_R %edx 9272.LOP_MONITOR_EXIT_errNullObject: 9273 ADVANCE_PC 1 # advance before throw 9274 jmp common_errNullObject 9275 9276/* continuation for OP_CHECK_CAST */ 9277 9278 /* 9279 * Trivial test failed, need to perform full check. This is common. 9280 * ecx holds obj->clazz 9281 * eax holds class resolved from BBBB 9282 * rINST holds object 9283 */ 9284.LOP_CHECK_CAST_fullcheck: 9285 movl %eax,sReg0 # we'll need the desired class on failure 9286 movl %eax,OUT_ARG1(%esp) 9287 movl %ecx,OUT_ARG0(%esp) 9288 call dvmInstanceofNonTrivial # eax<- boolean result 9289 testl %eax,%eax # failed? 9290 jne .LOP_CHECK_CAST_okay # no, success 9291 9292 # A cast has failed. We need to throw a ClassCastException. 9293 EXPORT_PC 9294 movl offObject_clazz(rINST),%eax 9295 movl %eax,OUT_ARG0(%esp) # arg0<- obj->clazz 9296 movl sReg0,%ecx 9297 movl %ecx,OUT_ARG1(%esp) # arg1<- desired class 9298 call dvmThrowClassCastException 9299 jmp common_exceptionThrown 9300 9301 /* 9302 * Resolution required. This is the least-likely path, and we're 9303 * going to have to recreate some data. 9304 * 9305 * rINST holds object 9306 */ 9307.LOP_CHECK_CAST_resolve: 9308 movl rSELF,%ecx 9309 EXPORT_PC 9310 movzwl 2(rPC),%eax # eax<- BBBB 9311 movl offThread_method(%ecx),%ecx # ecx<- self->method 9312 movl %eax,OUT_ARG1(%esp) # arg1<- BBBB 9313 movl offMethod_clazz(%ecx),%ecx # ecx<- metho->clazz 9314 movl $0,OUT_ARG2(%esp) # arg2<- false 9315 movl %ecx,OUT_ARG0(%esp) # arg0<- method->clazz 9316 call dvmResolveClass # eax<- resolved ClassObject ptr 9317 testl %eax,%eax # got null? 9318 je common_exceptionThrown # yes, handle exception 9319 movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz 9320 jmp .LOP_CHECK_CAST_resolved # pick up where we left off 9321 9322/* continuation for OP_INSTANCE_OF */ 9323 9324 /* 9325 * Trivial test failed, need to perform full check. This is common. 9326 * eax holds obj->clazz 9327 * ecx holds class resolved from BBBB 9328 * rINST has BA 9329 */ 9330.LOP_INSTANCE_OF_fullcheck: 9331 movl %eax,OUT_ARG0(%esp) 9332 movl %ecx,OUT_ARG1(%esp) 9333 call dvmInstanceofNonTrivial # eax<- boolean result 9334 # fall through to OP_INSTANCE_OF_store 9335 9336 /* 9337 * eax holds boolean result 9338 * rINST holds BA 9339 */ 9340.LOP_INSTANCE_OF_store: 9341 FETCH_INST_OPCODE 2 %edx 9342 andb $0xf,rINSTbl # <- A 9343 ADVANCE_PC 2 9344 SET_VREG %eax rINST # vA<- eax 9345 GOTO_NEXT_R %edx 9346 9347 /* 9348 * Trivial test succeeded, save and bail. 9349 * r9 holds A 9350 */ 9351.LOP_INSTANCE_OF_trivial: 9352 FETCH_INST_OPCODE 2 %edx 9353 andb $0xf,rINSTbl # <- A 9354 ADVANCE_PC 2 9355 movl $1,%eax 9356 SET_VREG %eax rINST # vA<- true 9357 GOTO_NEXT_R %edx 9358 9359 /* 9360 * Resolution required. This is the least-likely path. 9361 * 9362 * edx holds BBBB 9363 * rINST holds BA 9364 */ 9365.LOP_INSTANCE_OF_resolve: 9366 movl %edx,OUT_ARG1(%esp) # arg1<- BBBB 9367 movl rSELF,%ecx 9368 movl offThread_method(%ecx),%ecx 9369 movl $1,OUT_ARG2(%esp) # arg2<- true 9370 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 9371 EXPORT_PC 9372 movl %ecx,OUT_ARG0(%esp) # arg0<- method->clazz 9373 call dvmResolveClass # eax<- resolved ClassObject ptr 9374 testl %eax,%eax # success? 9375 je common_exceptionThrown # no, handle exception 9376/* Now, we need to sync up with fast path. We need eax to 9377 * hold the obj->clazz, and ecx to hold the resolved class 9378 */ 9379 movl %eax,%ecx # ecx<- resolved class 9380 movl rINST,%eax # eax<- BA 9381 sarl $4,%eax # eax<- B 9382 GET_VREG_R %eax %eax # eax<- vB (obj) 9383 movl offObject_clazz(%eax),%eax # eax<- obj->clazz 9384 jmp .LOP_INSTANCE_OF_resolved 9385 9386/* continuation for OP_NEW_INSTANCE */ 9387 9388.LOP_NEW_INSTANCE_initialized: # on entry, ecx<- class 9389 /* TODO: remove test for interface/abstract, now done in verifier */ 9390 testl $(ACC_INTERFACE|ACC_ABSTRACT),offClassObject_accessFlags(%ecx) 9391 movl $ALLOC_DONT_TRACK,OUT_ARG1(%esp) 9392 jne .LOP_NEW_INSTANCE_abstract 9393.LOP_NEW_INSTANCE_finish: # ecx=class 9394 movl %ecx,OUT_ARG0(%esp) 9395 call dvmAllocObject # eax<- new object 9396 FETCH_INST_OPCODE 2 %edx 9397 testl %eax,%eax # success? 9398 je common_exceptionThrown # no, bail out 9399 SET_VREG %eax rINST 9400 ADVANCE_PC 2 9401 GOTO_NEXT_R %edx 9402 9403 /* 9404 * Class initialization required. 9405 * 9406 * ecx holds class object 9407 */ 9408.LOP_NEW_INSTANCE_needinit: 9409 SPILL_TMP1(%ecx) # save object 9410 movl %ecx,OUT_ARG0(%esp) 9411 call dvmInitClass # initialize class 9412 UNSPILL_TMP1(%ecx) # restore object 9413 testl %eax,%eax # success? 9414 jne .LOP_NEW_INSTANCE_initialized # success, continue 9415 jmp common_exceptionThrown # go deal with init exception 9416 9417 /* 9418 * Resolution required. This is the least-likely path. 9419 * 9420 */ 9421.LOP_NEW_INSTANCE_resolve: 9422 movl rSELF,%ecx 9423 movzwl 2(rPC),%eax 9424 movl offThread_method(%ecx),%ecx # ecx<- self->method 9425 movl %eax,OUT_ARG1(%esp) 9426 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 9427 movl $0,OUT_ARG2(%esp) 9428 movl %ecx,OUT_ARG0(%esp) 9429 call dvmResolveClass # call(clazz,off,flags) 9430 movl %eax,%ecx # ecx<- resolved ClassObject ptr 9431 testl %ecx,%ecx # success? 9432 jne .LOP_NEW_INSTANCE_resolved # good to go 9433 jmp common_exceptionThrown # no, handle exception 9434 9435 /* 9436 * TODO: remove this 9437 * We can't instantiate an abstract class or interface, so throw an 9438 * InstantiationError with the class descriptor as the message. 9439 * 9440 * ecx holds class object 9441 */ 9442.LOP_NEW_INSTANCE_abstract: 9443 movl offClassObject_descriptor(%ecx),%eax 9444 movl $.LstrInstantiationError,OUT_ARG0(%esp) 9445 movl %eax,OUT_ARG1(%esp) 9446 call dvmThrowExceptionWithClassMessage 9447 jmp common_exceptionThrown 9448 9449/* continuation for OP_NEW_ARRAY */ 9450 9451 /* 9452 * Resolve class. (This is an uncommon case.) 9453 * ecx holds class (null here) 9454 * eax holds array length (vB) 9455 */ 9456.LOP_NEW_ARRAY_resolve: 9457 movl rSELF,%ecx 9458 SPILL_TMP1(%eax) # save array length 9459 movl offThread_method(%ecx),%ecx # ecx<- self->method 9460 movzwl 2(rPC),%eax # eax<- CCCC 9461 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 9462 movl %eax,OUT_ARG1(%esp) 9463 movl $0,OUT_ARG2(%esp) 9464 movl %ecx,OUT_ARG0(%esp) 9465 call dvmResolveClass # eax<- call(clazz,ref,flag) 9466 movl %eax,%ecx 9467 UNSPILL_TMP1(%eax) 9468 testl %ecx,%ecx # successful resolution? 9469 je common_exceptionThrown # no, bail. 9470# fall through to OP_NEW_ARRAY_finish 9471 9472 /* 9473 * Finish allocation 9474 * 9475 * ecx holds class 9476 * eax holds array length (vB) 9477 */ 9478.LOP_NEW_ARRAY_finish: 9479 movl %ecx,OUT_ARG0(%esp) 9480 movl %eax,OUT_ARG1(%esp) 9481 movl $ALLOC_DONT_TRACK,OUT_ARG2(%esp) 9482 call dvmAllocArrayByClass # eax<- call(clazz,length,flags) 9483 FETCH_INST_OPCODE 2 %edx 9484 testl %eax,%eax # failed? 9485 je common_exceptionThrown # yup - go handle 9486 SET_VREG %eax rINST 9487 ADVANCE_PC 2 9488 GOTO_NEXT_R %edx 9489 9490/* continuation for OP_FILLED_NEW_ARRAY */ 9491 9492.LOP_FILLED_NEW_ARRAY_more: 9493 movl offMethod_clazz(%eax),%eax # eax<- method->clazz 9494 movl %eax,OUT_ARG0(%esp) # arg0<- clazz 9495 call dvmResolveClass # eax<- call(clazz,ref,flag) 9496 testl %eax,%eax # null? 9497 je common_exceptionThrown # yes, handle it 9498 9499 # note: fall through to .LOP_FILLED_NEW_ARRAY_continue 9500 9501 /* 9502 * On entry: 9503 * eax holds array class [r0] 9504 * rINST holds AA or BB [r10] 9505 * ecx is scratch 9506 */ 9507.LOP_FILLED_NEW_ARRAY_continue: 9508 movl offClassObject_descriptor(%eax),%ecx # ecx<- arrayClass->descriptor 9509 movl $ALLOC_DONT_TRACK,OUT_ARG2(%esp) # arg2<- flags 9510 movzbl 1(%ecx),%ecx # ecx<- descriptor[1] 9511 movl %eax,OUT_ARG0(%esp) # arg0<- arrayClass 9512 movl rSELF,%eax 9513 cmpb $'I',%cl # supported? 9514 je 1f 9515 cmpb $'L',%cl 9516 je 1f 9517 cmpb $'[',%cl 9518 jne .LOP_FILLED_NEW_ARRAY_notimpl # no, not handled yet 95191: 9520 movl %ecx,offThread_retval+4(%eax) # save type 9521 .if (!0) 9522 SPILL_TMP1(rINST) # save copy, need "B" later 9523 sarl $4,rINST 9524 .endif 9525 movl rINST,OUT_ARG1(%esp) # arg1<- A or AA (length) 9526 call dvmAllocArrayByClass # eax<- call(arrayClass, length, flags) 9527 movl rSELF,%ecx 9528 testl %eax,%eax # alloc successful? 9529 je common_exceptionThrown # no, handle exception 9530 movl %eax,offThread_retval(%ecx) # retval.l<- new array 9531 movzwl 4(rPC),%ecx # ecx<- FEDC or CCCC 9532 leal offArrayObject_contents(%eax),%eax # eax<- newArray->contents 9533 9534/* at this point: 9535 * eax is pointer to tgt 9536 * rINST is length 9537 * ecx is FEDC or CCCC 9538 * TMP_SPILL1 is BA 9539 * We now need to copy values from registers into the array 9540 */ 9541 9542 .if 0 9543 # set up src pointer 9544 SPILL_TMP2(%esi) 9545 SPILL_TMP3(%edi) 9546 leal (rFP,%ecx,4),%esi # set up src ptr 9547 movl %eax,%edi # set up dst ptr 9548 movl rINST,%ecx # load count register 9549 rep 9550 movsd 9551 UNSPILL_TMP2(%esi) 9552 UNSPILL_TMP3(%edi) 9553 movl rSELF,%ecx 9554 movl offThread_retval+4(%ecx),%eax # eax<- type 9555 FETCH_INST_OPCODE 3 %edx 9556 .else 9557 testl rINST,rINST 9558 je 4f 9559 UNSPILL_TMP1(%edx) # restore "BA" 9560 andl $0x0f,%edx # edx<- 0000000A 9561 sall $16,%edx # edx<- 000A0000 9562 orl %ecx,%edx # edx<- 000AFEDC 95633: 9564 movl $0xf,%ecx 9565 andl %edx,%ecx # ecx<- next reg to load 9566 GET_VREG_R %ecx %ecx 9567 shrl $4,%edx 9568 leal 4(%eax),%eax 9569 movl %ecx,-4(%eax) 9570 sub $1,rINST 9571 jne 3b 95724: 9573 movl rSELF,%ecx 9574 movl offThread_retval+4(%ecx),%eax # eax<- type 9575 FETCH_INST_OPCODE 3 %edx 9576 .endif 9577 9578 cmpb $'I',%al # Int array? 9579 je 5f # skip card mark if so 9580 movl offThread_retval(%ecx),%eax # eax<- object head 9581 movl offThread_cardTable(%ecx),%ecx # card table base 9582 shrl $GC_CARD_SHIFT,%eax # convert to card num 9583 movb %cl,(%ecx,%eax) # mark card based on object head 95845: 9585 ADVANCE_PC 3 9586 GOTO_NEXT_R %edx 9587 9588 9589 /* 9590 * Throw an exception indicating that we have not implemented this 9591 * mode of filled-new-array. 9592 */ 9593.LOP_FILLED_NEW_ARRAY_notimpl: 9594 movl $.LstrInternalErrorA,%eax 9595 movl %eax,OUT_ARG0(%esp) 9596 movl $.LstrFilledNewArrayNotImplA,%eax 9597 movl %eax,OUT_ARG1(%esp) 9598 call dvmThrowException 9599 jmp common_exceptionThrown 9600 9601/* continuation for OP_FILLED_NEW_ARRAY_RANGE */ 9602 9603.LOP_FILLED_NEW_ARRAY_RANGE_more: 9604 movl offMethod_clazz(%eax),%eax # eax<- method->clazz 9605 movl %eax,OUT_ARG0(%esp) # arg0<- clazz 9606 call dvmResolveClass # eax<- call(clazz,ref,flag) 9607 testl %eax,%eax # null? 9608 je common_exceptionThrown # yes, handle it 9609 9610 # note: fall through to .LOP_FILLED_NEW_ARRAY_RANGE_continue 9611 9612 /* 9613 * On entry: 9614 * eax holds array class [r0] 9615 * rINST holds AA or BB [r10] 9616 * ecx is scratch 9617 */ 9618.LOP_FILLED_NEW_ARRAY_RANGE_continue: 9619 movl offClassObject_descriptor(%eax),%ecx # ecx<- arrayClass->descriptor 9620 movl $ALLOC_DONT_TRACK,OUT_ARG2(%esp) # arg2<- flags 9621 movzbl 1(%ecx),%ecx # ecx<- descriptor[1] 9622 movl %eax,OUT_ARG0(%esp) # arg0<- arrayClass 9623 movl rSELF,%eax 9624 cmpb $'I',%cl # supported? 9625 je 1f 9626 cmpb $'L',%cl 9627 je 1f 9628 cmpb $'[',%cl 9629 jne .LOP_FILLED_NEW_ARRAY_RANGE_notimpl # no, not handled yet 96301: 9631 movl %ecx,offThread_retval+4(%eax) # save type 9632 .if (!1) 9633 SPILL_TMP1(rINST) # save copy, need "B" later 9634 sarl $4,rINST 9635 .endif 9636 movl rINST,OUT_ARG1(%esp) # arg1<- A or AA (length) 9637 call dvmAllocArrayByClass # eax<- call(arrayClass, length, flags) 9638 movl rSELF,%ecx 9639 testl %eax,%eax # alloc successful? 9640 je common_exceptionThrown # no, handle exception 9641 movl %eax,offThread_retval(%ecx) # retval.l<- new array 9642 movzwl 4(rPC),%ecx # ecx<- FEDC or CCCC 9643 leal offArrayObject_contents(%eax),%eax # eax<- newArray->contents 9644 9645/* at this point: 9646 * eax is pointer to tgt 9647 * rINST is length 9648 * ecx is FEDC or CCCC 9649 * TMP_SPILL1 is BA 9650 * We now need to copy values from registers into the array 9651 */ 9652 9653 .if 1 9654 # set up src pointer 9655 SPILL_TMP2(%esi) 9656 SPILL_TMP3(%edi) 9657 leal (rFP,%ecx,4),%esi # set up src ptr 9658 movl %eax,%edi # set up dst ptr 9659 movl rINST,%ecx # load count register 9660 rep 9661 movsd 9662 UNSPILL_TMP2(%esi) 9663 UNSPILL_TMP3(%edi) 9664 movl rSELF,%ecx 9665 movl offThread_retval+4(%ecx),%eax # eax<- type 9666 FETCH_INST_OPCODE 3 %edx 9667 .else 9668 testl rINST,rINST 9669 je 4f 9670 UNSPILL_TMP1(%edx) # restore "BA" 9671 andl $0x0f,%edx # edx<- 0000000A 9672 sall $16,%edx # edx<- 000A0000 9673 orl %ecx,%edx # edx<- 000AFEDC 96743: 9675 movl $0xf,%ecx 9676 andl %edx,%ecx # ecx<- next reg to load 9677 GET_VREG_R %ecx %ecx 9678 shrl $4,%edx 9679 leal 4(%eax),%eax 9680 movl %ecx,-4(%eax) 9681 sub $1,rINST 9682 jne 3b 96834: 9684 movl rSELF,%ecx 9685 movl offThread_retval+4(%ecx),%eax # eax<- type 9686 FETCH_INST_OPCODE 3 %edx 9687 .endif 9688 9689 cmpb $'I',%al # Int array? 9690 je 5f # skip card mark if so 9691 movl offThread_retval(%ecx),%eax # eax<- object head 9692 movl offThread_cardTable(%ecx),%ecx # card table base 9693 shrl $GC_CARD_SHIFT,%eax # convert to card num 9694 movb %cl,(%ecx,%eax) # mark card based on object head 96955: 9696 ADVANCE_PC 3 9697 GOTO_NEXT_R %edx 9698 9699 9700 /* 9701 * Throw an exception indicating that we have not implemented this 9702 * mode of filled-new-array. 9703 */ 9704.LOP_FILLED_NEW_ARRAY_RANGE_notimpl: 9705 movl $.LstrInternalErrorA,%eax 9706 movl %eax,OUT_ARG0(%esp) 9707 movl $.LstrFilledNewArrayNotImplA,%eax 9708 movl %eax,OUT_ARG1(%esp) 9709 call dvmThrowException 9710 jmp common_exceptionThrown 9711 9712/* continuation for OP_CMPL_FLOAT */ 9713 9714.LOP_CMPL_FLOAT_isNaN: 9715 movl $-1,%ecx 9716 jmp .LOP_CMPL_FLOAT_finish 9717 9718/* continuation for OP_CMPG_FLOAT */ 9719 9720.LOP_CMPG_FLOAT_isNaN: 9721 movl $1,%ecx 9722 jmp .LOP_CMPG_FLOAT_finish 9723 9724/* continuation for OP_CMPL_DOUBLE */ 9725 9726.LOP_CMPL_DOUBLE_isNaN: 9727 movl $-1,%ecx 9728 jmp .LOP_CMPL_DOUBLE_finish 9729 9730/* continuation for OP_CMPG_DOUBLE */ 9731 9732.LOP_CMPG_DOUBLE_isNaN: 9733 movl $1,%ecx 9734 jmp .LOP_CMPG_DOUBLE_finish 9735 9736/* continuation for OP_CMP_LONG */ 9737 9738.LOP_CMP_LONG_bigger: 9739 movl $1,%ecx 9740 jmp .LOP_CMP_LONG_finish 9741.LOP_CMP_LONG_smaller: 9742 movl $-1,%ecx 9743.LOP_CMP_LONG_finish: 9744 SET_VREG %ecx rINST 9745 FETCH_INST_OPCODE 2 %edx 9746 ADVANCE_PC 2 9747 GOTO_NEXT_R %edx 9748 9749/* continuation for OP_AGET_WIDE */ 9750 9751.LOP_AGET_WIDE_finish: 9752 leal offArrayObject_contents(%eax,%ecx,8),%eax 9753 movl (%eax),%ecx 9754 movl 4(%eax),%eax 9755 SET_VREG_WORD %ecx rINST 0 9756 SET_VREG_WORD %eax rINST 1 9757 FETCH_INST_OPCODE 2 %edx 9758 ADVANCE_PC 2 9759 GOTO_NEXT_R %edx 9760 9761/* continuation for OP_APUT_WIDE */ 9762 9763.LOP_APUT_WIDE_finish: 9764 leal offArrayObject_contents(%eax,%ecx,8),%eax 9765 GET_VREG_WORD %ecx rINST 0 9766 GET_VREG_WORD rINST rINST 1 9767 movl rINST,4(%eax) 9768 FETCH_INST_OPCODE 2 %edx 9769 movl %ecx,(%eax) 9770 ADVANCE_PC 2 9771 GOTO_NEXT_R %edx 9772 9773/* continuation for OP_APUT_OBJECT */ 9774 9775 /* On entry: 9776 * eax<- array object 9777 * ecx<- index 9778 * rINST<- vAA 9779 */ 9780.LOP_APUT_OBJECT_continue: 9781 leal offArrayObject_contents(%eax,%ecx,4),%ecx 9782 testl rINST,rINST # storing null reference? 9783 je .LOP_APUT_OBJECT_skip_check 9784 SPILL_TMP1(%ecx) # save target address 9785 SPILL_TMP2(%eax) # save object head 9786 movl offObject_clazz(%eax),%eax # eax<- arrayObj->clazz 9787 movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz 9788 movl %eax,OUT_ARG1(%esp) 9789 movl %ecx,OUT_ARG0(%esp) 9790 movl %ecx,sReg0 # store the two classes for later 9791 movl %eax,sReg1 9792 call dvmCanPutArrayElement # test object type vs. array type 9793 UNSPILL_TMP1(%ecx) # recover target address 9794 testl %eax,%eax 9795 movl rSELF,%eax 9796 jne .LOP_APUT_OBJECT_types_okay 9797 9798 # The types don't match. We need to throw an ArrayStoreException. 9799 EXPORT_PC 9800 movl sReg0,%eax # restore the two classes... 9801 movl %eax,OUT_ARG0(%esp) 9802 movl sReg1,%ecx 9803 movl %ecx,OUT_ARG1(%esp) 9804 call dvmThrowArrayStoreException # ...and throw 9805 jmp common_exceptionThrown 9806 9807.LOP_APUT_OBJECT_types_okay: 9808 movl offThread_cardTable(%eax),%eax # get card table base 9809 movl rINST,(%ecx) # store into array 9810 UNSPILL_TMP2(%ecx) # recover object head 9811 FETCH_INST_OPCODE 2 %edx 9812 shrl $GC_CARD_SHIFT,%ecx # object head to card number 9813 movb %al,(%eax,%ecx) # mark card using object head 9814 ADVANCE_PC 2 9815 GOTO_NEXT_R %edx 9816 9817.LOP_APUT_OBJECT_skip_check: 9818 movl rINST,(%ecx) 9819 FETCH_INST_OPCODE 2 %edx 9820 ADVANCE_PC 2 9821 GOTO_NEXT_R %edx 9822 9823/* continuation for OP_IGET */ 9824 9825 9826.LOP_IGET_resolve: 9827 EXPORT_PC 9828 movl offThread_method(%edx),%edx # edx<- current method 9829 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 9830 SPILL_TMP1(%ecx) # save obj pointer across call 9831 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 9832 call dvmResolveInstField # ... to dvmResolveInstField 9833 UNSPILL_TMP1(%ecx) 9834 testl %eax,%eax # returns InstrField ptr 9835 jne .LOP_IGET_finish 9836 jmp common_exceptionThrown 9837 9838.LOP_IGET_finish: 9839 /* 9840 * Currently: 9841 * eax holds resolved field 9842 * ecx holds object 9843 * rINST holds A 9844 */ 9845 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 9846 testl %ecx,%ecx # object null? 9847 je common_errNullObject # object was null 9848 movl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 9849 movl rINST,%eax # eax<- A 9850 FETCH_INST_OPCODE 2 %edx 9851 SET_VREG %ecx %eax 9852 ADVANCE_PC 2 9853 GOTO_NEXT_R %edx 9854 9855/* continuation for OP_IGET_WIDE */ 9856 9857 9858.LOP_IGET_WIDE_resolve: 9859 EXPORT_PC 9860 movl offThread_method(%edx),%edx # edx<- current method 9861 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 9862 SPILL_TMP1(%ecx) # save objpointer across call 9863 movl rPC,OUT_ARG0(%esp) # pass in method->clazz 9864 call dvmResolveInstField # ... to dvmResolveInstField 9865 UNSPILL_TMP1(%ecx) 9866 testl %eax,%eax # returns InstrField ptr 9867 jne .LOP_IGET_WIDE_finish 9868 jmp common_exceptionThrown 9869 9870.LOP_IGET_WIDE_finish: 9871 /* 9872 * Currently: 9873 * eax holds resolved field 9874 * ecx holds object 9875 * rINST holds A 9876 */ 9877 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 9878 testl %ecx,%ecx # object null? 9879 je common_errNullObject # object was null 9880 leal (%ecx,%eax,1),%eax # eax<- address of field 9881 movl (%eax),%ecx # ecx<- lsw 9882 movl 4(%eax),%eax # eax<- msw 9883 FETCH_INST_OPCODE 2 %edx 9884 SET_VREG_WORD %ecx rINST 0 9885 SET_VREG_WORD %eax rINST 1 9886 ADVANCE_PC 2 9887 GOTO_NEXT_R %edx 9888 9889/* continuation for OP_IGET_OBJECT */ 9890 9891 9892.LOP_IGET_OBJECT_resolve: 9893 EXPORT_PC 9894 movl offThread_method(%edx),%edx # edx<- current method 9895 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 9896 SPILL_TMP1(%ecx) # save obj pointer across call 9897 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 9898 call dvmResolveInstField # ... to dvmResolveInstField 9899 UNSPILL_TMP1(%ecx) 9900 testl %eax,%eax # returns InstrField ptr 9901 jne .LOP_IGET_OBJECT_finish 9902 jmp common_exceptionThrown 9903 9904.LOP_IGET_OBJECT_finish: 9905 /* 9906 * Currently: 9907 * eax holds resolved field 9908 * ecx holds object 9909 * rINST holds A 9910 */ 9911 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 9912 testl %ecx,%ecx # object null? 9913 je common_errNullObject # object was null 9914 movl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 9915 movl rINST,%eax # eax<- A 9916 FETCH_INST_OPCODE 2 %edx 9917 SET_VREG %ecx %eax 9918 ADVANCE_PC 2 9919 GOTO_NEXT_R %edx 9920 9921/* continuation for OP_IGET_BOOLEAN */ 9922 9923 9924.LOP_IGET_BOOLEAN_resolve: 9925 EXPORT_PC 9926 movl offThread_method(%edx),%edx # edx<- current method 9927 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 9928 SPILL_TMP1(%ecx) # save obj pointer across call 9929 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 9930 call dvmResolveInstField # ... to dvmResolveInstField 9931 UNSPILL_TMP1(%ecx) 9932 testl %eax,%eax # returns InstrField ptr 9933 jne .LOP_IGET_BOOLEAN_finish 9934 jmp common_exceptionThrown 9935 9936.LOP_IGET_BOOLEAN_finish: 9937 /* 9938 * Currently: 9939 * eax holds resolved field 9940 * ecx holds object 9941 * rINST holds A 9942 */ 9943 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 9944 testl %ecx,%ecx # object null? 9945 je common_errNullObject # object was null 9946 movzbl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 9947 movl rINST,%eax # eax<- A 9948 FETCH_INST_OPCODE 2 %edx 9949 SET_VREG %ecx %eax 9950 ADVANCE_PC 2 9951 GOTO_NEXT_R %edx 9952 9953/* continuation for OP_IGET_BYTE */ 9954 9955 9956.LOP_IGET_BYTE_resolve: 9957 EXPORT_PC 9958 movl offThread_method(%edx),%edx # edx<- current method 9959 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 9960 SPILL_TMP1(%ecx) # save obj pointer across call 9961 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 9962 call dvmResolveInstField # ... to dvmResolveInstField 9963 UNSPILL_TMP1(%ecx) 9964 testl %eax,%eax # returns InstrField ptr 9965 jne .LOP_IGET_BYTE_finish 9966 jmp common_exceptionThrown 9967 9968.LOP_IGET_BYTE_finish: 9969 /* 9970 * Currently: 9971 * eax holds resolved field 9972 * ecx holds object 9973 * rINST holds A 9974 */ 9975 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 9976 testl %ecx,%ecx # object null? 9977 je common_errNullObject # object was null 9978 movsbl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 9979 movl rINST,%eax # eax<- A 9980 FETCH_INST_OPCODE 2 %edx 9981 SET_VREG %ecx %eax 9982 ADVANCE_PC 2 9983 GOTO_NEXT_R %edx 9984 9985/* continuation for OP_IGET_CHAR */ 9986 9987 9988.LOP_IGET_CHAR_resolve: 9989 EXPORT_PC 9990 movl offThread_method(%edx),%edx # edx<- current method 9991 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 9992 SPILL_TMP1(%ecx) # save obj pointer across call 9993 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 9994 call dvmResolveInstField # ... to dvmResolveInstField 9995 UNSPILL_TMP1(%ecx) 9996 testl %eax,%eax # returns InstrField ptr 9997 jne .LOP_IGET_CHAR_finish 9998 jmp common_exceptionThrown 9999 10000.LOP_IGET_CHAR_finish: 10001 /* 10002 * Currently: 10003 * eax holds resolved field 10004 * ecx holds object 10005 * rINST holds A 10006 */ 10007 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 10008 testl %ecx,%ecx # object null? 10009 je common_errNullObject # object was null 10010 movzwl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 10011 movl rINST,%eax # eax<- A 10012 FETCH_INST_OPCODE 2 %edx 10013 SET_VREG %ecx %eax 10014 ADVANCE_PC 2 10015 GOTO_NEXT_R %edx 10016 10017/* continuation for OP_IGET_SHORT */ 10018 10019 10020.LOP_IGET_SHORT_resolve: 10021 EXPORT_PC 10022 movl offThread_method(%edx),%edx # edx<- current method 10023 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 10024 SPILL_TMP1(%ecx) # save obj pointer across call 10025 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 10026 call dvmResolveInstField # ... to dvmResolveInstField 10027 UNSPILL_TMP1(%ecx) 10028 testl %eax,%eax # returns InstrField ptr 10029 jne .LOP_IGET_SHORT_finish 10030 jmp common_exceptionThrown 10031 10032.LOP_IGET_SHORT_finish: 10033 /* 10034 * Currently: 10035 * eax holds resolved field 10036 * ecx holds object 10037 * rINST holds A 10038 */ 10039 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 10040 testl %ecx,%ecx # object null? 10041 je common_errNullObject # object was null 10042 movswl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 10043 movl rINST,%eax # eax<- A 10044 FETCH_INST_OPCODE 2 %edx 10045 SET_VREG %ecx %eax 10046 ADVANCE_PC 2 10047 GOTO_NEXT_R %edx 10048 10049/* continuation for OP_IPUT */ 10050 10051 10052.LOP_IPUT_resolve: 10053 EXPORT_PC 10054 movl offThread_method(%edx),%edx # edx<- current method 10055 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 10056 SPILL_TMP1(%ecx) # save obj pointer across call 10057 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 10058 call dvmResolveInstField # ... to dvmResolveInstField 10059 UNSPILL_TMP1(%ecx) 10060 testl %eax,%eax # returns InstrField ptr 10061 jne .LOP_IPUT_finish 10062 jmp common_exceptionThrown 10063 10064.LOP_IPUT_finish: 10065 /* 10066 * Currently: 10067 * eax holds resolved field 10068 * ecx holds object 10069 * rINST holds A 10070 */ 10071 GET_VREG_R rINST rINST # rINST<- v[A] 10072 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 10073 testl %ecx,%ecx # object null? 10074 je common_errNullObject # object was null 10075 FETCH_INST_OPCODE 2 %edx 10076 movl rINST,(%ecx,%eax,1) # obj.field <- v[A](8/16/32 bits) 10077 ADVANCE_PC 2 10078 GOTO_NEXT_R %edx 10079 10080/* continuation for OP_IPUT_WIDE */ 10081 10082 10083.LOP_IPUT_WIDE_resolve: 10084 EXPORT_PC 10085 movl offThread_method(%edx),%edx # edx<- current method 10086 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 10087 SPILL_TMP1(%ecx) # save obj pointer across call 10088 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 10089 call dvmResolveInstField # ... to dvmResolveInstField 10090 UNSPILL_TMP1(%ecx) 10091 testl %eax,%eax # ... which returns InstrField ptr 10092 jne .LOP_IPUT_WIDE_finish 10093 jmp common_exceptionThrown 10094 10095.LOP_IPUT_WIDE_finish: 10096 /* 10097 * Currently: 10098 * eax holds resolved field 10099 * ecx holds object 10100 * %edx is scratch, but needs to be unspilled 10101 * rINST holds A 10102 */ 10103 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 10104 testl %ecx,%ecx # object null? 10105 je common_errNullObject # object was null 10106 leal (%ecx,%eax,1),%eax # eax<- address of field 10107 GET_VREG_WORD %ecx rINST 0 # ecx<- lsw 10108 GET_VREG_WORD rINST rINST 1 # rINST<- msw 10109 FETCH_INST_OPCODE 2 %edx 10110 movl rINST,4(%eax) 10111 movl %ecx,(%eax) 10112 ADVANCE_PC 2 10113 GOTO_NEXT_R %edx 10114 10115/* continuation for OP_IPUT_OBJECT */ 10116 10117 10118.LOP_IPUT_OBJECT_resolve: 10119 EXPORT_PC 10120 movl offThread_method(%edx),%edx # edx<- current method 10121 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 10122 SPILL_TMP1(%ecx) # save obj pointer across call 10123 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 10124 call dvmResolveInstField # ... to dvmResolveInstField 10125 UNSPILL_TMP1(%ecx) 10126 testl %eax,%eax # returns InstrField ptr 10127 jne .LOP_IPUT_OBJECT_finish 10128 jmp common_exceptionThrown 10129 10130.LOP_IPUT_OBJECT_finish: 10131 /* 10132 * Currently: 10133 * eax holds resolved field 10134 * ecx holds object 10135 * %edx is scratch, but needs to be unspilled 10136 * rINST holds A 10137 */ 10138 GET_VREG_R rINST rINST # rINST<- v[A] 10139 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 10140 testl %ecx,%ecx # object null? 10141 je common_errNullObject # object was null 10142 movl rINST,(%ecx,%eax) # obj.field <- v[A](8/16/32 bits) 10143 movl rSELF,%eax 10144 testl rINST,rINST # stored a NULL? 10145 movl offThread_cardTable(%eax),%eax # get card table base 10146 FETCH_INST_OPCODE 2 %edx 10147 je 1f # skip card mark if null store 10148 shrl $GC_CARD_SHIFT,%ecx # object head to card number 10149 movb %al,(%eax,%ecx) # mark card using object head 101501: 10151 ADVANCE_PC 2 10152 GOTO_NEXT_R %edx 10153 10154/* continuation for OP_IPUT_BOOLEAN */ 10155 10156 10157.LOP_IPUT_BOOLEAN_resolve: 10158 EXPORT_PC 10159 movl offThread_method(%edx),%edx # edx<- current method 10160 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 10161 SPILL_TMP1(%ecx) # save obj pointer across call 10162 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 10163 call dvmResolveInstField # ... to dvmResolveInstField 10164 UNSPILL_TMP1(%ecx) 10165 testl %eax,%eax # returns InstrField ptr 10166 jne .LOP_IPUT_BOOLEAN_finish 10167 jmp common_exceptionThrown 10168 10169.LOP_IPUT_BOOLEAN_finish: 10170 /* 10171 * Currently: 10172 * eax holds resolved field 10173 * ecx holds object 10174 * rINST holds A 10175 */ 10176 GET_VREG_R rINST rINST # rINST<- v[A] 10177 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 10178 testl %ecx,%ecx # object null? 10179 je common_errNullObject # object was null 10180 FETCH_INST_OPCODE 2 %edx 10181 movb rINSTbl,(%ecx,%eax,1) # obj.field <- v[A](8/16/32 bits) 10182 ADVANCE_PC 2 10183 GOTO_NEXT_R %edx 10184 10185/* continuation for OP_IPUT_BYTE */ 10186 10187 10188.LOP_IPUT_BYTE_resolve: 10189 EXPORT_PC 10190 movl offThread_method(%edx),%edx # edx<- current method 10191 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 10192 SPILL_TMP1(%ecx) # save obj pointer across call 10193 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 10194 call dvmResolveInstField # ... to dvmResolveInstField 10195 UNSPILL_TMP1(%ecx) 10196 testl %eax,%eax # returns InstrField ptr 10197 jne .LOP_IPUT_BYTE_finish 10198 jmp common_exceptionThrown 10199 10200.LOP_IPUT_BYTE_finish: 10201 /* 10202 * Currently: 10203 * eax holds resolved field 10204 * ecx holds object 10205 * rINST holds A 10206 */ 10207 GET_VREG_R rINST rINST # rINST<- v[A] 10208 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 10209 testl %ecx,%ecx # object null? 10210 je common_errNullObject # object was null 10211 FETCH_INST_OPCODE 2 %edx 10212 movb rINSTbl,(%ecx,%eax,1) # obj.field <- v[A](8/16/32 bits) 10213 ADVANCE_PC 2 10214 GOTO_NEXT_R %edx 10215 10216/* continuation for OP_IPUT_CHAR */ 10217 10218 10219.LOP_IPUT_CHAR_resolve: 10220 EXPORT_PC 10221 movl offThread_method(%edx),%edx # edx<- current method 10222 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 10223 SPILL_TMP1(%ecx) # save obj pointer across call 10224 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 10225 call dvmResolveInstField # ... to dvmResolveInstField 10226 UNSPILL_TMP1(%ecx) 10227 testl %eax,%eax # returns InstrField ptr 10228 jne .LOP_IPUT_CHAR_finish 10229 jmp common_exceptionThrown 10230 10231.LOP_IPUT_CHAR_finish: 10232 /* 10233 * Currently: 10234 * eax holds resolved field 10235 * ecx holds object 10236 * rINST holds A 10237 */ 10238 GET_VREG_R rINST rINST # rINST<- v[A] 10239 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 10240 testl %ecx,%ecx # object null? 10241 je common_errNullObject # object was null 10242 FETCH_INST_OPCODE 2 %edx 10243 movw rINSTw,(%ecx,%eax,1) # obj.field <- v[A](8/16/32 bits) 10244 ADVANCE_PC 2 10245 GOTO_NEXT_R %edx 10246 10247/* continuation for OP_IPUT_SHORT */ 10248 10249 10250.LOP_IPUT_SHORT_resolve: 10251 EXPORT_PC 10252 movl offThread_method(%edx),%edx # edx<- current method 10253 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 10254 SPILL_TMP1(%ecx) # save obj pointer across call 10255 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 10256 call dvmResolveInstField # ... to dvmResolveInstField 10257 UNSPILL_TMP1(%ecx) 10258 testl %eax,%eax # returns InstrField ptr 10259 jne .LOP_IPUT_SHORT_finish 10260 jmp common_exceptionThrown 10261 10262.LOP_IPUT_SHORT_finish: 10263 /* 10264 * Currently: 10265 * eax holds resolved field 10266 * ecx holds object 10267 * rINST holds A 10268 */ 10269 GET_VREG_R rINST rINST # rINST<- v[A] 10270 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 10271 testl %ecx,%ecx # object null? 10272 je common_errNullObject # object was null 10273 FETCH_INST_OPCODE 2 %edx 10274 movw rINSTw,(%ecx,%eax,1) # obj.field <- v[A](8/16/32 bits) 10275 ADVANCE_PC 2 10276 GOTO_NEXT_R %edx 10277 10278/* continuation for OP_SGET */ 10279 10280 /* 10281 * Go resolve the field 10282 */ 10283.LOP_SGET_resolve: 10284 movl rSELF,%ecx 10285 movzwl 2(rPC),%eax # eax<- field ref BBBB 10286 movl offThread_method(%ecx),%ecx # ecx<- current method 10287 EXPORT_PC # could throw, need to export 10288 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10289 movl %eax,OUT_ARG1(%esp) 10290 movl %ecx,OUT_ARG0(%esp) 10291 call dvmResolveStaticField # eax<- resolved StaticField ptr 10292 testl %eax,%eax 10293 jne .LOP_SGET_finish # success, continue 10294 jmp common_exceptionThrown # no, handle exception 10295 10296/* continuation for OP_SGET_WIDE */ 10297 10298 /* 10299 * Go resolve the field 10300 */ 10301.LOP_SGET_WIDE_resolve: 10302 movl rSELF,%ecx 10303 movzwl 2(rPC),%eax # eax<- field ref BBBB 10304 movl offThread_method(%ecx),%ecx # ecx<- current method 10305 EXPORT_PC # could throw, need to export 10306 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10307 movl %eax,OUT_ARG1(%esp) 10308 movl %ecx,OUT_ARG0(%esp) 10309 call dvmResolveStaticField # eax<- resolved StaticField ptr 10310 testl %eax,%eax 10311 jne .LOP_SGET_WIDE_finish # success, continue 10312 jmp common_exceptionThrown # no, handle exception 10313 10314/* continuation for OP_SGET_OBJECT */ 10315 10316 /* 10317 * Go resolve the field 10318 */ 10319.LOP_SGET_OBJECT_resolve: 10320 movl rSELF,%ecx 10321 movzwl 2(rPC),%eax # eax<- field ref BBBB 10322 movl offThread_method(%ecx),%ecx # ecx<- current method 10323 EXPORT_PC # could throw, need to export 10324 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10325 movl %eax,OUT_ARG1(%esp) 10326 movl %ecx,OUT_ARG0(%esp) 10327 call dvmResolveStaticField # eax<- resolved StaticField ptr 10328 testl %eax,%eax 10329 jne .LOP_SGET_OBJECT_finish # success, continue 10330 jmp common_exceptionThrown # no, handle exception 10331 10332/* continuation for OP_SGET_BOOLEAN */ 10333 10334 /* 10335 * Go resolve the field 10336 */ 10337.LOP_SGET_BOOLEAN_resolve: 10338 movl rSELF,%ecx 10339 movzwl 2(rPC),%eax # eax<- field ref BBBB 10340 movl offThread_method(%ecx),%ecx # ecx<- current method 10341 EXPORT_PC # could throw, need to export 10342 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10343 movl %eax,OUT_ARG1(%esp) 10344 movl %ecx,OUT_ARG0(%esp) 10345 call dvmResolveStaticField # eax<- resolved StaticField ptr 10346 testl %eax,%eax 10347 jne .LOP_SGET_BOOLEAN_finish # success, continue 10348 jmp common_exceptionThrown # no, handle exception 10349 10350/* continuation for OP_SGET_BYTE */ 10351 10352 /* 10353 * Go resolve the field 10354 */ 10355.LOP_SGET_BYTE_resolve: 10356 movl rSELF,%ecx 10357 movzwl 2(rPC),%eax # eax<- field ref BBBB 10358 movl offThread_method(%ecx),%ecx # ecx<- current method 10359 EXPORT_PC # could throw, need to export 10360 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10361 movl %eax,OUT_ARG1(%esp) 10362 movl %ecx,OUT_ARG0(%esp) 10363 call dvmResolveStaticField # eax<- resolved StaticField ptr 10364 testl %eax,%eax 10365 jne .LOP_SGET_BYTE_finish # success, continue 10366 jmp common_exceptionThrown # no, handle exception 10367 10368/* continuation for OP_SGET_CHAR */ 10369 10370 /* 10371 * Go resolve the field 10372 */ 10373.LOP_SGET_CHAR_resolve: 10374 movl rSELF,%ecx 10375 movzwl 2(rPC),%eax # eax<- field ref BBBB 10376 movl offThread_method(%ecx),%ecx # ecx<- current method 10377 EXPORT_PC # could throw, need to export 10378 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10379 movl %eax,OUT_ARG1(%esp) 10380 movl %ecx,OUT_ARG0(%esp) 10381 call dvmResolveStaticField # eax<- resolved StaticField ptr 10382 testl %eax,%eax 10383 jne .LOP_SGET_CHAR_finish # success, continue 10384 jmp common_exceptionThrown # no, handle exception 10385 10386/* continuation for OP_SGET_SHORT */ 10387 10388 /* 10389 * Go resolve the field 10390 */ 10391.LOP_SGET_SHORT_resolve: 10392 movl rSELF,%ecx 10393 movzwl 2(rPC),%eax # eax<- field ref BBBB 10394 movl offThread_method(%ecx),%ecx # ecx<- current method 10395 EXPORT_PC # could throw, need to export 10396 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10397 movl %eax,OUT_ARG1(%esp) 10398 movl %ecx,OUT_ARG0(%esp) 10399 call dvmResolveStaticField # eax<- resolved StaticField ptr 10400 testl %eax,%eax 10401 jne .LOP_SGET_SHORT_finish # success, continue 10402 jmp common_exceptionThrown # no, handle exception 10403 10404/* continuation for OP_SPUT */ 10405 10406 /* 10407 * Go resolve the field 10408 */ 10409.LOP_SPUT_resolve: 10410 movl rSELF,%ecx 10411 movzwl 2(rPC),%eax # eax<- field ref BBBB 10412 movl offThread_method(%ecx),%ecx # ecx<- current method 10413 EXPORT_PC # could throw, need to export 10414 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10415 movl %eax,OUT_ARG1(%esp) 10416 movl %ecx,OUT_ARG0(%esp) 10417 call dvmResolveStaticField # eax<- resolved StaticField ptr 10418 testl %eax,%eax 10419 jne .LOP_SPUT_finish # success, continue 10420 jmp common_exceptionThrown # no, handle exception 10421 10422/* continuation for OP_SPUT_WIDE */ 10423 10424 /* 10425 * Go resolve the field 10426 */ 10427.LOP_SPUT_WIDE_resolve: 10428 movl rSELF,%ecx 10429 movzwl 2(rPC),%eax # eax<- field ref BBBB 10430 movl offThread_method(%ecx),%ecx # ecx<- current method 10431 EXPORT_PC # could throw, need to export 10432 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10433 movl %eax,OUT_ARG1(%esp) 10434 movl %ecx,OUT_ARG0(%esp) 10435 call dvmResolveStaticField # eax<- resolved StaticField ptr 10436 testl %eax,%eax 10437 jne .LOP_SPUT_WIDE_finish # success, continue 10438 jmp common_exceptionThrown # no, handle exception 10439 10440/* continuation for OP_SPUT_OBJECT */ 10441 10442 10443.LOP_SPUT_OBJECT_continue: 10444 movl %ecx,offStaticField_value(%eax) # do the store 10445 testl %ecx,%ecx # stored null object ptr? 10446 FETCH_INST_OPCODE 2 %edx 10447 je 1f # skip card mark if null 10448 movl rSELF,%ecx 10449 movl offField_clazz(%eax),%eax # eax<- method->clazz 10450 movl offThread_cardTable(%ecx),%ecx # get card table base 10451 shrl $GC_CARD_SHIFT,%eax # head to card number 10452 movb %cl,(%ecx,%eax) # mark card 104531: 10454 ADVANCE_PC 2 10455 GOTO_NEXT_R %edx 10456 10457.LOP_SPUT_OBJECT_resolve: 10458 movl rSELF,%ecx 10459 movzwl 2(rPC),%eax # eax<- field ref BBBB 10460 movl offThread_method(%ecx),%ecx # ecx<- current method 10461 EXPORT_PC # could throw, need to export 10462 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10463 movl %eax,OUT_ARG1(%esp) 10464 movl %ecx,OUT_ARG0(%esp) 10465 call dvmResolveStaticField # eax<- resolved StaticField ptr 10466 testl %eax,%eax 10467 jne .LOP_SPUT_OBJECT_finish # success, continue 10468 jmp common_exceptionThrown # no, handle exception 10469 10470/* continuation for OP_SPUT_BOOLEAN */ 10471 10472 /* 10473 * Go resolve the field 10474 */ 10475.LOP_SPUT_BOOLEAN_resolve: 10476 movl rSELF,%ecx 10477 movzwl 2(rPC),%eax # eax<- field ref BBBB 10478 movl offThread_method(%ecx),%ecx # ecx<- current method 10479 EXPORT_PC # could throw, need to export 10480 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10481 movl %eax,OUT_ARG1(%esp) 10482 movl %ecx,OUT_ARG0(%esp) 10483 call dvmResolveStaticField # eax<- resolved StaticField ptr 10484 testl %eax,%eax 10485 jne .LOP_SPUT_BOOLEAN_finish # success, continue 10486 jmp common_exceptionThrown # no, handle exception 10487 10488/* continuation for OP_SPUT_BYTE */ 10489 10490 /* 10491 * Go resolve the field 10492 */ 10493.LOP_SPUT_BYTE_resolve: 10494 movl rSELF,%ecx 10495 movzwl 2(rPC),%eax # eax<- field ref BBBB 10496 movl offThread_method(%ecx),%ecx # ecx<- current method 10497 EXPORT_PC # could throw, need to export 10498 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10499 movl %eax,OUT_ARG1(%esp) 10500 movl %ecx,OUT_ARG0(%esp) 10501 call dvmResolveStaticField # eax<- resolved StaticField ptr 10502 testl %eax,%eax 10503 jne .LOP_SPUT_BYTE_finish # success, continue 10504 jmp common_exceptionThrown # no, handle exception 10505 10506/* continuation for OP_SPUT_CHAR */ 10507 10508 /* 10509 * Go resolve the field 10510 */ 10511.LOP_SPUT_CHAR_resolve: 10512 movl rSELF,%ecx 10513 movzwl 2(rPC),%eax # eax<- field ref BBBB 10514 movl offThread_method(%ecx),%ecx # ecx<- current method 10515 EXPORT_PC # could throw, need to export 10516 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10517 movl %eax,OUT_ARG1(%esp) 10518 movl %ecx,OUT_ARG0(%esp) 10519 call dvmResolveStaticField # eax<- resolved StaticField ptr 10520 testl %eax,%eax 10521 jne .LOP_SPUT_CHAR_finish # success, continue 10522 jmp common_exceptionThrown # no, handle exception 10523 10524/* continuation for OP_SPUT_SHORT */ 10525 10526 /* 10527 * Go resolve the field 10528 */ 10529.LOP_SPUT_SHORT_resolve: 10530 movl rSELF,%ecx 10531 movzwl 2(rPC),%eax # eax<- field ref BBBB 10532 movl offThread_method(%ecx),%ecx # ecx<- current method 10533 EXPORT_PC # could throw, need to export 10534 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10535 movl %eax,OUT_ARG1(%esp) 10536 movl %ecx,OUT_ARG0(%esp) 10537 call dvmResolveStaticField # eax<- resolved StaticField ptr 10538 testl %eax,%eax 10539 jne .LOP_SPUT_SHORT_finish # success, continue 10540 jmp common_exceptionThrown # no, handle exception 10541 10542/* continuation for OP_INVOKE_VIRTUAL */ 10543 10544 10545.LOP_INVOKE_VIRTUAL_more: 10546 movl offMethod_clazz(%eax),%eax # ecx<- method->clazz 10547 movl %eax,OUT_ARG0(%esp) # arg0<- clazz 10548 movl $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags 10549 call dvmResolveMethod # eax<- call(clazz, ref, flags) 10550 testl %eax,%eax # got null? 10551 jne .LOP_INVOKE_VIRTUAL_continue # no, continue 10552 jmp common_exceptionThrown # yes, handle exception 10553 10554 /* At this point: 10555 * eax = resolved base method 10556 * ecx = scratch 10557 */ 10558.LOP_INVOKE_VIRTUAL_continue: 10559 movzwl 4(rPC),%ecx # ecx<- GFED or CCCC 10560 .if (!0) 10561 andl $0xf,%ecx # ecx<- D (or stays CCCC) 10562 .endif 10563 GET_VREG_R %ecx %ecx # ecx<- "this" 10564 movzwl offMethod_methodIndex(%eax),%eax # eax<- baseMethod->methodIndex 10565 testl %ecx,%ecx # null this? 10566 je common_errNullObject # go if so 10567 movl offObject_clazz(%ecx),%ecx # ecx<- thisPtr->clazz 10568 movl offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable 10569 movl (%ecx,%eax,4),%eax # eax<- vtable[methodIndex] 10570 jmp common_invokeMethodNoRange 10571 10572/* continuation for OP_INVOKE_SUPER */ 10573 10574 /* 10575 * At this point: 10576 * ecx = resolved base method [r0] 10577 * eax = method->clazz [r9] 10578 */ 10579.LOP_INVOKE_SUPER_continue: 10580 movl offClassObject_super(%eax),%eax # eax<- method->clazz->super 10581 movzwl offMethod_methodIndex(%ecx),%ecx # ecx<- baseMthod->methodIndex 10582 cmpl offClassObject_vtableCount(%eax),%ecx # compare(methodIndex,vtableCount) 10583 jae .LOP_INVOKE_SUPER_nsm # method not present in superclass 10584 movl offClassObject_vtable(%eax),%eax # eax<- ...clazz->super->vtable 10585 movl (%eax,%ecx,4),%eax # eax<- vtable[methodIndex] 10586 jmp common_invokeMethodNoRange 10587 10588 10589 /* At this point: 10590 * ecx = null (needs to be resolved base method) 10591 * eax = method->clazz 10592 */ 10593.LOP_INVOKE_SUPER_resolve: 10594 SPILL_TMP1(%eax) # method->clazz 10595 movl %eax,OUT_ARG0(%esp) # arg0<- method->clazz 10596 movzwl 2(rPC),%ecx # ecx<- BBBB 10597 movl $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- resolver method type 10598 movl %ecx,OUT_ARG1(%esp) # arg1<- ref 10599 call dvmResolveMethod # eax<- call(clazz, ref, flags) 10600 testl %eax,%eax # got null? 10601 movl %eax,%ecx # ecx<- resolved base method 10602 UNSPILL_TMP1(%eax) # restore method->clazz 10603 jne .LOP_INVOKE_SUPER_continue # good to go - continue 10604 jmp common_exceptionThrown # handle exception 10605 10606 /* 10607 * Throw a NoSuchMethodError with the method name as the message. 10608 * ecx = resolved base method 10609 */ 10610.LOP_INVOKE_SUPER_nsm: 10611 movl offMethod_name(%ecx),%eax 10612 mov %eax,OUT_ARG1(%esp) 10613 jmp common_errNoSuchMethod 10614 10615/* continuation for OP_INVOKE_DIRECT */ 10616 10617 /* 10618 * On entry: 10619 * TMP_SPILL <- "this" register 10620 * Things a bit ugly on this path, but it's the less 10621 * frequent one. We'll have to do some reloading. 10622 */ 10623.LOP_INVOKE_DIRECT_resolve: 10624 SPILL_TMP1(%ecx) 10625 movl rSELF,%ecx 10626 movl offThread_method(%ecx),%ecx # ecx<- self->method 10627 movzwl 2(rPC),%eax # reference (BBBB or CCCC) 10628 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10629 movl $METHOD_DIRECT,OUT_ARG2(%esp) 10630 movl %eax,OUT_ARG1(%esp) 10631 movl %ecx,OUT_ARG0(%esp) 10632 call dvmResolveMethod # eax<- call(clazz, ref, flags) 10633 UNSPILL_TMP1(%ecx) 10634 testl %eax,%eax 10635 jne .LOP_INVOKE_DIRECT_finish 10636 jmp common_exceptionThrown 10637 10638/* continuation for OP_INVOKE_STATIC */ 10639 10640.LOP_INVOKE_STATIC_continue: 10641 movl $METHOD_STATIC,%eax 10642 movl %eax,OUT_ARG2(%esp) # arg2<- flags 10643 call dvmResolveMethod # call(clazz,ref,flags) 10644 testl %eax,%eax # got null? 10645 jne common_invokeMethodNoRange 10646 jmp common_exceptionThrown 10647 10648/* continuation for OP_INVOKE_INTERFACE */ 10649 10650.LOP_INVOKE_INTERFACE_continue: 10651 call dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex) 10652 testl %eax,%eax 10653 je common_exceptionThrown 10654 jmp common_invokeMethodNoRange 10655 10656/* continuation for OP_INVOKE_VIRTUAL_RANGE */ 10657 10658 10659.LOP_INVOKE_VIRTUAL_RANGE_more: 10660 movl offMethod_clazz(%eax),%eax # ecx<- method->clazz 10661 movl %eax,OUT_ARG0(%esp) # arg0<- clazz 10662 movl $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags 10663 call dvmResolveMethod # eax<- call(clazz, ref, flags) 10664 testl %eax,%eax # got null? 10665 jne .LOP_INVOKE_VIRTUAL_RANGE_continue # no, continue 10666 jmp common_exceptionThrown # yes, handle exception 10667 10668 /* At this point: 10669 * eax = resolved base method 10670 * ecx = scratch 10671 */ 10672.LOP_INVOKE_VIRTUAL_RANGE_continue: 10673 movzwl 4(rPC),%ecx # ecx<- GFED or CCCC 10674 .if (!1) 10675 andl $0xf,%ecx # ecx<- D (or stays CCCC) 10676 .endif 10677 GET_VREG_R %ecx %ecx # ecx<- "this" 10678 movzwl offMethod_methodIndex(%eax),%eax # eax<- baseMethod->methodIndex 10679 testl %ecx,%ecx # null this? 10680 je common_errNullObject # go if so 10681 movl offObject_clazz(%ecx),%ecx # ecx<- thisPtr->clazz 10682 movl offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable 10683 movl (%ecx,%eax,4),%eax # eax<- vtable[methodIndex] 10684 jmp common_invokeMethodRange 10685 10686/* continuation for OP_INVOKE_SUPER_RANGE */ 10687 10688 /* 10689 * At this point: 10690 * ecx = resolved base method [r0] 10691 * eax = method->clazz [r9] 10692 */ 10693.LOP_INVOKE_SUPER_RANGE_continue: 10694 movl offClassObject_super(%eax),%eax # eax<- method->clazz->super 10695 movzwl offMethod_methodIndex(%ecx),%ecx # ecx<- baseMthod->methodIndex 10696 cmpl offClassObject_vtableCount(%eax),%ecx # compare(methodIndex,vtableCount) 10697 jae .LOP_INVOKE_SUPER_RANGE_nsm # method not present in superclass 10698 movl offClassObject_vtable(%eax),%eax # eax<- ...clazz->super->vtable 10699 movl (%eax,%ecx,4),%eax # eax<- vtable[methodIndex] 10700 jmp common_invokeMethodRange 10701 10702 10703 /* At this point: 10704 * ecx = null (needs to be resolved base method) 10705 * eax = method->clazz 10706 */ 10707.LOP_INVOKE_SUPER_RANGE_resolve: 10708 SPILL_TMP1(%eax) # method->clazz 10709 movl %eax,OUT_ARG0(%esp) # arg0<- method->clazz 10710 movzwl 2(rPC),%ecx # ecx<- BBBB 10711 movl $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- resolver method type 10712 movl %ecx,OUT_ARG1(%esp) # arg1<- ref 10713 call dvmResolveMethod # eax<- call(clazz, ref, flags) 10714 testl %eax,%eax # got null? 10715 movl %eax,%ecx # ecx<- resolved base method 10716 UNSPILL_TMP1(%eax) # restore method->clazz 10717 jne .LOP_INVOKE_SUPER_RANGE_continue # good to go - continue 10718 jmp common_exceptionThrown # handle exception 10719 10720 /* 10721 * Throw a NoSuchMethodError with the method name as the message. 10722 * ecx = resolved base method 10723 */ 10724.LOP_INVOKE_SUPER_RANGE_nsm: 10725 movl offMethod_name(%ecx),%eax 10726 mov %eax,OUT_ARG1(%esp) 10727 jmp common_errNoSuchMethod 10728 10729/* continuation for OP_INVOKE_DIRECT_RANGE */ 10730 10731 /* 10732 * On entry: 10733 * TMP_SPILL <- "this" register 10734 * Things a bit ugly on this path, but it's the less 10735 * frequent one. We'll have to do some reloading. 10736 */ 10737.LOP_INVOKE_DIRECT_RANGE_resolve: 10738 SPILL_TMP1(%ecx) 10739 movl rSELF,%ecx 10740 movl offThread_method(%ecx),%ecx # ecx<- self->method 10741 movzwl 2(rPC),%eax # reference (BBBB or CCCC) 10742 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10743 movl $METHOD_DIRECT,OUT_ARG2(%esp) 10744 movl %eax,OUT_ARG1(%esp) 10745 movl %ecx,OUT_ARG0(%esp) 10746 call dvmResolveMethod # eax<- call(clazz, ref, flags) 10747 UNSPILL_TMP1(%ecx) 10748 testl %eax,%eax 10749 jne .LOP_INVOKE_DIRECT_RANGE_finish 10750 jmp common_exceptionThrown 10751 10752/* continuation for OP_INVOKE_STATIC_RANGE */ 10753 10754.LOP_INVOKE_STATIC_RANGE_continue: 10755 movl $METHOD_STATIC,%eax 10756 movl %eax,OUT_ARG2(%esp) # arg2<- flags 10757 call dvmResolveMethod # call(clazz,ref,flags) 10758 testl %eax,%eax # got null? 10759 jne common_invokeMethodRange 10760 jmp common_exceptionThrown 10761 10762/* continuation for OP_INVOKE_INTERFACE_RANGE */ 10763 10764.LOP_INVOKE_INTERFACE_RANGE_continue: 10765 call dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex) 10766 testl %eax,%eax 10767 je common_exceptionThrown 10768 jmp common_invokeMethodRange 10769 10770/* continuation for OP_FLOAT_TO_INT */ 10771 10772 10773.LOP_FLOAT_TO_INT_continue: 10774 .if 0 10775 movl $0x80000000,%eax 10776 xorl 4(rFP,%ecx,4),%eax 10777 orl (rFP,%ecx,4),%eax 10778 .else 10779 cmpl $0x80000000,(rFP,%ecx,4) 10780 .endif 10781 je .LOP_FLOAT_TO_INT_special_case # fix up result 10782 10783.LOP_FLOAT_TO_INT_finish: 10784 ADVANCE_PC 1 10785 GOTO_NEXT_R %edx 10786 10787.LOP_FLOAT_TO_INT_special_case: 10788 fnstsw %ax 10789 sahf 10790 jp .LOP_FLOAT_TO_INT_isNaN 10791 adcl $-1,(rFP,%ecx,4) 10792 .if 0 10793 adcl $-1,4(rFP,%ecx,4) 10794 .endif 10795 jmp .LOP_FLOAT_TO_INT_finish 10796.LOP_FLOAT_TO_INT_isNaN: 10797 movl $0,(rFP,%ecx,4) 10798 .if 0 10799 movl $0,4(rFP,%ecx,4) 10800 .endif 10801 jmp .LOP_FLOAT_TO_INT_finish 10802 10803/* continuation for OP_FLOAT_TO_LONG */ 10804 10805 10806.LOP_FLOAT_TO_LONG_continue: 10807 .if 1 10808 movl $0x80000000,%eax 10809 xorl 4(rFP,%ecx,4),%eax 10810 orl (rFP,%ecx,4),%eax 10811 .else 10812 cmpl $0x80000000,(rFP,%ecx,4) 10813 .endif 10814 je .LOP_FLOAT_TO_LONG_special_case # fix up result 10815 10816.LOP_FLOAT_TO_LONG_finish: 10817 ADVANCE_PC 1 10818 GOTO_NEXT_R %edx 10819 10820.LOP_FLOAT_TO_LONG_special_case: 10821 fnstsw %ax 10822 sahf 10823 jp .LOP_FLOAT_TO_LONG_isNaN 10824 adcl $-1,(rFP,%ecx,4) 10825 .if 1 10826 adcl $-1,4(rFP,%ecx,4) 10827 .endif 10828 jmp .LOP_FLOAT_TO_LONG_finish 10829.LOP_FLOAT_TO_LONG_isNaN: 10830 movl $0,(rFP,%ecx,4) 10831 .if 1 10832 movl $0,4(rFP,%ecx,4) 10833 .endif 10834 jmp .LOP_FLOAT_TO_LONG_finish 10835 10836/* continuation for OP_DOUBLE_TO_INT */ 10837 10838 10839.LOP_DOUBLE_TO_INT_continue: 10840 .if 0 10841 movl $0x80000000,%eax 10842 xorl 4(rFP,%ecx,4),%eax 10843 orl (rFP,%ecx,4),%eax 10844 .else 10845 cmpl $0x80000000,(rFP,%ecx,4) 10846 .endif 10847 je .LOP_DOUBLE_TO_INT_special_case # fix up result 10848 10849.LOP_DOUBLE_TO_INT_finish: 10850 ADVANCE_PC 1 10851 GOTO_NEXT_R %edx 10852 10853.LOP_DOUBLE_TO_INT_special_case: 10854 fnstsw %ax 10855 sahf 10856 jp .LOP_DOUBLE_TO_INT_isNaN 10857 adcl $-1,(rFP,%ecx,4) 10858 .if 0 10859 adcl $-1,4(rFP,%ecx,4) 10860 .endif 10861 jmp .LOP_DOUBLE_TO_INT_finish 10862.LOP_DOUBLE_TO_INT_isNaN: 10863 movl $0,(rFP,%ecx,4) 10864 .if 0 10865 movl $0,4(rFP,%ecx,4) 10866 .endif 10867 jmp .LOP_DOUBLE_TO_INT_finish 10868 10869/* continuation for OP_DOUBLE_TO_LONG */ 10870 10871 10872.LOP_DOUBLE_TO_LONG_continue: 10873 .if 1 10874 movl $0x80000000,%eax 10875 xorl 4(rFP,%ecx,4),%eax 10876 orl (rFP,%ecx,4),%eax 10877 .else 10878 cmpl $0x80000000,(rFP,%ecx,4) 10879 .endif 10880 je .LOP_DOUBLE_TO_LONG_special_case # fix up result 10881 10882.LOP_DOUBLE_TO_LONG_finish: 10883 ADVANCE_PC 1 10884 GOTO_NEXT_R %edx 10885 10886.LOP_DOUBLE_TO_LONG_special_case: 10887 fnstsw %ax 10888 sahf 10889 jp .LOP_DOUBLE_TO_LONG_isNaN 10890 adcl $-1,(rFP,%ecx,4) 10891 .if 1 10892 adcl $-1,4(rFP,%ecx,4) 10893 .endif 10894 jmp .LOP_DOUBLE_TO_LONG_finish 10895.LOP_DOUBLE_TO_LONG_isNaN: 10896 movl $0,(rFP,%ecx,4) 10897 .if 1 10898 movl $0,4(rFP,%ecx,4) 10899 .endif 10900 jmp .LOP_DOUBLE_TO_LONG_finish 10901 10902/* continuation for OP_DIV_INT */ 10903.LOP_DIV_INT_continue_div: 10904 cltd 10905 idivl %ecx 10906.LOP_DIV_INT_finish_div: 10907 SET_VREG %eax rINST 10908 FETCH_INST_OPCODE 2 %edx 10909 ADVANCE_PC 2 10910 GOTO_NEXT_R %edx 10911 10912/* continuation for OP_REM_INT */ 10913.LOP_REM_INT_continue_div: 10914 cltd 10915 idivl %ecx 10916.LOP_REM_INT_finish_div: 10917 SET_VREG %edx rINST 10918 FETCH_INST_OPCODE 2 %edx 10919 ADVANCE_PC 2 10920 GOTO_NEXT_R %edx 10921 10922/* continuation for OP_MUL_LONG */ 10923 10924.LOP_MUL_LONG_continue: 10925 leal (%ecx,%edx),%edx # full result now in %edx:%eax 10926 UNSPILL_TMP2(%esi) # Restore Dalvik PC 10927 FETCH_INST_OPCODE 2 %ecx # Fetch next instruction 10928 movl %edx,4(rFP,rINST,4) # v[B+1]<- %edx 10929 movl %eax,(rFP,rINST,4) # v[B]<- %eax 10930 ADVANCE_PC 2 10931 GOTO_NEXT_R %ecx 10932 10933/* continuation for OP_DIV_LONG */ 10934 10935.LOP_DIV_LONG_continue: 10936 call __divdi3 10937.LOP_DIV_LONG_finish: 10938 SET_VREG_WORD %edx rINST 1 10939 SET_VREG_WORD %eax rINST 0 10940 FETCH_INST_OPCODE 2 %edx 10941 ADVANCE_PC 2 10942 GOTO_NEXT_R %edx 10943 10944.LOP_DIV_LONG_check_zero: 10945 testl %edx,%edx 10946 jne .LOP_DIV_LONG_notSpecial 10947 jmp common_errDivideByZero 10948.LOP_DIV_LONG_check_neg1: 10949 testl %edx,%eax 10950 jne .LOP_DIV_LONG_notSpecial 10951 GET_VREG_WORD %edx %ecx 0 10952 GET_VREG_WORD %ecx %ecx 1 10953 testl %edx,%edx 10954 jne .LOP_DIV_LONG_notSpecial1 10955 cmpl $0x80000000,%ecx 10956 jne .LOP_DIV_LONG_notSpecial1 10957 /* minint / -1, return minint on div, 0 on rem */ 10958 xorl %eax,%eax 10959 movl $0x80000000,%edx 10960 jmp .LOP_DIV_LONG_finish 10961 10962/* continuation for OP_REM_LONG */ 10963 10964.LOP_REM_LONG_continue: 10965 call __moddi3 10966.LOP_REM_LONG_finish: 10967 SET_VREG_WORD %edx rINST 1 10968 SET_VREG_WORD %eax rINST 0 10969 FETCH_INST_OPCODE 2 %edx 10970 ADVANCE_PC 2 10971 GOTO_NEXT_R %edx 10972 10973.LOP_REM_LONG_check_zero: 10974 testl %edx,%edx 10975 jne .LOP_REM_LONG_notSpecial 10976 jmp common_errDivideByZero 10977.LOP_REM_LONG_check_neg1: 10978 testl %edx,%eax 10979 jne .LOP_REM_LONG_notSpecial 10980 GET_VREG_WORD %edx %ecx 0 10981 GET_VREG_WORD %ecx %ecx 1 10982 testl %edx,%edx 10983 jne .LOP_REM_LONG_notSpecial1 10984 cmpl $0x80000000,%ecx 10985 jne .LOP_REM_LONG_notSpecial1 10986 /* minint / -1, return minint on div, 0 on rem */ 10987 xorl %eax,%eax 10988 movl $0,%edx 10989 jmp .LOP_REM_LONG_finish 10990 10991/* continuation for OP_SHL_LONG */ 10992 10993.LOP_SHL_LONG_finish: 10994 SET_VREG_WORD %eax rINST 0 # v[AA+0]<- %eax 10995 ADVANCE_PC 2 10996 GOTO_NEXT_R %edx 10997 10998/* continuation for OP_SHR_LONG */ 10999 11000 11001.LOP_SHR_LONG_finish: 11002 SET_VREG_WORD %eax rINST 0 # v[AA+0]<- eax 11003 ADVANCE_PC 2 11004 GOTO_NEXT_R %edx 11005 11006/* continuation for OP_USHR_LONG */ 11007 11008 11009.LOP_USHR_LONG_finish: 11010 SET_VREG_WORD %eax rINST 0 # v[BB+0]<- eax 11011 ADVANCE_PC 2 11012 GOTO_NEXT_R %edx 11013 11014/* continuation for OP_DIV_INT_2ADDR */ 11015.LOP_DIV_INT_2ADDR_continue_div2addr: 11016 cltd 11017 idivl %ecx 11018.LOP_DIV_INT_2ADDR_finish_div2addr: 11019 SET_VREG %eax rINST 11020 FETCH_INST_OPCODE 1 %edx 11021 ADVANCE_PC 1 11022 GOTO_NEXT_R %edx 11023 11024/* continuation for OP_REM_INT_2ADDR */ 11025.LOP_REM_INT_2ADDR_continue_div2addr: 11026 cltd 11027 idivl %ecx 11028.LOP_REM_INT_2ADDR_finish_div2addr: 11029 SET_VREG %edx rINST 11030 FETCH_INST_OPCODE 1 %edx 11031 ADVANCE_PC 1 11032 GOTO_NEXT_R %edx 11033 11034/* continuation for OP_MUL_LONG_2ADDR */ 11035 11036.LOP_MUL_LONG_2ADDR_continue: 11037 leal (%ecx,%edx),%edx # full result now in %edx:%eax 11038 movl %edx,4(%esi) # v[A+1]<- %edx 11039 movl %eax,(%esi) # v[A]<- %eax 11040 UNSPILL_TMP2(%esi) 11041 FETCH_INST_OPCODE 1 %ecx 11042 UNSPILL(rFP) 11043 ADVANCE_PC 1 11044 GOTO_NEXT_R %ecx 11045 11046/* continuation for OP_DIV_LONG_2ADDR */ 11047 11048.LOP_DIV_LONG_2ADDR_continue: 11049 movl %eax,OUT_ARG3(%esp) 11050 movl %edx,OUT_ARG0(%esp) 11051 movl %ecx,OUT_ARG1(%esp) 11052 call __divdi3 11053.LOP_DIV_LONG_2ADDR_finish: 11054 SET_VREG_WORD %edx rINST 1 11055 SET_VREG_WORD %eax rINST 0 11056 FETCH_INST_OPCODE 1 %edx 11057 ADVANCE_PC 1 11058 GOTO_NEXT_R %edx 11059 11060.LOP_DIV_LONG_2ADDR_check_zero: 11061 testl %edx,%edx 11062 jne .LOP_DIV_LONG_2ADDR_notSpecial 11063 jmp common_errDivideByZero 11064.LOP_DIV_LONG_2ADDR_check_neg1: 11065 testl %edx,%eax 11066 jne .LOP_DIV_LONG_2ADDR_notSpecial 11067 GET_VREG_WORD %edx rINST 0 11068 GET_VREG_WORD %ecx rINST 1 11069 testl %edx,%edx 11070 jne .LOP_DIV_LONG_2ADDR_notSpecial1 11071 cmpl $0x80000000,%ecx 11072 jne .LOP_DIV_LONG_2ADDR_notSpecial1 11073 /* minint / -1, return minint on div, 0 on rem */ 11074 xorl %eax,%eax 11075 movl $0x80000000,%edx 11076 jmp .LOP_DIV_LONG_2ADDR_finish 11077 11078/* continuation for OP_REM_LONG_2ADDR */ 11079 11080.LOP_REM_LONG_2ADDR_continue: 11081 movl %eax,OUT_ARG3(%esp) 11082 movl %edx,OUT_ARG0(%esp) 11083 movl %ecx,OUT_ARG1(%esp) 11084 call __moddi3 11085.LOP_REM_LONG_2ADDR_finish: 11086 SET_VREG_WORD %edx rINST 1 11087 SET_VREG_WORD %eax rINST 0 11088 FETCH_INST_OPCODE 1 %edx 11089 ADVANCE_PC 1 11090 GOTO_NEXT_R %edx 11091 11092.LOP_REM_LONG_2ADDR_check_zero: 11093 testl %edx,%edx 11094 jne .LOP_REM_LONG_2ADDR_notSpecial 11095 jmp common_errDivideByZero 11096.LOP_REM_LONG_2ADDR_check_neg1: 11097 testl %edx,%eax 11098 jne .LOP_REM_LONG_2ADDR_notSpecial 11099 GET_VREG_WORD %edx rINST 0 11100 GET_VREG_WORD %ecx rINST 1 11101 testl %edx,%edx 11102 jne .LOP_REM_LONG_2ADDR_notSpecial1 11103 cmpl $0x80000000,%ecx 11104 jne .LOP_REM_LONG_2ADDR_notSpecial1 11105 /* minint / -1, return minint on div, 0 on rem */ 11106 xorl %eax,%eax 11107 movl $0,%edx 11108 jmp .LOP_REM_LONG_2ADDR_finish 11109 11110/* continuation for OP_SHL_LONG_2ADDR */ 11111 11112 11113.LOP_SHL_LONG_2ADDR_finish: 11114 FETCH_INST_OPCODE 1 %edx 11115 SET_VREG_WORD %eax rINST 0 # v[AA+0]<- eax 11116 ADVANCE_PC 1 11117 GOTO_NEXT_R %edx 11118 11119/* continuation for OP_SHR_LONG_2ADDR */ 11120 11121 11122.LOP_SHR_LONG_2ADDR_finish: 11123 FETCH_INST_OPCODE 1 %edx 11124 SET_VREG_WORD %eax rINST 0 # v[AA+0]<- eax 11125 ADVANCE_PC 1 11126 GOTO_NEXT_R %edx 11127 11128/* continuation for OP_USHR_LONG_2ADDR */ 11129 11130 11131.LOP_USHR_LONG_2ADDR_finish: 11132 FETCH_INST_OPCODE 1 %edx 11133 SET_VREG_WORD %eax rINST 0 # v[AA+0]<- eax 11134 ADVANCE_PC 1 11135 GOTO_NEXT_R %edx 11136 11137/* continuation for OP_DIV_INT_LIT16 */ 11138.LOP_DIV_INT_LIT16_continue_div: 11139 cltd 11140 idivl %ecx 11141.LOP_DIV_INT_LIT16_finish_div: 11142 SET_VREG %eax rINST 11143 FETCH_INST_OPCODE 2 %edx 11144 ADVANCE_PC 2 11145 GOTO_NEXT_R %edx 11146 11147/* continuation for OP_REM_INT_LIT16 */ 11148.LOP_REM_INT_LIT16_continue_div: 11149 cltd 11150 idivl %ecx 11151.LOP_REM_INT_LIT16_finish_div: 11152 SET_VREG %edx rINST 11153 FETCH_INST_OPCODE 2 %edx 11154 ADVANCE_PC 2 11155 GOTO_NEXT_R %edx 11156 11157/* continuation for OP_DIV_INT_LIT8 */ 11158.LOP_DIV_INT_LIT8_continue_div: 11159 cltd 11160 idivl %ecx 11161.LOP_DIV_INT_LIT8_finish_div: 11162 SET_VREG %eax rINST 11163 FETCH_INST_OPCODE 2 %edx 11164 ADVANCE_PC 2 11165 GOTO_NEXT_R %edx 11166 11167/* continuation for OP_REM_INT_LIT8 */ 11168.LOP_REM_INT_LIT8_continue_div: 11169 cltd 11170 idivl %ecx 11171.LOP_REM_INT_LIT8_finish_div: 11172 SET_VREG %edx rINST 11173 FETCH_INST_OPCODE 2 %edx 11174 ADVANCE_PC 2 11175 GOTO_NEXT_R %edx 11176 11177/* continuation for OP_IGET_VOLATILE */ 11178 11179 11180.LOP_IGET_VOLATILE_resolve: 11181 EXPORT_PC 11182 movl offThread_method(%edx),%edx # edx<- current method 11183 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11184 SPILL_TMP1(%ecx) # save obj pointer across call 11185 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11186 call dvmResolveInstField # ... to dvmResolveInstField 11187 UNSPILL_TMP1(%ecx) 11188 testl %eax,%eax # returns InstrField ptr 11189 jne .LOP_IGET_VOLATILE_finish 11190 jmp common_exceptionThrown 11191 11192.LOP_IGET_VOLATILE_finish: 11193 /* 11194 * Currently: 11195 * eax holds resolved field 11196 * ecx holds object 11197 * rINST holds A 11198 */ 11199 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11200 testl %ecx,%ecx # object null? 11201 je common_errNullObject # object was null 11202 movl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 11203 movl rINST,%eax # eax<- A 11204 FETCH_INST_OPCODE 2 %edx 11205 SET_VREG %ecx %eax 11206 ADVANCE_PC 2 11207 GOTO_NEXT_R %edx 11208 11209/* continuation for OP_IPUT_VOLATILE */ 11210 11211 11212.LOP_IPUT_VOLATILE_resolve: 11213 EXPORT_PC 11214 movl offThread_method(%edx),%edx # edx<- current method 11215 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11216 SPILL_TMP1(%ecx) # save obj pointer across call 11217 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11218 call dvmResolveInstField # ... to dvmResolveInstField 11219 UNSPILL_TMP1(%ecx) 11220 testl %eax,%eax # returns InstrField ptr 11221 jne .LOP_IPUT_VOLATILE_finish 11222 jmp common_exceptionThrown 11223 11224.LOP_IPUT_VOLATILE_finish: 11225 /* 11226 * Currently: 11227 * eax holds resolved field 11228 * ecx holds object 11229 * rINST holds A 11230 */ 11231 GET_VREG_R rINST rINST # rINST<- v[A] 11232 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11233 testl %ecx,%ecx # object null? 11234 je common_errNullObject # object was null 11235 FETCH_INST_OPCODE 2 %edx 11236 movl rINST,(%ecx,%eax,1) # obj.field <- v[A](8/16/32 bits) 11237 ADVANCE_PC 2 11238 GOTO_NEXT_R %edx 11239 11240/* continuation for OP_SGET_VOLATILE */ 11241 11242 /* 11243 * Go resolve the field 11244 */ 11245.LOP_SGET_VOLATILE_resolve: 11246 movl rSELF,%ecx 11247 movzwl 2(rPC),%eax # eax<- field ref BBBB 11248 movl offThread_method(%ecx),%ecx # ecx<- current method 11249 EXPORT_PC # could throw, need to export 11250 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 11251 movl %eax,OUT_ARG1(%esp) 11252 movl %ecx,OUT_ARG0(%esp) 11253 call dvmResolveStaticField # eax<- resolved StaticField ptr 11254 testl %eax,%eax 11255 jne .LOP_SGET_VOLATILE_finish # success, continue 11256 jmp common_exceptionThrown # no, handle exception 11257 11258/* continuation for OP_SPUT_VOLATILE */ 11259 11260 /* 11261 * Go resolve the field 11262 */ 11263.LOP_SPUT_VOLATILE_resolve: 11264 movl rSELF,%ecx 11265 movzwl 2(rPC),%eax # eax<- field ref BBBB 11266 movl offThread_method(%ecx),%ecx # ecx<- current method 11267 EXPORT_PC # could throw, need to export 11268 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 11269 movl %eax,OUT_ARG1(%esp) 11270 movl %ecx,OUT_ARG0(%esp) 11271 call dvmResolveStaticField # eax<- resolved StaticField ptr 11272 testl %eax,%eax 11273 jne .LOP_SPUT_VOLATILE_finish # success, continue 11274 jmp common_exceptionThrown # no, handle exception 11275 11276/* continuation for OP_IGET_OBJECT_VOLATILE */ 11277 11278 11279.LOP_IGET_OBJECT_VOLATILE_resolve: 11280 EXPORT_PC 11281 movl offThread_method(%edx),%edx # edx<- current method 11282 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11283 SPILL_TMP1(%ecx) # save obj pointer across call 11284 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11285 call dvmResolveInstField # ... to dvmResolveInstField 11286 UNSPILL_TMP1(%ecx) 11287 testl %eax,%eax # returns InstrField ptr 11288 jne .LOP_IGET_OBJECT_VOLATILE_finish 11289 jmp common_exceptionThrown 11290 11291.LOP_IGET_OBJECT_VOLATILE_finish: 11292 /* 11293 * Currently: 11294 * eax holds resolved field 11295 * ecx holds object 11296 * rINST holds A 11297 */ 11298 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11299 testl %ecx,%ecx # object null? 11300 je common_errNullObject # object was null 11301 movl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 11302 movl rINST,%eax # eax<- A 11303 FETCH_INST_OPCODE 2 %edx 11304 SET_VREG %ecx %eax 11305 ADVANCE_PC 2 11306 GOTO_NEXT_R %edx 11307 11308/* continuation for OP_EXECUTE_INLINE */ 11309 11310.LOP_EXECUTE_INLINE_continue: 11311 /* 11312 * Extract args, call function. 11313 * ecx = #of args (0-4) 11314 * eax = call index 11315 * @esp = return addr 11316 * esp is -4 from normal 11317 * 11318 * Go ahead and load all 4 args, even if not used. 11319 */ 11320 movzwl 4(rPC),%edx 11321 11322 movl $0xf,%ecx 11323 andl %edx,%ecx 11324 GET_VREG_R %ecx %ecx 11325 sarl $4,%edx 11326 movl %ecx,4+OUT_ARG0(%esp) 11327 11328 movl $0xf,%ecx 11329 andl %edx,%ecx 11330 GET_VREG_R %ecx %ecx 11331 sarl $4,%edx 11332 movl %ecx,4+OUT_ARG1(%esp) 11333 11334 movl $0xf,%ecx 11335 andl %edx,%ecx 11336 GET_VREG_R %ecx %ecx 11337 sarl $4,%edx 11338 movl %ecx,4+OUT_ARG2(%esp) 11339 11340 movl $0xf,%ecx 11341 andl %edx,%ecx 11342 GET_VREG_R %ecx %ecx 11343 sarl $4,%edx 11344 movl %ecx,4+OUT_ARG3(%esp) 11345 11346 sall $4,%eax # index *= sizeof(table entry) 11347 jmp *gDvmInlineOpsTable(%eax) 11348 # will return to caller of .LOP_EXECUTE_INLINE_continue 11349 11350/* continuation for OP_IPUT_OBJECT_QUICK */ 11351 11352.LOP_IPUT_OBJECT_QUICK_finish: 11353 testl rINST,rINST # did we store null? 11354 FETCH_INST_OPCODE 2 %edx 11355 movl offThread_cardTable(%eax),%eax # get card table base 11356 je 1f # skip card mark if null store 11357 shrl $GC_CARD_SHIFT,%ecx # object head to card number 11358 movb %al,(%eax,%ecx) # mark card based on object head 113591: 11360 ADVANCE_PC 2 11361 GOTO_NEXT_R %edx 11362 11363/* continuation for OP_IPUT_OBJECT_VOLATILE */ 11364 11365 11366.LOP_IPUT_OBJECT_VOLATILE_resolve: 11367 EXPORT_PC 11368 movl offThread_method(%edx),%edx # edx<- current method 11369 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11370 SPILL_TMP1(%ecx) # save obj pointer across call 11371 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11372 call dvmResolveInstField # ... to dvmResolveInstField 11373 UNSPILL_TMP1(%ecx) 11374 testl %eax,%eax # returns InstrField ptr 11375 jne .LOP_IPUT_OBJECT_VOLATILE_finish 11376 jmp common_exceptionThrown 11377 11378.LOP_IPUT_OBJECT_VOLATILE_finish: 11379 /* 11380 * Currently: 11381 * eax holds resolved field 11382 * ecx holds object 11383 * %edx is scratch, but needs to be unspilled 11384 * rINST holds A 11385 */ 11386 GET_VREG_R rINST rINST # rINST<- v[A] 11387 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11388 testl %ecx,%ecx # object null? 11389 je common_errNullObject # object was null 11390 movl rINST,(%ecx,%eax) # obj.field <- v[A](8/16/32 bits) 11391 movl rSELF,%eax 11392 testl rINST,rINST # stored a NULL? 11393 movl offThread_cardTable(%eax),%eax # get card table base 11394 FETCH_INST_OPCODE 2 %edx 11395 je 1f # skip card mark if null store 11396 shrl $GC_CARD_SHIFT,%ecx # object head to card number 11397 movb %al,(%eax,%ecx) # mark card using object head 113981: 11399 ADVANCE_PC 2 11400 GOTO_NEXT_R %edx 11401 11402/* continuation for OP_SGET_OBJECT_VOLATILE */ 11403 11404 /* 11405 * Go resolve the field 11406 */ 11407.LOP_SGET_OBJECT_VOLATILE_resolve: 11408 movl rSELF,%ecx 11409 movzwl 2(rPC),%eax # eax<- field ref BBBB 11410 movl offThread_method(%ecx),%ecx # ecx<- current method 11411 EXPORT_PC # could throw, need to export 11412 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 11413 movl %eax,OUT_ARG1(%esp) 11414 movl %ecx,OUT_ARG0(%esp) 11415 call dvmResolveStaticField # eax<- resolved StaticField ptr 11416 testl %eax,%eax 11417 jne .LOP_SGET_OBJECT_VOLATILE_finish # success, continue 11418 jmp common_exceptionThrown # no, handle exception 11419 11420/* continuation for OP_SPUT_OBJECT_VOLATILE */ 11421 11422 11423.LOP_SPUT_OBJECT_VOLATILE_continue: 11424 movl %ecx,offStaticField_value(%eax) # do the store 11425 testl %ecx,%ecx # stored null object ptr? 11426 FETCH_INST_OPCODE 2 %edx 11427 je 1f # skip card mark if null 11428 movl rSELF,%ecx 11429 movl offField_clazz(%eax),%eax # eax<- method->clazz 11430 movl offThread_cardTable(%ecx),%ecx # get card table base 11431 shrl $GC_CARD_SHIFT,%eax # head to card number 11432 movb %cl,(%ecx,%eax) # mark card 114331: 11434 ADVANCE_PC 2 11435 GOTO_NEXT_R %edx 11436 11437.LOP_SPUT_OBJECT_VOLATILE_resolve: 11438 movl rSELF,%ecx 11439 movzwl 2(rPC),%eax # eax<- field ref BBBB 11440 movl offThread_method(%ecx),%ecx # ecx<- current method 11441 EXPORT_PC # could throw, need to export 11442 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 11443 movl %eax,OUT_ARG1(%esp) 11444 movl %ecx,OUT_ARG0(%esp) 11445 call dvmResolveStaticField # eax<- resolved StaticField ptr 11446 testl %eax,%eax 11447 jne .LOP_SPUT_OBJECT_VOLATILE_finish # success, continue 11448 jmp common_exceptionThrown # no, handle exception 11449 11450/* continuation for OP_CONST_CLASS_JUMBO */ 11451 11452/* This is the less common path, so we'll redo some work 11453 here rather than force spills on the common path */ 11454.LOP_CONST_CLASS_JUMBO_resolve: 11455 movl rSELF,%eax 11456 EXPORT_PC 11457 movl offThread_method(%eax),%eax # eax<- self->method 11458 movl $1,OUT_ARG2(%esp) # true 11459 movl 2(rPC),%ecx # ecx<- AAAAAAAA 11460 movl offMethod_clazz(%eax),%eax 11461 movl %ecx,OUT_ARG1(%esp) 11462 movl %eax,OUT_ARG0(%esp) 11463 call dvmResolveClass # go resolve 11464 testl %eax,%eax # failed? 11465 je common_exceptionThrown 11466 SET_VREG %eax rINST 11467 FETCH_INST_OPCODE 4 %edx 11468 ADVANCE_PC 4 11469 GOTO_NEXT_R %edx 11470 11471/* continuation for OP_CHECK_CAST_JUMBO */ 11472 11473 /* 11474 * Trivial test failed, need to perform full check. This is common. 11475 * ecx holds obj->clazz 11476 * eax holds class resolved from AAAAAAAA 11477 * rINST holds object 11478 */ 11479.LOP_CHECK_CAST_JUMBO_fullcheck: 11480 movl %eax,sReg0 # we'll need the desired class on failure 11481 movl %eax,OUT_ARG1(%esp) 11482 movl %ecx,OUT_ARG0(%esp) 11483 call dvmInstanceofNonTrivial # eax<- boolean result 11484 testl %eax,%eax # failed? 11485 jne .LOP_CHECK_CAST_JUMBO_okay # no, success 11486 11487 # A cast has failed. We need to throw a ClassCastException. 11488 EXPORT_PC 11489 movl offObject_clazz(rINST),%eax 11490 movl %eax,OUT_ARG0(%esp) # arg0<- obj->clazz 11491 movl sReg0,%ecx 11492 movl %ecx,OUT_ARG1(%esp) # arg1<- desired class 11493 call dvmThrowClassCastException 11494 jmp common_exceptionThrown 11495 11496 /* 11497 * Resolution required. This is the least-likely path, and we're 11498 * going to have to recreate some data. 11499 * 11500 * rINST holds object 11501 */ 11502.LOP_CHECK_CAST_JUMBO_resolve: 11503 movl rSELF,%ecx 11504 EXPORT_PC 11505 movl 2(rPC),%eax # eax<- AAAAAAAA 11506 movl offThread_method(%ecx),%ecx # ecx<- self->method 11507 movl %eax,OUT_ARG1(%esp) # arg1<- AAAAAAAA 11508 movl offMethod_clazz(%ecx),%ecx # ecx<- metho->clazz 11509 movl $0,OUT_ARG2(%esp) # arg2<- false 11510 movl %ecx,OUT_ARG0(%esp) # arg0<- method->clazz 11511 call dvmResolveClass # eax<- resolved ClassObject ptr 11512 testl %eax,%eax # got null? 11513 je common_exceptionThrown # yes, handle exception 11514 movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz 11515 jmp .LOP_CHECK_CAST_JUMBO_resolved # pick up where we left off 11516 11517/* continuation for OP_INSTANCE_OF_JUMBO */ 11518 11519 /* 11520 * Trivial test failed, need to perform full check. This is common. 11521 * eax holds obj->clazz 11522 * ecx holds class resolved from BBBB 11523 * rINST has BA 11524 */ 11525.LOP_INSTANCE_OF_JUMBO_fullcheck: 11526 movl %eax,OUT_ARG0(%esp) 11527 movl %ecx,OUT_ARG1(%esp) 11528 call dvmInstanceofNonTrivial # eax<- boolean result 11529 # fall through to OP_INSTANCE_OF_JUMBO_store 11530 11531 /* 11532 * eax holds boolean result 11533 * rINST holds BBBB 11534 */ 11535.LOP_INSTANCE_OF_JUMBO_store: 11536 FETCH_INST_OPCODE 5 %edx 11537 ADVANCE_PC 5 11538 SET_VREG %eax rINST # vBBBB<- eax 11539 GOTO_NEXT_R %edx 11540 11541 /* 11542 * Trivial test succeeded, save and bail. 11543 * r9 holds BBBB 11544 */ 11545.LOP_INSTANCE_OF_JUMBO_trivial: 11546 FETCH_INST_OPCODE 5 %edx 11547 ADVANCE_PC 5 11548 movl $1,%eax 11549 SET_VREG %eax rINST # vBBBB<- true 11550 GOTO_NEXT_R %edx 11551 11552 /* 11553 * Resolution required. This is the least-likely path. 11554 * 11555 * edx holds AAAAAAAA 11556 */ 11557.LOP_INSTANCE_OF_JUMBO_resolve: 11558 movl %edx,OUT_ARG1(%esp) # arg1<- AAAAAAAA 11559 movl rSELF,%ecx 11560 movl offThread_method(%ecx),%ecx 11561 movl $1,OUT_ARG2(%esp) # arg2<- true 11562 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 11563 EXPORT_PC 11564 movl %ecx,OUT_ARG0(%esp) # arg0<- method->clazz 11565 call dvmResolveClass # eax<- resolved ClassObject ptr 11566 testl %eax,%eax # success? 11567 je common_exceptionThrown # no, handle exception 11568/* Now, we need to sync up with fast path. We need eax to 11569 * hold the obj->clazz, and ecx to hold the resolved class 11570 */ 11571 movl %eax,%ecx # ecx<- resolved class 11572 movzwl 8(rPC),%eax # eax<- CCCC 11573 GET_VREG_R %eax %eax # eax<- vCCCC (obj) 11574 movl offObject_clazz(%eax),%eax # eax<- obj->clazz 11575 jmp .LOP_INSTANCE_OF_JUMBO_resolved 11576 11577/* continuation for OP_NEW_INSTANCE_JUMBO */ 11578 11579.LOP_NEW_INSTANCE_JUMBO_initialized: # on entry, ecx<- class 11580 /* TODO: remove test for interface/abstract, now done in verifier */ 11581 testl $(ACC_INTERFACE|ACC_ABSTRACT),offClassObject_accessFlags(%ecx) 11582 movl $ALLOC_DONT_TRACK,OUT_ARG1(%esp) 11583 jne .LOP_NEW_INSTANCE_JUMBO_abstract 11584.LOP_NEW_INSTANCE_JUMBO_finish: # ecx=class 11585 movl %ecx,OUT_ARG0(%esp) 11586 call dvmAllocObject # eax<- new object 11587 FETCH_INST_OPCODE 4 %edx 11588 testl %eax,%eax # success? 11589 je common_exceptionThrown # no, bail out 11590 SET_VREG %eax rINST 11591 ADVANCE_PC 4 11592 GOTO_NEXT_R %edx 11593 11594 /* 11595 * Class initialization required. 11596 * 11597 * ecx holds class object 11598 */ 11599.LOP_NEW_INSTANCE_JUMBO_needinit: 11600 SPILL_TMP1(%ecx) # save object 11601 movl %ecx,OUT_ARG0(%esp) 11602 call dvmInitClass # initialize class 11603 UNSPILL_TMP1(%ecx) # restore object 11604 testl %eax,%eax # success? 11605 jne .LOP_NEW_INSTANCE_JUMBO_initialized # success, continue 11606 jmp common_exceptionThrown # go deal with init exception 11607 11608 /* 11609 * Resolution required. This is the least-likely path. 11610 * 11611 */ 11612.LOP_NEW_INSTANCE_JUMBO_resolve: 11613 movl rSELF,%ecx 11614 movl 2(rPC),%eax # eax<- AAAAAAAA 11615 movl offThread_method(%ecx),%ecx # ecx<- self->method 11616 movl %eax,OUT_ARG1(%esp) 11617 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 11618 movl $0,OUT_ARG2(%esp) 11619 movl %ecx,OUT_ARG0(%esp) 11620 call dvmResolveClass # call(clazz,off,flags) 11621 movl %eax,%ecx # ecx<- resolved ClassObject ptr 11622 testl %ecx,%ecx # success? 11623 jne .LOP_NEW_INSTANCE_JUMBO_resolved # good to go 11624 jmp common_exceptionThrown # no, handle exception 11625 11626 /* 11627 * TODO: remove this 11628 * We can't instantiate an abstract class or interface, so throw an 11629 * InstantiationError with the class descriptor as the message. 11630 * 11631 * ecx holds class object 11632 */ 11633.LOP_NEW_INSTANCE_JUMBO_abstract: 11634 movl offClassObject_descriptor(%ecx),%eax 11635 movl $.LstrInstantiationError,OUT_ARG0(%esp) 11636 movl %eax,OUT_ARG1(%esp) 11637 call dvmThrowExceptionWithClassMessage 11638 jmp common_exceptionThrown 11639 11640/* continuation for OP_NEW_ARRAY_JUMBO */ 11641 11642 /* 11643 * Resolve class. (This is an uncommon case.) 11644 * ecx holds class (null here) 11645 * eax holds array length (vCCCC) 11646 */ 11647.LOP_NEW_ARRAY_JUMBO_resolve: 11648 movl rSELF,%ecx 11649 SPILL_TMP1(%eax) # save array length 11650 movl offThread_method(%ecx),%ecx # ecx<- self->method 11651 movl 2(rPC),%eax # eax<- AAAAAAAA 11652 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 11653 movl %eax,OUT_ARG1(%esp) 11654 movl $0,OUT_ARG2(%esp) 11655 movl %ecx,OUT_ARG0(%esp) 11656 call dvmResolveClass # eax<- call(clazz,ref,flag) 11657 movl %eax,%ecx 11658 UNSPILL_TMP1(%eax) 11659 testl %ecx,%ecx # successful resolution? 11660 je common_exceptionThrown # no, bail. 11661# fall through to OP_NEW_ARRAY_JUMBO_finish 11662 11663 /* 11664 * Finish allocation 11665 * 11666 * ecx holds class 11667 * eax holds array length (vCCCC) 11668 */ 11669.LOP_NEW_ARRAY_JUMBO_finish: 11670 movl %ecx,OUT_ARG0(%esp) 11671 movl %eax,OUT_ARG1(%esp) 11672 movl $ALLOC_DONT_TRACK,OUT_ARG2(%esp) 11673 call dvmAllocArrayByClass # eax<- call(clazz,length,flags) 11674 FETCH_INST_OPCODE 5 %edx 11675 testl %eax,%eax # failed? 11676 je common_exceptionThrown # yup - go handle 11677 SET_VREG %eax rINST 11678 ADVANCE_PC 5 11679 GOTO_NEXT_R %edx 11680 11681/* continuation for OP_FILLED_NEW_ARRAY_JUMBO */ 11682 11683.LOP_FILLED_NEW_ARRAY_JUMBO_more: 11684 movl offMethod_clazz(%eax),%eax # eax<- method->clazz 11685 movl %eax,OUT_ARG0(%esp) # arg0<- clazz 11686 call dvmResolveClass # eax<- call(clazz,ref,flag) 11687 testl %eax,%eax # null? 11688 je common_exceptionThrown # yes, handle it 11689 11690 # note: fall through to .LOP_FILLED_NEW_ARRAY_JUMBO_continue 11691 11692 /* 11693 * On entry: 11694 * eax holds array class [r0] 11695 * ecx is scratch 11696 */ 11697.LOP_FILLED_NEW_ARRAY_JUMBO_continue: 11698 movl offClassObject_descriptor(%eax),%ecx # ecx<- arrayClass->descriptor 11699 movl $ALLOC_DONT_TRACK,OUT_ARG2(%esp) # arg2<- flags 11700 movzbl 1(%ecx),%ecx # ecx<- descriptor[1] 11701 movl %eax,OUT_ARG0(%esp) # arg0<- arrayClass 11702 movl rSELF,%eax 11703 cmpb $'I',%cl # supported? 11704 je 1f 11705 cmpb $'L',%cl 11706 je 1f 11707 cmpb $'[',%cl 11708 jne .LOP_FILLED_NEW_ARRAY_JUMBO_notimpl # no, not handled yet 117091: 11710 movl %ecx,offThread_retval+4(%eax) # save type 11711 movl rINST,OUT_ARG1(%esp) # arg1<- BBBB (length) 11712 call dvmAllocArrayByClass # eax<- call(arrayClass, length, flags) 11713 movl rSELF,%ecx 11714 testl %eax,%eax # alloc successful? 11715 je common_exceptionThrown # no, handle exception 11716 movl %eax,offThread_retval(%ecx) # retval.l<- new array 11717 movzwl 8(rPC),%ecx # ecx<- CCCC 11718 leal offArrayObject_contents(%eax),%eax # eax<- newArray->contents 11719 11720/* at this point: 11721 * eax is pointer to tgt 11722 * rINST is length 11723 * ecx is CCCC 11724 * We now need to copy values from registers into the array 11725 */ 11726 11727 # set up src pointer 11728 SPILL_TMP2(%esi) 11729 SPILL_TMP3(%edi) 11730 leal (rFP,%ecx,4),%esi # set up src ptr 11731 movl %eax,%edi # set up dst ptr 11732 movl rINST,%ecx # load count register 11733 rep 11734 movsd 11735 UNSPILL_TMP2(%esi) 11736 UNSPILL_TMP3(%edi) 11737 movl rSELF,%ecx 11738 movl offThread_retval+4(%ecx),%eax # eax<- type 11739 FETCH_INST_OPCODE 5 %edx 11740 11741 cmpb $'I',%al # Int array? 11742 je 5f # skip card mark if so 11743 movl offThread_retval(%ecx),%eax # eax<- object head 11744 movl offThread_cardTable(%ecx),%ecx # card table base 11745 shrl $GC_CARD_SHIFT,%eax # convert to card num 11746 movb %cl,(%ecx,%eax) # mark card based on object head 117475: 11748 ADVANCE_PC 5 11749 GOTO_NEXT_R %edx 11750 11751 11752 /* 11753 * Throw an exception indicating that we have not implemented this 11754 * mode of filled-new-array. 11755 */ 11756.LOP_FILLED_NEW_ARRAY_JUMBO_notimpl: 11757 movl $.LstrInternalErrorA,%eax 11758 movl %eax,OUT_ARG0(%esp) 11759 movl $.LstrFilledNewArrayNotImplA,%eax 11760 movl %eax,OUT_ARG1(%esp) 11761 call dvmThrowException 11762 jmp common_exceptionThrown 11763 11764/* continuation for OP_IGET_JUMBO */ 11765 11766 11767.LOP_IGET_JUMBO_resolve: 11768 EXPORT_PC 11769 movl offThread_method(%edx),%edx # edx<- current method 11770 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11771 SPILL_TMP1(%ecx) # save obj pointer across call 11772 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11773 call dvmResolveInstField # ... to dvmResolveInstField 11774 UNSPILL_TMP1(%ecx) 11775 testl %eax,%eax # returns InstrField ptr 11776 jne .LOP_IGET_JUMBO_finish 11777 jmp common_exceptionThrown 11778 11779.LOP_IGET_JUMBO_finish: 11780 /* 11781 * Currently: 11782 * eax holds resolved field 11783 * ecx holds object 11784 * rINST holds BBBB 11785 */ 11786 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11787 testl %ecx,%ecx # object null? 11788 je common_errNullObject # object was null 11789 movl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 11790 movl rINST,%eax # eax<- BBBB 11791 FETCH_INST_OPCODE 5 %edx 11792 SET_VREG %ecx %eax 11793 ADVANCE_PC 5 11794 GOTO_NEXT_R %edx 11795 11796/* continuation for OP_IGET_WIDE_JUMBO */ 11797 11798 11799.LOP_IGET_WIDE_JUMBO_resolve: 11800 EXPORT_PC 11801 movl offThread_method(%edx),%edx # edx<- current method 11802 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11803 SPILL_TMP1(%ecx) # save objpointer across call 11804 movl rPC,OUT_ARG0(%esp) # pass in method->clazz 11805 call dvmResolveInstField # ... to dvmResolveInstField 11806 UNSPILL_TMP1(%ecx) 11807 testl %eax,%eax # returns InstrField ptr 11808 jne .LOP_IGET_WIDE_JUMBO_finish 11809 jmp common_exceptionThrown 11810 11811.LOP_IGET_WIDE_JUMBO_finish: 11812 /* 11813 * Currently: 11814 * eax holds resolved field 11815 * ecx holds object 11816 * rINST holds BBBB 11817 */ 11818 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11819 testl %ecx,%ecx # object null? 11820 je common_errNullObject # object was null 11821 leal (%ecx,%eax,1),%eax # eax<- address of field 11822 movl (%eax),%ecx # ecx<- lsw 11823 movl 4(%eax),%eax # eax<- msw 11824 FETCH_INST_OPCODE 5 %edx 11825 SET_VREG_WORD %ecx rINST 0 11826 SET_VREG_WORD %eax rINST 1 11827 ADVANCE_PC 5 11828 GOTO_NEXT_R %edx 11829 11830/* continuation for OP_IGET_OBJECT_JUMBO */ 11831 11832 11833.LOP_IGET_OBJECT_JUMBO_resolve: 11834 EXPORT_PC 11835 movl offThread_method(%edx),%edx # edx<- current method 11836 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11837 SPILL_TMP1(%ecx) # save obj pointer across call 11838 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11839 call dvmResolveInstField # ... to dvmResolveInstField 11840 UNSPILL_TMP1(%ecx) 11841 testl %eax,%eax # returns InstrField ptr 11842 jne .LOP_IGET_OBJECT_JUMBO_finish 11843 jmp common_exceptionThrown 11844 11845.LOP_IGET_OBJECT_JUMBO_finish: 11846 /* 11847 * Currently: 11848 * eax holds resolved field 11849 * ecx holds object 11850 * rINST holds BBBB 11851 */ 11852 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11853 testl %ecx,%ecx # object null? 11854 je common_errNullObject # object was null 11855 movl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 11856 movl rINST,%eax # eax<- BBBB 11857 FETCH_INST_OPCODE 5 %edx 11858 SET_VREG %ecx %eax 11859 ADVANCE_PC 5 11860 GOTO_NEXT_R %edx 11861 11862/* continuation for OP_IGET_BOOLEAN_JUMBO */ 11863 11864 11865.LOP_IGET_BOOLEAN_JUMBO_resolve: 11866 EXPORT_PC 11867 movl offThread_method(%edx),%edx # edx<- current method 11868 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11869 SPILL_TMP1(%ecx) # save obj pointer across call 11870 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11871 call dvmResolveInstField # ... to dvmResolveInstField 11872 UNSPILL_TMP1(%ecx) 11873 testl %eax,%eax # returns InstrField ptr 11874 jne .LOP_IGET_BOOLEAN_JUMBO_finish 11875 jmp common_exceptionThrown 11876 11877.LOP_IGET_BOOLEAN_JUMBO_finish: 11878 /* 11879 * Currently: 11880 * eax holds resolved field 11881 * ecx holds object 11882 * rINST holds BBBB 11883 */ 11884 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11885 testl %ecx,%ecx # object null? 11886 je common_errNullObject # object was null 11887 movzbl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 11888 movl rINST,%eax # eax<- BBBB 11889 FETCH_INST_OPCODE 5 %edx 11890 SET_VREG %ecx %eax 11891 ADVANCE_PC 5 11892 GOTO_NEXT_R %edx 11893 11894/* continuation for OP_IGET_BYTE_JUMBO */ 11895 11896 11897.LOP_IGET_BYTE_JUMBO_resolve: 11898 EXPORT_PC 11899 movl offThread_method(%edx),%edx # edx<- current method 11900 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11901 SPILL_TMP1(%ecx) # save obj pointer across call 11902 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11903 call dvmResolveInstField # ... to dvmResolveInstField 11904 UNSPILL_TMP1(%ecx) 11905 testl %eax,%eax # returns InstrField ptr 11906 jne .LOP_IGET_BYTE_JUMBO_finish 11907 jmp common_exceptionThrown 11908 11909.LOP_IGET_BYTE_JUMBO_finish: 11910 /* 11911 * Currently: 11912 * eax holds resolved field 11913 * ecx holds object 11914 * rINST holds BBBB 11915 */ 11916 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11917 testl %ecx,%ecx # object null? 11918 je common_errNullObject # object was null 11919 movsbl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 11920 movl rINST,%eax # eax<- BBBB 11921 FETCH_INST_OPCODE 5 %edx 11922 SET_VREG %ecx %eax 11923 ADVANCE_PC 5 11924 GOTO_NEXT_R %edx 11925 11926/* continuation for OP_IGET_CHAR_JUMBO */ 11927 11928 11929.LOP_IGET_CHAR_JUMBO_resolve: 11930 EXPORT_PC 11931 movl offThread_method(%edx),%edx # edx<- current method 11932 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11933 SPILL_TMP1(%ecx) # save obj pointer across call 11934 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11935 call dvmResolveInstField # ... to dvmResolveInstField 11936 UNSPILL_TMP1(%ecx) 11937 testl %eax,%eax # returns InstrField ptr 11938 jne .LOP_IGET_CHAR_JUMBO_finish 11939 jmp common_exceptionThrown 11940 11941.LOP_IGET_CHAR_JUMBO_finish: 11942 /* 11943 * Currently: 11944 * eax holds resolved field 11945 * ecx holds object 11946 * rINST holds BBBB 11947 */ 11948 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11949 testl %ecx,%ecx # object null? 11950 je common_errNullObject # object was null 11951 movzwl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 11952 movl rINST,%eax # eax<- BBBB 11953 FETCH_INST_OPCODE 5 %edx 11954 SET_VREG %ecx %eax 11955 ADVANCE_PC 5 11956 GOTO_NEXT_R %edx 11957 11958/* continuation for OP_IGET_SHORT_JUMBO */ 11959 11960 11961.LOP_IGET_SHORT_JUMBO_resolve: 11962 EXPORT_PC 11963 movl offThread_method(%edx),%edx # edx<- current method 11964 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11965 SPILL_TMP1(%ecx) # save obj pointer across call 11966 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11967 call dvmResolveInstField # ... to dvmResolveInstField 11968 UNSPILL_TMP1(%ecx) 11969 testl %eax,%eax # returns InstrField ptr 11970 jne .LOP_IGET_SHORT_JUMBO_finish 11971 jmp common_exceptionThrown 11972 11973.LOP_IGET_SHORT_JUMBO_finish: 11974 /* 11975 * Currently: 11976 * eax holds resolved field 11977 * ecx holds object 11978 * rINST holds BBBB 11979 */ 11980 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11981 testl %ecx,%ecx # object null? 11982 je common_errNullObject # object was null 11983 movswl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 11984 movl rINST,%eax # eax<- BBBB 11985 FETCH_INST_OPCODE 5 %edx 11986 SET_VREG %ecx %eax 11987 ADVANCE_PC 5 11988 GOTO_NEXT_R %edx 11989 11990/* continuation for OP_IPUT_JUMBO */ 11991 11992 11993.LOP_IPUT_JUMBO_resolve: 11994 EXPORT_PC 11995 movl offThread_method(%edx),%edx # edx<- current method 11996 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11997 SPILL_TMP1(%ecx) # save obj pointer across call 11998 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11999 call dvmResolveInstField # ... to dvmResolveInstField 12000 UNSPILL_TMP1(%ecx) 12001 testl %eax,%eax # returns InstrField ptr 12002 jne .LOP_IPUT_JUMBO_finish 12003 jmp common_exceptionThrown 12004 12005.LOP_IPUT_JUMBO_finish: 12006 /* 12007 * Currently: 12008 * eax holds resolved field 12009 * ecx holds object 12010 * rINST holds BBBB 12011 */ 12012 GET_VREG_R rINST rINST # rINST<- v[BBBB] 12013 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 12014 testl %ecx,%ecx # object null? 12015 je common_errNullObject # object was null 12016 FETCH_INST_OPCODE 5 %edx 12017 movl rINST,(%ecx,%eax,1) # obj.field <- v[BBBB](8/16/32 bits) 12018 ADVANCE_PC 5 12019 GOTO_NEXT_R %edx 12020 12021/* continuation for OP_IPUT_WIDE_JUMBO */ 12022 12023 12024.LOP_IPUT_WIDE_JUMBO_resolve: 12025 EXPORT_PC 12026 movl offThread_method(%edx),%edx # edx<- current method 12027 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 12028 SPILL_TMP1(%ecx) # save obj pointer across call 12029 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 12030 call dvmResolveInstField # ... to dvmResolveInstField 12031 UNSPILL_TMP1(%ecx) 12032 testl %eax,%eax # ... which returns InstrField ptr 12033 jne .LOP_IPUT_WIDE_JUMBO_finish 12034 jmp common_exceptionThrown 12035 12036.LOP_IPUT_WIDE_JUMBO_finish: 12037 /* 12038 * Currently: 12039 * eax holds resolved field 12040 * ecx holds object 12041 * %edx is scratch, but needs to be unspilled 12042 * rINST holds BBBB 12043 */ 12044 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 12045 testl %ecx,%ecx # object null? 12046 je common_errNullObject # object was null 12047 leal (%ecx,%eax,1),%eax # eax<- address of field 12048 GET_VREG_WORD %ecx rINST 0 # ecx<- lsw 12049 GET_VREG_WORD rINST rINST 1 # rINST<- msw 12050 FETCH_INST_OPCODE 5 %edx 12051 movl rINST,4(%eax) 12052 movl %ecx,(%eax) 12053 ADVANCE_PC 5 12054 GOTO_NEXT_R %edx 12055 12056/* continuation for OP_IPUT_OBJECT_JUMBO */ 12057 12058 12059.LOP_IPUT_OBJECT_JUMBO_resolve: 12060 EXPORT_PC 12061 movl offThread_method(%edx),%edx # edx<- current method 12062 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 12063 SPILL_TMP1(%ecx) # save obj pointer across call 12064 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 12065 call dvmResolveInstField # ... to dvmResolveInstField 12066 UNSPILL_TMP1(%ecx) 12067 testl %eax,%eax # returns InstrField ptr 12068 jne .LOP_IPUT_OBJECT_JUMBO_finish 12069 jmp common_exceptionThrown 12070 12071.LOP_IPUT_OBJECT_JUMBO_finish: 12072 /* 12073 * Currently: 12074 * eax holds resolved field 12075 * ecx holds object 12076 * %edx is scratch, but needs to be unspilled 12077 * rINST holds BBBB 12078 */ 12079 GET_VREG_R rINST rINST # rINST<- v[BBBB] 12080 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 12081 testl %ecx,%ecx # object null? 12082 je common_errNullObject # object was null 12083 movl rINST,(%ecx,%eax) # obj.field <- v[BBBB](8/16/32 bits) 12084 movl rSELF,%eax 12085 testl rINST,rINST # stored a NULL? 12086 movl offThread_cardTable(%eax),%eax # get card table base 12087 FETCH_INST_OPCODE 5 %edx 12088 je 1f # skip card mark if null store 12089 shrl $GC_CARD_SHIFT,%ecx # object head to card number 12090 movb %al,(%eax,%ecx) # mark card using object head 120911: 12092 ADVANCE_PC 5 12093 GOTO_NEXT_R %edx 12094 12095/* continuation for OP_IPUT_BOOLEAN_JUMBO */ 12096 12097 12098.LOP_IPUT_BOOLEAN_JUMBO_resolve: 12099 EXPORT_PC 12100 movl offThread_method(%edx),%edx # edx<- current method 12101 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 12102 SPILL_TMP1(%ecx) # save obj pointer across call 12103 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 12104 call dvmResolveInstField # ... to dvmResolveInstField 12105 UNSPILL_TMP1(%ecx) 12106 testl %eax,%eax # returns InstrField ptr 12107 jne .LOP_IPUT_BOOLEAN_JUMBO_finish 12108 jmp common_exceptionThrown 12109 12110.LOP_IPUT_BOOLEAN_JUMBO_finish: 12111 /* 12112 * Currently: 12113 * eax holds resolved field 12114 * ecx holds object 12115 * rINST holds BBBB 12116 */ 12117 GET_VREG_R rINST rINST # rINST<- v[BBBB] 12118 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 12119 testl %ecx,%ecx # object null? 12120 je common_errNullObject # object was null 12121 FETCH_INST_OPCODE 5 %edx 12122 movb rINSTbl,(%ecx,%eax,1) # obj.field <- v[BBBB](8/16/32 bits) 12123 ADVANCE_PC 5 12124 GOTO_NEXT_R %edx 12125 12126/* continuation for OP_IPUT_BYTE_JUMBO */ 12127 12128 12129.LOP_IPUT_BYTE_JUMBO_resolve: 12130 EXPORT_PC 12131 movl offThread_method(%edx),%edx # edx<- current method 12132 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 12133 SPILL_TMP1(%ecx) # save obj pointer across call 12134 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 12135 call dvmResolveInstField # ... to dvmResolveInstField 12136 UNSPILL_TMP1(%ecx) 12137 testl %eax,%eax # returns InstrField ptr 12138 jne .LOP_IPUT_BYTE_JUMBO_finish 12139 jmp common_exceptionThrown 12140 12141.LOP_IPUT_BYTE_JUMBO_finish: 12142 /* 12143 * Currently: 12144 * eax holds resolved field 12145 * ecx holds object 12146 * rINST holds BBBB 12147 */ 12148 GET_VREG_R rINST rINST # rINST<- v[BBBB] 12149 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 12150 testl %ecx,%ecx # object null? 12151 je common_errNullObject # object was null 12152 FETCH_INST_OPCODE 5 %edx 12153 movb rINSTbl,(%ecx,%eax,1) # obj.field <- v[BBBB](8/16/32 bits) 12154 ADVANCE_PC 5 12155 GOTO_NEXT_R %edx 12156 12157/* continuation for OP_IPUT_CHAR_JUMBO */ 12158 12159 12160.LOP_IPUT_CHAR_JUMBO_resolve: 12161 EXPORT_PC 12162 movl offThread_method(%edx),%edx # edx<- current method 12163 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 12164 SPILL_TMP1(%ecx) # save obj pointer across call 12165 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 12166 call dvmResolveInstField # ... to dvmResolveInstField 12167 UNSPILL_TMP1(%ecx) 12168 testl %eax,%eax # returns InstrField ptr 12169 jne .LOP_IPUT_CHAR_JUMBO_finish 12170 jmp common_exceptionThrown 12171 12172.LOP_IPUT_CHAR_JUMBO_finish: 12173 /* 12174 * Currently: 12175 * eax holds resolved field 12176 * ecx holds object 12177 * rINST holds BBBB 12178 */ 12179 GET_VREG_R rINST rINST # rINST<- v[BBBB] 12180 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 12181 testl %ecx,%ecx # object null? 12182 je common_errNullObject # object was null 12183 FETCH_INST_OPCODE 5 %edx 12184 movw rINSTw,(%ecx,%eax,1) # obj.field <- v[BBBB](8/16/32 bits) 12185 ADVANCE_PC 5 12186 GOTO_NEXT_R %edx 12187 12188/* continuation for OP_IPUT_SHORT_JUMBO */ 12189 12190 12191.LOP_IPUT_SHORT_JUMBO_resolve: 12192 EXPORT_PC 12193 movl offThread_method(%edx),%edx # edx<- current method 12194 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 12195 SPILL_TMP1(%ecx) # save obj pointer across call 12196 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 12197 call dvmResolveInstField # ... to dvmResolveInstField 12198 UNSPILL_TMP1(%ecx) 12199 testl %eax,%eax # returns InstrField ptr 12200 jne .LOP_IPUT_SHORT_JUMBO_finish 12201 jmp common_exceptionThrown 12202 12203.LOP_IPUT_SHORT_JUMBO_finish: 12204 /* 12205 * Currently: 12206 * eax holds resolved field 12207 * ecx holds object 12208 * rINST holds BBBB 12209 */ 12210 GET_VREG_R rINST rINST # rINST<- v[BBBB] 12211 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 12212 testl %ecx,%ecx # object null? 12213 je common_errNullObject # object was null 12214 FETCH_INST_OPCODE 5 %edx 12215 movw rINSTw,(%ecx,%eax,1) # obj.field <- v[BBBB](8/16/32 bits) 12216 ADVANCE_PC 5 12217 GOTO_NEXT_R %edx 12218 12219/* continuation for OP_SGET_JUMBO */ 12220 12221 /* 12222 * Go resolve the field 12223 */ 12224.LOP_SGET_JUMBO_resolve: 12225 movl rSELF,%ecx 12226 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12227 movl offThread_method(%ecx),%ecx # ecx<- current method 12228 EXPORT_PC # could throw, need to export 12229 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12230 movl %eax,OUT_ARG1(%esp) 12231 movl %ecx,OUT_ARG0(%esp) 12232 call dvmResolveStaticField # eax<- resolved StaticField ptr 12233 testl %eax,%eax 12234 jne .LOP_SGET_JUMBO_finish # success, continue 12235 jmp common_exceptionThrown # no, handle exception 12236 12237/* continuation for OP_SGET_WIDE_JUMBO */ 12238 12239 /* 12240 * Go resolve the field 12241 */ 12242.LOP_SGET_WIDE_JUMBO_resolve: 12243 movl rSELF,%ecx 12244 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12245 movl offThread_method(%ecx),%ecx # ecx<- current method 12246 EXPORT_PC # could throw, need to export 12247 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12248 movl %eax,OUT_ARG1(%esp) 12249 movl %ecx,OUT_ARG0(%esp) 12250 call dvmResolveStaticField # eax<- resolved StaticField ptr 12251 testl %eax,%eax 12252 jne .LOP_SGET_WIDE_JUMBO_finish # success, continue 12253 jmp common_exceptionThrown # no, handle exception 12254 12255/* continuation for OP_SGET_OBJECT_JUMBO */ 12256 12257 /* 12258 * Go resolve the field 12259 */ 12260.LOP_SGET_OBJECT_JUMBO_resolve: 12261 movl rSELF,%ecx 12262 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12263 movl offThread_method(%ecx),%ecx # ecx<- current method 12264 EXPORT_PC # could throw, need to export 12265 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12266 movl %eax,OUT_ARG1(%esp) 12267 movl %ecx,OUT_ARG0(%esp) 12268 call dvmResolveStaticField # eax<- resolved StaticField ptr 12269 testl %eax,%eax 12270 jne .LOP_SGET_OBJECT_JUMBO_finish # success, continue 12271 jmp common_exceptionThrown # no, handle exception 12272 12273/* continuation for OP_SGET_BOOLEAN_JUMBO */ 12274 12275 /* 12276 * Go resolve the field 12277 */ 12278.LOP_SGET_BOOLEAN_JUMBO_resolve: 12279 movl rSELF,%ecx 12280 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12281 movl offThread_method(%ecx),%ecx # ecx<- current method 12282 EXPORT_PC # could throw, need to export 12283 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12284 movl %eax,OUT_ARG1(%esp) 12285 movl %ecx,OUT_ARG0(%esp) 12286 call dvmResolveStaticField # eax<- resolved StaticField ptr 12287 testl %eax,%eax 12288 jne .LOP_SGET_BOOLEAN_JUMBO_finish # success, continue 12289 jmp common_exceptionThrown # no, handle exception 12290 12291/* continuation for OP_SGET_BYTE_JUMBO */ 12292 12293 /* 12294 * Go resolve the field 12295 */ 12296.LOP_SGET_BYTE_JUMBO_resolve: 12297 movl rSELF,%ecx 12298 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12299 movl offThread_method(%ecx),%ecx # ecx<- current method 12300 EXPORT_PC # could throw, need to export 12301 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12302 movl %eax,OUT_ARG1(%esp) 12303 movl %ecx,OUT_ARG0(%esp) 12304 call dvmResolveStaticField # eax<- resolved StaticField ptr 12305 testl %eax,%eax 12306 jne .LOP_SGET_BYTE_JUMBO_finish # success, continue 12307 jmp common_exceptionThrown # no, handle exception 12308 12309/* continuation for OP_SGET_CHAR_JUMBO */ 12310 12311 /* 12312 * Go resolve the field 12313 */ 12314.LOP_SGET_CHAR_JUMBO_resolve: 12315 movl rSELF,%ecx 12316 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12317 movl offThread_method(%ecx),%ecx # ecx<- current method 12318 EXPORT_PC # could throw, need to export 12319 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12320 movl %eax,OUT_ARG1(%esp) 12321 movl %ecx,OUT_ARG0(%esp) 12322 call dvmResolveStaticField # eax<- resolved StaticField ptr 12323 testl %eax,%eax 12324 jne .LOP_SGET_CHAR_JUMBO_finish # success, continue 12325 jmp common_exceptionThrown # no, handle exception 12326 12327/* continuation for OP_SGET_SHORT_JUMBO */ 12328 12329 /* 12330 * Go resolve the field 12331 */ 12332.LOP_SGET_SHORT_JUMBO_resolve: 12333 movl rSELF,%ecx 12334 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12335 movl offThread_method(%ecx),%ecx # ecx<- current method 12336 EXPORT_PC # could throw, need to export 12337 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12338 movl %eax,OUT_ARG1(%esp) 12339 movl %ecx,OUT_ARG0(%esp) 12340 call dvmResolveStaticField # eax<- resolved StaticField ptr 12341 testl %eax,%eax 12342 jne .LOP_SGET_SHORT_JUMBO_finish # success, continue 12343 jmp common_exceptionThrown # no, handle exception 12344 12345/* continuation for OP_SPUT_JUMBO */ 12346 12347 /* 12348 * Go resolve the field 12349 */ 12350.LOP_SPUT_JUMBO_resolve: 12351 movl rSELF,%ecx 12352 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12353 movl offThread_method(%ecx),%ecx # ecx<- current method 12354 EXPORT_PC # could throw, need to export 12355 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12356 movl %eax,OUT_ARG1(%esp) 12357 movl %ecx,OUT_ARG0(%esp) 12358 call dvmResolveStaticField # eax<- resolved StaticField ptr 12359 testl %eax,%eax 12360 jne .LOP_SPUT_JUMBO_finish # success, continue 12361 jmp common_exceptionThrown # no, handle exception 12362 12363/* continuation for OP_SPUT_WIDE_JUMBO */ 12364 12365 /* 12366 * Go resolve the field 12367 */ 12368.LOP_SPUT_WIDE_JUMBO_resolve: 12369 movl rSELF,%ecx 12370 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12371 movl offThread_method(%ecx),%ecx # ecx<- current method 12372 EXPORT_PC # could throw, need to export 12373 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12374 movl %eax,OUT_ARG1(%esp) 12375 movl %ecx,OUT_ARG0(%esp) 12376 call dvmResolveStaticField # eax<- resolved StaticField ptr 12377 testl %eax,%eax 12378 jne .LOP_SPUT_WIDE_JUMBO_finish # success, continue 12379 jmp common_exceptionThrown # no, handle exception 12380 12381/* continuation for OP_SPUT_OBJECT_JUMBO */ 12382 12383 12384.LOP_SPUT_OBJECT_JUMBO_continue: 12385 movl %ecx,offStaticField_value(%eax) # do the store 12386 testl %ecx,%ecx # stored null object ptr? 12387 FETCH_INST_OPCODE 4 %edx 12388 je 1f # skip card mark if null 12389 movl rSELF,%ecx 12390 movl offField_clazz(%eax),%eax # eax<- method->clazz 12391 movl offThread_cardTable(%ecx),%ecx # get card table base 12392 shrl $GC_CARD_SHIFT,%eax # head to card number 12393 movb %cl,(%ecx,%eax) # mark card 123941: 12395 ADVANCE_PC 4 12396 GOTO_NEXT_R %edx 12397 12398.LOP_SPUT_OBJECT_JUMBO_resolve: 12399 movl rSELF,%ecx 12400 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12401 movl offThread_method(%ecx),%ecx # ecx<- current method 12402 EXPORT_PC # could throw, need to export 12403 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12404 movl %eax,OUT_ARG1(%esp) 12405 movl %ecx,OUT_ARG0(%esp) 12406 call dvmResolveStaticField # eax<- resolved StaticField ptr 12407 testl %eax,%eax 12408 jne .LOP_SPUT_OBJECT_JUMBO_finish # success, continue 12409 jmp common_exceptionThrown # no, handle exception 12410 12411/* continuation for OP_SPUT_BOOLEAN_JUMBO */ 12412 12413 /* 12414 * Go resolve the field 12415 */ 12416.LOP_SPUT_BOOLEAN_JUMBO_resolve: 12417 movl rSELF,%ecx 12418 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12419 movl offThread_method(%ecx),%ecx # ecx<- current method 12420 EXPORT_PC # could throw, need to export 12421 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12422 movl %eax,OUT_ARG1(%esp) 12423 movl %ecx,OUT_ARG0(%esp) 12424 call dvmResolveStaticField # eax<- resolved StaticField ptr 12425 testl %eax,%eax 12426 jne .LOP_SPUT_BOOLEAN_JUMBO_finish # success, continue 12427 jmp common_exceptionThrown # no, handle exception 12428 12429/* continuation for OP_SPUT_BYTE_JUMBO */ 12430 12431 /* 12432 * Go resolve the field 12433 */ 12434.LOP_SPUT_BYTE_JUMBO_resolve: 12435 movl rSELF,%ecx 12436 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12437 movl offThread_method(%ecx),%ecx # ecx<- current method 12438 EXPORT_PC # could throw, need to export 12439 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12440 movl %eax,OUT_ARG1(%esp) 12441 movl %ecx,OUT_ARG0(%esp) 12442 call dvmResolveStaticField # eax<- resolved StaticField ptr 12443 testl %eax,%eax 12444 jne .LOP_SPUT_BYTE_JUMBO_finish # success, continue 12445 jmp common_exceptionThrown # no, handle exception 12446 12447/* continuation for OP_SPUT_CHAR_JUMBO */ 12448 12449 /* 12450 * Go resolve the field 12451 */ 12452.LOP_SPUT_CHAR_JUMBO_resolve: 12453 movl rSELF,%ecx 12454 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12455 movl offThread_method(%ecx),%ecx # ecx<- current method 12456 EXPORT_PC # could throw, need to export 12457 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12458 movl %eax,OUT_ARG1(%esp) 12459 movl %ecx,OUT_ARG0(%esp) 12460 call dvmResolveStaticField # eax<- resolved StaticField ptr 12461 testl %eax,%eax 12462 jne .LOP_SPUT_CHAR_JUMBO_finish # success, continue 12463 jmp common_exceptionThrown # no, handle exception 12464 12465/* continuation for OP_SPUT_SHORT_JUMBO */ 12466 12467 /* 12468 * Go resolve the field 12469 */ 12470.LOP_SPUT_SHORT_JUMBO_resolve: 12471 movl rSELF,%ecx 12472 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12473 movl offThread_method(%ecx),%ecx # ecx<- current method 12474 EXPORT_PC # could throw, need to export 12475 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12476 movl %eax,OUT_ARG1(%esp) 12477 movl %ecx,OUT_ARG0(%esp) 12478 call dvmResolveStaticField # eax<- resolved StaticField ptr 12479 testl %eax,%eax 12480 jne .LOP_SPUT_SHORT_JUMBO_finish # success, continue 12481 jmp common_exceptionThrown # no, handle exception 12482 12483/* continuation for OP_INVOKE_VIRTUAL_JUMBO */ 12484 12485 12486.LOP_INVOKE_VIRTUAL_JUMBO_more: 12487 movl offMethod_clazz(%eax),%eax # ecx<- method->clazz 12488 movl %eax,OUT_ARG0(%esp) # arg0<- clazz 12489 movl $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags 12490 call dvmResolveMethod # eax<- call(clazz, ref, flags) 12491 testl %eax,%eax # got null? 12492 jne .LOP_INVOKE_VIRTUAL_JUMBO_continue # no, continue 12493 jmp common_exceptionThrown # yes, handle exception 12494 12495 /* At this point: 12496 * eax = resolved base method 12497 * ecx = scratch 12498 */ 12499.LOP_INVOKE_VIRTUAL_JUMBO_continue: 12500 movzwl 8(rPC),%ecx # ecx<- CCCC 12501 GET_VREG_R %ecx %ecx # ecx<- "this" 12502 movzwl offMethod_methodIndex(%eax),%eax # eax<- baseMethod->methodIndex 12503 testl %ecx,%ecx # null this? 12504 je common_errNullObject # go if so 12505 movl offObject_clazz(%ecx),%ecx # ecx<- thisPtr->clazz 12506 movl offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable 12507 movl (%ecx,%eax,4),%eax # eax<- vtable[methodIndex] 12508 jmp common_invokeMethodJumbo 12509 12510/* continuation for OP_INVOKE_SUPER_JUMBO */ 12511 12512 /* 12513 * At this point: 12514 * ecx = resolved base method [r0] 12515 * eax = method->clazz [r9] 12516 */ 12517.LOP_INVOKE_SUPER_JUMBO_continue: 12518 movl offClassObject_super(%eax),%eax # eax<- method->clazz->super 12519 movzwl offMethod_methodIndex(%ecx),%ecx # ecx<- baseMthod->methodIndex 12520 cmpl offClassObject_vtableCount(%eax),%ecx # compare(methodIndex,vtableCount) 12521 jae .LOP_INVOKE_SUPER_JUMBO_nsm # method not present in superclass 12522 movl offClassObject_vtable(%eax),%eax # eax<- ...clazz->super->vtable 12523 movl (%eax,%ecx,4),%eax # eax<- vtable[methodIndex] 12524 jmp common_invokeMethodJumbo 12525 12526 12527 /* At this point: 12528 * ecx = null (needs to be resolved base method) 12529 * eax = method->clazz 12530 */ 12531.LOP_INVOKE_SUPER_JUMBO_resolve: 12532 SPILL_TMP1(%eax) # method->clazz 12533 movl %eax,OUT_ARG0(%esp) # arg0<- method->clazz 12534 movl 2(rPC),%ecx # ecx<- AAAAAAAA 12535 movl $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- resolver method type 12536 movl %ecx,OUT_ARG1(%esp) # arg1<- ref 12537 call dvmResolveMethod # eax<- call(clazz, ref, flags) 12538 testl %eax,%eax # got null? 12539 movl %eax,%ecx # ecx<- resolved base method 12540 UNSPILL_TMP1(%eax) # restore method->clazz 12541 jne .LOP_INVOKE_SUPER_JUMBO_continue # good to go - continue 12542 jmp common_exceptionThrown # handle exception 12543 12544 /* 12545 * Throw a NoSuchMethodError with the method name as the message. 12546 * ecx = resolved base method 12547 */ 12548.LOP_INVOKE_SUPER_JUMBO_nsm: 12549 movl offMethod_name(%ecx),%eax 12550 mov %eax,OUT_ARG1(%esp) 12551 jmp common_errNoSuchMethod 12552 12553/* continuation for OP_INVOKE_DIRECT_JUMBO */ 12554 12555 /* 12556 * On entry: 12557 * TMP_SPILL <- "this" register 12558 * Things a bit ugly on this path, but it's the less 12559 * frequent one. We'll have to do some reloading. 12560 */ 12561.LOP_INVOKE_DIRECT_JUMBO_resolve: 12562 SPILL_TMP1(%ecx) 12563 movl rSELF,%ecx 12564 movl offThread_method(%ecx),%ecx # ecx<- self->method 12565 movl 2(rPC),%eax # reference AAAAAAAA 12566 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12567 movl $METHOD_DIRECT,OUT_ARG2(%esp) 12568 movl %eax,OUT_ARG1(%esp) 12569 movl %ecx,OUT_ARG0(%esp) 12570 call dvmResolveMethod # eax<- call(clazz, ref, flags) 12571 UNSPILL_TMP1(%ecx) 12572 testl %eax,%eax 12573 jne .LOP_INVOKE_DIRECT_JUMBO_finish 12574 jmp common_exceptionThrown 12575 12576/* continuation for OP_INVOKE_STATIC_JUMBO */ 12577 12578.LOP_INVOKE_STATIC_JUMBO_continue: 12579 movl $METHOD_STATIC,%eax 12580 movl %eax,OUT_ARG2(%esp) # arg2<- flags 12581 call dvmResolveMethod # call(clazz,ref,flags) 12582 testl %eax,%eax # got null? 12583 jne common_invokeMethodJumbo 12584 jmp common_exceptionThrown 12585 12586/* continuation for OP_INVOKE_INTERFACE_JUMBO */ 12587 12588.LOP_INVOKE_INTERFACE_JUMBO_continue: 12589 call dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex) 12590 testl %eax,%eax 12591 je common_exceptionThrown 12592 jmp common_invokeMethodJumbo 12593 12594 .size dvmAsmSisterStart, .-dvmAsmSisterStart 12595 .global dvmAsmSisterEnd 12596dvmAsmSisterEnd: 12597 12598/* File: x86/entry.S */ 12599/* 12600 * Copyright (C) 2008 The Android Open Source Project 12601 * 12602 * Licensed under the Apache License, Version 2.0 (the "License"); 12603 * you may not use this file except in compliance with the License. 12604 * You may obtain a copy of the License at 12605 * 12606 * http://www.apache.org/licenses/LICENSE-2.0 12607 * 12608 * Unless required by applicable law or agreed to in writing, software 12609 * distributed under the License is distributed on an "AS IS" BASIS, 12610 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12611 * See the License for the specific language governing permissions and 12612 * limitations under the License. 12613 */ 12614 12615 12616 .text 12617 .global dvmMterpStdRun 12618 .type dvmMterpStdRun, %function 12619/* 12620 * bool dvmMterpStdRun(Thread* self) 12621 * 12622 * Interpreter entry point. Returns changeInterp. 12623 * 12624 */ 12625dvmMterpStdRun: 12626 movl 4(%esp), %ecx # get incoming rSELF 12627 push %ebp # save caller base pointer 12628 push %ecx # save rSELF at (%ebp) 12629 movl %esp, %ebp # set our %ebp 12630/* 12631 * At this point we've allocated two slots on the stack 12632 * via push and stack is 8-byte aligned. Allocate space 12633 * for 8 spill slots, 3 local slots, 5 arg slots + 2 slots for 12634 * padding to bring us to 16-byte alignment 12635 */ 12636 subl $(FRAME_SIZE-8), %esp 12637 12638/* Spill callee save regs */ 12639 movl %edi,EDI_SPILL(%ebp) 12640 movl %esi,ESI_SPILL(%ebp) 12641 movl %ebx,EBX_SPILL(%ebp) 12642 12643/* Set up "named" registers */ 12644 movl offThread_pc(%ecx),rPC 12645 movl offThread_fp(%ecx),rFP 12646 12647/* Remember %esp for future "longjmp" */ 12648 movl %esp,offThread_bailPtr(%ecx) 12649 12650/* How to start? */ 12651 movb offThread_entryPoint(%ecx),%al 12652 12653/* Normal start? */ 12654 cmpb $kInterpEntryInstr,%al 12655 jne .Lnot_instr 12656 12657 /* Normal case: start executing the instruction at rPC */ 12658 FETCH_INST 12659 GOTO_NEXT 12660 12661.Lnot_instr: 12662 /* Reset to normal case */ 12663 movb $kInterpEntryInstr,offThread_entryPoint(%ecx) 12664 cmpb $kInterpEntryReturn,%al 12665 je common_returnFromMethod 12666 cmpb $kInterpEntryThrow,%al 12667 je common_exceptionThrown 12668 movzx %al,%eax 12669 movl %eax,OUT_ARG1(%esp) 12670 movl $.LstrBadEntryPoint,OUT_ARG0(%esp) 12671 call printf 12672 call dvmAbort 12673 /* Not reached */ 12674 12675 12676 .global dvmMterpStdBail 12677 .type dvmMterpStdBail, %function 12678/* 12679 * void dvmMterpStdBail(Thread* self, bool changeInterp) 12680 * 12681 * Restore the stack pointer and PC from the save point established on entry. 12682 * This is essentially the same as a longjmp, but should be cheaper. The 12683 * last instruction causes us to return to whoever called dvmMterpStdRun. 12684 * 12685 * We're not going to build a standard frame here, so the arg accesses will 12686 * look a little strange. 12687 * 12688 * On entry: 12689 * esp+4 (arg0) Thread* self 12690 * esp+8 (arg1) bool changeInterp 12691 */ 12692dvmMterpStdBail: 12693 movl 4(%esp),%ecx # grab self 12694 movl 8(%esp),%eax # changeInterp to return reg 12695 movl offThread_bailPtr(%ecx),%esp # Restore "setjmp" esp 12696 movl %esp,%ebp 12697 addl $(FRAME_SIZE-8), %ebp # Restore %ebp at point of setjmp 12698 movl EDI_SPILL(%ebp),%edi 12699 movl ESI_SPILL(%ebp),%esi 12700 movl EBX_SPILL(%ebp),%ebx 12701 movl PREV_FP(%ebp),%ebp # restore caller's ebp 12702 addl $FRAME_SIZE,%esp # strip frame 12703 ret # return to dvmMterpStdRun's caller 12704 12705 12706/* 12707 * Strings 12708 */ 12709 .section .rodata 12710.LstrBadEntryPoint: 12711 .asciz "Bad entry point %d\n" 12712 12713 12714/* 12715 * FIXME: Should have the config/rebuild mechanism generate this 12716 * for targets that need it. 12717 */ 12718 12719/* Jump table */ 12720dvmAsmInstructionJmpTable = .LdvmAsmInstructionJmpTable 12721.LdvmAsmInstructionJmpTable: 12722.long .L_OP_NOP 12723.long .L_OP_MOVE 12724.long .L_OP_MOVE_FROM16 12725.long .L_OP_MOVE_16 12726.long .L_OP_MOVE_WIDE 12727.long .L_OP_MOVE_WIDE_FROM16 12728.long .L_OP_MOVE_WIDE_16 12729.long .L_OP_MOVE_OBJECT 12730.long .L_OP_MOVE_OBJECT_FROM16 12731.long .L_OP_MOVE_OBJECT_16 12732.long .L_OP_MOVE_RESULT 12733.long .L_OP_MOVE_RESULT_WIDE 12734.long .L_OP_MOVE_RESULT_OBJECT 12735.long .L_OP_MOVE_EXCEPTION 12736.long .L_OP_RETURN_VOID 12737.long .L_OP_RETURN 12738.long .L_OP_RETURN_WIDE 12739.long .L_OP_RETURN_OBJECT 12740.long .L_OP_CONST_4 12741.long .L_OP_CONST_16 12742.long .L_OP_CONST 12743.long .L_OP_CONST_HIGH16 12744.long .L_OP_CONST_WIDE_16 12745.long .L_OP_CONST_WIDE_32 12746.long .L_OP_CONST_WIDE 12747.long .L_OP_CONST_WIDE_HIGH16 12748.long .L_OP_CONST_STRING 12749.long .L_OP_CONST_STRING_JUMBO 12750.long .L_OP_CONST_CLASS 12751.long .L_OP_MONITOR_ENTER 12752.long .L_OP_MONITOR_EXIT 12753.long .L_OP_CHECK_CAST 12754.long .L_OP_INSTANCE_OF 12755.long .L_OP_ARRAY_LENGTH 12756.long .L_OP_NEW_INSTANCE 12757.long .L_OP_NEW_ARRAY 12758.long .L_OP_FILLED_NEW_ARRAY 12759.long .L_OP_FILLED_NEW_ARRAY_RANGE 12760.long .L_OP_FILL_ARRAY_DATA 12761.long .L_OP_THROW 12762.long .L_OP_GOTO 12763.long .L_OP_GOTO_16 12764.long .L_OP_GOTO_32 12765.long .L_OP_PACKED_SWITCH 12766.long .L_OP_SPARSE_SWITCH 12767.long .L_OP_CMPL_FLOAT 12768.long .L_OP_CMPG_FLOAT 12769.long .L_OP_CMPL_DOUBLE 12770.long .L_OP_CMPG_DOUBLE 12771.long .L_OP_CMP_LONG 12772.long .L_OP_IF_EQ 12773.long .L_OP_IF_NE 12774.long .L_OP_IF_LT 12775.long .L_OP_IF_GE 12776.long .L_OP_IF_GT 12777.long .L_OP_IF_LE 12778.long .L_OP_IF_EQZ 12779.long .L_OP_IF_NEZ 12780.long .L_OP_IF_LTZ 12781.long .L_OP_IF_GEZ 12782.long .L_OP_IF_GTZ 12783.long .L_OP_IF_LEZ 12784.long .L_OP_UNUSED_3E 12785.long .L_OP_UNUSED_3F 12786.long .L_OP_UNUSED_40 12787.long .L_OP_UNUSED_41 12788.long .L_OP_UNUSED_42 12789.long .L_OP_UNUSED_43 12790.long .L_OP_AGET 12791.long .L_OP_AGET_WIDE 12792.long .L_OP_AGET_OBJECT 12793.long .L_OP_AGET_BOOLEAN 12794.long .L_OP_AGET_BYTE 12795.long .L_OP_AGET_CHAR 12796.long .L_OP_AGET_SHORT 12797.long .L_OP_APUT 12798.long .L_OP_APUT_WIDE 12799.long .L_OP_APUT_OBJECT 12800.long .L_OP_APUT_BOOLEAN 12801.long .L_OP_APUT_BYTE 12802.long .L_OP_APUT_CHAR 12803.long .L_OP_APUT_SHORT 12804.long .L_OP_IGET 12805.long .L_OP_IGET_WIDE 12806.long .L_OP_IGET_OBJECT 12807.long .L_OP_IGET_BOOLEAN 12808.long .L_OP_IGET_BYTE 12809.long .L_OP_IGET_CHAR 12810.long .L_OP_IGET_SHORT 12811.long .L_OP_IPUT 12812.long .L_OP_IPUT_WIDE 12813.long .L_OP_IPUT_OBJECT 12814.long .L_OP_IPUT_BOOLEAN 12815.long .L_OP_IPUT_BYTE 12816.long .L_OP_IPUT_CHAR 12817.long .L_OP_IPUT_SHORT 12818.long .L_OP_SGET 12819.long .L_OP_SGET_WIDE 12820.long .L_OP_SGET_OBJECT 12821.long .L_OP_SGET_BOOLEAN 12822.long .L_OP_SGET_BYTE 12823.long .L_OP_SGET_CHAR 12824.long .L_OP_SGET_SHORT 12825.long .L_OP_SPUT 12826.long .L_OP_SPUT_WIDE 12827.long .L_OP_SPUT_OBJECT 12828.long .L_OP_SPUT_BOOLEAN 12829.long .L_OP_SPUT_BYTE 12830.long .L_OP_SPUT_CHAR 12831.long .L_OP_SPUT_SHORT 12832.long .L_OP_INVOKE_VIRTUAL 12833.long .L_OP_INVOKE_SUPER 12834.long .L_OP_INVOKE_DIRECT 12835.long .L_OP_INVOKE_STATIC 12836.long .L_OP_INVOKE_INTERFACE 12837.long .L_OP_UNUSED_73 12838.long .L_OP_INVOKE_VIRTUAL_RANGE 12839.long .L_OP_INVOKE_SUPER_RANGE 12840.long .L_OP_INVOKE_DIRECT_RANGE 12841.long .L_OP_INVOKE_STATIC_RANGE 12842.long .L_OP_INVOKE_INTERFACE_RANGE 12843.long .L_OP_UNUSED_79 12844.long .L_OP_UNUSED_7A 12845.long .L_OP_NEG_INT 12846.long .L_OP_NOT_INT 12847.long .L_OP_NEG_LONG 12848.long .L_OP_NOT_LONG 12849.long .L_OP_NEG_FLOAT 12850.long .L_OP_NEG_DOUBLE 12851.long .L_OP_INT_TO_LONG 12852.long .L_OP_INT_TO_FLOAT 12853.long .L_OP_INT_TO_DOUBLE 12854.long .L_OP_LONG_TO_INT 12855.long .L_OP_LONG_TO_FLOAT 12856.long .L_OP_LONG_TO_DOUBLE 12857.long .L_OP_FLOAT_TO_INT 12858.long .L_OP_FLOAT_TO_LONG 12859.long .L_OP_FLOAT_TO_DOUBLE 12860.long .L_OP_DOUBLE_TO_INT 12861.long .L_OP_DOUBLE_TO_LONG 12862.long .L_OP_DOUBLE_TO_FLOAT 12863.long .L_OP_INT_TO_BYTE 12864.long .L_OP_INT_TO_CHAR 12865.long .L_OP_INT_TO_SHORT 12866.long .L_OP_ADD_INT 12867.long .L_OP_SUB_INT 12868.long .L_OP_MUL_INT 12869.long .L_OP_DIV_INT 12870.long .L_OP_REM_INT 12871.long .L_OP_AND_INT 12872.long .L_OP_OR_INT 12873.long .L_OP_XOR_INT 12874.long .L_OP_SHL_INT 12875.long .L_OP_SHR_INT 12876.long .L_OP_USHR_INT 12877.long .L_OP_ADD_LONG 12878.long .L_OP_SUB_LONG 12879.long .L_OP_MUL_LONG 12880.long .L_OP_DIV_LONG 12881.long .L_OP_REM_LONG 12882.long .L_OP_AND_LONG 12883.long .L_OP_OR_LONG 12884.long .L_OP_XOR_LONG 12885.long .L_OP_SHL_LONG 12886.long .L_OP_SHR_LONG 12887.long .L_OP_USHR_LONG 12888.long .L_OP_ADD_FLOAT 12889.long .L_OP_SUB_FLOAT 12890.long .L_OP_MUL_FLOAT 12891.long .L_OP_DIV_FLOAT 12892.long .L_OP_REM_FLOAT 12893.long .L_OP_ADD_DOUBLE 12894.long .L_OP_SUB_DOUBLE 12895.long .L_OP_MUL_DOUBLE 12896.long .L_OP_DIV_DOUBLE 12897.long .L_OP_REM_DOUBLE 12898.long .L_OP_ADD_INT_2ADDR 12899.long .L_OP_SUB_INT_2ADDR 12900.long .L_OP_MUL_INT_2ADDR 12901.long .L_OP_DIV_INT_2ADDR 12902.long .L_OP_REM_INT_2ADDR 12903.long .L_OP_AND_INT_2ADDR 12904.long .L_OP_OR_INT_2ADDR 12905.long .L_OP_XOR_INT_2ADDR 12906.long .L_OP_SHL_INT_2ADDR 12907.long .L_OP_SHR_INT_2ADDR 12908.long .L_OP_USHR_INT_2ADDR 12909.long .L_OP_ADD_LONG_2ADDR 12910.long .L_OP_SUB_LONG_2ADDR 12911.long .L_OP_MUL_LONG_2ADDR 12912.long .L_OP_DIV_LONG_2ADDR 12913.long .L_OP_REM_LONG_2ADDR 12914.long .L_OP_AND_LONG_2ADDR 12915.long .L_OP_OR_LONG_2ADDR 12916.long .L_OP_XOR_LONG_2ADDR 12917.long .L_OP_SHL_LONG_2ADDR 12918.long .L_OP_SHR_LONG_2ADDR 12919.long .L_OP_USHR_LONG_2ADDR 12920.long .L_OP_ADD_FLOAT_2ADDR 12921.long .L_OP_SUB_FLOAT_2ADDR 12922.long .L_OP_MUL_FLOAT_2ADDR 12923.long .L_OP_DIV_FLOAT_2ADDR 12924.long .L_OP_REM_FLOAT_2ADDR 12925.long .L_OP_ADD_DOUBLE_2ADDR 12926.long .L_OP_SUB_DOUBLE_2ADDR 12927.long .L_OP_MUL_DOUBLE_2ADDR 12928.long .L_OP_DIV_DOUBLE_2ADDR 12929.long .L_OP_REM_DOUBLE_2ADDR 12930.long .L_OP_ADD_INT_LIT16 12931.long .L_OP_RSUB_INT 12932.long .L_OP_MUL_INT_LIT16 12933.long .L_OP_DIV_INT_LIT16 12934.long .L_OP_REM_INT_LIT16 12935.long .L_OP_AND_INT_LIT16 12936.long .L_OP_OR_INT_LIT16 12937.long .L_OP_XOR_INT_LIT16 12938.long .L_OP_ADD_INT_LIT8 12939.long .L_OP_RSUB_INT_LIT8 12940.long .L_OP_MUL_INT_LIT8 12941.long .L_OP_DIV_INT_LIT8 12942.long .L_OP_REM_INT_LIT8 12943.long .L_OP_AND_INT_LIT8 12944.long .L_OP_OR_INT_LIT8 12945.long .L_OP_XOR_INT_LIT8 12946.long .L_OP_SHL_INT_LIT8 12947.long .L_OP_SHR_INT_LIT8 12948.long .L_OP_USHR_INT_LIT8 12949.long .L_OP_IGET_VOLATILE 12950.long .L_OP_IPUT_VOLATILE 12951.long .L_OP_SGET_VOLATILE 12952.long .L_OP_SPUT_VOLATILE 12953.long .L_OP_IGET_OBJECT_VOLATILE 12954.long .L_OP_IGET_WIDE_VOLATILE 12955.long .L_OP_IPUT_WIDE_VOLATILE 12956.long .L_OP_SGET_WIDE_VOLATILE 12957.long .L_OP_SPUT_WIDE_VOLATILE 12958.long .L_OP_BREAKPOINT 12959.long .L_OP_THROW_VERIFICATION_ERROR 12960.long .L_OP_EXECUTE_INLINE 12961.long .L_OP_EXECUTE_INLINE_RANGE 12962.long .L_OP_INVOKE_OBJECT_INIT 12963.long .L_OP_RETURN_VOID_BARRIER 12964.long .L_OP_IGET_QUICK 12965.long .L_OP_IGET_WIDE_QUICK 12966.long .L_OP_IGET_OBJECT_QUICK 12967.long .L_OP_IPUT_QUICK 12968.long .L_OP_IPUT_WIDE_QUICK 12969.long .L_OP_IPUT_OBJECT_QUICK 12970.long .L_OP_INVOKE_VIRTUAL_QUICK 12971.long .L_OP_INVOKE_VIRTUAL_QUICK_RANGE 12972.long .L_OP_INVOKE_SUPER_QUICK 12973.long .L_OP_INVOKE_SUPER_QUICK_RANGE 12974.long .L_OP_IPUT_OBJECT_VOLATILE 12975.long .L_OP_SGET_OBJECT_VOLATILE 12976.long .L_OP_SPUT_OBJECT_VOLATILE 12977.long .L_OP_DISPATCH_FF 12978.long .L_OP_CONST_CLASS_JUMBO 12979.long .L_OP_CHECK_CAST_JUMBO 12980.long .L_OP_INSTANCE_OF_JUMBO 12981.long .L_OP_NEW_INSTANCE_JUMBO 12982.long .L_OP_NEW_ARRAY_JUMBO 12983.long .L_OP_FILLED_NEW_ARRAY_JUMBO 12984.long .L_OP_IGET_JUMBO 12985.long .L_OP_IGET_WIDE_JUMBO 12986.long .L_OP_IGET_OBJECT_JUMBO 12987.long .L_OP_IGET_BOOLEAN_JUMBO 12988.long .L_OP_IGET_BYTE_JUMBO 12989.long .L_OP_IGET_CHAR_JUMBO 12990.long .L_OP_IGET_SHORT_JUMBO 12991.long .L_OP_IPUT_JUMBO 12992.long .L_OP_IPUT_WIDE_JUMBO 12993.long .L_OP_IPUT_OBJECT_JUMBO 12994.long .L_OP_IPUT_BOOLEAN_JUMBO 12995.long .L_OP_IPUT_BYTE_JUMBO 12996.long .L_OP_IPUT_CHAR_JUMBO 12997.long .L_OP_IPUT_SHORT_JUMBO 12998.long .L_OP_SGET_JUMBO 12999.long .L_OP_SGET_WIDE_JUMBO 13000.long .L_OP_SGET_OBJECT_JUMBO 13001.long .L_OP_SGET_BOOLEAN_JUMBO 13002.long .L_OP_SGET_BYTE_JUMBO 13003.long .L_OP_SGET_CHAR_JUMBO 13004.long .L_OP_SGET_SHORT_JUMBO 13005.long .L_OP_SPUT_JUMBO 13006.long .L_OP_SPUT_WIDE_JUMBO 13007.long .L_OP_SPUT_OBJECT_JUMBO 13008.long .L_OP_SPUT_BOOLEAN_JUMBO 13009.long .L_OP_SPUT_BYTE_JUMBO 13010.long .L_OP_SPUT_CHAR_JUMBO 13011.long .L_OP_SPUT_SHORT_JUMBO 13012.long .L_OP_INVOKE_VIRTUAL_JUMBO 13013.long .L_OP_INVOKE_SUPER_JUMBO 13014.long .L_OP_INVOKE_DIRECT_JUMBO 13015.long .L_OP_INVOKE_STATIC_JUMBO 13016.long .L_OP_INVOKE_INTERFACE_JUMBO 13017.long .L_OP_UNUSED_27FF 13018.long .L_OP_UNUSED_28FF 13019.long .L_OP_UNUSED_29FF 13020.long .L_OP_UNUSED_2AFF 13021.long .L_OP_UNUSED_2BFF 13022.long .L_OP_UNUSED_2CFF 13023.long .L_OP_UNUSED_2DFF 13024.long .L_OP_UNUSED_2EFF 13025.long .L_OP_UNUSED_2FFF 13026.long .L_OP_UNUSED_30FF 13027.long .L_OP_UNUSED_31FF 13028.long .L_OP_UNUSED_32FF 13029.long .L_OP_UNUSED_33FF 13030.long .L_OP_UNUSED_34FF 13031.long .L_OP_UNUSED_35FF 13032.long .L_OP_UNUSED_36FF 13033.long .L_OP_UNUSED_37FF 13034.long .L_OP_UNUSED_38FF 13035.long .L_OP_UNUSED_39FF 13036.long .L_OP_UNUSED_3AFF 13037.long .L_OP_UNUSED_3BFF 13038.long .L_OP_UNUSED_3CFF 13039.long .L_OP_UNUSED_3DFF 13040.long .L_OP_UNUSED_3EFF 13041.long .L_OP_UNUSED_3FFF 13042.long .L_OP_UNUSED_40FF 13043.long .L_OP_UNUSED_41FF 13044.long .L_OP_UNUSED_42FF 13045.long .L_OP_UNUSED_43FF 13046.long .L_OP_UNUSED_44FF 13047.long .L_OP_UNUSED_45FF 13048.long .L_OP_UNUSED_46FF 13049.long .L_OP_UNUSED_47FF 13050.long .L_OP_UNUSED_48FF 13051.long .L_OP_UNUSED_49FF 13052.long .L_OP_UNUSED_4AFF 13053.long .L_OP_UNUSED_4BFF 13054.long .L_OP_UNUSED_4CFF 13055.long .L_OP_UNUSED_4DFF 13056.long .L_OP_UNUSED_4EFF 13057.long .L_OP_UNUSED_4FFF 13058.long .L_OP_UNUSED_50FF 13059.long .L_OP_UNUSED_51FF 13060.long .L_OP_UNUSED_52FF 13061.long .L_OP_UNUSED_53FF 13062.long .L_OP_UNUSED_54FF 13063.long .L_OP_UNUSED_55FF 13064.long .L_OP_UNUSED_56FF 13065.long .L_OP_UNUSED_57FF 13066.long .L_OP_UNUSED_58FF 13067.long .L_OP_UNUSED_59FF 13068.long .L_OP_UNUSED_5AFF 13069.long .L_OP_UNUSED_5BFF 13070.long .L_OP_UNUSED_5CFF 13071.long .L_OP_UNUSED_5DFF 13072.long .L_OP_UNUSED_5EFF 13073.long .L_OP_UNUSED_5FFF 13074.long .L_OP_UNUSED_60FF 13075.long .L_OP_UNUSED_61FF 13076.long .L_OP_UNUSED_62FF 13077.long .L_OP_UNUSED_63FF 13078.long .L_OP_UNUSED_64FF 13079.long .L_OP_UNUSED_65FF 13080.long .L_OP_UNUSED_66FF 13081.long .L_OP_UNUSED_67FF 13082.long .L_OP_UNUSED_68FF 13083.long .L_OP_UNUSED_69FF 13084.long .L_OP_UNUSED_6AFF 13085.long .L_OP_UNUSED_6BFF 13086.long .L_OP_UNUSED_6CFF 13087.long .L_OP_UNUSED_6DFF 13088.long .L_OP_UNUSED_6EFF 13089.long .L_OP_UNUSED_6FFF 13090.long .L_OP_UNUSED_70FF 13091.long .L_OP_UNUSED_71FF 13092.long .L_OP_UNUSED_72FF 13093.long .L_OP_UNUSED_73FF 13094.long .L_OP_UNUSED_74FF 13095.long .L_OP_UNUSED_75FF 13096.long .L_OP_UNUSED_76FF 13097.long .L_OP_UNUSED_77FF 13098.long .L_OP_UNUSED_78FF 13099.long .L_OP_UNUSED_79FF 13100.long .L_OP_UNUSED_7AFF 13101.long .L_OP_UNUSED_7BFF 13102.long .L_OP_UNUSED_7CFF 13103.long .L_OP_UNUSED_7DFF 13104.long .L_OP_UNUSED_7EFF 13105.long .L_OP_UNUSED_7FFF 13106.long .L_OP_UNUSED_80FF 13107.long .L_OP_UNUSED_81FF 13108.long .L_OP_UNUSED_82FF 13109.long .L_OP_UNUSED_83FF 13110.long .L_OP_UNUSED_84FF 13111.long .L_OP_UNUSED_85FF 13112.long .L_OP_UNUSED_86FF 13113.long .L_OP_UNUSED_87FF 13114.long .L_OP_UNUSED_88FF 13115.long .L_OP_UNUSED_89FF 13116.long .L_OP_UNUSED_8AFF 13117.long .L_OP_UNUSED_8BFF 13118.long .L_OP_UNUSED_8CFF 13119.long .L_OP_UNUSED_8DFF 13120.long .L_OP_UNUSED_8EFF 13121.long .L_OP_UNUSED_8FFF 13122.long .L_OP_UNUSED_90FF 13123.long .L_OP_UNUSED_91FF 13124.long .L_OP_UNUSED_92FF 13125.long .L_OP_UNUSED_93FF 13126.long .L_OP_UNUSED_94FF 13127.long .L_OP_UNUSED_95FF 13128.long .L_OP_UNUSED_96FF 13129.long .L_OP_UNUSED_97FF 13130.long .L_OP_UNUSED_98FF 13131.long .L_OP_UNUSED_99FF 13132.long .L_OP_UNUSED_9AFF 13133.long .L_OP_UNUSED_9BFF 13134.long .L_OP_UNUSED_9CFF 13135.long .L_OP_UNUSED_9DFF 13136.long .L_OP_UNUSED_9EFF 13137.long .L_OP_UNUSED_9FFF 13138.long .L_OP_UNUSED_A0FF 13139.long .L_OP_UNUSED_A1FF 13140.long .L_OP_UNUSED_A2FF 13141.long .L_OP_UNUSED_A3FF 13142.long .L_OP_UNUSED_A4FF 13143.long .L_OP_UNUSED_A5FF 13144.long .L_OP_UNUSED_A6FF 13145.long .L_OP_UNUSED_A7FF 13146.long .L_OP_UNUSED_A8FF 13147.long .L_OP_UNUSED_A9FF 13148.long .L_OP_UNUSED_AAFF 13149.long .L_OP_UNUSED_ABFF 13150.long .L_OP_UNUSED_ACFF 13151.long .L_OP_UNUSED_ADFF 13152.long .L_OP_UNUSED_AEFF 13153.long .L_OP_UNUSED_AFFF 13154.long .L_OP_UNUSED_B0FF 13155.long .L_OP_UNUSED_B1FF 13156.long .L_OP_UNUSED_B2FF 13157.long .L_OP_UNUSED_B3FF 13158.long .L_OP_UNUSED_B4FF 13159.long .L_OP_UNUSED_B5FF 13160.long .L_OP_UNUSED_B6FF 13161.long .L_OP_UNUSED_B7FF 13162.long .L_OP_UNUSED_B8FF 13163.long .L_OP_UNUSED_B9FF 13164.long .L_OP_UNUSED_BAFF 13165.long .L_OP_UNUSED_BBFF 13166.long .L_OP_UNUSED_BCFF 13167.long .L_OP_UNUSED_BDFF 13168.long .L_OP_UNUSED_BEFF 13169.long .L_OP_UNUSED_BFFF 13170.long .L_OP_UNUSED_C0FF 13171.long .L_OP_UNUSED_C1FF 13172.long .L_OP_UNUSED_C2FF 13173.long .L_OP_UNUSED_C3FF 13174.long .L_OP_UNUSED_C4FF 13175.long .L_OP_UNUSED_C5FF 13176.long .L_OP_UNUSED_C6FF 13177.long .L_OP_UNUSED_C7FF 13178.long .L_OP_UNUSED_C8FF 13179.long .L_OP_UNUSED_C9FF 13180.long .L_OP_UNUSED_CAFF 13181.long .L_OP_UNUSED_CBFF 13182.long .L_OP_UNUSED_CCFF 13183.long .L_OP_UNUSED_CDFF 13184.long .L_OP_UNUSED_CEFF 13185.long .L_OP_UNUSED_CFFF 13186.long .L_OP_UNUSED_D0FF 13187.long .L_OP_UNUSED_D1FF 13188.long .L_OP_UNUSED_D2FF 13189.long .L_OP_UNUSED_D3FF 13190.long .L_OP_UNUSED_D4FF 13191.long .L_OP_UNUSED_D5FF 13192.long .L_OP_UNUSED_D6FF 13193.long .L_OP_UNUSED_D7FF 13194.long .L_OP_UNUSED_D8FF 13195.long .L_OP_UNUSED_D9FF 13196.long .L_OP_UNUSED_DAFF 13197.long .L_OP_UNUSED_DBFF 13198.long .L_OP_UNUSED_DCFF 13199.long .L_OP_UNUSED_DDFF 13200.long .L_OP_UNUSED_DEFF 13201.long .L_OP_UNUSED_DFFF 13202.long .L_OP_UNUSED_E0FF 13203.long .L_OP_UNUSED_E1FF 13204.long .L_OP_UNUSED_E2FF 13205.long .L_OP_UNUSED_E3FF 13206.long .L_OP_UNUSED_E4FF 13207.long .L_OP_UNUSED_E5FF 13208.long .L_OP_UNUSED_E6FF 13209.long .L_OP_UNUSED_E7FF 13210.long .L_OP_UNUSED_E8FF 13211.long .L_OP_UNUSED_E9FF 13212.long .L_OP_UNUSED_EAFF 13213.long .L_OP_UNUSED_EBFF 13214.long .L_OP_UNUSED_ECFF 13215.long .L_OP_UNUSED_EDFF 13216.long .L_OP_UNUSED_EEFF 13217.long .L_OP_UNUSED_EFFF 13218.long .L_OP_UNUSED_F0FF 13219.long .L_OP_UNUSED_F1FF 13220.long .L_OP_UNUSED_F2FF 13221.long .L_OP_UNUSED_F3FF 13222.long .L_OP_UNUSED_F4FF 13223.long .L_OP_UNUSED_F5FF 13224.long .L_OP_UNUSED_F6FF 13225.long .L_OP_UNUSED_F7FF 13226.long .L_OP_UNUSED_F8FF 13227.long .L_OP_UNUSED_F9FF 13228.long .L_OP_UNUSED_FAFF 13229.long .L_OP_UNUSED_FBFF 13230.long .L_OP_UNUSED_FCFF 13231.long .L_OP_UNUSED_FDFF 13232.long .L_OP_UNUSED_FEFF 13233.long .L_OP_THROW_VERIFICATION_ERROR_JUMBO 13234 13235/* File: x86/footer.S */ 13236/* 13237 * Copyright (C) 2008 The Android Open Source Project 13238 * 13239 * Licensed under the Apache License, Version 2.0 (the "License"); 13240 * you may not use this file except in compliance with the License. 13241 * You may obtain a copy of the License at 13242 * 13243 * http://www.apache.org/licenses/LICENSE-2.0 13244 * 13245 * Unless required by applicable law or agreed to in writing, software 13246 * distributed under the License is distributed on an "AS IS" BASIS, 13247 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13248 * See the License for the specific language governing permissions and 13249 * limitations under the License. 13250 */ 13251/* 13252 * Common subroutines and data. 13253 */ 13254 13255#if defined(WITH_JIT) 13256/* 13257 * JIT-related re-entries into the interpreter. In general, if the 13258 * exit from a translation can at some point be chained, the entry 13259 * here requires that control arrived via a call, and that the "rp" 13260 * on TOS is actually a pointer to a 32-bit cell containing the Dalvik PC 13261 * of the next insn to handle. If no chaining will happen, the entry 13262 * should be reached via a direct jump and rPC set beforehand. 13263 */ 13264 13265 .global dvmJitToInterpPunt 13266/* 13267 * The compiler will generate a jump to this entry point when it is 13268 * having difficulty translating a Dalvik instruction. We must skip 13269 * the code cache lookup & prevent chaining to avoid bouncing between 13270 * the interpreter and code cache. rPC must be set on entry. 13271 */ 13272dvmJitToInterpPunt: 13273#if defined(WITH_JIT_TUNING) 13274 movl rPC, OUT_ARG0(%esp) 13275 call dvmBumpPunt 13276#endif 13277 FETCH_INST_R %edx 13278 GOTO_NEXT_R %edx 13279 13280 .global dvmJitToInterpSingleStep 13281/* 13282 * Return to the interpreter to handle a single instruction. 13283 * Should be reached via a call. 13284 * On entry: 13285 * 0(%esp) <= native return address within trace 13286 * rPC <= Dalvik PC of this instruction 13287 * OUT_ARG0+4(%esp) <= Dalvik PC of next instruction 13288 */ 13289dvmJitToInterpSingleStep: 13290 pop %eax 13291 movl rSELF, %ecx 13292 movl OUT_ARG0(%esp), %edx 13293 movl %eax,offThread_jitResumeNPC(%ecx) 13294 movl %edx,offThread_jitResumeDPC(%ecx) 13295 movl $kInterpEntryInstr,offThread_entryPoint(%ecx) 13296 movl $1,rINST # changeInterp <= true 13297 jmp common_gotoBail 13298 13299 .global dvmJitToInterpNoChainNoProfile 13300/* 13301 * Return from the translation cache to the interpreter to do method 13302 * invocation. Check if the translation exists for the callee, but don't 13303 * chain to it. rPC must be set on entry. 13304 */ 13305dvmJitToInterpNoChainNoProfile: 13306#if defined(WITH_JIT_TUNING) 13307 call dvmBumpNoChain 13308#endif 13309 movl rPC,OUT_ARG0(%esp) 13310 call dvmJitGetTraceAddr # is there a translation? 13311 movl rSELF,%ecx # ecx <- self 13312 movl %eax,offThread_inJitCodeCache(%ecx) # set inJitCodeCache flag 13313 cmpl $0, %eax 13314 jz 1f 13315 call *%eax # exec translation if we've got one 13316 # won't return 133171: 13318 FETCH_INST_R %edx 13319 GOTO_NEXT_R %edx 13320 13321/* 13322 * Return from the translation cache and immediately request a 13323 * translation fro the exit target, but don't attempt to chain. 13324 * rPC set on entry. 13325 */ 13326 .global dvmJitToInterpTraceSelectNoChain 13327dvmJitToInterpTraceSelectNoChain: 13328#if defined(WITH_JIT_TUNING) 13329 call dvmBumpNoChain 13330#endif 13331 movl rPC,OUT_ARG0(%esp) 13332 call dvmJitGetTraceAddr # is there a translation? 13333 movl rSELF,%ecx 13334 cmpl $0,%eax 13335 movl %eax,offThread_inJitCodeCache(%ecx) # set inJitCodeCache flag 13336 jz 1f 13337 call *%eax # jump to tranlation 13338 # won't return 13339 13340/* No Translation - request one */ 133411: 13342 GET_JIT_PROF_TABLE %ecx %eax 13343 cmpl $0, %eax # JIT enabled? 13344 jnz 2f # Request one if so 13345 FETCH_INST_R %edx # Continue interpreting if not 13346 GOTO_NEXT_R %edx 133472: 13348 movl $kJitTSelectRequestHot,rINST # ask for trace select 13349 jmp common_selectTrace 13350 13351/* 13352 * Return from the translation cache and immediately request a 13353 * translation for the exit target. Reached via a call, and 13354 * (TOS)->rPC. 13355 */ 13356 .global dvmJitToInterpTraceSelect 13357dvmJitToInterpTraceSelect: 13358 pop rINST # save chain cell address in callee save reg 13359 movl (rINST),rPC 13360 movl rPC,OUT_ARG0(%esp) 13361 call dvmJitGetTraceAddr # is there a translation? 13362 cmpl $0,%eax 13363 jz 1b # no - ask for one 13364 movl %eax,OUT_ARG0(%esp) 13365# FIXME - need to adjust rINST to beginning of sequence 13366 movl rINST,OUT_ARG1(%esp) 13367 call dvmJitChain # Attempt dvmJitChain(codeAddr,chainAddr) 13368 cmpl $0,%eax # Success? 13369 jz toInterpreter # didn't chain - interpret 13370 call *%eax 13371 # won't return 13372 13373/* 13374 * Placeholder entries for x86 JIT 13375 */ 13376 .global dvmJitToInterpBackwardBranch 13377dvmJitToInterpBackwardBranch: 13378 .global dvmJitToInterpNormal 13379dvmJitToInterpNormal: 13380 .global dvmJitToInterpNoChain 13381dvmJitToInterpNoChain: 13382toInterpreter: 13383 jmp common_abort 13384#endif 13385 13386/* 13387 * Common code when a backwards branch is taken 13388 * 13389 * On entry: 13390 * ebx (a.k.a. rINST) -> PC adjustment in 16-bit words 13391 */ 13392common_backwardBranch: 13393 movl rSELF,%ecx 13394 call common_periodicChecks # rPC and ecx/rSELF preserved 13395#if defined(WITH_JIT) 13396 GET_JIT_PROF_TABLE %ecx %edx 13397 ADVANCE_PC_INDEXED rINST 13398 cmpl $0,%edx 13399 FETCH_INST 13400 jz 1f # Profiling off - continue 13401 .global updateProfile 13402updateProfile: 13403common_updateProfile: 13404 # quick & dirty hash 13405 movl rPC, %eax 13406 shrl $12, %eax 13407 xorl rPC, %eax 13408 andl $((1<<JIT_PROF_SIZE_LOG_2)-1),%eax 13409 decb (%edx,%eax) 13410 jz 2f 134111: 13412 GOTO_NEXT 134132: 13414/* 13415 * Here, we switch to the debug interpreter to request 13416 * trace selection. First, though, check to see if there 13417 * is already a native translation in place (and, if so, 13418 * jump to it now. 13419 */ 13420 GET_JIT_THRESHOLD %ecx rINST # leaves rSELF in %ecx 13421 EXPORT_PC 13422 movb rINSTbl,(%edx,%eax) # reset counter 13423 movl %ecx,rINST # preserve rSELF 13424 movl rPC,OUT_ARG0(%esp) 13425 call dvmJitGetTraceAddr # already have one? 13426 movl %eax,offThread_inJitCodeCache(rINST) # set the inJitCodeCache flag 13427 cmpl $0,%eax 13428 jz 1f 13429 call *%eax # FIXME: decide call vs/ jmp!. No return either way 134301: 13431 movl $kJitTSelectRequest,%eax 13432 # On entry, eax<- jitState, rPC valid 13433common_selectTrace: 13434 13435 movl rSELF,%ecx 13436 movl %eax,offThread_jitState(%ecx) 13437 movl $kInterpEntryInstr,offThread_entryPoint(%ecx) 13438 movl $1,rINST 13439 jmp common_gotoBail 13440#else 13441 ADVANCE_PC_INDEXED rINST 13442 FETCH_INST 13443 GOTO_NEXT 13444#endif 13445 13446 13447 13448/* 13449 * Common code for jumbo method invocation. 13450 * 13451 * On entry: 13452 * eax = Method* methodToCall 13453 * rINSTw trashed, must reload 13454 */ 13455 13456common_invokeMethodJumbo: 13457.LinvokeNewJumbo: 13458 13459 /* 13460 * prepare to copy args to "outs" area of current frame 13461 */ 13462 movzwl 6(rPC),rINST # rINST<- BBBB 13463 movzwl 8(rPC), %ecx # %ecx<- CCCC 13464 ADVANCE_PC 2 # adjust pc to make return similar 13465 SAVEAREA_FROM_FP %edx # %edx<- &StackSaveArea 13466 test rINST, rINST 13467 movl rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- BBBB 13468 jz .LinvokeArgsDone # no args; jump to args done 13469 jmp .LinvokeRangeArgs # handle args like invoke range 13470 13471/* 13472 * Common code for method invocation with range. 13473 * 13474 * On entry: 13475 * eax = Method* methodToCall 13476 * rINSTw trashed, must reload 13477 */ 13478 13479common_invokeMethodRange: 13480.LinvokeNewRange: 13481 13482 /* 13483 * prepare to copy args to "outs" area of current frame 13484 */ 13485 13486 movzbl 1(rPC),rINST # rINST<- AA 13487 movzwl 4(rPC), %ecx # %ecx<- CCCC 13488 SAVEAREA_FROM_FP %edx # %edx<- &StackSaveArea 13489 test rINST, rINST 13490 movl rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- AA 13491 jz .LinvokeArgsDone # no args; jump to args done 13492 13493 13494 /* 13495 * %eax=methodToCall, %ecx=CCCC, LOCAL0_OFFSET(%ebp)=count, %edx=&outs (&stackSaveArea) 13496 * (very few methods have > 10 args; could unroll for common cases) 13497 */ 13498 13499.LinvokeRangeArgs: 13500 movl %ebx, LOCAL1_OFFSET(%ebp) # LOCAL1_OFFSET(%ebp)<- save %ebx 13501 lea (rFP, %ecx, 4), %ecx # %ecx<- &vCCCC 13502 shll $2, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- offset 13503 subl LOCAL0_OFFSET(%ebp), %edx # %edx<- update &outs 13504 shrl $2, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- offset 135051: 13506 movl (%ecx), %ebx # %ebx<- vCCCC 13507 lea 4(%ecx), %ecx # %ecx<- &vCCCC++ 13508 subl $1, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET<- LOCAL0_OFFSET-- 13509 movl %ebx, (%edx) # *outs<- vCCCC 13510 lea 4(%edx), %edx # outs++ 13511 jne 1b # loop if count (LOCAL0_OFFSET(%ebp)) not zero 13512 movl LOCAL1_OFFSET(%ebp), %ebx # %ebx<- restore %ebx 13513 jmp .LinvokeArgsDone # continue 13514 13515 /* 13516 * %eax is "Method* methodToCall", the method we're trying to call 13517 * prepare to copy args to "outs" area of current frame 13518 */ 13519 13520common_invokeMethodNoRange: 13521.LinvokeNewNoRange: 13522 movzbl 1(rPC),rINST # rINST<- BA 13523 movl rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- BA 13524 shrl $4, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- B 13525 je .LinvokeArgsDone # no args; jump to args done 13526 movzwl 4(rPC), %ecx # %ecx<- GFED 13527 SAVEAREA_FROM_FP %edx # %edx<- &StackSaveArea 13528 13529 /* 13530 * %eax=methodToCall, %ecx=GFED, LOCAL0_OFFSET(%ebp)=count, %edx=outs 13531 */ 13532 13533.LinvokeNonRange: 13534 cmp $2, LOCAL0_OFFSET(%ebp) # compare LOCAL0_OFFSET(%ebp) to 2 13535 movl %ecx, LOCAL1_OFFSET(%ebp) # LOCAL1_OFFSET(%ebp)<- GFED 13536 jl 1f # handle 1 arg 13537 je 2f # handle 2 args 13538 cmp $4, LOCAL0_OFFSET(%ebp) # compare LOCAL0_OFFSET(%ebp) to 4 13539 jl 3f # handle 3 args 13540 je 4f # handle 4 args 135415: 13542 andl $15, rINST # rINSTw<- A 13543 lea -4(%edx), %edx # %edx<- update &outs; &outs-- 13544 movl (rFP, rINST, 4), %ecx # %ecx<- vA 13545 movl %ecx, (%edx) # *outs<- vA 13546 movl LOCAL1_OFFSET(%ebp), %ecx # %ecx<- GFED 135474: 13548 shr $12, %ecx # %ecx<- G 13549 lea -4(%edx), %edx # %edx<- update &outs; &outs-- 13550 movl (rFP, %ecx, 4), %ecx # %ecx<- vG 13551 movl %ecx, (%edx) # *outs<- vG 13552 movl LOCAL1_OFFSET(%ebp), %ecx # %ecx<- GFED 135533: 13554 and $0x0f00, %ecx # %ecx<- 0F00 13555 shr $8, %ecx # %ecx<- F 13556 lea -4(%edx), %edx # %edx<- update &outs; &outs-- 13557 movl (rFP, %ecx, 4), %ecx # %ecx<- vF 13558 movl %ecx, (%edx) # *outs<- vF 13559 movl LOCAL1_OFFSET(%ebp), %ecx # %ecx<- GFED 135602: 13561 and $0x00f0, %ecx # %ecx<- 00E0 13562 shr $4, %ecx # %ecx<- E 13563 lea -4(%edx), %edx # %edx<- update &outs; &outs-- 13564 movl (rFP, %ecx, 4), %ecx # %ecx<- vE 13565 movl %ecx, (%edx) # *outs<- vE 13566 movl LOCAL1_OFFSET(%ebp), %ecx # %ecx<- GFED 135671: 13568 and $0x000f, %ecx # %ecx<- 000D 13569 movl (rFP, %ecx, 4), %ecx # %ecx<- vD 13570 movl %ecx, -4(%edx) # *--outs<- vD 135710: 13572 13573 /* 13574 * %eax is "Method* methodToCall", the method we're trying to call 13575 * find space for the new stack frame, check for overflow 13576 */ 13577 13578.LinvokeArgsDone: 13579 movzwl offMethod_registersSize(%eax), %edx # %edx<- methodToCall->regsSize 13580 movzwl offMethod_outsSize(%eax), %ecx # %ecx<- methodToCall->outsSize 13581 movl %eax, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET<- methodToCall 13582 shl $2, %edx # %edx<- update offset 13583 SAVEAREA_FROM_FP %eax # %eax<- &StackSaveArea 13584 subl %edx, %eax # %eax<- newFP; (old savearea - regsSize) 13585 movl rSELF,%edx # %edx<- pthread 13586 movl %eax, LOCAL1_OFFSET(%ebp) # LOCAL1_OFFSET(%ebp)<- &outs 13587 subl $sizeofStackSaveArea, %eax # %eax<- newSaveArea (stack save area using newFP) 13588 movl offThread_interpStackEnd(%edx), %edx # %edx<- self->interpStackEnd 13589 movl %edx, LOCAL2_OFFSET(%ebp) # LOCAL2_OFFSET<- self->interpStackEnd 13590 shl $2, %ecx # %ecx<- update offset for outsSize 13591 movl %eax, %edx # %edx<- newSaveArea 13592 sub %ecx, %eax # %eax<- bottom; (newSaveArea - outsSize) 13593 cmp LOCAL2_OFFSET(%ebp), %eax # compare interpStackEnd and bottom 13594 movl LOCAL0_OFFSET(%ebp), %eax # %eax<- restore methodToCall 13595 jl .LstackOverflow # handle frame overflow 13596 13597 /* 13598 * set up newSaveArea 13599 */ 13600 13601#ifdef EASY_GDB 13602 SAVEAREA_FROM_FP %ecx # %ecx<- &StackSaveArea 13603 movl %ecx, offStackSaveArea_prevSave(%edx) # newSaveArea->prevSave<- &outs 13604#endif 13605 movl rFP, offStackSaveArea_prevFrame(%edx) # newSaveArea->prevFrame<- rFP 13606 movl rPC, offStackSaveArea_savedPc(%edx) # newSaveArea->savedPc<- rPC 13607 testl $ACC_NATIVE, offMethod_accessFlags(%eax) # check for native call 13608 movl %eax, offStackSaveArea_method(%edx) # newSaveArea->method<- method to call 13609 jne .LinvokeNative # handle native call 13610 13611 /* 13612 * Update "self" values for the new method 13613 * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFp 13614 */ 13615 13616 movl offMethod_clazz(%eax), %edx # %edx<- method->clazz 13617 movl rSELF,%ecx # %ecx<- pthread 13618 movl offClassObject_pDvmDex(%edx), %edx # %edx<- method->clazz->pDvmDex 13619 movl %eax, offThread_method(%ecx) # self->method<- methodToCall 13620 movl %edx, offThread_methodClassDex(%ecx) # self->methodClassDex<- method->clazz->pDvmDex 13621 movl offMethod_insns(%eax), rPC # rPC<- methodToCall->insns 13622 movl LOCAL1_OFFSET(%ebp), rFP # rFP<- newFP 13623 movl rFP, offThread_curFrame(%ecx) # self->curFrame<- newFP 13624 FETCH_INST 13625 GOTO_NEXT # jump to methodToCall->insns 13626 13627 /* 13628 * Prep for the native call 13629 * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFP, %edx=newSaveArea 13630 */ 13631 13632.LinvokeNative: 13633 movl rSELF,%ecx # %ecx<- pthread 13634 movl %eax, OUT_ARG1(%esp) # push parameter methodToCall 13635 movl offThread_jniLocal_topCookie(%ecx), %eax # %eax<- self->localRef->... 13636 movl %eax, offStackSaveArea_localRefCookie(%edx) # newSaveArea->localRefCookie<- top 13637 movl %edx, OUT_ARG4(%esp) # save newSaveArea 13638 movl LOCAL1_OFFSET(%ebp), %edx # %edx<- newFP 13639 movl %edx, offThread_curFrame(%ecx) # self->self->curFrame<- newFP 13640 movl %ecx, OUT_ARG3(%esp) # save self->self 13641 movl %ecx, OUT_ARG2(%esp) # push parameter self->self 13642 movl rSELF,%ecx # %ecx<- pthread 13643 movl OUT_ARG1(%esp), %eax # %eax<- methodToCall 13644 lea offThread_retval(%ecx), %ecx # %ecx<- &retval 13645 movl %ecx, OUT_ARG0(%esp) # push parameter pthread 13646 push %edx # push parameter newFP 13647 13648 call *offMethod_nativeFunc(%eax) # call methodToCall->nativeFunc 13649 lea 4(%esp), %esp 13650 movl OUT_ARG4(%esp), %ecx # %ecx<- newSaveArea 13651 movl OUT_ARG3(%esp), %eax # %eax<- self->self 13652 movl offStackSaveArea_localRefCookie(%ecx), %edx # %edx<- old top 13653 cmp $0, offThread_exception(%eax) # check for exception 13654 movl rFP, offThread_curFrame(%eax) # self->self->curFrame<- rFP 13655 movl %edx, offThread_jniLocal_topCookie(%eax) # new top <- old top 13656 jne common_exceptionThrown # handle exception 13657 FETCH_INST_OPCODE 3 %edx 13658 ADVANCE_PC 3 13659 GOTO_NEXT_R %edx # jump to next instruction 13660 13661.LstackOverflow: # eax=methodToCall 13662 movl %eax, OUT_ARG1(%esp) # push parameter methodToCall 13663 movl rSELF,%eax # %eax<- self 13664 movl %eax, OUT_ARG0(%esp) # push parameter self 13665 call dvmHandleStackOverflow # call: (Thread* self, Method* meth) 13666 jmp common_exceptionThrown # handle exception 13667 13668 13669/* 13670 * Do we need the thread to be suspended or have debugger/profiling activity? 13671 * 13672 * On entry: 13673 * ebx -> PC adjustment in 16-bit words (must be preserved) 13674 * ecx -> SELF pointer 13675 * reentry type, e.g. kInterpEntryInstr stored in rSELF->entryPoint 13676 * 13677 * Note: A call will normally kill %eax and %ecx. To 13678 * streamline the normal case, this routine will preserve 13679 * %ecx in addition to the normal caller save regs. The save/restore 13680 * is a bit ugly, but will happen in the relatively uncommon path. 13681 * TODO: Basic-block style Jit will need a hook here as well. Fold it into 13682 * the suspendCount check so we can get both in 1 shot. 13683 * TUNING: Improve scheduling here & do initial single test for all. 13684 */ 13685common_periodicChecks: 13686 cmpl $0,offThread_suspendCount(%ecx) # non-zero suspendCount? 13687 jne 1f 13688 136896: 13690 movl offThread_pInterpBreak(%ecx),%eax # eax <- &interpBreak 13691 cmpl $0,(%eax) # something interesting happening? 13692 jne 3f # yes - switch interpreters 13693 ret 13694 13695 /* Check for suspend */ 136961: 13697 /* At this point, the return pointer to the caller of 13698 * common_periodicChecks is on the top of stack. We need to preserve 13699 * SELF(ecx). 13700 * The outgoing profile is: 13701 * bool dvmCheckSuspendPending(Thread* self) 13702 * Because we reached here via a call, go ahead and build a new frame. 13703 */ 13704 EXPORT_PC # need for precise GC 13705 movl %ecx,%eax # eax<- self 13706 push %ebp 13707 movl %esp,%ebp 13708 subl $24,%esp 13709 movl %eax,OUT_ARG0(%esp) 13710 call dvmCheckSuspendPending 13711 addl $24,%esp 13712 pop %ebp 13713 movl rSELF,%ecx 13714 13715 /* 13716 * Need to check to see if debugger or profiler flags got set 13717 * while we were suspended. 13718 */ 13719 jmp 6b 13720 13721 /* Switch interpreters */ 13722 /* Note: %ebx contains the 16-bit word offset to be applied to rPC to 13723 * "complete" the interpretation of backwards branches. In effect, we 13724 * are completing the interpretation of the branch instruction here, 13725 * and the new interpreter will resume interpretation at the branch 13726 * target. However, a switch request recognized during the handling 13727 * of a return from method instruction results in an immediate abort, 13728 * and the new interpreter will resume by re-interpreting the return 13729 * instruction. 13730 */ 137313: 13732 leal (rPC,%ebx,2),rPC # adjust pc to show target 13733 movl rSELF,%ecx # bail expect SELF already loaded 13734 movl $1,rINST # set changeInterp to true 13735 jmp common_gotoBail 13736 13737 13738/* 13739 * Common code for handling a return instruction 13740 */ 13741common_returnFromMethod: 13742 movl rSELF,%ecx 13743 /* Set entry mode in case we bail */ 13744 movb $kInterpEntryReturn,offThread_entryPoint(%ecx) 13745 xorl rINST,rINST # zero offset in case we switch interps 13746 call common_periodicChecks # Note: expects %ecx to be preserved 13747 13748 SAVEAREA_FROM_FP %eax # eax<- saveArea (old) 13749 movl offStackSaveArea_prevFrame(%eax),rFP # rFP<- prevFrame 13750 movl (offStackSaveArea_method-sizeofStackSaveArea)(rFP),rINST 13751 cmpl $0,rINST # break? 13752 je common_gotoBail # break frame, bail out completely 13753 13754 movl offStackSaveArea_savedPc(%eax),rPC # pc<- saveArea->savedPC 13755 movl rINST,offThread_method(%ecx) # self->method = newSave->meethod 13756 movl rFP,offThread_curFrame(%ecx) # self->curFrame = fp 13757 movl offMethod_clazz(rINST),%eax # eax<- method->clazz 13758 FETCH_INST_OPCODE 3 %edx 13759 movl offClassObject_pDvmDex(%eax),%eax # eax<- method->clazz->pDvmDex 13760 ADVANCE_PC 3 13761 movl %eax,offThread_methodClassDex(%ecx) 13762 /* not bailing - restore entry mode to default */ 13763 movb $kInterpEntryInstr,offThread_entryPoint(%ecx) 13764 GOTO_NEXT_R %edx 13765 13766/* 13767 * Prepare to strip the current frame and "longjump" back to caller of 13768 * dvmMterpStdRun. 13769 * 13770 * on entry: 13771 * rINST holds changeInterp 13772 * ecx holds self pointer 13773 * 13774 * expected profile: dvmMterpStdBail(Thread *self, bool changeInterp) 13775 */ 13776common_gotoBail: 13777 movl rPC,offThread_pc(%ecx) # export state to self 13778 movl rFP,offThread_fp(%ecx) 13779 movl %ecx,OUT_ARG0(%esp) # self in arg0 13780 movl rINST,OUT_ARG1(%esp) # changeInterp in arg1 13781 call dvmMterpStdBail # bail out.... 13782 13783 13784/* 13785 * After returning from a "selfd" function, pull out the updated values 13786 * and start executing at the next instruction. 13787 */ 13788 common_resumeAfterGlueCall: 13789 LOAD_PC_FP_FROM_SELF 13790 FETCH_INST 13791 GOTO_NEXT 13792 13793/* 13794 * Integer divide or mod by zero 13795 */ 13796common_errDivideByZero: 13797 EXPORT_PC 13798 movl $.LstrArithmeticException,%eax 13799 movl %eax,OUT_ARG0(%esp) 13800 movl $.LstrDivideByZero,%eax 13801 movl %eax,OUT_ARG1(%esp) 13802 call dvmThrowException 13803 jmp common_exceptionThrown 13804 13805/* 13806 * Attempt to allocate an array with a negative size. 13807 */ 13808common_errNegativeArraySize: 13809 EXPORT_PC 13810 movl $.LstrNegativeArraySizeException,%eax 13811 movl %eax,OUT_ARG0(%esp) 13812 xorl %eax,%eax 13813 movl %eax,OUT_ARG1(%esp) 13814 call dvmThrowException 13815 jmp common_exceptionThrown 13816 13817/* 13818 * Attempt to allocate an array with a negative size. 13819 */ 13820common_errNoSuchMethod: 13821 13822 EXPORT_PC 13823 movl $.LstrNoSuchMethodError,%eax 13824 movl %eax,OUT_ARG0(%esp) 13825 xorl %eax,%eax 13826 movl %eax,OUT_ARG1(%esp) 13827 call dvmThrowException 13828 jmp common_exceptionThrown 13829 13830/* 13831 * Hit a null object when we weren't expecting one. Export the PC, throw a 13832 * NullPointerException and goto the exception processing code. 13833 */ 13834common_errNullObject: 13835 EXPORT_PC 13836 movl $.LstrNullPointerException,%eax 13837 movl %eax,OUT_ARG0(%esp) 13838 xorl %eax,%eax 13839 movl %eax,OUT_ARG1(%esp) 13840 call dvmThrowException 13841 jmp common_exceptionThrown 13842 13843/* 13844 * Array index exceeds max. 13845 * On entry: 13846 * eax <- array object 13847 * ecx <- index 13848 */ 13849common_errArrayIndex: 13850 EXPORT_PC 13851 movl offArrayObject_length(%eax), %eax 13852 movl %ecx,OUT_ARG0(%esp) 13853 movl %eax,OUT_ARG1(%esp) 13854 call dvmThrowAIOOBE # dvmThrowAIOO(index, length) 13855 jmp common_exceptionThrown 13856 13857/* 13858 * Somebody has thrown an exception. Handle it. 13859 * 13860 * If the exception processing code returns to us (instead of falling 13861 * out of the interpreter), continue with whatever the next instruction 13862 * now happens to be. 13863 * 13864 * This does not return. 13865 */ 13866common_exceptionThrown: 13867 movl rSELF,%ecx 13868 movl rPC,offThread_pc(%ecx) 13869 movl rFP,offThread_fp(%ecx) 13870 movl %ecx,OUT_ARG0(%esp) 13871 call dvmMterp_exceptionThrown 13872 jmp common_resumeAfterGlueCall 13873 13874common_abort: 13875 movl $0xdeadf00d,%eax 13876 call *%eax 13877 13878 13879/* 13880 * Strings 13881 */ 13882 13883 .section .rodata 13884.LstrNullPointerException: 13885 .asciz "Ljava/lang/NullPointerException;" 13886.LstrArithmeticException: 13887 .asciz "Ljava/lang/ArithmeticException;" 13888.LstrDivideByZero: 13889 .asciz "divide by zero" 13890.LstrNegativeArraySizeException: 13891 .asciz "Ljava/lang/NegativeArraySizeException;" 13892.LstrInstantiationError: 13893 .asciz "Ljava/lang/InstantiationError;" 13894.LstrNoSuchMethodError: 13895 .asciz "Ljava/lang/NoSuchMethodError;" 13896.LstrInternalErrorA: 13897 .asciz "Ljava/lang/InternalError;" 13898.LstrFilledNewArrayNotImplA: 13899 .asciz "filled-new-array only implemented for 'int'" 13900 13901