InterpAsm-x86.S revision 750d110b62cef538e193b6f91f5239b0c4b63ef1
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 rGLUE (%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 rGLUE_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 _glue _reg 122 movl offGlue_pJitProfTable(\_glue),\_reg 123.endm 124.macro GET_JIT_THRESHOLD _glue _reg 125 movl offGlue_jitThreshold(\_glue),\_reg 126.endm 127#endif 128 129/* save/restore the PC and/or FP from the glue struct */ 130.macro SAVE_PC_FP_TO_GLUE _reg 131 movl rGLUE,\_reg 132 movl rPC,offGlue_pc(\_reg) 133 movl rFP,offGlue_fp(\_reg) 134.endm 135 136.macro LOAD_PC_FP_FROM_GLUE 137 movl rGLUE,rFP 138 movl offGlue_pc(rFP),rPC 139 movl offGlue_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 rGLUE,%eax # eax<- rGLUE 779 movzx rINSTbl,%ecx # ecx<- AA 780 movl offGlue_retval(%eax),%eax # eax<- glue->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 rGLUE,%ecx 792 movl offGlue_retval(%ecx),%eax 793 movl 4+offGlue_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 rGLUE,%eax # eax<- rGLUE 808 movzx rINSTbl,%ecx # ecx<- AA 809 movl offGlue_retval(%eax),%eax # eax<- glue->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 rGLUE,%ecx 822 movl offGlue_self(%ecx),%ecx # ecx<- glue->self 823 movl offThread_exception(%ecx),%eax # eax<- dvmGetException bypass 824 SET_VREG %eax rINST # fp[AA]<- exception object 825 FETCH_INST_OPCODE 1 %edx 826 ADVANCE_PC 1 827 movl $0,offThread_exception(%ecx) # dvmClearException bypass 828 GOTO_NEXT_R %edx 829 830/* ------------------------------ */ 831 .balign 64 832.L_OP_RETURN_VOID: /* 0x0e */ 833/* File: x86/OP_RETURN_VOID.S */ 834 jmp common_returnFromMethod 835 836/* ------------------------------ */ 837 .balign 64 838.L_OP_RETURN: /* 0x0f */ 839/* File: x86/OP_RETURN.S */ 840 /* 841 * Return a 32-bit value. Copies the return value into the "glue" 842 * structure, then jumps to the return handler. 843 * 844 * for: return, return-object 845 */ 846 /* op vAA */ 847 movl rGLUE,%ecx 848 GET_VREG_R %eax rINST # eax<- vAA 849 movl %eax,offGlue_retval(%ecx) # retval.i <- AA 850 jmp common_returnFromMethod 851 852/* ------------------------------ */ 853 .balign 64 854.L_OP_RETURN_WIDE: /* 0x10 */ 855/* File: x86/OP_RETURN_WIDE.S */ 856 /* 857 * Return a 64-bit value. Copies the return value into the "glue" 858 * structure, then jumps to the return handler. 859 */ 860 /* return-wide vAA */ 861 movl rGLUE,%ecx 862 GET_VREG_WORD %eax rINST 0 # eax<- v[AA+0] 863 GET_VREG_WORD rINST rINST 1 # rINST<- v[AA+1] 864 movl %eax,offGlue_retval(%ecx) 865 movl rINST,4+offGlue_retval(%ecx) 866 jmp common_returnFromMethod 867 868/* ------------------------------ */ 869 .balign 64 870.L_OP_RETURN_OBJECT: /* 0x11 */ 871/* File: x86/OP_RETURN_OBJECT.S */ 872/* File: x86/OP_RETURN.S */ 873 /* 874 * Return a 32-bit value. Copies the return value into the "glue" 875 * structure, then jumps to the return handler. 876 * 877 * for: return, return-object 878 */ 879 /* op vAA */ 880 movl rGLUE,%ecx 881 GET_VREG_R %eax rINST # eax<- vAA 882 movl %eax,offGlue_retval(%ecx) # retval.i <- AA 883 jmp common_returnFromMethod 884 885 886/* ------------------------------ */ 887 .balign 64 888.L_OP_CONST_4: /* 0x12 */ 889/* File: x86/OP_CONST_4.S */ 890 /* const/4 vA, #+B */ 891 movsx rINSTbl,%eax # eax<-ssssssBx 892 movl $0xf,%ecx 893 andl %eax,%ecx # ecx<- A 894 FETCH_INST_OPCODE 1 %edx 895 ADVANCE_PC 1 896 sarl $4,%eax 897 SET_VREG %eax %ecx 898 GOTO_NEXT_R %edx 899 900/* ------------------------------ */ 901 .balign 64 902.L_OP_CONST_16: /* 0x13 */ 903/* File: x86/OP_CONST_16.S */ 904 /* const/16 vAA, #+BBBB */ 905 movswl 2(rPC),%ecx # ecx<- ssssBBBB 906 movl rINST,%eax # eax<- AA 907 FETCH_INST_OPCODE 2 %edx 908 ADVANCE_PC 2 909 SET_VREG %ecx %eax # vAA<- ssssBBBB 910 GOTO_NEXT_R %edx 911 912/* ------------------------------ */ 913 .balign 64 914.L_OP_CONST: /* 0x14 */ 915/* File: x86/OP_CONST.S */ 916 /* const vAA, #+BBBBbbbb */ 917 movl 2(rPC),%eax # grab all 32 bits at once 918 movl rINST,%ecx # ecx<- AA 919 FETCH_INST_OPCODE 3 %edx 920 ADVANCE_PC 3 921 SET_VREG %eax %ecx # vAA<- eax 922 GOTO_NEXT_R %edx 923 924/* ------------------------------ */ 925 .balign 64 926.L_OP_CONST_HIGH16: /* 0x15 */ 927/* File: x86/OP_CONST_HIGH16.S */ 928 /* const/high16 vAA, #+BBBB0000 */ 929 movzwl 2(rPC),%eax # eax<- 0000BBBB 930 movl rINST,%ecx # ecx<- AA 931 FETCH_INST_OPCODE 2 %edx 932 ADVANCE_PC 2 933 sall $16,%eax # eax<- BBBB0000 934 SET_VREG %eax %ecx # vAA<- eax 935 GOTO_NEXT_R %edx 936 937/* ------------------------------ */ 938 .balign 64 939.L_OP_CONST_WIDE_16: /* 0x16 */ 940/* File: x86/OP_CONST_WIDE_16.S */ 941 /* const-wide/16 vAA, #+BBBB */ 942 movswl 2(rPC),%eax # eax<- ssssBBBB 943 cltd # rPC:eax<- ssssssssssssBBBB 944 SET_VREG_WORD %edx rINST 1 # store msw 945 FETCH_INST_OPCODE 2 %edx 946 SET_VREG_WORD %eax rINST 0 # store lsw 947 ADVANCE_PC 2 948 GOTO_NEXT_R %edx 949 950/* ------------------------------ */ 951 .balign 64 952.L_OP_CONST_WIDE_32: /* 0x17 */ 953/* File: x86/OP_CONST_WIDE_32.S */ 954 /* const-wide/32 vAA, #+BBBBbbbb */ 955 movl 2(rPC),%eax # eax<- BBBBbbbb 956 cltd # rPC:eax<- ssssssssssssBBBB 957 SET_VREG_WORD %edx rINST,1 # store msw 958 FETCH_INST_OPCODE 3 %edx 959 SET_VREG_WORD %eax rINST 0 # store lsw 960 ADVANCE_PC 3 961 GOTO_NEXT_R %edx 962 963/* ------------------------------ */ 964 .balign 64 965.L_OP_CONST_WIDE: /* 0x18 */ 966/* File: x86/OP_CONST_WIDE.S */ 967 /* const-wide vAA, #+HHHHhhhhBBBBbbbb */ 968 movl 2(rPC),%eax # eax<- lsw 969 movzbl rINSTbl,%ecx # ecx<- AA 970 movl 6(rPC),rINST # rINST<- msw 971 leal (rFP,%ecx,4),%ecx # dst addr 972 movl rINST,4(%ecx) 973 FETCH_INST_OPCODE 5 %edx 974 movl %eax,(%ecx) 975 ADVANCE_PC 5 976 GOTO_NEXT_R %edx 977 978/* ------------------------------ */ 979 .balign 64 980.L_OP_CONST_WIDE_HIGH16: /* 0x19 */ 981/* File: x86/OP_CONST_WIDE_HIGH16.S */ 982 /* const-wide/high16 vAA, #+BBBB000000000000 */ 983 movzwl 2(rPC),%eax # eax<- 0000BBBB 984 FETCH_INST_OPCODE 2 %edx 985 ADVANCE_PC 2 986 sall $16,%eax # eax<- BBBB0000 987 SET_VREG_WORD %eax rINST 1 # v[AA+1]<- eax 988 xorl %eax,%eax 989 SET_VREG_WORD %eax rINST 0 # v[AA+0]<- eax 990 GOTO_NEXT_R %edx 991 992/* ------------------------------ */ 993 .balign 64 994.L_OP_CONST_STRING: /* 0x1a */ 995/* File: x86/OP_CONST_STRING.S */ 996 997 /* const/string vAA, String@BBBB */ 998 movl rGLUE,%ecx 999 movzwl 2(rPC),%eax # eax<- BBBB 1000 movl offGlue_methodClassDex(%ecx),%ecx# ecx<- glue->methodClassDex 1001 movl offDvmDex_pResStrings(%ecx),%ecx # ecx<- dvmDex->pResStrings 1002 movl (%ecx,%eax,4),%eax # eax<- rResString[BBBB] 1003 movl rINST,%ecx 1004 FETCH_INST_OPCODE 2 %edx 1005 testl %eax,%eax # resolved yet? 1006 je .LOP_CONST_STRING_resolve 1007 SET_VREG %eax %ecx # vAA<- rResString[BBBB] 1008 ADVANCE_PC 2 1009 GOTO_NEXT_R %edx 1010 1011/* ------------------------------ */ 1012 .balign 64 1013.L_OP_CONST_STRING_JUMBO: /* 0x1b */ 1014/* File: x86/OP_CONST_STRING_JUMBO.S */ 1015 1016 /* const/string vAA, String@BBBBBBBB */ 1017 movl rGLUE,%ecx 1018 movl 2(rPC),%eax # eax<- BBBBBBBB 1019 movl offGlue_methodClassDex(%ecx),%ecx# ecx<- glue->methodClassDex 1020 movl offDvmDex_pResStrings(%ecx),%ecx # ecx<- dvmDex->pResStrings 1021 movl (%ecx,%eax,4),%eax # eax<- rResString[BBBB] 1022 movl rINST,%ecx 1023 FETCH_INST_OPCODE 3 %edx 1024 testl %eax,%eax # resolved yet? 1025 je .LOP_CONST_STRING_JUMBO_resolve 1026 SET_VREG %eax %ecx # vAA<- rResString[BBBB] 1027 ADVANCE_PC 3 1028 GOTO_NEXT_R %edx 1029 1030/* ------------------------------ */ 1031 .balign 64 1032.L_OP_CONST_CLASS: /* 0x1c */ 1033/* File: x86/OP_CONST_CLASS.S */ 1034 1035 /* const/class vAA, Class@BBBB */ 1036 movl rGLUE,%ecx 1037 movzwl 2(rPC),%eax # eax<- BBBB 1038 movl offGlue_methodClassDex(%ecx),%ecx# ecx<- glue->methodClassDex 1039 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- dvmDex->pResClasses 1040 movl (%ecx,%eax,4),%eax # eax<- rResClasses[BBBB] 1041 movl rINST,%ecx 1042 FETCH_INST_OPCODE 2 %edx 1043 testl %eax,%eax # resolved yet? 1044 je .LOP_CONST_CLASS_resolve 1045 SET_VREG %eax %ecx # vAA<- rResClasses[BBBB] 1046 ADVANCE_PC 2 1047 GOTO_NEXT_R %edx 1048 1049/* ------------------------------ */ 1050 .balign 64 1051.L_OP_MONITOR_ENTER: /* 0x1d */ 1052/* File: x86/OP_MONITOR_ENTER.S */ 1053 /* 1054 * Synchronize on an object. 1055 */ 1056 /* monitor-enter vAA */ 1057 movl rGLUE,%ecx 1058 GET_VREG_R %eax rINST # eax<- vAA 1059 movl offGlue_self(%ecx),%ecx # ecx<- glue->self 1060 FETCH_INST_WORD 1 1061 testl %eax,%eax # null object? 1062 EXPORT_PC # need for precise GC 1063 jne .LOP_MONITOR_ENTER_continue 1064 jmp common_errNullObject 1065 1066/* ------------------------------ */ 1067 .balign 64 1068.L_OP_MONITOR_EXIT: /* 0x1e */ 1069/* File: x86/OP_MONITOR_EXIT.S */ 1070 /* 1071 * Unlock an object. 1072 * 1073 * Exceptions that occur when unlocking a monitor need to appear as 1074 * if they happened at the following instruction. See the Dalvik 1075 * instruction spec. 1076 */ 1077 /* monitor-exit vAA */ 1078 GET_VREG_R %eax rINST 1079 movl rGLUE,%ecx 1080 EXPORT_PC 1081 testl %eax,%eax # null object? 1082 je .LOP_MONITOR_EXIT_errNullObject # go if so 1083 movl offGlue_self(%ecx),%ecx # ecx<- glue->self 1084 movl %eax,OUT_ARG1(%esp) 1085 movl %ecx,OUT_ARG0(%esp) 1086 jmp .LOP_MONITOR_EXIT_continue 1087 1088/* ------------------------------ */ 1089 .balign 64 1090.L_OP_CHECK_CAST: /* 0x1f */ 1091/* File: x86/OP_CHECK_CAST.S */ 1092 /* 1093 * Check to see if a cast from one class to another is allowed. 1094 */ 1095 /* check-cast vAA, class@BBBB */ 1096 movl rGLUE,%ecx 1097 GET_VREG_R rINST,rINST # rINST<- vAA (object) 1098 movzwl 2(rPC),%eax # eax<- BBBB 1099 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 1100 testl rINST,rINST # is oject null? 1101 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 1102 je .LOP_CHECK_CAST_okay # null obj, cast always succeeds 1103 movl (%ecx,%eax,4),%eax # eax<- resolved class 1104 movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz 1105 testl %eax,%eax # have we resolved this before? 1106 je .LOP_CHECK_CAST_resolve # no, go do it now 1107.LOP_CHECK_CAST_resolved: 1108 cmpl %eax,%ecx # same class (trivial success)? 1109 jne .LOP_CHECK_CAST_fullcheck # no, do full check 1110.LOP_CHECK_CAST_okay: 1111 FETCH_INST_OPCODE 2 %edx 1112 ADVANCE_PC 2 1113 GOTO_NEXT_R %edx 1114 1115/* ------------------------------ */ 1116 .balign 64 1117.L_OP_INSTANCE_OF: /* 0x20 */ 1118/* File: x86/OP_INSTANCE_OF.S */ 1119 /* 1120 * Check to see if an object reference is an instance of a class. 1121 * 1122 * Most common situation is a non-null object, being compared against 1123 * an already-resolved class. 1124 */ 1125 /* instance-of vA, vB, class@CCCC */ 1126 movl rINST,%eax # eax<- BA 1127 sarl $4,%eax # eax<- B 1128 GET_VREG_R %eax %eax # eax<- vB (obj) 1129 movl rGLUE,%ecx 1130 testl %eax,%eax # object null? 1131 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 1132 je .LOP_INSTANCE_OF_store # null obj, not instance, store it 1133 movzwl 2(rPC),%edx # edx<- CCCC 1134 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 1135 movl (%ecx,%edx,4),%ecx # ecx<- resolved class 1136 movl offObject_clazz(%eax),%eax # eax<- obj->clazz 1137 testl %ecx,%ecx # have we resolved this before? 1138 je .LOP_INSTANCE_OF_resolve # not resolved, do it now 1139.LOP_INSTANCE_OF_resolved: # eax<- obj->clazz, ecx<- resolved class 1140 cmpl %eax,%ecx # same class (trivial success)? 1141 je .LOP_INSTANCE_OF_trivial # yes, trivial finish 1142 jmp .LOP_INSTANCE_OF_fullcheck # no, do full check 1143 1144/* ------------------------------ */ 1145 .balign 64 1146.L_OP_ARRAY_LENGTH: /* 0x21 */ 1147/* File: x86/OP_ARRAY_LENGTH.S */ 1148 /* 1149 * Return the length of an array. 1150 */ 1151 mov rINST,%eax # eax<- BA 1152 sarl $4,rINST # rINST<- B 1153 GET_VREG_R %ecx rINST # ecx<- vB (object ref) 1154 andb $0xf,%al # eax<- A 1155 testl %ecx,%ecx # is null? 1156 je common_errNullObject 1157 FETCH_INST_OPCODE 1 %edx 1158 movl offArrayObject_length(%ecx),%ecx 1159 ADVANCE_PC 1 1160 SET_VREG %ecx %eax 1161 GOTO_NEXT_R %edx 1162 1163/* ------------------------------ */ 1164 .balign 64 1165.L_OP_NEW_INSTANCE: /* 0x22 */ 1166/* File: x86/OP_NEW_INSTANCE.S */ 1167 /* 1168 * Create a new instance of a class. 1169 */ 1170 /* new-instance vAA, class@BBBB */ 1171 movl rGLUE,%ecx 1172 movzwl 2(rPC),%eax # eax<- BBBB 1173 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 1174 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 1175 EXPORT_PC 1176 movl (%ecx,%eax,4),%ecx # ecx<- resolved class 1177 testl %ecx,%ecx # resolved? 1178 je .LOP_NEW_INSTANCE_resolve # no, go do it 1179.LOP_NEW_INSTANCE_resolved: # on entry, ecx<- class 1180 cmpb $CLASS_INITIALIZED,offClassObject_status(%ecx) 1181 je .LOP_NEW_INSTANCE_initialized 1182 jmp .LOP_NEW_INSTANCE_needinit 1183 1184/* ------------------------------ */ 1185 .balign 64 1186.L_OP_NEW_ARRAY: /* 0x23 */ 1187/* File: x86/OP_NEW_ARRAY.S */ 1188 /* 1189 * Allocate an array of objects, specified with the array class 1190 * and a count. 1191 * 1192 * The verifier guarantees that this is an array class, so we don't 1193 * check for it here. 1194 */ 1195 /* new-array vA, vB, class@CCCC */ 1196 movl rGLUE,%ecx 1197 EXPORT_PC 1198 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 1199 movzwl 2(rPC),%eax # eax<- CCCC 1200 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 1201 movl (%ecx,%eax,4),%ecx # ecx<- resolved class 1202 movzbl rINSTbl,%eax 1203 sarl $4,%eax # eax<- B 1204 GET_VREG_R %eax %eax # eax<- vB (array length) 1205 andb $0xf,rINSTbl # rINST<- A 1206 testl %eax,%eax 1207 js common_errNegativeArraySize # bail 1208 testl %ecx,%ecx # already resolved? 1209 jne .LOP_NEW_ARRAY_finish # yes, fast path 1210 jmp .LOP_NEW_ARRAY_resolve # resolve now 1211 1212/* ------------------------------ */ 1213 .balign 64 1214.L_OP_FILLED_NEW_ARRAY: /* 0x24 */ 1215/* File: x86/OP_FILLED_NEW_ARRAY.S */ 1216 /* 1217 * Create a new array with elements filled from registers. 1218 * 1219 * for: filled-new-array, filled-new-array/range 1220 */ 1221 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1222 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1223 movl rGLUE,%eax 1224 movl offGlue_methodClassDex(%eax),%eax # eax<- pDvmDex 1225 movzwl 2(rPC),%ecx # ecx<- BBBB 1226 movl offDvmDex_pResClasses(%eax),%eax # eax<- pDvmDex->pResClasses 1227 movl (%eax,%ecx,4),%eax # eax<- resolved class 1228 EXPORT_PC 1229 testl %eax,%eax # already resolved? 1230 jne .LOP_FILLED_NEW_ARRAY_continue # yes, continue 1231 # less frequent path, so we'll redo some work 1232 movl rGLUE,%eax 1233 movl $0,OUT_ARG2(%esp) # arg2<- false 1234 movl %ecx,OUT_ARG1(%esp) # arg1<- BBBB 1235 movl offGlue_method(%eax),%eax # eax<- glue->method 1236 jmp .LOP_FILLED_NEW_ARRAY_more 1237 1238/* ------------------------------ */ 1239 .balign 64 1240.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */ 1241/* File: x86/OP_FILLED_NEW_ARRAY_RANGE.S */ 1242/* File: x86/OP_FILLED_NEW_ARRAY.S */ 1243 /* 1244 * Create a new array with elements filled from registers. 1245 * 1246 * for: filled-new-array, filled-new-array/range 1247 */ 1248 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1249 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1250 movl rGLUE,%eax 1251 movl offGlue_methodClassDex(%eax),%eax # eax<- pDvmDex 1252 movzwl 2(rPC),%ecx # ecx<- BBBB 1253 movl offDvmDex_pResClasses(%eax),%eax # eax<- pDvmDex->pResClasses 1254 movl (%eax,%ecx,4),%eax # eax<- resolved class 1255 EXPORT_PC 1256 testl %eax,%eax # already resolved? 1257 jne .LOP_FILLED_NEW_ARRAY_RANGE_continue # yes, continue 1258 # less frequent path, so we'll redo some work 1259 movl rGLUE,%eax 1260 movl $0,OUT_ARG2(%esp) # arg2<- false 1261 movl %ecx,OUT_ARG1(%esp) # arg1<- BBBB 1262 movl offGlue_method(%eax),%eax # eax<- glue->method 1263 jmp .LOP_FILLED_NEW_ARRAY_RANGE_more 1264 1265 1266/* ------------------------------ */ 1267 .balign 64 1268.L_OP_FILL_ARRAY_DATA: /* 0x26 */ 1269/* File: x86/OP_FILL_ARRAY_DATA.S */ 1270 /* fill-array-data vAA, +BBBBBBBB */ 1271 movl 2(rPC),%ecx # ecx<- BBBBbbbb 1272 leal (rPC,%ecx,2),%ecx # ecx<- PC + BBBBbbbb*2 1273 GET_VREG_R %eax rINST 1274 EXPORT_PC 1275 movl %eax,OUT_ARG0(%esp) 1276 movl %ecx,OUT_ARG1(%esp) 1277 call dvmInterpHandleFillArrayData 1278 FETCH_INST_OPCODE 3 %edx 1279 testl %eax,%eax # exception thrown? 1280 je common_exceptionThrown 1281 ADVANCE_PC 3 1282 GOTO_NEXT_R %edx 1283 1284/* ------------------------------ */ 1285 .balign 64 1286.L_OP_THROW: /* 0x27 */ 1287/* File: x86/OP_THROW.S */ 1288 /* 1289 * Throw an exception object in the current thread. 1290 */ 1291 /* throw vAA */ 1292 movl rGLUE,%ecx 1293 EXPORT_PC 1294 GET_VREG_R %eax rINST # eax<- exception object 1295 movl offGlue_self(%ecx),%ecx # ecx<- glue->self 1296 testl %eax,%eax # null object? 1297 je common_errNullObject 1298 movl %eax,offThread_exception(%ecx) # thread->exception<- obj 1299 jmp common_exceptionThrown 1300 1301/* ------------------------------ */ 1302 .balign 64 1303.L_OP_GOTO: /* 0x28 */ 1304/* File: x86/OP_GOTO.S */ 1305 /* 1306 * Unconditional branch, 8-bit offset. 1307 * 1308 * The branch distance is a signed code-unit offset, which we need to 1309 * double to get a byte offset. 1310 */ 1311 /* goto +AA */ 1312 movsbl rINSTbl,rINST # ebx<- ssssssAA 1313 testl rINST,rINST # test for <0 1314 js common_backwardBranch 1315 movl rINST,%eax 1316 FETCH_INST_INDEXED %eax 1317 ADVANCE_PC_INDEXED %eax 1318 GOTO_NEXT 1319 1320/* ------------------------------ */ 1321 .balign 64 1322.L_OP_GOTO_16: /* 0x29 */ 1323/* File: x86/OP_GOTO_16.S */ 1324 /* 1325 * Unconditional branch, 16-bit offset. 1326 * 1327 * The branch distance is a signed code-unit offset 1328 */ 1329 /* goto/16 +AAAA */ 1330 movswl 2(rPC),rINST # rINST<- ssssAAAA 1331 testl rINST,rINST # test for <0 1332 js common_backwardBranch 1333 movl rINST,%eax 1334 FETCH_INST_INDEXED %eax 1335 ADVANCE_PC_INDEXED %eax 1336 GOTO_NEXT 1337 1338/* ------------------------------ */ 1339 .balign 64 1340.L_OP_GOTO_32: /* 0x2a */ 1341/* File: x86/OP_GOTO_32.S */ 1342 /* 1343 * Unconditional branch, 32-bit offset. 1344 * 1345 * The branch distance is a signed code-unit offset. 1346 * 1347 * Unlike most opcodes, this one is allowed to branch to itself, so 1348 * our "backward branch" test must be "<=0" instead of "<0". 1349 */ 1350 /* goto/32 AAAAAAAA */ 1351 movl 2(rPC),rINST # rINST<- AAAAAAAA 1352 cmpl $0,rINST # test for <= 0 1353 jle common_backwardBranch 1354 movl rINST,%eax 1355 FETCH_INST_INDEXED %eax 1356 ADVANCE_PC_INDEXED %eax 1357 GOTO_NEXT 1358 1359/* ------------------------------ */ 1360 .balign 64 1361.L_OP_PACKED_SWITCH: /* 0x2b */ 1362/* File: x86/OP_PACKED_SWITCH.S */ 1363 /* 1364 * Handle a packed-switch or sparse-switch instruction. In both cases 1365 * we decode it and hand it off to a helper function. 1366 * 1367 * We don't really expect backward branches in a switch statement, but 1368 * they're perfectly legal, so we check for them here. 1369 * 1370 * for: packed-switch, sparse-switch 1371 */ 1372 /* op vAA, +BBBB */ 1373 movl 2(rPC),%ecx # ecx<- BBBBbbbb 1374 GET_VREG_R %eax rINST # eax<- vAA 1375 leal (rPC,%ecx,2),%ecx # ecx<- PC + BBBBbbbb*2 1376 movl %eax,OUT_ARG1(%esp) # ARG1<- vAA 1377 movl %ecx,OUT_ARG0(%esp) # ARG0<- switchData 1378 call dvmInterpHandlePackedSwitch 1379 testl %eax,%eax 1380 movl %eax,rINST # set up word offset 1381 jle common_backwardBranch # check on special actions 1382 ADVANCE_PC_INDEXED rINST 1383 FETCH_INST 1384 GOTO_NEXT 1385 1386/* ------------------------------ */ 1387 .balign 64 1388.L_OP_SPARSE_SWITCH: /* 0x2c */ 1389/* File: x86/OP_SPARSE_SWITCH.S */ 1390/* File: x86/OP_PACKED_SWITCH.S */ 1391 /* 1392 * Handle a packed-switch or sparse-switch instruction. In both cases 1393 * we decode it and hand it off to a helper function. 1394 * 1395 * We don't really expect backward branches in a switch statement, but 1396 * they're perfectly legal, so we check for them here. 1397 * 1398 * for: packed-switch, sparse-switch 1399 */ 1400 /* op vAA, +BBBB */ 1401 movl 2(rPC),%ecx # ecx<- BBBBbbbb 1402 GET_VREG_R %eax rINST # eax<- vAA 1403 leal (rPC,%ecx,2),%ecx # ecx<- PC + BBBBbbbb*2 1404 movl %eax,OUT_ARG1(%esp) # ARG1<- vAA 1405 movl %ecx,OUT_ARG0(%esp) # ARG0<- switchData 1406 call dvmInterpHandleSparseSwitch 1407 testl %eax,%eax 1408 movl %eax,rINST # set up word offset 1409 jle common_backwardBranch # check on special actions 1410 ADVANCE_PC_INDEXED rINST 1411 FETCH_INST 1412 GOTO_NEXT 1413 1414 1415/* ------------------------------ */ 1416 .balign 64 1417.L_OP_CMPL_FLOAT: /* 0x2d */ 1418/* File: x86/OP_CMPL_FLOAT.S */ 1419/* File: x86/OP_CMPG_DOUBLE.S */ 1420 /* float/double_cmp[gl] vAA, vBB, vCC */ 1421 movzbl 3(rPC),%eax # eax<- CC 1422 movzbl 2(rPC),%ecx # ecx<- BB 1423 .if 0 1424 fldl (rFP,%eax,4) 1425 fldl (rFP,%ecx,4) 1426 .else 1427 flds (rFP,%eax,4) 1428 flds (rFP,%ecx,4) 1429 .endif 1430 xorl %ecx,%ecx 1431 fucompp # z if equal, p set if NaN, c set if st0 < st1 1432 fnstsw %ax 1433 sahf 1434 movl rINST,%eax 1435 FETCH_INST_OPCODE 2 %edx 1436 jp .LOP_CMPL_FLOAT_isNaN 1437 je .LOP_CMPL_FLOAT_finish 1438 sbbl %ecx,%ecx 1439 jb .LOP_CMPL_FLOAT_finish 1440 incl %ecx 1441.LOP_CMPL_FLOAT_finish: 1442 SET_VREG %ecx %eax 1443 ADVANCE_PC 2 1444 GOTO_NEXT_R %edx 1445 1446 1447/* ------------------------------ */ 1448 .balign 64 1449.L_OP_CMPG_FLOAT: /* 0x2e */ 1450/* File: x86/OP_CMPG_FLOAT.S */ 1451/* File: x86/OP_CMPG_DOUBLE.S */ 1452 /* float/double_cmp[gl] vAA, vBB, vCC */ 1453 movzbl 3(rPC),%eax # eax<- CC 1454 movzbl 2(rPC),%ecx # ecx<- BB 1455 .if 0 1456 fldl (rFP,%eax,4) 1457 fldl (rFP,%ecx,4) 1458 .else 1459 flds (rFP,%eax,4) 1460 flds (rFP,%ecx,4) 1461 .endif 1462 xorl %ecx,%ecx 1463 fucompp # z if equal, p set if NaN, c set if st0 < st1 1464 fnstsw %ax 1465 sahf 1466 movl rINST,%eax 1467 FETCH_INST_OPCODE 2 %edx 1468 jp .LOP_CMPG_FLOAT_isNaN 1469 je .LOP_CMPG_FLOAT_finish 1470 sbbl %ecx,%ecx 1471 jb .LOP_CMPG_FLOAT_finish 1472 incl %ecx 1473.LOP_CMPG_FLOAT_finish: 1474 SET_VREG %ecx %eax 1475 ADVANCE_PC 2 1476 GOTO_NEXT_R %edx 1477 1478 1479/* ------------------------------ */ 1480 .balign 64 1481.L_OP_CMPL_DOUBLE: /* 0x2f */ 1482/* File: x86/OP_CMPL_DOUBLE.S */ 1483/* File: x86/OP_CMPG_DOUBLE.S */ 1484 /* float/double_cmp[gl] vAA, vBB, vCC */ 1485 movzbl 3(rPC),%eax # eax<- CC 1486 movzbl 2(rPC),%ecx # ecx<- BB 1487 .if 1 1488 fldl (rFP,%eax,4) 1489 fldl (rFP,%ecx,4) 1490 .else 1491 flds (rFP,%eax,4) 1492 flds (rFP,%ecx,4) 1493 .endif 1494 xorl %ecx,%ecx 1495 fucompp # z if equal, p set if NaN, c set if st0 < st1 1496 fnstsw %ax 1497 sahf 1498 movl rINST,%eax 1499 FETCH_INST_OPCODE 2 %edx 1500 jp .LOP_CMPL_DOUBLE_isNaN 1501 je .LOP_CMPL_DOUBLE_finish 1502 sbbl %ecx,%ecx 1503 jb .LOP_CMPL_DOUBLE_finish 1504 incl %ecx 1505.LOP_CMPL_DOUBLE_finish: 1506 SET_VREG %ecx %eax 1507 ADVANCE_PC 2 1508 GOTO_NEXT_R %edx 1509 1510 1511/* ------------------------------ */ 1512 .balign 64 1513.L_OP_CMPG_DOUBLE: /* 0x30 */ 1514/* File: x86/OP_CMPG_DOUBLE.S */ 1515 /* float/double_cmp[gl] vAA, vBB, vCC */ 1516 movzbl 3(rPC),%eax # eax<- CC 1517 movzbl 2(rPC),%ecx # ecx<- BB 1518 .if 1 1519 fldl (rFP,%eax,4) 1520 fldl (rFP,%ecx,4) 1521 .else 1522 flds (rFP,%eax,4) 1523 flds (rFP,%ecx,4) 1524 .endif 1525 xorl %ecx,%ecx 1526 fucompp # z if equal, p set if NaN, c set if st0 < st1 1527 fnstsw %ax 1528 sahf 1529 movl rINST,%eax 1530 FETCH_INST_OPCODE 2 %edx 1531 jp .LOP_CMPG_DOUBLE_isNaN 1532 je .LOP_CMPG_DOUBLE_finish 1533 sbbl %ecx,%ecx 1534 jb .LOP_CMPG_DOUBLE_finish 1535 incl %ecx 1536.LOP_CMPG_DOUBLE_finish: 1537 SET_VREG %ecx %eax 1538 ADVANCE_PC 2 1539 GOTO_NEXT_R %edx 1540 1541/* ------------------------------ */ 1542 .balign 64 1543.L_OP_CMP_LONG: /* 0x31 */ 1544/* File: x86/OP_CMP_LONG.S */ 1545 /* 1546 * Compare two 64-bit values. Puts 0, 1, or -1 into the destination 1547 * register based on the results of the comparison. 1548 */ 1549 /* cmp-long vAA, vBB, vCC */ 1550 movzbl 2(rPC),%ecx # ecx<- BB 1551 movzbl 3(rPC),%edx # edx<- CC 1552 GET_VREG_WORD %eax %ecx,1 # eax<- v[BB+1] 1553 GET_VREG_WORD %ecx %ecx 0 # ecx<- v[BB+0] 1554 cmpl 4(rFP,%edx,4),%eax 1555 jl .LOP_CMP_LONG_smaller 1556 jg .LOP_CMP_LONG_bigger 1557 sub (rFP,%edx,4),%ecx 1558 ja .LOP_CMP_LONG_bigger 1559 jb .LOP_CMP_LONG_smaller 1560 jmp .LOP_CMP_LONG_finish 1561 1562/* ------------------------------ */ 1563 .balign 64 1564.L_OP_IF_EQ: /* 0x32 */ 1565/* File: x86/OP_IF_EQ.S */ 1566/* File: x86/bincmp.S */ 1567 /* 1568 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1569 * fragment that specifies the *reverse* comparison to perform, e.g. 1570 * for "if-le" you would use "gt". 1571 * 1572 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1573 */ 1574 /* if-cmp vA, vB, +CCCC */ 1575 movzx rINSTbl,%ecx # ecx <- A+ 1576 andb $0xf,%cl # ecx <- A 1577 GET_VREG_R %eax %ecx # eax <- vA 1578 sarl $4,rINST # rINST<- B 1579 cmpl (rFP,rINST,4),%eax # compare (vA, vB) 1580 movswl 2(rPC),rINST # Get signed branch offset 1581 movl $2,%eax # assume not taken 1582 jne 1f 1583 testl rINST,rINST 1584 js common_backwardBranch 1585 movl rINST,%eax 15861: 1587 FETCH_INST_INDEXED %eax 1588 ADVANCE_PC_INDEXED %eax 1589 GOTO_NEXT 1590 1591 1592/* ------------------------------ */ 1593 .balign 64 1594.L_OP_IF_NE: /* 0x33 */ 1595/* File: x86/OP_IF_NE.S */ 1596/* File: x86/bincmp.S */ 1597 /* 1598 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1599 * fragment that specifies the *reverse* comparison to perform, e.g. 1600 * for "if-le" you would use "gt". 1601 * 1602 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1603 */ 1604 /* if-cmp vA, vB, +CCCC */ 1605 movzx rINSTbl,%ecx # ecx <- A+ 1606 andb $0xf,%cl # ecx <- A 1607 GET_VREG_R %eax %ecx # eax <- vA 1608 sarl $4,rINST # rINST<- B 1609 cmpl (rFP,rINST,4),%eax # compare (vA, vB) 1610 movswl 2(rPC),rINST # Get signed branch offset 1611 movl $2,%eax # assume not taken 1612 je 1f 1613 testl rINST,rINST 1614 js common_backwardBranch 1615 movl rINST,%eax 16161: 1617 FETCH_INST_INDEXED %eax 1618 ADVANCE_PC_INDEXED %eax 1619 GOTO_NEXT 1620 1621 1622/* ------------------------------ */ 1623 .balign 64 1624.L_OP_IF_LT: /* 0x34 */ 1625/* File: x86/OP_IF_LT.S */ 1626/* File: x86/bincmp.S */ 1627 /* 1628 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1629 * fragment that specifies the *reverse* comparison to perform, e.g. 1630 * for "if-le" you would use "gt". 1631 * 1632 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1633 */ 1634 /* if-cmp vA, vB, +CCCC */ 1635 movzx rINSTbl,%ecx # ecx <- A+ 1636 andb $0xf,%cl # ecx <- A 1637 GET_VREG_R %eax %ecx # eax <- vA 1638 sarl $4,rINST # rINST<- B 1639 cmpl (rFP,rINST,4),%eax # compare (vA, vB) 1640 movswl 2(rPC),rINST # Get signed branch offset 1641 movl $2,%eax # assume not taken 1642 jge 1f 1643 testl rINST,rINST 1644 js common_backwardBranch 1645 movl rINST,%eax 16461: 1647 FETCH_INST_INDEXED %eax 1648 ADVANCE_PC_INDEXED %eax 1649 GOTO_NEXT 1650 1651 1652/* ------------------------------ */ 1653 .balign 64 1654.L_OP_IF_GE: /* 0x35 */ 1655/* File: x86/OP_IF_GE.S */ 1656/* File: x86/bincmp.S */ 1657 /* 1658 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1659 * fragment that specifies the *reverse* comparison to perform, e.g. 1660 * for "if-le" you would use "gt". 1661 * 1662 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1663 */ 1664 /* if-cmp vA, vB, +CCCC */ 1665 movzx rINSTbl,%ecx # ecx <- A+ 1666 andb $0xf,%cl # ecx <- A 1667 GET_VREG_R %eax %ecx # eax <- vA 1668 sarl $4,rINST # rINST<- B 1669 cmpl (rFP,rINST,4),%eax # compare (vA, vB) 1670 movswl 2(rPC),rINST # Get signed branch offset 1671 movl $2,%eax # assume not taken 1672 jl 1f 1673 testl rINST,rINST 1674 js common_backwardBranch 1675 movl rINST,%eax 16761: 1677 FETCH_INST_INDEXED %eax 1678 ADVANCE_PC_INDEXED %eax 1679 GOTO_NEXT 1680 1681 1682/* ------------------------------ */ 1683 .balign 64 1684.L_OP_IF_GT: /* 0x36 */ 1685/* File: x86/OP_IF_GT.S */ 1686/* File: x86/bincmp.S */ 1687 /* 1688 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1689 * fragment that specifies the *reverse* comparison to perform, e.g. 1690 * for "if-le" you would use "gt". 1691 * 1692 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1693 */ 1694 /* if-cmp vA, vB, +CCCC */ 1695 movzx rINSTbl,%ecx # ecx <- A+ 1696 andb $0xf,%cl # ecx <- A 1697 GET_VREG_R %eax %ecx # eax <- vA 1698 sarl $4,rINST # rINST<- B 1699 cmpl (rFP,rINST,4),%eax # compare (vA, vB) 1700 movswl 2(rPC),rINST # Get signed branch offset 1701 movl $2,%eax # assume not taken 1702 jle 1f 1703 testl rINST,rINST 1704 js common_backwardBranch 1705 movl rINST,%eax 17061: 1707 FETCH_INST_INDEXED %eax 1708 ADVANCE_PC_INDEXED %eax 1709 GOTO_NEXT 1710 1711 1712/* ------------------------------ */ 1713 .balign 64 1714.L_OP_IF_LE: /* 0x37 */ 1715/* File: x86/OP_IF_LE.S */ 1716/* File: x86/bincmp.S */ 1717 /* 1718 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1719 * fragment that specifies the *reverse* comparison to perform, e.g. 1720 * for "if-le" you would use "gt". 1721 * 1722 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1723 */ 1724 /* if-cmp vA, vB, +CCCC */ 1725 movzx rINSTbl,%ecx # ecx <- A+ 1726 andb $0xf,%cl # ecx <- A 1727 GET_VREG_R %eax %ecx # eax <- vA 1728 sarl $4,rINST # rINST<- B 1729 cmpl (rFP,rINST,4),%eax # compare (vA, vB) 1730 movswl 2(rPC),rINST # Get signed branch offset 1731 movl $2,%eax # assume not taken 1732 jg 1f 1733 testl rINST,rINST 1734 js common_backwardBranch 1735 movl rINST,%eax 17361: 1737 FETCH_INST_INDEXED %eax 1738 ADVANCE_PC_INDEXED %eax 1739 GOTO_NEXT 1740 1741 1742/* ------------------------------ */ 1743 .balign 64 1744.L_OP_IF_EQZ: /* 0x38 */ 1745/* File: x86/OP_IF_EQZ.S */ 1746/* File: x86/zcmp.S */ 1747 /* 1748 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1749 * fragment that specifies the *reverse* comparison to perform, e.g. 1750 * for "if-le" you would use "gt". 1751 * 1752 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1753 */ 1754 /* if-cmp vAA, +BBBB */ 1755 cmpl $0,(rFP,rINST,4) # compare (vA, 0) 1756 movswl 2(rPC),rINST # fetch signed displacement 1757 movl $2,%eax # assume branch not taken 1758 jne 1f 1759 testl rINST,rINST 1760 js common_backwardBranch 1761 movl rINST,%eax 17621: 1763 FETCH_INST_INDEXED %eax 1764 ADVANCE_PC_INDEXED %eax 1765 GOTO_NEXT 1766 1767 1768/* ------------------------------ */ 1769 .balign 64 1770.L_OP_IF_NEZ: /* 0x39 */ 1771/* File: x86/OP_IF_NEZ.S */ 1772/* File: x86/zcmp.S */ 1773 /* 1774 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1775 * fragment that specifies the *reverse* comparison to perform, e.g. 1776 * for "if-le" you would use "gt". 1777 * 1778 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1779 */ 1780 /* if-cmp vAA, +BBBB */ 1781 cmpl $0,(rFP,rINST,4) # compare (vA, 0) 1782 movswl 2(rPC),rINST # fetch signed displacement 1783 movl $2,%eax # assume branch not taken 1784 je 1f 1785 testl rINST,rINST 1786 js common_backwardBranch 1787 movl rINST,%eax 17881: 1789 FETCH_INST_INDEXED %eax 1790 ADVANCE_PC_INDEXED %eax 1791 GOTO_NEXT 1792 1793 1794/* ------------------------------ */ 1795 .balign 64 1796.L_OP_IF_LTZ: /* 0x3a */ 1797/* File: x86/OP_IF_LTZ.S */ 1798/* File: x86/zcmp.S */ 1799 /* 1800 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1801 * fragment that specifies the *reverse* comparison to perform, e.g. 1802 * for "if-le" you would use "gt". 1803 * 1804 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1805 */ 1806 /* if-cmp vAA, +BBBB */ 1807 cmpl $0,(rFP,rINST,4) # compare (vA, 0) 1808 movswl 2(rPC),rINST # fetch signed displacement 1809 movl $2,%eax # assume branch not taken 1810 jge 1f 1811 testl rINST,rINST 1812 js common_backwardBranch 1813 movl rINST,%eax 18141: 1815 FETCH_INST_INDEXED %eax 1816 ADVANCE_PC_INDEXED %eax 1817 GOTO_NEXT 1818 1819 1820/* ------------------------------ */ 1821 .balign 64 1822.L_OP_IF_GEZ: /* 0x3b */ 1823/* File: x86/OP_IF_GEZ.S */ 1824/* File: x86/zcmp.S */ 1825 /* 1826 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1827 * fragment that specifies the *reverse* comparison to perform, e.g. 1828 * for "if-le" you would use "gt". 1829 * 1830 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1831 */ 1832 /* if-cmp vAA, +BBBB */ 1833 cmpl $0,(rFP,rINST,4) # compare (vA, 0) 1834 movswl 2(rPC),rINST # fetch signed displacement 1835 movl $2,%eax # assume branch not taken 1836 jl 1f 1837 testl rINST,rINST 1838 js common_backwardBranch 1839 movl rINST,%eax 18401: 1841 FETCH_INST_INDEXED %eax 1842 ADVANCE_PC_INDEXED %eax 1843 GOTO_NEXT 1844 1845 1846/* ------------------------------ */ 1847 .balign 64 1848.L_OP_IF_GTZ: /* 0x3c */ 1849/* File: x86/OP_IF_GTZ.S */ 1850/* File: x86/zcmp.S */ 1851 /* 1852 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1853 * fragment that specifies the *reverse* comparison to perform, e.g. 1854 * for "if-le" you would use "gt". 1855 * 1856 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1857 */ 1858 /* if-cmp vAA, +BBBB */ 1859 cmpl $0,(rFP,rINST,4) # compare (vA, 0) 1860 movswl 2(rPC),rINST # fetch signed displacement 1861 movl $2,%eax # assume branch not taken 1862 jle 1f 1863 testl rINST,rINST 1864 js common_backwardBranch 1865 movl rINST,%eax 18661: 1867 FETCH_INST_INDEXED %eax 1868 ADVANCE_PC_INDEXED %eax 1869 GOTO_NEXT 1870 1871 1872/* ------------------------------ */ 1873 .balign 64 1874.L_OP_IF_LEZ: /* 0x3d */ 1875/* File: x86/OP_IF_LEZ.S */ 1876/* File: x86/zcmp.S */ 1877 /* 1878 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1879 * fragment that specifies the *reverse* comparison to perform, e.g. 1880 * for "if-le" you would use "gt". 1881 * 1882 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1883 */ 1884 /* if-cmp vAA, +BBBB */ 1885 cmpl $0,(rFP,rINST,4) # compare (vA, 0) 1886 movswl 2(rPC),rINST # fetch signed displacement 1887 movl $2,%eax # assume branch not taken 1888 jg 1f 1889 testl rINST,rINST 1890 js common_backwardBranch 1891 movl rINST,%eax 18921: 1893 FETCH_INST_INDEXED %eax 1894 ADVANCE_PC_INDEXED %eax 1895 GOTO_NEXT 1896 1897 1898/* ------------------------------ */ 1899 .balign 64 1900.L_OP_UNUSED_3E: /* 0x3e */ 1901/* File: x86/OP_UNUSED_3E.S */ 1902/* File: x86/unused.S */ 1903 jmp common_abort 1904 1905 1906/* ------------------------------ */ 1907 .balign 64 1908.L_OP_UNUSED_3F: /* 0x3f */ 1909/* File: x86/OP_UNUSED_3F.S */ 1910/* File: x86/unused.S */ 1911 jmp common_abort 1912 1913 1914/* ------------------------------ */ 1915 .balign 64 1916.L_OP_UNUSED_40: /* 0x40 */ 1917/* File: x86/OP_UNUSED_40.S */ 1918/* File: x86/unused.S */ 1919 jmp common_abort 1920 1921 1922/* ------------------------------ */ 1923 .balign 64 1924.L_OP_UNUSED_41: /* 0x41 */ 1925/* File: x86/OP_UNUSED_41.S */ 1926/* File: x86/unused.S */ 1927 jmp common_abort 1928 1929 1930/* ------------------------------ */ 1931 .balign 64 1932.L_OP_UNUSED_42: /* 0x42 */ 1933/* File: x86/OP_UNUSED_42.S */ 1934/* File: x86/unused.S */ 1935 jmp common_abort 1936 1937 1938/* ------------------------------ */ 1939 .balign 64 1940.L_OP_UNUSED_43: /* 0x43 */ 1941/* File: x86/OP_UNUSED_43.S */ 1942/* File: x86/unused.S */ 1943 jmp common_abort 1944 1945 1946/* ------------------------------ */ 1947 .balign 64 1948.L_OP_AGET: /* 0x44 */ 1949/* File: x86/OP_AGET.S */ 1950 /* 1951 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1952 * 1953 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1954 */ 1955 /* op vAA, vBB, vCC */ 1956 movzbl 2(rPC),%eax # eax<- BB 1957 movzbl 3(rPC),%ecx # ecx<- CC 1958 GET_VREG_R %eax %eax # eax<- vBB (array object) 1959 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 1960 testl %eax,%eax # null array object? 1961 je common_errNullObject # bail if so 1962 cmpl offArrayObject_length(%eax),%ecx 1963 jae common_errArrayIndex # index >= length, bail. Expects 1964 # arrayObj in eax 1965 # index in ecx 1966 movl offArrayObject_contents(%eax,%ecx,4),%eax 1967.LOP_AGET_finish: 1968 FETCH_INST_OPCODE 2 %edx 1969 SET_VREG %eax rINST 1970 ADVANCE_PC 2 1971 GOTO_NEXT_R %edx 1972 1973/* ------------------------------ */ 1974 .balign 64 1975.L_OP_AGET_WIDE: /* 0x45 */ 1976/* File: x86/OP_AGET_WIDE.S */ 1977 /* 1978 * Array get, 64 bits. vAA <- vBB[vCC]. 1979 * 1980 */ 1981 /* op vAA, vBB, vCC */ 1982 movzbl 2(rPC),%eax # eax<- BB 1983 movzbl 3(rPC),%ecx # ecx<- CC 1984 GET_VREG_R %eax %eax # eax<- vBB (array object) 1985 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 1986 testl %eax,%eax # null array object? 1987 je common_errNullObject # bail if so 1988 cmpl offArrayObject_length(%eax),%ecx 1989 jb .LOP_AGET_WIDE_finish # index < length, OK 1990 jmp common_errArrayIndex # index >= length, bail. Expects 1991 # arrayObj in eax 1992 # index in ecx 1993 1994/* ------------------------------ */ 1995 .balign 64 1996.L_OP_AGET_OBJECT: /* 0x46 */ 1997/* File: x86/OP_AGET_OBJECT.S */ 1998/* File: x86/OP_AGET.S */ 1999 /* 2000 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2001 * 2002 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2003 */ 2004 /* op vAA, vBB, vCC */ 2005 movzbl 2(rPC),%eax # eax<- BB 2006 movzbl 3(rPC),%ecx # ecx<- CC 2007 GET_VREG_R %eax %eax # eax<- vBB (array object) 2008 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2009 testl %eax,%eax # null array object? 2010 je common_errNullObject # bail if so 2011 cmpl offArrayObject_length(%eax),%ecx 2012 jae common_errArrayIndex # index >= length, bail. Expects 2013 # arrayObj in eax 2014 # index in ecx 2015 movl offArrayObject_contents(%eax,%ecx,4),%eax 2016.LOP_AGET_OBJECT_finish: 2017 FETCH_INST_OPCODE 2 %edx 2018 SET_VREG %eax rINST 2019 ADVANCE_PC 2 2020 GOTO_NEXT_R %edx 2021 2022 2023/* ------------------------------ */ 2024 .balign 64 2025.L_OP_AGET_BOOLEAN: /* 0x47 */ 2026/* File: x86/OP_AGET_BOOLEAN.S */ 2027/* File: x86/OP_AGET.S */ 2028 /* 2029 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2030 * 2031 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2032 */ 2033 /* op vAA, vBB, vCC */ 2034 movzbl 2(rPC),%eax # eax<- BB 2035 movzbl 3(rPC),%ecx # ecx<- CC 2036 GET_VREG_R %eax %eax # eax<- vBB (array object) 2037 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2038 testl %eax,%eax # null array object? 2039 je common_errNullObject # bail if so 2040 cmpl offArrayObject_length(%eax),%ecx 2041 jae common_errArrayIndex # index >= length, bail. Expects 2042 # arrayObj in eax 2043 # index in ecx 2044 movzbl offArrayObject_contents(%eax,%ecx,1),%eax 2045.LOP_AGET_BOOLEAN_finish: 2046 FETCH_INST_OPCODE 2 %edx 2047 SET_VREG %eax rINST 2048 ADVANCE_PC 2 2049 GOTO_NEXT_R %edx 2050 2051 2052/* ------------------------------ */ 2053 .balign 64 2054.L_OP_AGET_BYTE: /* 0x48 */ 2055/* File: x86/OP_AGET_BYTE.S */ 2056/* File: x86/OP_AGET.S */ 2057 /* 2058 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2059 * 2060 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2061 */ 2062 /* op vAA, vBB, vCC */ 2063 movzbl 2(rPC),%eax # eax<- BB 2064 movzbl 3(rPC),%ecx # ecx<- CC 2065 GET_VREG_R %eax %eax # eax<- vBB (array object) 2066 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2067 testl %eax,%eax # null array object? 2068 je common_errNullObject # bail if so 2069 cmpl offArrayObject_length(%eax),%ecx 2070 jae common_errArrayIndex # index >= length, bail. Expects 2071 # arrayObj in eax 2072 # index in ecx 2073 movsbl offArrayObject_contents(%eax,%ecx,1),%eax 2074.LOP_AGET_BYTE_finish: 2075 FETCH_INST_OPCODE 2 %edx 2076 SET_VREG %eax rINST 2077 ADVANCE_PC 2 2078 GOTO_NEXT_R %edx 2079 2080 2081/* ------------------------------ */ 2082 .balign 64 2083.L_OP_AGET_CHAR: /* 0x49 */ 2084/* File: x86/OP_AGET_CHAR.S */ 2085/* File: x86/OP_AGET.S */ 2086 /* 2087 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2088 * 2089 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2090 */ 2091 /* op vAA, vBB, vCC */ 2092 movzbl 2(rPC),%eax # eax<- BB 2093 movzbl 3(rPC),%ecx # ecx<- CC 2094 GET_VREG_R %eax %eax # eax<- vBB (array object) 2095 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2096 testl %eax,%eax # null array object? 2097 je common_errNullObject # bail if so 2098 cmpl offArrayObject_length(%eax),%ecx 2099 jae common_errArrayIndex # index >= length, bail. Expects 2100 # arrayObj in eax 2101 # index in ecx 2102 movzwl offArrayObject_contents(%eax,%ecx,2),%eax 2103.LOP_AGET_CHAR_finish: 2104 FETCH_INST_OPCODE 2 %edx 2105 SET_VREG %eax rINST 2106 ADVANCE_PC 2 2107 GOTO_NEXT_R %edx 2108 2109 2110/* ------------------------------ */ 2111 .balign 64 2112.L_OP_AGET_SHORT: /* 0x4a */ 2113/* File: x86/OP_AGET_SHORT.S */ 2114/* File: x86/OP_AGET.S */ 2115 /* 2116 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2117 * 2118 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2119 */ 2120 /* op vAA, vBB, vCC */ 2121 movzbl 2(rPC),%eax # eax<- BB 2122 movzbl 3(rPC),%ecx # ecx<- CC 2123 GET_VREG_R %eax %eax # eax<- vBB (array object) 2124 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2125 testl %eax,%eax # null array object? 2126 je common_errNullObject # bail if so 2127 cmpl offArrayObject_length(%eax),%ecx 2128 jae common_errArrayIndex # index >= length, bail. Expects 2129 # arrayObj in eax 2130 # index in ecx 2131 movswl offArrayObject_contents(%eax,%ecx,2),%eax 2132.LOP_AGET_SHORT_finish: 2133 FETCH_INST_OPCODE 2 %edx 2134 SET_VREG %eax rINST 2135 ADVANCE_PC 2 2136 GOTO_NEXT_R %edx 2137 2138 2139/* ------------------------------ */ 2140 .balign 64 2141.L_OP_APUT: /* 0x4b */ 2142/* File: x86/OP_APUT.S */ 2143 /* 2144 * Array put, 32 bits or less. vBB[vCC] <- vAA 2145 * 2146 * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short 2147 */ 2148 /* op vAA, vBB, vCC */ 2149 movzbl 2(rPC),%eax # eax<- BB 2150 movzbl 3(rPC),%ecx # ecx<- CC 2151 GET_VREG_R %eax %eax # eax<- vBB (array object) 2152 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2153 testl %eax,%eax # null array object? 2154 je common_errNullObject # bail if so 2155 cmpl offArrayObject_length(%eax),%ecx 2156 jae common_errArrayIndex # index >= length, bail. Expects: 2157 # arrayObj in eax 2158 # index in ecx 2159 leal offArrayObject_contents(%eax,%ecx,4),%eax 2160.LOP_APUT_finish: 2161 GET_VREG_R %ecx rINST 2162 FETCH_INST_OPCODE 2 %edx 2163 movl %ecx,(%eax) 2164 ADVANCE_PC 2 2165 GOTO_NEXT_R %edx 2166 2167/* ------------------------------ */ 2168 .balign 64 2169.L_OP_APUT_WIDE: /* 0x4c */ 2170/* File: x86/OP_APUT_WIDE.S */ 2171 /* 2172 * Array put, 64 bits. vBB[vCC]<-vAA. 2173 * 2174 */ 2175 /* op vAA, vBB, vCC */ 2176 movzbl 2(rPC),%eax # eax<- BB 2177 movzbl 3(rPC),%ecx # ecx<- CC 2178 GET_VREG_R %eax %eax # eax<- vBB (array object) 2179 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2180 testl %eax,%eax # null array object? 2181 je common_errNullObject # bail if so 2182 cmpl offArrayObject_length(%eax),%ecx 2183 jb .LOP_APUT_WIDE_finish # index < length, OK 2184 jmp common_errArrayIndex # index >= length, bail. Expects: 2185 # arrayObj in eax 2186 # index in ecx 2187 2188/* ------------------------------ */ 2189 .balign 64 2190.L_OP_APUT_OBJECT: /* 0x4d */ 2191/* File: x86/OP_APUT_OBJECT.S */ 2192 /* 2193 * Array put, 32 bits or less. vBB[vCC] <- vAA 2194 * 2195 * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short 2196 */ 2197 /* op vAA, vBB, vCC */ 2198 movzbl 2(rPC),%eax # eax<- BB 2199 movzbl 3(rPC),%ecx # ecx<- CC 2200 GET_VREG_R %eax %eax # eax<- vBB (array object) 2201 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2202 GET_VREG_R rINST rINST # rINST<- vAA 2203 testl %eax,%eax # null array object? 2204 je common_errNullObject # bail if so 2205 cmpl offArrayObject_length(%eax),%ecx 2206 jb .LOP_APUT_OBJECT_continue 2207 jmp common_errArrayIndex # index >= length, bail. Expects 2208 # arrayObj in eax 2209 # index in ecx 2210 2211/* ------------------------------ */ 2212 .balign 64 2213.L_OP_APUT_BOOLEAN: /* 0x4e */ 2214/* File: x86/OP_APUT_BOOLEAN.S */ 2215/* File: x86/OP_APUT.S */ 2216 /* 2217 * Array put, 32 bits or less. vBB[vCC] <- vAA 2218 * 2219 * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short 2220 */ 2221 /* op vAA, vBB, vCC */ 2222 movzbl 2(rPC),%eax # eax<- BB 2223 movzbl 3(rPC),%ecx # ecx<- CC 2224 GET_VREG_R %eax %eax # eax<- vBB (array object) 2225 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2226 testl %eax,%eax # null array object? 2227 je common_errNullObject # bail if so 2228 cmpl offArrayObject_length(%eax),%ecx 2229 jae common_errArrayIndex # index >= length, bail. Expects: 2230 # arrayObj in eax 2231 # index in ecx 2232 leal offArrayObject_contents(%eax,%ecx,1),%eax 2233.LOP_APUT_BOOLEAN_finish: 2234 GET_VREG_R %ecx rINST 2235 FETCH_INST_OPCODE 2 %edx 2236 movb %cl,(%eax) 2237 ADVANCE_PC 2 2238 GOTO_NEXT_R %edx 2239 2240 2241/* ------------------------------ */ 2242 .balign 64 2243.L_OP_APUT_BYTE: /* 0x4f */ 2244/* File: x86/OP_APUT_BYTE.S */ 2245/* File: x86/OP_APUT.S */ 2246 /* 2247 * Array put, 32 bits or less. vBB[vCC] <- vAA 2248 * 2249 * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short 2250 */ 2251 /* op vAA, vBB, vCC */ 2252 movzbl 2(rPC),%eax # eax<- BB 2253 movzbl 3(rPC),%ecx # ecx<- CC 2254 GET_VREG_R %eax %eax # eax<- vBB (array object) 2255 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2256 testl %eax,%eax # null array object? 2257 je common_errNullObject # bail if so 2258 cmpl offArrayObject_length(%eax),%ecx 2259 jae common_errArrayIndex # index >= length, bail. Expects: 2260 # arrayObj in eax 2261 # index in ecx 2262 leal offArrayObject_contents(%eax,%ecx,1),%eax 2263.LOP_APUT_BYTE_finish: 2264 GET_VREG_R %ecx rINST 2265 FETCH_INST_OPCODE 2 %edx 2266 movb %cl,(%eax) 2267 ADVANCE_PC 2 2268 GOTO_NEXT_R %edx 2269 2270 2271/* ------------------------------ */ 2272 .balign 64 2273.L_OP_APUT_CHAR: /* 0x50 */ 2274/* File: x86/OP_APUT_CHAR.S */ 2275/* File: x86/OP_APUT.S */ 2276 /* 2277 * Array put, 32 bits or less. vBB[vCC] <- vAA 2278 * 2279 * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short 2280 */ 2281 /* op vAA, vBB, vCC */ 2282 movzbl 2(rPC),%eax # eax<- BB 2283 movzbl 3(rPC),%ecx # ecx<- CC 2284 GET_VREG_R %eax %eax # eax<- vBB (array object) 2285 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2286 testl %eax,%eax # null array object? 2287 je common_errNullObject # bail if so 2288 cmpl offArrayObject_length(%eax),%ecx 2289 jae common_errArrayIndex # index >= length, bail. Expects: 2290 # arrayObj in eax 2291 # index in ecx 2292 leal offArrayObject_contents(%eax,%ecx,2),%eax 2293.LOP_APUT_CHAR_finish: 2294 GET_VREG_R %ecx rINST 2295 FETCH_INST_OPCODE 2 %edx 2296 movw %cx,(%eax) 2297 ADVANCE_PC 2 2298 GOTO_NEXT_R %edx 2299 2300 2301/* ------------------------------ */ 2302 .balign 64 2303.L_OP_APUT_SHORT: /* 0x51 */ 2304/* File: x86/OP_APUT_SHORT.S */ 2305/* File: x86/OP_APUT.S */ 2306 /* 2307 * Array put, 32 bits or less. vBB[vCC] <- vAA 2308 * 2309 * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short 2310 */ 2311 /* op vAA, vBB, vCC */ 2312 movzbl 2(rPC),%eax # eax<- BB 2313 movzbl 3(rPC),%ecx # ecx<- CC 2314 GET_VREG_R %eax %eax # eax<- vBB (array object) 2315 GET_VREG_R %ecx %ecx # ecs<- vCC (requested index) 2316 testl %eax,%eax # null array object? 2317 je common_errNullObject # bail if so 2318 cmpl offArrayObject_length(%eax),%ecx 2319 jae common_errArrayIndex # index >= length, bail. Expects: 2320 # arrayObj in eax 2321 # index in ecx 2322 leal offArrayObject_contents(%eax,%ecx,2),%eax 2323.LOP_APUT_SHORT_finish: 2324 GET_VREG_R %ecx rINST 2325 FETCH_INST_OPCODE 2 %edx 2326 movw %cx,(%eax) 2327 ADVANCE_PC 2 2328 GOTO_NEXT_R %edx 2329 2330 2331/* ------------------------------ */ 2332 .balign 64 2333.L_OP_IGET: /* 0x52 */ 2334/* File: x86/OP_IGET.S */ 2335 /* 2336 * General 32-bit instance field get. 2337 * 2338 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2339 */ 2340 /* op vA, vB, field@CCCC */ 2341 movl rGLUE,%ecx 2342 movzwl 2(rPC),%edx # edx<- 0000CCCC 2343 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 2344 movzbl rINSTbl,%ecx # ecx<- BA 2345 sarl $4,%ecx # ecx<- B 2346 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2347 andb $0xf,rINSTbl # rINST<- A 2348 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2349 movl (%eax,%edx,4),%eax # resolved entry 2350 testl %eax,%eax # is resolved entry null? 2351 jne .LOP_IGET_finish # no, already resolved 2352 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 2353 movl rGLUE,%edx 2354 jmp .LOP_IGET_resolve 2355 2356/* ------------------------------ */ 2357 .balign 64 2358.L_OP_IGET_WIDE: /* 0x53 */ 2359/* File: x86/OP_IGET_WIDE.S */ 2360 /* 2361 * 64-bit instance field get. 2362 * 2363 */ 2364 /* op vA, vB, field@CCCC */ 2365 movl rGLUE,%ecx 2366 movzwl 2(rPC),%edx # edx<- 0000CCCC 2367 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 2368 movzbl rINSTbl,%ecx # ecx<- BA 2369 sarl $4,%ecx # ecx<- B 2370 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2371 andb $0xf,rINSTbl # rINST<- A 2372 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2373 movl (%eax,%edx,4),%eax # resolved entry 2374 testl %eax,%eax # is resolved entry null? 2375 jne .LOP_IGET_WIDE_finish # no, already resolved 2376 movl %edx,OUT_ARG1(%esp) # for dvmResolveInstField 2377 movl rGLUE,%edx 2378 jmp .LOP_IGET_WIDE_resolve 2379 2380/* ------------------------------ */ 2381 .balign 64 2382.L_OP_IGET_OBJECT: /* 0x54 */ 2383/* File: x86/OP_IGET_OBJECT.S */ 2384/* File: x86/OP_IGET.S */ 2385 /* 2386 * General 32-bit instance field get. 2387 * 2388 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2389 */ 2390 /* op vA, vB, field@CCCC */ 2391 movl rGLUE,%ecx 2392 movzwl 2(rPC),%edx # edx<- 0000CCCC 2393 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 2394 movzbl rINSTbl,%ecx # ecx<- BA 2395 sarl $4,%ecx # ecx<- B 2396 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2397 andb $0xf,rINSTbl # rINST<- A 2398 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2399 movl (%eax,%edx,4),%eax # resolved entry 2400 testl %eax,%eax # is resolved entry null? 2401 jne .LOP_IGET_OBJECT_finish # no, already resolved 2402 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 2403 movl rGLUE,%edx 2404 jmp .LOP_IGET_OBJECT_resolve 2405 2406 2407/* ------------------------------ */ 2408 .balign 64 2409.L_OP_IGET_BOOLEAN: /* 0x55 */ 2410/* File: x86/OP_IGET_BOOLEAN.S */ 2411/* File: x86/OP_IGET.S */ 2412 /* 2413 * General 32-bit instance field get. 2414 * 2415 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2416 */ 2417 /* op vA, vB, field@CCCC */ 2418 movl rGLUE,%ecx 2419 movzwl 2(rPC),%edx # edx<- 0000CCCC 2420 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 2421 movzbl rINSTbl,%ecx # ecx<- BA 2422 sarl $4,%ecx # ecx<- B 2423 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2424 andb $0xf,rINSTbl # rINST<- A 2425 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2426 movl (%eax,%edx,4),%eax # resolved entry 2427 testl %eax,%eax # is resolved entry null? 2428 jne .LOP_IGET_BOOLEAN_finish # no, already resolved 2429 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 2430 movl rGLUE,%edx 2431 jmp .LOP_IGET_BOOLEAN_resolve 2432 2433 2434/* ------------------------------ */ 2435 .balign 64 2436.L_OP_IGET_BYTE: /* 0x56 */ 2437/* File: x86/OP_IGET_BYTE.S */ 2438/* File: x86/OP_IGET.S */ 2439 /* 2440 * General 32-bit instance field get. 2441 * 2442 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2443 */ 2444 /* op vA, vB, field@CCCC */ 2445 movl rGLUE,%ecx 2446 movzwl 2(rPC),%edx # edx<- 0000CCCC 2447 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 2448 movzbl rINSTbl,%ecx # ecx<- BA 2449 sarl $4,%ecx # ecx<- B 2450 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2451 andb $0xf,rINSTbl # rINST<- A 2452 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2453 movl (%eax,%edx,4),%eax # resolved entry 2454 testl %eax,%eax # is resolved entry null? 2455 jne .LOP_IGET_BYTE_finish # no, already resolved 2456 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 2457 movl rGLUE,%edx 2458 jmp .LOP_IGET_BYTE_resolve 2459 2460 2461/* ------------------------------ */ 2462 .balign 64 2463.L_OP_IGET_CHAR: /* 0x57 */ 2464/* File: x86/OP_IGET_CHAR.S */ 2465/* File: x86/OP_IGET.S */ 2466 /* 2467 * General 32-bit instance field get. 2468 * 2469 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2470 */ 2471 /* op vA, vB, field@CCCC */ 2472 movl rGLUE,%ecx 2473 movzwl 2(rPC),%edx # edx<- 0000CCCC 2474 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 2475 movzbl rINSTbl,%ecx # ecx<- BA 2476 sarl $4,%ecx # ecx<- B 2477 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2478 andb $0xf,rINSTbl # rINST<- A 2479 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2480 movl (%eax,%edx,4),%eax # resolved entry 2481 testl %eax,%eax # is resolved entry null? 2482 jne .LOP_IGET_CHAR_finish # no, already resolved 2483 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 2484 movl rGLUE,%edx 2485 jmp .LOP_IGET_CHAR_resolve 2486 2487 2488/* ------------------------------ */ 2489 .balign 64 2490.L_OP_IGET_SHORT: /* 0x58 */ 2491/* File: x86/OP_IGET_SHORT.S */ 2492/* File: x86/OP_IGET.S */ 2493 /* 2494 * General 32-bit instance field get. 2495 * 2496 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2497 */ 2498 /* op vA, vB, field@CCCC */ 2499 movl rGLUE,%ecx 2500 movzwl 2(rPC),%edx # edx<- 0000CCCC 2501 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 2502 movzbl rINSTbl,%ecx # ecx<- BA 2503 sarl $4,%ecx # ecx<- B 2504 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2505 andb $0xf,rINSTbl # rINST<- A 2506 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2507 movl (%eax,%edx,4),%eax # resolved entry 2508 testl %eax,%eax # is resolved entry null? 2509 jne .LOP_IGET_SHORT_finish # no, already resolved 2510 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 2511 movl rGLUE,%edx 2512 jmp .LOP_IGET_SHORT_resolve 2513 2514 2515/* ------------------------------ */ 2516 .balign 64 2517.L_OP_IPUT: /* 0x59 */ 2518/* File: x86/OP_IPUT.S */ 2519 2520 /* 2521 * General 32-bit instance field put. 2522 * 2523 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 2524 */ 2525 /* op vA, vB, field@CCCC */ 2526 movl rGLUE,%ecx 2527 movzwl 2(rPC),%edx # %edx<- 0000CCCC 2528 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 2529 movzbl rINSTbl,%ecx # ecx<- BA 2530 sarl $4,%ecx # ecx<- B 2531 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2532 andb $0xf,rINSTbl # rINST<- A 2533 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2534 movl (%eax,%edx,4),%eax # resolved entry 2535 testl %eax,%eax # is resolved entry null? 2536 jne .LOP_IPUT_finish # no, already resolved 2537 movl %edx,OUT_ARG1(%esp) 2538 movl rGLUE,%edx 2539 jmp .LOP_IPUT_resolve 2540 2541/* ------------------------------ */ 2542 .balign 64 2543.L_OP_IPUT_WIDE: /* 0x5a */ 2544/* File: x86/OP_IPUT_WIDE.S */ 2545 /* 2546 * 64-bit instance field put. 2547 * 2548 */ 2549 /* op vA, vB, field@CCCC */ 2550 movl rGLUE,%ecx 2551 movzwl 2(rPC),%edx # edx<- 0000CCCC 2552 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 2553 movzbl rINSTbl,%ecx # ecx<- BA 2554 sarl $4,%ecx # ecx<- B 2555 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2556 andb $0xf,rINSTbl # rINST<- A 2557 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2558 movl (%eax,%edx,4),%eax # resolved entry 2559 testl %eax,%eax # is resolved entry null? 2560 jne .LOP_IPUT_WIDE_finish # no, already resolved 2561 movl %edx,OUT_ARG1(%esp) 2562 movl rGLUE,%edx 2563 jmp .LOP_IPUT_WIDE_resolve 2564 2565/* ------------------------------ */ 2566 .balign 64 2567.L_OP_IPUT_OBJECT: /* 0x5b */ 2568/* File: x86/OP_IPUT_OBJECT.S */ 2569 /* 2570 * Object field put. 2571 * 2572 * for: iput-object 2573 */ 2574 /* op vA, vB, field@CCCC */ 2575 movl rGLUE,%ecx 2576 movzwl 2(rPC),%edx # edx<- 0000CCCC 2577 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 2578 movzbl rINSTbl,%ecx # ecx<- BA 2579 sarl $4,%ecx # ecx<- B 2580 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2581 andb $0xf,rINSTbl # rINST<- A 2582 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2583 movl (%eax,%edx,4),%eax # resolved entry 2584 testl %eax,%eax # is resolved entry null? 2585 jne .LOP_IPUT_OBJECT_finish # no, already resolved 2586 movl %edx,OUT_ARG1(%esp) 2587 movl rGLUE,%edx 2588 jmp .LOP_IPUT_OBJECT_resolve 2589 2590/* ------------------------------ */ 2591 .balign 64 2592.L_OP_IPUT_BOOLEAN: /* 0x5c */ 2593/* File: x86/OP_IPUT_BOOLEAN.S */ 2594/* File: x86/OP_IPUT.S */ 2595 2596 /* 2597 * General 32-bit instance field put. 2598 * 2599 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 2600 */ 2601 /* op vA, vB, field@CCCC */ 2602 movl rGLUE,%ecx 2603 movzwl 2(rPC),%edx # %edx<- 0000CCCC 2604 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 2605 movzbl rINSTbl,%ecx # ecx<- BA 2606 sarl $4,%ecx # ecx<- B 2607 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2608 andb $0xf,rINSTbl # rINST<- A 2609 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2610 movl (%eax,%edx,4),%eax # resolved entry 2611 testl %eax,%eax # is resolved entry null? 2612 jne .LOP_IPUT_BOOLEAN_finish # no, already resolved 2613 movl %edx,OUT_ARG1(%esp) 2614 movl rGLUE,%edx 2615 jmp .LOP_IPUT_BOOLEAN_resolve 2616 2617 2618/* ------------------------------ */ 2619 .balign 64 2620.L_OP_IPUT_BYTE: /* 0x5d */ 2621/* File: x86/OP_IPUT_BYTE.S */ 2622/* File: x86/OP_IPUT.S */ 2623 2624 /* 2625 * General 32-bit instance field put. 2626 * 2627 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 2628 */ 2629 /* op vA, vB, field@CCCC */ 2630 movl rGLUE,%ecx 2631 movzwl 2(rPC),%edx # %edx<- 0000CCCC 2632 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 2633 movzbl rINSTbl,%ecx # ecx<- BA 2634 sarl $4,%ecx # ecx<- B 2635 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2636 andb $0xf,rINSTbl # rINST<- A 2637 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2638 movl (%eax,%edx,4),%eax # resolved entry 2639 testl %eax,%eax # is resolved entry null? 2640 jne .LOP_IPUT_BYTE_finish # no, already resolved 2641 movl %edx,OUT_ARG1(%esp) 2642 movl rGLUE,%edx 2643 jmp .LOP_IPUT_BYTE_resolve 2644 2645 2646/* ------------------------------ */ 2647 .balign 64 2648.L_OP_IPUT_CHAR: /* 0x5e */ 2649/* File: x86/OP_IPUT_CHAR.S */ 2650/* File: x86/OP_IPUT.S */ 2651 2652 /* 2653 * General 32-bit instance field put. 2654 * 2655 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 2656 */ 2657 /* op vA, vB, field@CCCC */ 2658 movl rGLUE,%ecx 2659 movzwl 2(rPC),%edx # %edx<- 0000CCCC 2660 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 2661 movzbl rINSTbl,%ecx # ecx<- BA 2662 sarl $4,%ecx # ecx<- B 2663 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2664 andb $0xf,rINSTbl # rINST<- A 2665 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2666 movl (%eax,%edx,4),%eax # resolved entry 2667 testl %eax,%eax # is resolved entry null? 2668 jne .LOP_IPUT_CHAR_finish # no, already resolved 2669 movl %edx,OUT_ARG1(%esp) 2670 movl rGLUE,%edx 2671 jmp .LOP_IPUT_CHAR_resolve 2672 2673 2674/* ------------------------------ */ 2675 .balign 64 2676.L_OP_IPUT_SHORT: /* 0x5f */ 2677/* File: x86/OP_IPUT_SHORT.S */ 2678/* File: x86/OP_IPUT.S */ 2679 2680 /* 2681 * General 32-bit instance field put. 2682 * 2683 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 2684 */ 2685 /* op vA, vB, field@CCCC */ 2686 movl rGLUE,%ecx 2687 movzwl 2(rPC),%edx # %edx<- 0000CCCC 2688 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 2689 movzbl rINSTbl,%ecx # ecx<- BA 2690 sarl $4,%ecx # ecx<- B 2691 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 2692 andb $0xf,rINSTbl # rINST<- A 2693 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 2694 movl (%eax,%edx,4),%eax # resolved entry 2695 testl %eax,%eax # is resolved entry null? 2696 jne .LOP_IPUT_SHORT_finish # no, already resolved 2697 movl %edx,OUT_ARG1(%esp) 2698 movl rGLUE,%edx 2699 jmp .LOP_IPUT_SHORT_resolve 2700 2701 2702/* ------------------------------ */ 2703 .balign 64 2704.L_OP_SGET: /* 0x60 */ 2705/* File: x86/OP_SGET.S */ 2706 /* 2707 * General 32-bit SGET handler. 2708 * 2709 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2710 */ 2711 /* op vAA, field@BBBB */ 2712 movl rGLUE,%ecx 2713 movzwl 2(rPC),%eax # eax<- field ref BBBB 2714 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2715 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2716 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2717 testl %eax,%eax # resolved entry null? 2718 je .LOP_SGET_resolve # if not, make it so 2719.LOP_SGET_finish: # field ptr in eax 2720 movl offStaticField_value(%eax),%eax 2721 FETCH_INST_OPCODE 2 %edx 2722 ADVANCE_PC 2 2723 SET_VREG %eax rINST 2724 GOTO_NEXT_R %edx 2725 2726/* ------------------------------ */ 2727 .balign 64 2728.L_OP_SGET_WIDE: /* 0x61 */ 2729/* File: x86/OP_SGET_WIDE.S */ 2730 /* 2731 * 64-bit SGET handler. 2732 * 2733 */ 2734 /* sget-wide vAA, field@BBBB */ 2735 movl rGLUE,%ecx 2736 movzwl 2(rPC),%eax # eax<- field ref BBBB 2737 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2738 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2739 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2740 testl %eax,%eax # resolved entry null? 2741 je .LOP_SGET_WIDE_resolve # if not, make it so 2742.LOP_SGET_WIDE_finish: # field ptr in eax 2743 movl offStaticField_value(%eax),%ecx # ecx<- lsw 2744 movl 4+offStaticField_value(%eax),%eax # eax<- msw 2745 FETCH_INST_OPCODE 2 %edx 2746 ADVANCE_PC 2 2747 SET_VREG_WORD %ecx rINST 0 2748 SET_VREG_WORD %eax rINST 1 2749 GOTO_NEXT_R %edx 2750 2751/* ------------------------------ */ 2752 .balign 64 2753.L_OP_SGET_OBJECT: /* 0x62 */ 2754/* File: x86/OP_SGET_OBJECT.S */ 2755/* File: x86/OP_SGET.S */ 2756 /* 2757 * General 32-bit SGET handler. 2758 * 2759 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2760 */ 2761 /* op vAA, field@BBBB */ 2762 movl rGLUE,%ecx 2763 movzwl 2(rPC),%eax # eax<- field ref BBBB 2764 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2765 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2766 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2767 testl %eax,%eax # resolved entry null? 2768 je .LOP_SGET_OBJECT_resolve # if not, make it so 2769.LOP_SGET_OBJECT_finish: # field ptr in eax 2770 movl offStaticField_value(%eax),%eax 2771 FETCH_INST_OPCODE 2 %edx 2772 ADVANCE_PC 2 2773 SET_VREG %eax rINST 2774 GOTO_NEXT_R %edx 2775 2776 2777/* ------------------------------ */ 2778 .balign 64 2779.L_OP_SGET_BOOLEAN: /* 0x63 */ 2780/* File: x86/OP_SGET_BOOLEAN.S */ 2781/* File: x86/OP_SGET.S */ 2782 /* 2783 * General 32-bit SGET handler. 2784 * 2785 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2786 */ 2787 /* op vAA, field@BBBB */ 2788 movl rGLUE,%ecx 2789 movzwl 2(rPC),%eax # eax<- field ref BBBB 2790 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2791 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2792 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2793 testl %eax,%eax # resolved entry null? 2794 je .LOP_SGET_BOOLEAN_resolve # if not, make it so 2795.LOP_SGET_BOOLEAN_finish: # field ptr in eax 2796 movl offStaticField_value(%eax),%eax 2797 FETCH_INST_OPCODE 2 %edx 2798 ADVANCE_PC 2 2799 SET_VREG %eax rINST 2800 GOTO_NEXT_R %edx 2801 2802 2803/* ------------------------------ */ 2804 .balign 64 2805.L_OP_SGET_BYTE: /* 0x64 */ 2806/* File: x86/OP_SGET_BYTE.S */ 2807/* File: x86/OP_SGET.S */ 2808 /* 2809 * General 32-bit SGET handler. 2810 * 2811 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2812 */ 2813 /* op vAA, field@BBBB */ 2814 movl rGLUE,%ecx 2815 movzwl 2(rPC),%eax # eax<- field ref BBBB 2816 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2817 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2818 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2819 testl %eax,%eax # resolved entry null? 2820 je .LOP_SGET_BYTE_resolve # if not, make it so 2821.LOP_SGET_BYTE_finish: # field ptr in eax 2822 movl offStaticField_value(%eax),%eax 2823 FETCH_INST_OPCODE 2 %edx 2824 ADVANCE_PC 2 2825 SET_VREG %eax rINST 2826 GOTO_NEXT_R %edx 2827 2828 2829/* ------------------------------ */ 2830 .balign 64 2831.L_OP_SGET_CHAR: /* 0x65 */ 2832/* File: x86/OP_SGET_CHAR.S */ 2833/* File: x86/OP_SGET.S */ 2834 /* 2835 * General 32-bit SGET handler. 2836 * 2837 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2838 */ 2839 /* op vAA, field@BBBB */ 2840 movl rGLUE,%ecx 2841 movzwl 2(rPC),%eax # eax<- field ref BBBB 2842 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2843 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2844 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2845 testl %eax,%eax # resolved entry null? 2846 je .LOP_SGET_CHAR_resolve # if not, make it so 2847.LOP_SGET_CHAR_finish: # field ptr in eax 2848 movl offStaticField_value(%eax),%eax 2849 FETCH_INST_OPCODE 2 %edx 2850 ADVANCE_PC 2 2851 SET_VREG %eax rINST 2852 GOTO_NEXT_R %edx 2853 2854 2855/* ------------------------------ */ 2856 .balign 64 2857.L_OP_SGET_SHORT: /* 0x66 */ 2858/* File: x86/OP_SGET_SHORT.S */ 2859/* File: x86/OP_SGET.S */ 2860 /* 2861 * General 32-bit SGET handler. 2862 * 2863 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2864 */ 2865 /* op vAA, field@BBBB */ 2866 movl rGLUE,%ecx 2867 movzwl 2(rPC),%eax # eax<- field ref BBBB 2868 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2869 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2870 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2871 testl %eax,%eax # resolved entry null? 2872 je .LOP_SGET_SHORT_resolve # if not, make it so 2873.LOP_SGET_SHORT_finish: # field ptr in eax 2874 movl offStaticField_value(%eax),%eax 2875 FETCH_INST_OPCODE 2 %edx 2876 ADVANCE_PC 2 2877 SET_VREG %eax rINST 2878 GOTO_NEXT_R %edx 2879 2880 2881/* ------------------------------ */ 2882 .balign 64 2883.L_OP_SPUT: /* 0x67 */ 2884/* File: x86/OP_SPUT.S */ 2885 /* 2886 * General 32-bit SPUT handler. 2887 * 2888 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2889 */ 2890 /* op vAA, field@BBBB */ 2891 movl rGLUE,%ecx 2892 movzwl 2(rPC),%eax # eax<- field ref BBBB 2893 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2894 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2895 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2896 testl %eax,%eax # resolved entry null? 2897 je .LOP_SPUT_resolve # if not, make it so 2898.LOP_SPUT_finish: # field ptr in eax 2899 GET_VREG_R %ecx rINST 2900 FETCH_INST_OPCODE 2 %edx 2901 ADVANCE_PC 2 2902 movl %ecx,offStaticField_value(%eax) 2903 GOTO_NEXT_R %edx 2904 2905/* ------------------------------ */ 2906 .balign 64 2907.L_OP_SPUT_WIDE: /* 0x68 */ 2908/* File: x86/OP_SPUT_WIDE.S */ 2909 /* 2910 * General 32-bit SPUT handler. 2911 * 2912 * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short 2913 */ 2914 /* op vAA, field@BBBB */ 2915 movl rGLUE,%ecx 2916 movzwl 2(rPC),%eax # eax<- field ref BBBB 2917 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2918 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2919 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2920 testl %eax,%eax # resolved entry null? 2921 je .LOP_SPUT_WIDE_resolve # if not, make it so 2922.LOP_SPUT_WIDE_finish: # field ptr in eax 2923 GET_VREG_WORD %ecx rINST 0 # rINST<- lsw 2924 GET_VREG_WORD rINST rINST 1 # ecx<- msw 2925 FETCH_INST_OPCODE 2 %edx 2926 ADVANCE_PC 2 2927 movl %ecx,offStaticField_value(%eax) 2928 movl rINST,4+offStaticField_value(%eax) 2929 GOTO_NEXT_R %edx 2930 2931/* ------------------------------ */ 2932 .balign 64 2933.L_OP_SPUT_OBJECT: /* 0x69 */ 2934/* File: x86/OP_SPUT_OBJECT.S */ 2935 /* 2936 * SPUT object handler. 2937 */ 2938 /* op vAA, field@BBBB */ 2939 movl rGLUE,%ecx 2940 movzwl 2(rPC),%eax # eax<- field ref BBBB 2941 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2942 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2943 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField 2944 testl %eax,%eax # resolved entry null? 2945 je .LOP_SPUT_OBJECT_resolve # if not, make it so 2946.LOP_SPUT_OBJECT_finish: # field ptr in eax 2947 movzbl rINSTbl,%ecx # ecx<- AA 2948 GET_VREG_R %ecx %ecx 2949 jmp .LOP_SPUT_OBJECT_continue 2950 2951/* ------------------------------ */ 2952 .balign 64 2953.L_OP_SPUT_BOOLEAN: /* 0x6a */ 2954/* File: x86/OP_SPUT_BOOLEAN.S */ 2955/* File: x86/OP_SPUT.S */ 2956 /* 2957 * General 32-bit SPUT handler. 2958 * 2959 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2960 */ 2961 /* op vAA, field@BBBB */ 2962 movl rGLUE,%ecx 2963 movzwl 2(rPC),%eax # eax<- field ref BBBB 2964 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2965 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2966 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2967 testl %eax,%eax # resolved entry null? 2968 je .LOP_SPUT_BOOLEAN_resolve # if not, make it so 2969.LOP_SPUT_BOOLEAN_finish: # field ptr in eax 2970 GET_VREG_R %ecx rINST 2971 FETCH_INST_OPCODE 2 %edx 2972 ADVANCE_PC 2 2973 movl %ecx,offStaticField_value(%eax) 2974 GOTO_NEXT_R %edx 2975 2976 2977/* ------------------------------ */ 2978 .balign 64 2979.L_OP_SPUT_BYTE: /* 0x6b */ 2980/* File: x86/OP_SPUT_BYTE.S */ 2981/* File: x86/OP_SPUT.S */ 2982 /* 2983 * General 32-bit SPUT handler. 2984 * 2985 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2986 */ 2987 /* op vAA, field@BBBB */ 2988 movl rGLUE,%ecx 2989 movzwl 2(rPC),%eax # eax<- field ref BBBB 2990 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 2991 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 2992 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 2993 testl %eax,%eax # resolved entry null? 2994 je .LOP_SPUT_BYTE_resolve # if not, make it so 2995.LOP_SPUT_BYTE_finish: # field ptr in eax 2996 GET_VREG_R %ecx rINST 2997 FETCH_INST_OPCODE 2 %edx 2998 ADVANCE_PC 2 2999 movl %ecx,offStaticField_value(%eax) 3000 GOTO_NEXT_R %edx 3001 3002 3003/* ------------------------------ */ 3004 .balign 64 3005.L_OP_SPUT_CHAR: /* 0x6c */ 3006/* File: x86/OP_SPUT_CHAR.S */ 3007/* File: x86/OP_SPUT.S */ 3008 /* 3009 * General 32-bit SPUT handler. 3010 * 3011 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3012 */ 3013 /* op vAA, field@BBBB */ 3014 movl rGLUE,%ecx 3015 movzwl 2(rPC),%eax # eax<- field ref BBBB 3016 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 3017 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 3018 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 3019 testl %eax,%eax # resolved entry null? 3020 je .LOP_SPUT_CHAR_resolve # if not, make it so 3021.LOP_SPUT_CHAR_finish: # field ptr in eax 3022 GET_VREG_R %ecx rINST 3023 FETCH_INST_OPCODE 2 %edx 3024 ADVANCE_PC 2 3025 movl %ecx,offStaticField_value(%eax) 3026 GOTO_NEXT_R %edx 3027 3028 3029/* ------------------------------ */ 3030 .balign 64 3031.L_OP_SPUT_SHORT: /* 0x6d */ 3032/* File: x86/OP_SPUT_SHORT.S */ 3033/* File: x86/OP_SPUT.S */ 3034 /* 3035 * General 32-bit SPUT handler. 3036 * 3037 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3038 */ 3039 /* op vAA, field@BBBB */ 3040 movl rGLUE,%ecx 3041 movzwl 2(rPC),%eax # eax<- field ref BBBB 3042 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 3043 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 3044 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 3045 testl %eax,%eax # resolved entry null? 3046 je .LOP_SPUT_SHORT_resolve # if not, make it so 3047.LOP_SPUT_SHORT_finish: # field ptr in eax 3048 GET_VREG_R %ecx rINST 3049 FETCH_INST_OPCODE 2 %edx 3050 ADVANCE_PC 2 3051 movl %ecx,offStaticField_value(%eax) 3052 GOTO_NEXT_R %edx 3053 3054 3055/* ------------------------------ */ 3056 .balign 64 3057.L_OP_INVOKE_VIRTUAL: /* 0x6e */ 3058/* File: x86/OP_INVOKE_VIRTUAL.S */ 3059 3060 /* 3061 * Handle a virtual method call. 3062 * 3063 * for: invoke-virtual, invoke-virtual/range 3064 */ 3065 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3066 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3067 movl rGLUE,%eax 3068 movzwl 2(rPC),%ecx # ecx<- BBBB 3069 movl offGlue_methodClassDex(%eax),%eax # eax<- pDvmDex 3070 EXPORT_PC 3071 movl offDvmDex_pResMethods(%eax),%eax # eax<- pDvmDex->pResMethods 3072 movl (%eax,%ecx,4),%eax # eax<- resolved baseMethod 3073 testl %eax,%eax # already resolved? 3074 jne .LOP_INVOKE_VIRTUAL_continue # yes, continue 3075 movl rGLUE,%eax 3076 movl %ecx,OUT_ARG1(%esp) # arg1<- ref 3077 movl offGlue_method(%eax),%eax # eax<- glue->method 3078 jmp .LOP_INVOKE_VIRTUAL_more 3079 3080/* ------------------------------ */ 3081 .balign 64 3082.L_OP_INVOKE_SUPER: /* 0x6f */ 3083/* File: x86/OP_INVOKE_SUPER.S */ 3084 /* 3085 * Handle a "super" method call. 3086 * 3087 * for: invoke-super, invoke-super/range 3088 */ 3089 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3090 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3091 movl rGLUE,rINST 3092 movzwl 2(rPC),%eax # eax<- BBBB 3093 movl offGlue_methodClassDex(rINST),%ecx # ecx<- pDvmDex 3094 EXPORT_PC 3095 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 3096 movl (%ecx,%eax,4),%ecx # ecx<- resolved baseMethod 3097 movl offGlue_method(rINST),%eax # eax<- method 3098 movzwl 4(rPC),rINST # rINST<- GFED or CCCC 3099 .if (!0) 3100 andl $0xf,rINST # rINST<- D (or stays CCCC) 3101 .endif 3102 GET_VREG_R rINST rINST # rINST<- "this" ptr 3103 testl rINST,rINST # null "this"? 3104 je common_errNullObject # yes, throw 3105 movl offMethod_clazz(%eax),%eax # eax<- method->clazz 3106 testl %ecx,%ecx # already resolved? 3107 jne .LOP_INVOKE_SUPER_continue # yes - go on 3108 jmp .LOP_INVOKE_SUPER_resolve 3109 3110/* ------------------------------ */ 3111 .balign 64 3112.L_OP_INVOKE_DIRECT: /* 0x70 */ 3113/* File: x86/OP_INVOKE_DIRECT.S */ 3114 /* 3115 * Handle a direct method call. 3116 * 3117 * (We could defer the "is 'this' pointer null" test to the common 3118 * method invocation code, and use a flag to indicate that static 3119 * calls don't count. If we do this as part of copying the arguments 3120 * out we could avoiding loading the first arg twice.) 3121 * 3122 * for: invoke-direct, invoke-direct/range 3123 */ 3124 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3125 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3126 movl rGLUE,%ecx 3127 movzwl 2(rPC),%eax # eax<- BBBB 3128 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 3129 EXPORT_PC 3130 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 3131 movzwl 4(rPC),%edx # edx<- GFED or CCCC 3132 movl (%ecx,%eax,4),%eax # eax<- resolved methodToCall 3133 .if (!0) 3134 andl $0xf,%edx # edx<- D (or stays CCCC) 3135 .endif 3136 testl %eax,%eax # already resolved? 3137 GET_VREG_R %ecx %edx # ecx<- "this" ptr 3138 je .LOP_INVOKE_DIRECT_resolve # not resolved, do it now 3139.LOP_INVOKE_DIRECT_finish: 3140 testl %ecx,%ecx # null "this"? 3141 jne common_invokeMethodNoRange # no, continue on 3142 jmp common_errNullObject 3143 3144/* ------------------------------ */ 3145 .balign 64 3146.L_OP_INVOKE_STATIC: /* 0x71 */ 3147/* File: x86/OP_INVOKE_STATIC.S */ 3148 /* 3149 * Handle a static method call. 3150 * 3151 * for: invoke-static, invoke-static/range 3152 */ 3153 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3154 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3155 movl rGLUE,%ecx 3156 movzwl 2(rPC),%eax # eax<- BBBB 3157 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 3158 EXPORT_PC 3159 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 3160 movl (%ecx,%eax,4),%eax # eax<- resolved methodToCall 3161 testl %eax,%eax 3162 jne common_invokeMethodNoRange 3163 movl rGLUE,%ecx 3164 movl offGlue_method(%ecx),%ecx # ecx<- glue->method 3165 movzwl 2(rPC),%eax 3166 movl offMethod_clazz(%ecx),%ecx# ecx<- method->clazz 3167 movl %eax,OUT_ARG1(%esp) # arg1<- BBBB 3168 movl %ecx,OUT_ARG0(%esp) # arg0<- clazz 3169 jmp .LOP_INVOKE_STATIC_continue 3170 3171/* ------------------------------ */ 3172 .balign 64 3173.L_OP_INVOKE_INTERFACE: /* 0x72 */ 3174/* File: x86/OP_INVOKE_INTERFACE.S */ 3175 /* 3176 * Handle an interface method call. 3177 * 3178 * for: invoke-interface, invoke-interface/range 3179 */ 3180 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3181 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3182 movzwl 4(rPC),%eax # eax<- FEDC or CCCC 3183 movl rGLUE,%ecx 3184 .if (!0) 3185 andl $0xf,%eax # eax<- C (or stays CCCC) 3186 .endif 3187 GET_VREG_R %eax %eax # eax<- "this" 3188 EXPORT_PC 3189 testl %eax,%eax # null this? 3190 je common_errNullObject # yes, fail 3191 movl offObject_clazz(%eax),%eax# eax<- thisPtr->clazz 3192 movl %eax,OUT_ARG0(%esp) # arg0<- class 3193 movl offGlue_methodClassDex(%ecx),%eax # eax<- methodClassDex 3194 movl offGlue_method(%ecx),%ecx # ecx<- method 3195 movl %eax,OUT_ARG3(%esp) # arg3<- dex 3196 movzwl 2(rPC),%eax # eax<- BBBB 3197 movl %ecx,OUT_ARG2(%esp) # arg2<- method 3198 movl %eax,OUT_ARG1(%esp) # arg1<- BBBB 3199 jmp .LOP_INVOKE_INTERFACE_continue 3200 3201/* ------------------------------ */ 3202 .balign 64 3203.L_OP_UNUSED_73: /* 0x73 */ 3204/* File: x86/OP_UNUSED_73.S */ 3205/* File: x86/unused.S */ 3206 jmp common_abort 3207 3208 3209/* ------------------------------ */ 3210 .balign 64 3211.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */ 3212/* File: x86/OP_INVOKE_VIRTUAL_RANGE.S */ 3213/* File: x86/OP_INVOKE_VIRTUAL.S */ 3214 3215 /* 3216 * Handle a virtual method call. 3217 * 3218 * for: invoke-virtual, invoke-virtual/range 3219 */ 3220 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3221 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3222 movl rGLUE,%eax 3223 movzwl 2(rPC),%ecx # ecx<- BBBB 3224 movl offGlue_methodClassDex(%eax),%eax # eax<- pDvmDex 3225 EXPORT_PC 3226 movl offDvmDex_pResMethods(%eax),%eax # eax<- pDvmDex->pResMethods 3227 movl (%eax,%ecx,4),%eax # eax<- resolved baseMethod 3228 testl %eax,%eax # already resolved? 3229 jne .LOP_INVOKE_VIRTUAL_RANGE_continue # yes, continue 3230 movl rGLUE,%eax 3231 movl %ecx,OUT_ARG1(%esp) # arg1<- ref 3232 movl offGlue_method(%eax),%eax # eax<- glue->method 3233 jmp .LOP_INVOKE_VIRTUAL_RANGE_more 3234 3235 3236/* ------------------------------ */ 3237 .balign 64 3238.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */ 3239/* File: x86/OP_INVOKE_SUPER_RANGE.S */ 3240/* File: x86/OP_INVOKE_SUPER.S */ 3241 /* 3242 * Handle a "super" method call. 3243 * 3244 * for: invoke-super, invoke-super/range 3245 */ 3246 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3247 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3248 movl rGLUE,rINST 3249 movzwl 2(rPC),%eax # eax<- BBBB 3250 movl offGlue_methodClassDex(rINST),%ecx # ecx<- pDvmDex 3251 EXPORT_PC 3252 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 3253 movl (%ecx,%eax,4),%ecx # ecx<- resolved baseMethod 3254 movl offGlue_method(rINST),%eax # eax<- method 3255 movzwl 4(rPC),rINST # rINST<- GFED or CCCC 3256 .if (!1) 3257 andl $0xf,rINST # rINST<- D (or stays CCCC) 3258 .endif 3259 GET_VREG_R rINST rINST # rINST<- "this" ptr 3260 testl rINST,rINST # null "this"? 3261 je common_errNullObject # yes, throw 3262 movl offMethod_clazz(%eax),%eax # eax<- method->clazz 3263 testl %ecx,%ecx # already resolved? 3264 jne .LOP_INVOKE_SUPER_RANGE_continue # yes - go on 3265 jmp .LOP_INVOKE_SUPER_RANGE_resolve 3266 3267 3268/* ------------------------------ */ 3269 .balign 64 3270.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */ 3271/* File: x86/OP_INVOKE_DIRECT_RANGE.S */ 3272/* File: x86/OP_INVOKE_DIRECT.S */ 3273 /* 3274 * Handle a direct method call. 3275 * 3276 * (We could defer the "is 'this' pointer null" test to the common 3277 * method invocation code, and use a flag to indicate that static 3278 * calls don't count. If we do this as part of copying the arguments 3279 * out we could avoiding loading the first arg twice.) 3280 * 3281 * for: invoke-direct, invoke-direct/range 3282 */ 3283 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3284 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3285 movl rGLUE,%ecx 3286 movzwl 2(rPC),%eax # eax<- BBBB 3287 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 3288 EXPORT_PC 3289 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 3290 movzwl 4(rPC),%edx # edx<- GFED or CCCC 3291 movl (%ecx,%eax,4),%eax # eax<- resolved methodToCall 3292 .if (!1) 3293 andl $0xf,%edx # edx<- D (or stays CCCC) 3294 .endif 3295 testl %eax,%eax # already resolved? 3296 GET_VREG_R %ecx %edx # ecx<- "this" ptr 3297 je .LOP_INVOKE_DIRECT_RANGE_resolve # not resolved, do it now 3298.LOP_INVOKE_DIRECT_RANGE_finish: 3299 testl %ecx,%ecx # null "this"? 3300 jne common_invokeMethodRange # no, continue on 3301 jmp common_errNullObject 3302 3303 3304/* ------------------------------ */ 3305 .balign 64 3306.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */ 3307/* File: x86/OP_INVOKE_STATIC_RANGE.S */ 3308/* File: x86/OP_INVOKE_STATIC.S */ 3309 /* 3310 * Handle a static method call. 3311 * 3312 * for: invoke-static, invoke-static/range 3313 */ 3314 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3315 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3316 movl rGLUE,%ecx 3317 movzwl 2(rPC),%eax # eax<- BBBB 3318 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 3319 EXPORT_PC 3320 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 3321 movl (%ecx,%eax,4),%eax # eax<- resolved methodToCall 3322 testl %eax,%eax 3323 jne common_invokeMethodRange 3324 movl rGLUE,%ecx 3325 movl offGlue_method(%ecx),%ecx # ecx<- glue->method 3326 movzwl 2(rPC),%eax 3327 movl offMethod_clazz(%ecx),%ecx# ecx<- method->clazz 3328 movl %eax,OUT_ARG1(%esp) # arg1<- BBBB 3329 movl %ecx,OUT_ARG0(%esp) # arg0<- clazz 3330 jmp .LOP_INVOKE_STATIC_RANGE_continue 3331 3332 3333/* ------------------------------ */ 3334 .balign 64 3335.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */ 3336/* File: x86/OP_INVOKE_INTERFACE_RANGE.S */ 3337/* File: x86/OP_INVOKE_INTERFACE.S */ 3338 /* 3339 * Handle an interface method call. 3340 * 3341 * for: invoke-interface, invoke-interface/range 3342 */ 3343 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3344 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3345 movzwl 4(rPC),%eax # eax<- FEDC or CCCC 3346 movl rGLUE,%ecx 3347 .if (!1) 3348 andl $0xf,%eax # eax<- C (or stays CCCC) 3349 .endif 3350 GET_VREG_R %eax %eax # eax<- "this" 3351 EXPORT_PC 3352 testl %eax,%eax # null this? 3353 je common_errNullObject # yes, fail 3354 movl offObject_clazz(%eax),%eax# eax<- thisPtr->clazz 3355 movl %eax,OUT_ARG0(%esp) # arg0<- class 3356 movl offGlue_methodClassDex(%ecx),%eax # eax<- methodClassDex 3357 movl offGlue_method(%ecx),%ecx # ecx<- method 3358 movl %eax,OUT_ARG3(%esp) # arg3<- dex 3359 movzwl 2(rPC),%eax # eax<- BBBB 3360 movl %ecx,OUT_ARG2(%esp) # arg2<- method 3361 movl %eax,OUT_ARG1(%esp) # arg1<- BBBB 3362 jmp .LOP_INVOKE_INTERFACE_RANGE_continue 3363 3364 3365/* ------------------------------ */ 3366 .balign 64 3367.L_OP_UNUSED_79: /* 0x79 */ 3368/* File: x86/OP_UNUSED_79.S */ 3369/* File: x86/unused.S */ 3370 jmp common_abort 3371 3372 3373/* ------------------------------ */ 3374 .balign 64 3375.L_OP_UNUSED_7A: /* 0x7a */ 3376/* File: x86/OP_UNUSED_7A.S */ 3377/* File: x86/unused.S */ 3378 jmp common_abort 3379 3380 3381/* ------------------------------ */ 3382 .balign 64 3383.L_OP_NEG_INT: /* 0x7b */ 3384/* File: x86/OP_NEG_INT.S */ 3385/* File: x86/unop.S */ 3386 /* 3387 * Generic 32-bit unary operation. Provide an "instr" line that 3388 * specifies an instruction that performs "result = op eax". 3389 */ 3390 /* unop vA, vB */ 3391 movzbl rINSTbl,%ecx # ecx<- A+ 3392 sarl $4,rINST # rINST<- B 3393 GET_VREG_R %eax rINST # eax<- vB 3394 andb $0xf,%cl # ecx<- A 3395 FETCH_INST_OPCODE 1 %edx 3396 ADVANCE_PC 1 3397 3398 3399 negl %eax 3400 SET_VREG %eax %ecx 3401 GOTO_NEXT_R %edx 3402 3403 3404/* ------------------------------ */ 3405 .balign 64 3406.L_OP_NOT_INT: /* 0x7c */ 3407/* File: x86/OP_NOT_INT.S */ 3408/* File: x86/unop.S */ 3409 /* 3410 * Generic 32-bit unary operation. Provide an "instr" line that 3411 * specifies an instruction that performs "result = op eax". 3412 */ 3413 /* unop vA, vB */ 3414 movzbl rINSTbl,%ecx # ecx<- A+ 3415 sarl $4,rINST # rINST<- B 3416 GET_VREG_R %eax rINST # eax<- vB 3417 andb $0xf,%cl # ecx<- A 3418 FETCH_INST_OPCODE 1 %edx 3419 ADVANCE_PC 1 3420 3421 3422 notl %eax 3423 SET_VREG %eax %ecx 3424 GOTO_NEXT_R %edx 3425 3426 3427/* ------------------------------ */ 3428 .balign 64 3429.L_OP_NEG_LONG: /* 0x7d */ 3430/* File: x86/OP_NEG_LONG.S */ 3431 /* unop vA, vB */ 3432 movzbl rINSTbl,%ecx # ecx<- BA 3433 sarl $4,%ecx # ecx<- B 3434 andb $0xf,rINSTbl # rINST<- A 3435 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 3436 GET_VREG_WORD %ecx %ecx 1 # ecx<- v[B+1] 3437 negl %eax 3438 adcl $0,%ecx 3439 negl %ecx 3440 FETCH_INST_OPCODE 1 %edx 3441 SET_VREG_WORD %eax rINST 0 # v[A+0]<- eax 3442 SET_VREG_WORD %ecx rINST 1 # v[A+1]<- ecx 3443 ADVANCE_PC 1 3444 GOTO_NEXT_R %edx 3445 3446/* ------------------------------ */ 3447 .balign 64 3448.L_OP_NOT_LONG: /* 0x7e */ 3449/* File: x86/OP_NOT_LONG.S */ 3450 /* unop vA, vB */ 3451 movzbl rINSTbl,%ecx # ecx<- BA 3452 sarl $4,%ecx # ecx<- B 3453 andb $0xf,rINSTbl # rINST<- A 3454 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 3455 GET_VREG_WORD %ecx %ecx 1 # ecx<- v[B+1] 3456 FETCH_INST_OPCODE 1 %edx 3457 notl %eax 3458 notl %ecx 3459 SET_VREG_WORD %eax rINST 0 # v[A+0]<- eax 3460 SET_VREG_WORD %ecx rINST 1 # v[A+1]<- ecx 3461 ADVANCE_PC 1 3462 GOTO_NEXT_R %edx 3463 3464/* ------------------------------ */ 3465 .balign 64 3466.L_OP_NEG_FLOAT: /* 0x7f */ 3467/* File: x86/OP_NEG_FLOAT.S */ 3468/* File: x86/fpcvt.S */ 3469 /* 3470 * Generic 32-bit FP conversion operation. 3471 */ 3472 /* unop vA, vB */ 3473 movzbl rINSTbl,%ecx # ecx<- A+ 3474 sarl $4,rINST # rINST<- B 3475 flds (rFP,rINST,4) # %st0<- vB 3476 andb $0xf,%cl # ecx<- A 3477 FETCH_INST_OPCODE 1 %edx 3478 ADVANCE_PC 1 3479 fchs 3480 fstps (rFP,%ecx,4) # vA<- %st0 3481 GOTO_NEXT_R %edx 3482 3483 3484/* ------------------------------ */ 3485 .balign 64 3486.L_OP_NEG_DOUBLE: /* 0x80 */ 3487/* File: x86/OP_NEG_DOUBLE.S */ 3488/* File: x86/fpcvt.S */ 3489 /* 3490 * Generic 32-bit FP conversion operation. 3491 */ 3492 /* unop vA, vB */ 3493 movzbl rINSTbl,%ecx # ecx<- A+ 3494 sarl $4,rINST # rINST<- B 3495 fldl (rFP,rINST,4) # %st0<- vB 3496 andb $0xf,%cl # ecx<- A 3497 FETCH_INST_OPCODE 1 %edx 3498 ADVANCE_PC 1 3499 fchs 3500 fstpl (rFP,%ecx,4) # vA<- %st0 3501 GOTO_NEXT_R %edx 3502 3503 3504/* ------------------------------ */ 3505 .balign 64 3506.L_OP_INT_TO_LONG: /* 0x81 */ 3507/* File: x86/OP_INT_TO_LONG.S */ 3508 /* int to long vA, vB */ 3509 movzbl rINSTbl,%eax # eax<- +A 3510 sarl $4,%eax # eax<- B 3511 GET_VREG_R %eax %eax # eax<- vB 3512 andb $0xf,rINSTbl # rINST<- A 3513 cltd # edx:eax<- sssssssBBBBBBBB 3514 SET_VREG_WORD %edx rINST 1 # v[A+1]<- edx/rPC 3515 FETCH_INST_OPCODE 1 %edx 3516 SET_VREG_WORD %eax rINST 0 # v[A+0]<- %eax 3517 ADVANCE_PC 1 3518 GOTO_NEXT_R %edx 3519 3520/* ------------------------------ */ 3521 .balign 64 3522.L_OP_INT_TO_FLOAT: /* 0x82 */ 3523/* File: x86/OP_INT_TO_FLOAT.S */ 3524/* File: x86/fpcvt.S */ 3525 /* 3526 * Generic 32-bit FP conversion operation. 3527 */ 3528 /* unop vA, vB */ 3529 movzbl rINSTbl,%ecx # ecx<- A+ 3530 sarl $4,rINST # rINST<- B 3531 fildl (rFP,rINST,4) # %st0<- vB 3532 andb $0xf,%cl # ecx<- A 3533 FETCH_INST_OPCODE 1 %edx 3534 ADVANCE_PC 1 3535 3536 fstps (rFP,%ecx,4) # vA<- %st0 3537 GOTO_NEXT_R %edx 3538 3539 3540/* ------------------------------ */ 3541 .balign 64 3542.L_OP_INT_TO_DOUBLE: /* 0x83 */ 3543/* File: x86/OP_INT_TO_DOUBLE.S */ 3544/* File: x86/fpcvt.S */ 3545 /* 3546 * Generic 32-bit FP conversion operation. 3547 */ 3548 /* unop vA, vB */ 3549 movzbl rINSTbl,%ecx # ecx<- A+ 3550 sarl $4,rINST # rINST<- B 3551 fildl (rFP,rINST,4) # %st0<- vB 3552 andb $0xf,%cl # ecx<- A 3553 FETCH_INST_OPCODE 1 %edx 3554 ADVANCE_PC 1 3555 3556 fstpl (rFP,%ecx,4) # vA<- %st0 3557 GOTO_NEXT_R %edx 3558 3559 3560/* ------------------------------ */ 3561 .balign 64 3562.L_OP_LONG_TO_INT: /* 0x84 */ 3563/* File: x86/OP_LONG_TO_INT.S */ 3564/* we ignore the high word, making this equivalent to a 32-bit reg move */ 3565/* File: x86/OP_MOVE.S */ 3566 /* for move, move-object, long-to-int */ 3567 /* op vA, vB */ 3568 movzbl rINSTbl,%eax # eax<- BA 3569 andb $0xf,%al # eax<- A 3570 shrl $4,rINST # rINST<- B 3571 GET_VREG_R %ecx rINST 3572 FETCH_INST_OPCODE 1 %edx 3573 ADVANCE_PC 1 3574 SET_VREG %ecx %eax # fp[A]<-fp[B] 3575 GOTO_NEXT_R %edx 3576 3577 3578/* ------------------------------ */ 3579 .balign 64 3580.L_OP_LONG_TO_FLOAT: /* 0x85 */ 3581/* File: x86/OP_LONG_TO_FLOAT.S */ 3582/* File: x86/fpcvt.S */ 3583 /* 3584 * Generic 32-bit FP conversion operation. 3585 */ 3586 /* unop vA, vB */ 3587 movzbl rINSTbl,%ecx # ecx<- A+ 3588 sarl $4,rINST # rINST<- B 3589 fildll (rFP,rINST,4) # %st0<- vB 3590 andb $0xf,%cl # ecx<- A 3591 FETCH_INST_OPCODE 1 %edx 3592 ADVANCE_PC 1 3593 3594 fstps (rFP,%ecx,4) # vA<- %st0 3595 GOTO_NEXT_R %edx 3596 3597 3598/* ------------------------------ */ 3599 .balign 64 3600.L_OP_LONG_TO_DOUBLE: /* 0x86 */ 3601/* File: x86/OP_LONG_TO_DOUBLE.S */ 3602/* File: x86/fpcvt.S */ 3603 /* 3604 * Generic 32-bit FP conversion operation. 3605 */ 3606 /* unop vA, vB */ 3607 movzbl rINSTbl,%ecx # ecx<- A+ 3608 sarl $4,rINST # rINST<- B 3609 fildll (rFP,rINST,4) # %st0<- vB 3610 andb $0xf,%cl # ecx<- A 3611 FETCH_INST_OPCODE 1 %edx 3612 ADVANCE_PC 1 3613 3614 fstpl (rFP,%ecx,4) # vA<- %st0 3615 GOTO_NEXT_R %edx 3616 3617 3618/* ------------------------------ */ 3619 .balign 64 3620.L_OP_FLOAT_TO_INT: /* 0x87 */ 3621/* File: x86/OP_FLOAT_TO_INT.S */ 3622/* File: x86/cvtfp_int.S */ 3623/* On fp to int conversions, Java requires that 3624 * if the result > maxint, it should be clamped to maxint. If it is less 3625 * than minint, it should be clamped to minint. If it is a nan, the result 3626 * should be zero. Further, the rounding mode is to truncate. This model 3627 * differs from what is delivered normally via the x86 fpu, so we have 3628 * to play some games. 3629 */ 3630 /* float/double to int/long vA, vB */ 3631 movzbl rINSTbl,%ecx # ecx<- A+ 3632 sarl $4,rINST # rINST<- B 3633 .if 0 3634 fldl (rFP,rINST,4) # %st0<- vB 3635 .else 3636 flds (rFP,rINST,4) # %st0<- vB 3637 .endif 3638 ftst 3639 fnstcw LOCAL0_OFFSET(%ebp) # remember original rounding mode 3640 movzwl LOCAL0_OFFSET(%ebp),%eax 3641 movb $0xc,%ah 3642 movw %ax,LOCAL0_OFFSET+2(%ebp) 3643 fldcw LOCAL0_OFFSET+2(%ebp) # set "to zero" rounding mode 3644 FETCH_INST_OPCODE 1 %edx 3645 andb $0xf,%cl # ecx<- A 3646 .if 0 3647 fistpll (rFP,%ecx,4) # convert and store 3648 .else 3649 fistpl (rFP,%ecx,4) # convert and store 3650 .endif 3651 fldcw LOCAL0_OFFSET(%ebp) # restore previous rounding mode 3652 jmp .LOP_FLOAT_TO_INT_continue 3653 3654 3655/* ------------------------------ */ 3656 .balign 64 3657.L_OP_FLOAT_TO_LONG: /* 0x88 */ 3658/* File: x86/OP_FLOAT_TO_LONG.S */ 3659/* File: x86/cvtfp_int.S */ 3660/* On fp to int conversions, Java requires that 3661 * if the result > maxint, it should be clamped to maxint. If it is less 3662 * than minint, it should be clamped to minint. If it is a nan, the result 3663 * should be zero. Further, the rounding mode is to truncate. This model 3664 * differs from what is delivered normally via the x86 fpu, so we have 3665 * to play some games. 3666 */ 3667 /* float/double to int/long vA, vB */ 3668 movzbl rINSTbl,%ecx # ecx<- A+ 3669 sarl $4,rINST # rINST<- B 3670 .if 0 3671 fldl (rFP,rINST,4) # %st0<- vB 3672 .else 3673 flds (rFP,rINST,4) # %st0<- vB 3674 .endif 3675 ftst 3676 fnstcw LOCAL0_OFFSET(%ebp) # remember original rounding mode 3677 movzwl LOCAL0_OFFSET(%ebp),%eax 3678 movb $0xc,%ah 3679 movw %ax,LOCAL0_OFFSET+2(%ebp) 3680 fldcw LOCAL0_OFFSET+2(%ebp) # set "to zero" rounding mode 3681 FETCH_INST_OPCODE 1 %edx 3682 andb $0xf,%cl # ecx<- A 3683 .if 1 3684 fistpll (rFP,%ecx,4) # convert and store 3685 .else 3686 fistpl (rFP,%ecx,4) # convert and store 3687 .endif 3688 fldcw LOCAL0_OFFSET(%ebp) # restore previous rounding mode 3689 jmp .LOP_FLOAT_TO_LONG_continue 3690 3691 3692/* ------------------------------ */ 3693 .balign 64 3694.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */ 3695/* File: x86/OP_FLOAT_TO_DOUBLE.S */ 3696/* File: x86/fpcvt.S */ 3697 /* 3698 * Generic 32-bit FP conversion operation. 3699 */ 3700 /* unop vA, vB */ 3701 movzbl rINSTbl,%ecx # ecx<- A+ 3702 sarl $4,rINST # rINST<- B 3703 flds (rFP,rINST,4) # %st0<- vB 3704 andb $0xf,%cl # ecx<- A 3705 FETCH_INST_OPCODE 1 %edx 3706 ADVANCE_PC 1 3707 3708 fstpl (rFP,%ecx,4) # vA<- %st0 3709 GOTO_NEXT_R %edx 3710 3711 3712/* ------------------------------ */ 3713 .balign 64 3714.L_OP_DOUBLE_TO_INT: /* 0x8a */ 3715/* File: x86/OP_DOUBLE_TO_INT.S */ 3716/* File: x86/cvtfp_int.S */ 3717/* On fp to int conversions, Java requires that 3718 * if the result > maxint, it should be clamped to maxint. If it is less 3719 * than minint, it should be clamped to minint. If it is a nan, the result 3720 * should be zero. Further, the rounding mode is to truncate. This model 3721 * differs from what is delivered normally via the x86 fpu, so we have 3722 * to play some games. 3723 */ 3724 /* float/double to int/long vA, vB */ 3725 movzbl rINSTbl,%ecx # ecx<- A+ 3726 sarl $4,rINST # rINST<- B 3727 .if 1 3728 fldl (rFP,rINST,4) # %st0<- vB 3729 .else 3730 flds (rFP,rINST,4) # %st0<- vB 3731 .endif 3732 ftst 3733 fnstcw LOCAL0_OFFSET(%ebp) # remember original rounding mode 3734 movzwl LOCAL0_OFFSET(%ebp),%eax 3735 movb $0xc,%ah 3736 movw %ax,LOCAL0_OFFSET+2(%ebp) 3737 fldcw LOCAL0_OFFSET+2(%ebp) # set "to zero" rounding mode 3738 FETCH_INST_OPCODE 1 %edx 3739 andb $0xf,%cl # ecx<- A 3740 .if 0 3741 fistpll (rFP,%ecx,4) # convert and store 3742 .else 3743 fistpl (rFP,%ecx,4) # convert and store 3744 .endif 3745 fldcw LOCAL0_OFFSET(%ebp) # restore previous rounding mode 3746 jmp .LOP_DOUBLE_TO_INT_continue 3747 3748 3749/* ------------------------------ */ 3750 .balign 64 3751.L_OP_DOUBLE_TO_LONG: /* 0x8b */ 3752/* File: x86/OP_DOUBLE_TO_LONG.S */ 3753/* File: x86/cvtfp_int.S */ 3754/* On fp to int conversions, Java requires that 3755 * if the result > maxint, it should be clamped to maxint. If it is less 3756 * than minint, it should be clamped to minint. If it is a nan, the result 3757 * should be zero. Further, the rounding mode is to truncate. This model 3758 * differs from what is delivered normally via the x86 fpu, so we have 3759 * to play some games. 3760 */ 3761 /* float/double to int/long vA, vB */ 3762 movzbl rINSTbl,%ecx # ecx<- A+ 3763 sarl $4,rINST # rINST<- B 3764 .if 1 3765 fldl (rFP,rINST,4) # %st0<- vB 3766 .else 3767 flds (rFP,rINST,4) # %st0<- vB 3768 .endif 3769 ftst 3770 fnstcw LOCAL0_OFFSET(%ebp) # remember original rounding mode 3771 movzwl LOCAL0_OFFSET(%ebp),%eax 3772 movb $0xc,%ah 3773 movw %ax,LOCAL0_OFFSET+2(%ebp) 3774 fldcw LOCAL0_OFFSET+2(%ebp) # set "to zero" rounding mode 3775 FETCH_INST_OPCODE 1 %edx 3776 andb $0xf,%cl # ecx<- A 3777 .if 1 3778 fistpll (rFP,%ecx,4) # convert and store 3779 .else 3780 fistpl (rFP,%ecx,4) # convert and store 3781 .endif 3782 fldcw LOCAL0_OFFSET(%ebp) # restore previous rounding mode 3783 jmp .LOP_DOUBLE_TO_LONG_continue 3784 3785 3786/* ------------------------------ */ 3787 .balign 64 3788.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */ 3789/* File: x86/OP_DOUBLE_TO_FLOAT.S */ 3790/* File: x86/fpcvt.S */ 3791 /* 3792 * Generic 32-bit FP conversion operation. 3793 */ 3794 /* unop vA, vB */ 3795 movzbl rINSTbl,%ecx # ecx<- A+ 3796 sarl $4,rINST # rINST<- B 3797 fldl (rFP,rINST,4) # %st0<- vB 3798 andb $0xf,%cl # ecx<- A 3799 FETCH_INST_OPCODE 1 %edx 3800 ADVANCE_PC 1 3801 3802 fstps (rFP,%ecx,4) # vA<- %st0 3803 GOTO_NEXT_R %edx 3804 3805 3806/* ------------------------------ */ 3807 .balign 64 3808.L_OP_INT_TO_BYTE: /* 0x8d */ 3809/* File: x86/OP_INT_TO_BYTE.S */ 3810/* File: x86/unop.S */ 3811 /* 3812 * Generic 32-bit unary operation. Provide an "instr" line that 3813 * specifies an instruction that performs "result = op eax". 3814 */ 3815 /* unop vA, vB */ 3816 movzbl rINSTbl,%ecx # ecx<- A+ 3817 sarl $4,rINST # rINST<- B 3818 GET_VREG_R %eax rINST # eax<- vB 3819 andb $0xf,%cl # ecx<- A 3820 FETCH_INST_OPCODE 1 %edx 3821 ADVANCE_PC 1 3822 3823 3824 movsbl %al,%eax 3825 SET_VREG %eax %ecx 3826 GOTO_NEXT_R %edx 3827 3828 3829/* ------------------------------ */ 3830 .balign 64 3831.L_OP_INT_TO_CHAR: /* 0x8e */ 3832/* File: x86/OP_INT_TO_CHAR.S */ 3833/* File: x86/unop.S */ 3834 /* 3835 * Generic 32-bit unary operation. Provide an "instr" line that 3836 * specifies an instruction that performs "result = op eax". 3837 */ 3838 /* unop vA, vB */ 3839 movzbl rINSTbl,%ecx # ecx<- A+ 3840 sarl $4,rINST # rINST<- B 3841 GET_VREG_R %eax rINST # eax<- vB 3842 andb $0xf,%cl # ecx<- A 3843 FETCH_INST_OPCODE 1 %edx 3844 ADVANCE_PC 1 3845 3846 3847 movzwl %ax,%eax 3848 SET_VREG %eax %ecx 3849 GOTO_NEXT_R %edx 3850 3851 3852/* ------------------------------ */ 3853 .balign 64 3854.L_OP_INT_TO_SHORT: /* 0x8f */ 3855/* File: x86/OP_INT_TO_SHORT.S */ 3856/* File: x86/unop.S */ 3857 /* 3858 * Generic 32-bit unary operation. Provide an "instr" line that 3859 * specifies an instruction that performs "result = op eax". 3860 */ 3861 /* unop vA, vB */ 3862 movzbl rINSTbl,%ecx # ecx<- A+ 3863 sarl $4,rINST # rINST<- B 3864 GET_VREG_R %eax rINST # eax<- vB 3865 andb $0xf,%cl # ecx<- A 3866 FETCH_INST_OPCODE 1 %edx 3867 ADVANCE_PC 1 3868 3869 3870 movswl %ax,%eax 3871 SET_VREG %eax %ecx 3872 GOTO_NEXT_R %edx 3873 3874 3875/* ------------------------------ */ 3876 .balign 64 3877.L_OP_ADD_INT: /* 0x90 */ 3878/* File: x86/OP_ADD_INT.S */ 3879/* File: x86/binop.S */ 3880 /* 3881 * Generic 32-bit binary operation. Provide an "instr" line that 3882 * specifies an instruction that performs "result = eax op (rFP,%ecx,4)". 3883 * This could be an x86 instruction or a function call. (If the result 3884 * comes back in a register other than eax, you can override "result".) 3885 * 3886 * For: add-int, sub-int, and-int, or-int, 3887 * xor-int, shl-int, shr-int, ushr-int 3888 */ 3889 /* binop vAA, vBB, vCC */ 3890 movzbl 2(rPC),%eax # eax<- BB 3891 movzbl 3(rPC),%ecx # ecx<- CC 3892 GET_VREG_R %eax %eax # eax<- vBB 3893 addl (rFP,%ecx,4),%eax # ex: addl (rFP,%ecx,4),%eax 3894 FETCH_INST_OPCODE 2 %edx 3895 ADVANCE_PC 2 3896 SET_VREG %eax rINST 3897 GOTO_NEXT_R %edx 3898 3899 3900/* ------------------------------ */ 3901 .balign 64 3902.L_OP_SUB_INT: /* 0x91 */ 3903/* File: x86/OP_SUB_INT.S */ 3904/* File: x86/binop.S */ 3905 /* 3906 * Generic 32-bit binary operation. Provide an "instr" line that 3907 * specifies an instruction that performs "result = eax op (rFP,%ecx,4)". 3908 * This could be an x86 instruction or a function call. (If the result 3909 * comes back in a register other than eax, you can override "result".) 3910 * 3911 * For: add-int, sub-int, and-int, or-int, 3912 * xor-int, shl-int, shr-int, ushr-int 3913 */ 3914 /* binop vAA, vBB, vCC */ 3915 movzbl 2(rPC),%eax # eax<- BB 3916 movzbl 3(rPC),%ecx # ecx<- CC 3917 GET_VREG_R %eax %eax # eax<- vBB 3918 subl (rFP,%ecx,4),%eax # ex: addl (rFP,%ecx,4),%eax 3919 FETCH_INST_OPCODE 2 %edx 3920 ADVANCE_PC 2 3921 SET_VREG %eax rINST 3922 GOTO_NEXT_R %edx 3923 3924 3925/* ------------------------------ */ 3926 .balign 64 3927.L_OP_MUL_INT: /* 0x92 */ 3928/* File: x86/OP_MUL_INT.S */ 3929 /* 3930 * 32-bit binary multiplication. 3931 */ 3932 /* mul vAA, vBB, vCC */ 3933 movzbl 2(rPC),%eax # eax<- BB 3934 movzbl 3(rPC),%ecx # ecx<- CC 3935 GET_VREG_R %eax %eax # eax<- vBB 3936 imull (rFP,%ecx,4),%eax # trashes edx 3937 FETCH_INST_OPCODE 2 %edx 3938 ADVANCE_PC 2 3939 SET_VREG %eax rINST 3940 GOTO_NEXT_R %edx 3941 3942/* ------------------------------ */ 3943 .balign 64 3944.L_OP_DIV_INT: /* 0x93 */ 3945/* File: x86/OP_DIV_INT.S */ 3946/* File: x86/bindiv.S */ 3947 3948 /* 3949 * 32-bit binary div/rem operation. Handles special case of op0=minint and 3950 * op1=-1. 3951 */ 3952 /* binop vAA, vBB, vCC */ 3953 movzbl 2(rPC),%eax # eax<- BB 3954 movzbl 3(rPC),%ecx # ecx<- CC 3955 GET_VREG_R %eax %eax # eax<- vBB 3956 GET_VREG_R %ecx %ecx # eax<- vBB 3957 cmpl $0,%ecx 3958 je common_errDivideByZero 3959 cmpl $-1,%ecx 3960 jne .LOP_DIV_INT_continue_div 3961 cmpl $0x80000000,%eax 3962 jne .LOP_DIV_INT_continue_div 3963 movl $0x80000000,%eax 3964 jmp .LOP_DIV_INT_finish_div 3965 3966 3967 3968/* ------------------------------ */ 3969 .balign 64 3970.L_OP_REM_INT: /* 0x94 */ 3971/* File: x86/OP_REM_INT.S */ 3972/* File: x86/bindiv.S */ 3973 3974 /* 3975 * 32-bit binary div/rem operation. Handles special case of op0=minint and 3976 * op1=-1. 3977 */ 3978 /* binop vAA, vBB, vCC */ 3979 movzbl 2(rPC),%eax # eax<- BB 3980 movzbl 3(rPC),%ecx # ecx<- CC 3981 GET_VREG_R %eax %eax # eax<- vBB 3982 GET_VREG_R %ecx %ecx # eax<- vBB 3983 cmpl $0,%ecx 3984 je common_errDivideByZero 3985 cmpl $-1,%ecx 3986 jne .LOP_REM_INT_continue_div 3987 cmpl $0x80000000,%eax 3988 jne .LOP_REM_INT_continue_div 3989 movl $0,%edx 3990 jmp .LOP_REM_INT_finish_div 3991 3992 3993 3994/* ------------------------------ */ 3995 .balign 64 3996.L_OP_AND_INT: /* 0x95 */ 3997/* File: x86/OP_AND_INT.S */ 3998/* File: x86/binop.S */ 3999 /* 4000 * Generic 32-bit binary operation. Provide an "instr" line that 4001 * specifies an instruction that performs "result = eax op (rFP,%ecx,4)". 4002 * This could be an x86 instruction or a function call. (If the result 4003 * comes back in a register other than eax, you can override "result".) 4004 * 4005 * For: add-int, sub-int, and-int, or-int, 4006 * xor-int, shl-int, shr-int, ushr-int 4007 */ 4008 /* binop vAA, vBB, vCC */ 4009 movzbl 2(rPC),%eax # eax<- BB 4010 movzbl 3(rPC),%ecx # ecx<- CC 4011 GET_VREG_R %eax %eax # eax<- vBB 4012 andl (rFP,%ecx,4),%eax # ex: addl (rFP,%ecx,4),%eax 4013 FETCH_INST_OPCODE 2 %edx 4014 ADVANCE_PC 2 4015 SET_VREG %eax rINST 4016 GOTO_NEXT_R %edx 4017 4018 4019/* ------------------------------ */ 4020 .balign 64 4021.L_OP_OR_INT: /* 0x96 */ 4022/* File: x86/OP_OR_INT.S */ 4023/* File: x86/binop.S */ 4024 /* 4025 * Generic 32-bit binary operation. Provide an "instr" line that 4026 * specifies an instruction that performs "result = eax op (rFP,%ecx,4)". 4027 * This could be an x86 instruction or a function call. (If the result 4028 * comes back in a register other than eax, you can override "result".) 4029 * 4030 * For: add-int, sub-int, and-int, or-int, 4031 * xor-int, shl-int, shr-int, ushr-int 4032 */ 4033 /* binop vAA, vBB, vCC */ 4034 movzbl 2(rPC),%eax # eax<- BB 4035 movzbl 3(rPC),%ecx # ecx<- CC 4036 GET_VREG_R %eax %eax # eax<- vBB 4037 orl (rFP,%ecx,4),%eax # ex: addl (rFP,%ecx,4),%eax 4038 FETCH_INST_OPCODE 2 %edx 4039 ADVANCE_PC 2 4040 SET_VREG %eax rINST 4041 GOTO_NEXT_R %edx 4042 4043 4044/* ------------------------------ */ 4045 .balign 64 4046.L_OP_XOR_INT: /* 0x97 */ 4047/* File: x86/OP_XOR_INT.S */ 4048/* File: x86/binop.S */ 4049 /* 4050 * Generic 32-bit binary operation. Provide an "instr" line that 4051 * specifies an instruction that performs "result = eax op (rFP,%ecx,4)". 4052 * This could be an x86 instruction or a function call. (If the result 4053 * comes back in a register other than eax, you can override "result".) 4054 * 4055 * For: add-int, sub-int, and-int, or-int, 4056 * xor-int, shl-int, shr-int, ushr-int 4057 */ 4058 /* binop vAA, vBB, vCC */ 4059 movzbl 2(rPC),%eax # eax<- BB 4060 movzbl 3(rPC),%ecx # ecx<- CC 4061 GET_VREG_R %eax %eax # eax<- vBB 4062 xorl (rFP,%ecx,4),%eax # ex: addl (rFP,%ecx,4),%eax 4063 FETCH_INST_OPCODE 2 %edx 4064 ADVANCE_PC 2 4065 SET_VREG %eax rINST 4066 GOTO_NEXT_R %edx 4067 4068 4069/* ------------------------------ */ 4070 .balign 64 4071.L_OP_SHL_INT: /* 0x98 */ 4072/* File: x86/OP_SHL_INT.S */ 4073/* File: x86/binop1.S */ 4074 /* 4075 * Generic 32-bit binary operation in which both operands loaded to 4076 * registers (op0 in eax, op1 in ecx). 4077 */ 4078 /* binop vAA, vBB, vCC */ 4079 movzbl 2(rPC),%eax # eax<- BB 4080 movzbl 3(rPC),%ecx # ecx<- CC 4081 GET_VREG_R %eax %eax # eax<- vBB 4082 GET_VREG_R %ecx %ecx # eax<- vBB 4083 sall %cl,%eax # ex: addl %ecx,%eax 4084 FETCH_INST_OPCODE 2 %edx 4085 ADVANCE_PC 2 4086 SET_VREG %eax rINST 4087 GOTO_NEXT_R %edx 4088 4089 4090/* ------------------------------ */ 4091 .balign 64 4092.L_OP_SHR_INT: /* 0x99 */ 4093/* File: x86/OP_SHR_INT.S */ 4094/* File: x86/binop1.S */ 4095 /* 4096 * Generic 32-bit binary operation in which both operands loaded to 4097 * registers (op0 in eax, op1 in ecx). 4098 */ 4099 /* binop vAA, vBB, vCC */ 4100 movzbl 2(rPC),%eax # eax<- BB 4101 movzbl 3(rPC),%ecx # ecx<- CC 4102 GET_VREG_R %eax %eax # eax<- vBB 4103 GET_VREG_R %ecx %ecx # eax<- vBB 4104 sarl %cl,%eax # ex: addl %ecx,%eax 4105 FETCH_INST_OPCODE 2 %edx 4106 ADVANCE_PC 2 4107 SET_VREG %eax rINST 4108 GOTO_NEXT_R %edx 4109 4110 4111/* ------------------------------ */ 4112 .balign 64 4113.L_OP_USHR_INT: /* 0x9a */ 4114/* File: x86/OP_USHR_INT.S */ 4115/* File: x86/binop1.S */ 4116 /* 4117 * Generic 32-bit binary operation in which both operands loaded to 4118 * registers (op0 in eax, op1 in ecx). 4119 */ 4120 /* binop vAA, vBB, vCC */ 4121 movzbl 2(rPC),%eax # eax<- BB 4122 movzbl 3(rPC),%ecx # ecx<- CC 4123 GET_VREG_R %eax %eax # eax<- vBB 4124 GET_VREG_R %ecx %ecx # eax<- vBB 4125 shrl %cl,%eax # ex: addl %ecx,%eax 4126 FETCH_INST_OPCODE 2 %edx 4127 ADVANCE_PC 2 4128 SET_VREG %eax rINST 4129 GOTO_NEXT_R %edx 4130 4131 4132/* ------------------------------ */ 4133 .balign 64 4134.L_OP_ADD_LONG: /* 0x9b */ 4135/* File: x86/OP_ADD_LONG.S */ 4136/* File: x86/binopWide.S */ 4137 /* 4138 * Generic 64-bit binary operation. 4139 */ 4140 /* binop vAA, vBB, vCC */ 4141 4142 movzbl 2(rPC),%eax # eax<- BB 4143 movzbl 3(rPC),%ecx # ecx<- CC 4144 GET_VREG_WORD %edx %eax 0 # edx<- v[BB+0] 4145 GET_VREG_WORD %eax %eax 1 # eax<- v[BB+1] 4146 addl (rFP,%ecx,4),%edx # ex: addl (rFP,%ecx,4),%edx 4147 adcl 4(rFP,%ecx,4),%eax # ex: adcl 4(rFP,%ecx,4),%eax 4148 SET_VREG_WORD %edx rINST 0 # v[AA+0] <- edx 4149 FETCH_INST_OPCODE 2 %edx 4150 SET_VREG_WORD %eax rINST 1 # v[AA+1] <- eax 4151 ADVANCE_PC 2 4152 GOTO_NEXT_R %edx 4153 4154 4155/* ------------------------------ */ 4156 .balign 64 4157.L_OP_SUB_LONG: /* 0x9c */ 4158/* File: x86/OP_SUB_LONG.S */ 4159/* File: x86/binopWide.S */ 4160 /* 4161 * Generic 64-bit binary operation. 4162 */ 4163 /* binop vAA, vBB, vCC */ 4164 4165 movzbl 2(rPC),%eax # eax<- BB 4166 movzbl 3(rPC),%ecx # ecx<- CC 4167 GET_VREG_WORD %edx %eax 0 # edx<- v[BB+0] 4168 GET_VREG_WORD %eax %eax 1 # eax<- v[BB+1] 4169 subl (rFP,%ecx,4),%edx # ex: addl (rFP,%ecx,4),%edx 4170 sbbl 4(rFP,%ecx,4),%eax # ex: adcl 4(rFP,%ecx,4),%eax 4171 SET_VREG_WORD %edx rINST 0 # v[AA+0] <- edx 4172 FETCH_INST_OPCODE 2 %edx 4173 SET_VREG_WORD %eax rINST 1 # v[AA+1] <- eax 4174 ADVANCE_PC 2 4175 GOTO_NEXT_R %edx 4176 4177 4178/* ------------------------------ */ 4179 .balign 64 4180.L_OP_MUL_LONG: /* 0x9d */ 4181/* File: x86/OP_MUL_LONG.S */ 4182 /* 4183 * Signed 64-bit integer multiply. 4184 * 4185 * We could definately use more free registers for 4186 * this code. We spill rINSTw (ebx), 4187 * giving us eax, ebc, ecx and edx as computational 4188 * temps. On top of that, we'll spill edi (rFP) 4189 * for use as the vB pointer and esi (rPC) for use 4190 * as the vC pointer. Yuck. 4191 */ 4192 /* mul-long vAA, vBB, vCC */ 4193 movzbl 2(rPC),%eax # eax<- B 4194 movzbl 3(rPC),%ecx # ecx<- C 4195 SPILL_TMP2(%esi) # save Dalvik PC 4196 SPILL(rFP) 4197 SPILL(rINST) 4198 leal (rFP,%eax,4),%esi # esi<- &v[B] 4199 leal (rFP,%ecx,4),rFP # rFP<- &v[C] 4200 movl 4(%esi),%ecx # ecx<- Bmsw 4201 imull (rFP),%ecx # ecx<- (Bmsw*Clsw) 4202 movl 4(rFP),%eax # eax<- Cmsw 4203 imull (%esi),%eax # eax<- (Cmsw*Blsw) 4204 addl %eax,%ecx # ecx<- (Bmsw*Clsw)+(Cmsw*Blsw) 4205 movl (rFP),%eax # eax<- Clsw 4206 mull (%esi) # eax<- (Clsw*Alsw) 4207 UNSPILL(rINST) 4208 UNSPILL(rFP) 4209 jmp .LOP_MUL_LONG_continue 4210 4211/* ------------------------------ */ 4212 .balign 64 4213.L_OP_DIV_LONG: /* 0x9e */ 4214/* File: x86/OP_DIV_LONG.S */ 4215 /* div vAA, vBB, vCC */ 4216 movzbl 3(rPC),%eax # eax<- CC 4217 movzbl 2(rPC),%ecx # ecx<- BB 4218 GET_VREG_WORD %edx %eax 0 4219 GET_VREG_WORD %eax %eax 1 4220 movl %edx,OUT_ARG2(%esp) 4221 testl %eax,%eax 4222 je .LOP_DIV_LONG_check_zero 4223 cmpl $-1,%eax 4224 je .LOP_DIV_LONG_check_neg1 4225.LOP_DIV_LONG_notSpecial: 4226 GET_VREG_WORD %edx %ecx 0 4227 GET_VREG_WORD %ecx %ecx 1 4228.LOP_DIV_LONG_notSpecial1: 4229 movl %eax,OUT_ARG3(%esp) 4230 movl %edx,OUT_ARG0(%esp) 4231 movl %ecx,OUT_ARG1(%esp) 4232 jmp .LOP_DIV_LONG_continue 4233 4234/* ------------------------------ */ 4235 .balign 64 4236.L_OP_REM_LONG: /* 0x9f */ 4237/* File: x86/OP_REM_LONG.S */ 4238/* File: x86/OP_DIV_LONG.S */ 4239 /* div vAA, vBB, vCC */ 4240 movzbl 3(rPC),%eax # eax<- CC 4241 movzbl 2(rPC),%ecx # ecx<- BB 4242 GET_VREG_WORD %edx %eax 0 4243 GET_VREG_WORD %eax %eax 1 4244 movl %edx,OUT_ARG2(%esp) 4245 testl %eax,%eax 4246 je .LOP_REM_LONG_check_zero 4247 cmpl $-1,%eax 4248 je .LOP_REM_LONG_check_neg1 4249.LOP_REM_LONG_notSpecial: 4250 GET_VREG_WORD %edx %ecx 0 4251 GET_VREG_WORD %ecx %ecx 1 4252.LOP_REM_LONG_notSpecial1: 4253 movl %eax,OUT_ARG3(%esp) 4254 movl %edx,OUT_ARG0(%esp) 4255 movl %ecx,OUT_ARG1(%esp) 4256 jmp .LOP_REM_LONG_continue 4257 4258 4259/* ------------------------------ */ 4260 .balign 64 4261.L_OP_AND_LONG: /* 0xa0 */ 4262/* File: x86/OP_AND_LONG.S */ 4263/* File: x86/binopWide.S */ 4264 /* 4265 * Generic 64-bit binary operation. 4266 */ 4267 /* binop vAA, vBB, vCC */ 4268 4269 movzbl 2(rPC),%eax # eax<- BB 4270 movzbl 3(rPC),%ecx # ecx<- CC 4271 GET_VREG_WORD %edx %eax 0 # edx<- v[BB+0] 4272 GET_VREG_WORD %eax %eax 1 # eax<- v[BB+1] 4273 andl (rFP,%ecx,4),%edx # ex: addl (rFP,%ecx,4),%edx 4274 andl 4(rFP,%ecx,4),%eax # ex: adcl 4(rFP,%ecx,4),%eax 4275 SET_VREG_WORD %edx rINST 0 # v[AA+0] <- edx 4276 FETCH_INST_OPCODE 2 %edx 4277 SET_VREG_WORD %eax rINST 1 # v[AA+1] <- eax 4278 ADVANCE_PC 2 4279 GOTO_NEXT_R %edx 4280 4281 4282/* ------------------------------ */ 4283 .balign 64 4284.L_OP_OR_LONG: /* 0xa1 */ 4285/* File: x86/OP_OR_LONG.S */ 4286/* File: x86/binopWide.S */ 4287 /* 4288 * Generic 64-bit binary operation. 4289 */ 4290 /* binop vAA, vBB, vCC */ 4291 4292 movzbl 2(rPC),%eax # eax<- BB 4293 movzbl 3(rPC),%ecx # ecx<- CC 4294 GET_VREG_WORD %edx %eax 0 # edx<- v[BB+0] 4295 GET_VREG_WORD %eax %eax 1 # eax<- v[BB+1] 4296 orl (rFP,%ecx,4),%edx # ex: addl (rFP,%ecx,4),%edx 4297 orl 4(rFP,%ecx,4),%eax # ex: adcl 4(rFP,%ecx,4),%eax 4298 SET_VREG_WORD %edx rINST 0 # v[AA+0] <- edx 4299 FETCH_INST_OPCODE 2 %edx 4300 SET_VREG_WORD %eax rINST 1 # v[AA+1] <- eax 4301 ADVANCE_PC 2 4302 GOTO_NEXT_R %edx 4303 4304 4305/* ------------------------------ */ 4306 .balign 64 4307.L_OP_XOR_LONG: /* 0xa2 */ 4308/* File: x86/OP_XOR_LONG.S */ 4309/* File: x86/binopWide.S */ 4310 /* 4311 * Generic 64-bit binary operation. 4312 */ 4313 /* binop vAA, vBB, vCC */ 4314 4315 movzbl 2(rPC),%eax # eax<- BB 4316 movzbl 3(rPC),%ecx # ecx<- CC 4317 GET_VREG_WORD %edx %eax 0 # edx<- v[BB+0] 4318 GET_VREG_WORD %eax %eax 1 # eax<- v[BB+1] 4319 xorl (rFP,%ecx,4),%edx # ex: addl (rFP,%ecx,4),%edx 4320 xorl 4(rFP,%ecx,4),%eax # ex: adcl 4(rFP,%ecx,4),%eax 4321 SET_VREG_WORD %edx rINST 0 # v[AA+0] <- edx 4322 FETCH_INST_OPCODE 2 %edx 4323 SET_VREG_WORD %eax rINST 1 # v[AA+1] <- eax 4324 ADVANCE_PC 2 4325 GOTO_NEXT_R %edx 4326 4327 4328/* ------------------------------ */ 4329 .balign 64 4330.L_OP_SHL_LONG: /* 0xa3 */ 4331/* File: x86/OP_SHL_LONG.S */ 4332 /* 4333 * Long integer shift. This is different from the generic 32/64-bit 4334 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4335 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4336 * 6 bits of the shift distance. x86 shifts automatically mask off 4337 * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31 4338 * case specially. 4339 */ 4340 /* shl-long vAA, vBB, vCC */ 4341 /* ecx gets shift count */ 4342 /* Need to spill edx */ 4343 /* rINSTw gets AA */ 4344 movzbl 2(rPC),%eax # eax<- BB 4345 movzbl 3(rPC),%ecx # ecx<- CC 4346 GET_VREG_WORD %edx %eax 1 # ecx<- v[BB+1] 4347 GET_VREG_R %ecx %ecx # ecx<- vCC 4348 GET_VREG_WORD %eax %eax 0 # eax<- v[BB+0] 4349 shldl %eax,%edx 4350 sall %cl,%eax 4351 testb $32,%cl 4352 je 2f 4353 movl %eax,%edx 4354 xorl %eax,%eax 43552: 4356 SET_VREG_WORD %edx rINST 1 # v[AA+1]<- %edx 4357 FETCH_INST_OPCODE 2 %edx 4358 jmp .LOP_SHL_LONG_finish 4359 4360/* ------------------------------ */ 4361 .balign 64 4362.L_OP_SHR_LONG: /* 0xa4 */ 4363/* File: x86/OP_SHR_LONG.S */ 4364 /* 4365 * Long integer shift. This is different from the generic 32/64-bit 4366 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4367 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4368 * 6 bits of the shift distance. x86 shifts automatically mask off 4369 * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31 4370 * case specially. 4371 */ 4372 /* shr-long vAA, vBB, vCC */ 4373 /* ecx gets shift count */ 4374 /* Need to spill edx */ 4375 /* rINSTw gets AA */ 4376 movzbl 2(rPC),%eax # eax<- BB 4377 movzbl 3(rPC),%ecx # ecx<- CC 4378 GET_VREG_WORD %edx %eax 1 # edx<- v[BB+1] 4379 GET_VREG_R %ecx %ecx # ecx<- vCC 4380 GET_VREG_WORD %eax %eax 0 # eax<- v[BB+0] 4381 shrdl %edx,%eax 4382 sarl %cl,%edx 4383 testb $32,%cl 4384 je 2f 4385 movl %edx,%eax 4386 sarl $31,%edx 43872: 4388 SET_VREG_WORD %edx rINST 1 # v[AA+1]<- edx 4389 FETCH_INST_OPCODE 2 %edx 4390 jmp .LOP_SHR_LONG_finish 4391 4392/* ------------------------------ */ 4393 .balign 64 4394.L_OP_USHR_LONG: /* 0xa5 */ 4395/* File: x86/OP_USHR_LONG.S */ 4396 /* 4397 * Long integer shift. This is different from the generic 32/64-bit 4398 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4399 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4400 * 6 bits of the shift distance. x86 shifts automatically mask off 4401 * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31 4402 * case specially. 4403 */ 4404 /* shr-long vAA, vBB, vCC */ 4405 /* ecx gets shift count */ 4406 /* Need to spill edx */ 4407 /* rINSTw gets AA */ 4408 movzbl 2(rPC),%eax # eax<- BB 4409 movzbl 3(rPC),%ecx # ecx<- CC 4410 GET_VREG_WORD %edx %eax 1 # edx<- v[BB+1] 4411 GET_VREG_R %ecx %ecx # ecx<- vCC 4412 GET_VREG_WORD %eax %eax 0 # eax<- v[BB+0] 4413 shrdl %edx,%eax 4414 shrl %cl,%edx 4415 testb $32,%cl 4416 je 2f 4417 movl %edx,%eax 4418 xorl %edx,%edx 44192: 4420 SET_VREG_WORD %edx rINST 1 # v[AA+1]<- edx 4421 FETCH_INST_OPCODE 2 %edx 4422 jmp .LOP_USHR_LONG_finish 4423 4424/* ------------------------------ */ 4425 .balign 64 4426.L_OP_ADD_FLOAT: /* 0xa6 */ 4427/* File: x86/OP_ADD_FLOAT.S */ 4428/* File: x86/binflop.S */ 4429 /* 4430 * Generic 32-bit binary float operation. 4431 * 4432 * For: add-fp, sub-fp, mul-fp, div-fp 4433 */ 4434 /* binop vAA, vBB, vCC */ 4435 movzbl 2(rPC),%eax # eax<- CC 4436 movzbl 3(rPC),%ecx # ecx<- BB 4437 flds (rFP,%eax,4) # vCC to fp stack 4438 fadds (rFP,%ecx,4) # ex: faddp 4439 FETCH_INST_OPCODE 2 %edx 4440 ADVANCE_PC 2 4441 fstps (rFP,rINST,4) # %st to vAA 4442 GOTO_NEXT_R %edx 4443 4444 4445/* ------------------------------ */ 4446 .balign 64 4447.L_OP_SUB_FLOAT: /* 0xa7 */ 4448/* File: x86/OP_SUB_FLOAT.S */ 4449/* File: x86/binflop.S */ 4450 /* 4451 * Generic 32-bit binary float operation. 4452 * 4453 * For: add-fp, sub-fp, mul-fp, div-fp 4454 */ 4455 /* binop vAA, vBB, vCC */ 4456 movzbl 2(rPC),%eax # eax<- CC 4457 movzbl 3(rPC),%ecx # ecx<- BB 4458 flds (rFP,%eax,4) # vCC to fp stack 4459 fsubs (rFP,%ecx,4) # ex: faddp 4460 FETCH_INST_OPCODE 2 %edx 4461 ADVANCE_PC 2 4462 fstps (rFP,rINST,4) # %st to vAA 4463 GOTO_NEXT_R %edx 4464 4465 4466/* ------------------------------ */ 4467 .balign 64 4468.L_OP_MUL_FLOAT: /* 0xa8 */ 4469/* File: x86/OP_MUL_FLOAT.S */ 4470/* File: x86/binflop.S */ 4471 /* 4472 * Generic 32-bit binary float operation. 4473 * 4474 * For: add-fp, sub-fp, mul-fp, div-fp 4475 */ 4476 /* binop vAA, vBB, vCC */ 4477 movzbl 2(rPC),%eax # eax<- CC 4478 movzbl 3(rPC),%ecx # ecx<- BB 4479 flds (rFP,%eax,4) # vCC to fp stack 4480 fmuls (rFP,%ecx,4) # ex: faddp 4481 FETCH_INST_OPCODE 2 %edx 4482 ADVANCE_PC 2 4483 fstps (rFP,rINST,4) # %st to vAA 4484 GOTO_NEXT_R %edx 4485 4486 4487/* ------------------------------ */ 4488 .balign 64 4489.L_OP_DIV_FLOAT: /* 0xa9 */ 4490/* File: x86/OP_DIV_FLOAT.S */ 4491/* File: x86/binflop.S */ 4492 /* 4493 * Generic 32-bit binary float operation. 4494 * 4495 * For: add-fp, sub-fp, mul-fp, div-fp 4496 */ 4497 /* binop vAA, vBB, vCC */ 4498 movzbl 2(rPC),%eax # eax<- CC 4499 movzbl 3(rPC),%ecx # ecx<- BB 4500 flds (rFP,%eax,4) # vCC to fp stack 4501 fdivs (rFP,%ecx,4) # ex: faddp 4502 FETCH_INST_OPCODE 2 %edx 4503 ADVANCE_PC 2 4504 fstps (rFP,rINST,4) # %st to vAA 4505 GOTO_NEXT_R %edx 4506 4507 4508/* ------------------------------ */ 4509 .balign 64 4510.L_OP_REM_FLOAT: /* 0xaa */ 4511/* File: x86/OP_REM_FLOAT.S */ 4512 /* rem_float vAA, vBB, vCC */ 4513 movzbl 3(rPC),%ecx # ecx<- BB 4514 movzbl 2(rPC),%eax # eax<- CC 4515 flds (rFP,%ecx,4) # vCC to fp stack 4516 flds (rFP,%eax,4) # vCC to fp stack 4517 movzbl rINSTbl,%ecx # ecx<- AA 4518 FETCH_INST_OPCODE 2 %edx 45191: 4520 fprem 4521 fstsw %ax 4522 sahf 4523 jp 1b 4524 fstp %st(1) 4525 ADVANCE_PC 2 4526 fstps (rFP,%ecx,4) # %st to vAA 4527 GOTO_NEXT_R %edx 4528 4529/* ------------------------------ */ 4530 .balign 64 4531.L_OP_ADD_DOUBLE: /* 0xab */ 4532/* File: x86/OP_ADD_DOUBLE.S */ 4533/* File: x86/binflop.S */ 4534 /* 4535 * Generic 32-bit binary float operation. 4536 * 4537 * For: add-fp, sub-fp, mul-fp, div-fp 4538 */ 4539 /* binop vAA, vBB, vCC */ 4540 movzbl 2(rPC),%eax # eax<- CC 4541 movzbl 3(rPC),%ecx # ecx<- BB 4542 fldl (rFP,%eax,4) # vCC to fp stack 4543 faddl (rFP,%ecx,4) # ex: faddp 4544 FETCH_INST_OPCODE 2 %edx 4545 ADVANCE_PC 2 4546 fstpl (rFP,rINST,4) # %st to vAA 4547 GOTO_NEXT_R %edx 4548 4549 4550/* ------------------------------ */ 4551 .balign 64 4552.L_OP_SUB_DOUBLE: /* 0xac */ 4553/* File: x86/OP_SUB_DOUBLE.S */ 4554/* File: x86/binflop.S */ 4555 /* 4556 * Generic 32-bit binary float operation. 4557 * 4558 * For: add-fp, sub-fp, mul-fp, div-fp 4559 */ 4560 /* binop vAA, vBB, vCC */ 4561 movzbl 2(rPC),%eax # eax<- CC 4562 movzbl 3(rPC),%ecx # ecx<- BB 4563 fldl (rFP,%eax,4) # vCC to fp stack 4564 fsubl (rFP,%ecx,4) # ex: faddp 4565 FETCH_INST_OPCODE 2 %edx 4566 ADVANCE_PC 2 4567 fstpl (rFP,rINST,4) # %st to vAA 4568 GOTO_NEXT_R %edx 4569 4570 4571/* ------------------------------ */ 4572 .balign 64 4573.L_OP_MUL_DOUBLE: /* 0xad */ 4574/* File: x86/OP_MUL_DOUBLE.S */ 4575/* File: x86/binflop.S */ 4576 /* 4577 * Generic 32-bit binary float operation. 4578 * 4579 * For: add-fp, sub-fp, mul-fp, div-fp 4580 */ 4581 /* binop vAA, vBB, vCC */ 4582 movzbl 2(rPC),%eax # eax<- CC 4583 movzbl 3(rPC),%ecx # ecx<- BB 4584 fldl (rFP,%eax,4) # vCC to fp stack 4585 fmull (rFP,%ecx,4) # ex: faddp 4586 FETCH_INST_OPCODE 2 %edx 4587 ADVANCE_PC 2 4588 fstpl (rFP,rINST,4) # %st to vAA 4589 GOTO_NEXT_R %edx 4590 4591 4592/* ------------------------------ */ 4593 .balign 64 4594.L_OP_DIV_DOUBLE: /* 0xae */ 4595/* File: x86/OP_DIV_DOUBLE.S */ 4596/* File: x86/binflop.S */ 4597 /* 4598 * Generic 32-bit binary float operation. 4599 * 4600 * For: add-fp, sub-fp, mul-fp, div-fp 4601 */ 4602 /* binop vAA, vBB, vCC */ 4603 movzbl 2(rPC),%eax # eax<- CC 4604 movzbl 3(rPC),%ecx # ecx<- BB 4605 fldl (rFP,%eax,4) # vCC to fp stack 4606 fdivl (rFP,%ecx,4) # ex: faddp 4607 FETCH_INST_OPCODE 2 %edx 4608 ADVANCE_PC 2 4609 fstpl (rFP,rINST,4) # %st to vAA 4610 GOTO_NEXT_R %edx 4611 4612 4613/* ------------------------------ */ 4614 .balign 64 4615.L_OP_REM_DOUBLE: /* 0xaf */ 4616/* File: x86/OP_REM_DOUBLE.S */ 4617 /* rem_float vAA, vBB, vCC */ 4618 movzbl 3(rPC),%ecx # ecx<- BB 4619 movzbl 2(rPC),%eax # eax<- CC 4620 fldl (rFP,%ecx,4) # vCC to fp stack 4621 fldl (rFP,%eax,4) # vCC to fp stack 4622 movzbl rINSTbl,%ecx # ecx<- AA 4623 FETCH_INST_OPCODE 2 %edx 46241: 4625 fprem 4626 fstsw %ax 4627 sahf 4628 jp 1b 4629 fstp %st(1) 4630 ADVANCE_PC 2 4631 fstpl (rFP,%ecx,4) # %st to vAA 4632 GOTO_NEXT_R %edx 4633 4634/* ------------------------------ */ 4635 .balign 64 4636.L_OP_ADD_INT_2ADDR: /* 0xb0 */ 4637/* File: x86/OP_ADD_INT_2ADDR.S */ 4638/* File: x86/binop2addr.S */ 4639 /* 4640 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 4641 * that specifies an instruction that performs "result = r0 op r1". 4642 * This could be an ARM instruction or a function call. (If the result 4643 * comes back in a register other than r0, you can override "result".) 4644 * 4645 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4646 * vCC (r1). Useful for integer division and modulus. 4647 * 4648 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 4649 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 4650 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 4651 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 4652 */ 4653 /* binop/2addr vA, vB */ 4654 movzx rINSTbl,%ecx # ecx<- A+ 4655 sarl $4,rINST # rINST<- B 4656 GET_VREG_R %eax rINST # eax<- vB 4657 FETCH_INST_OPCODE 1 %edx 4658 andb $0xf,%cl # ecx<- A 4659 addl %eax,(rFP,%ecx,4) # for ex: addl %eax,(rFP,%ecx,4) 4660 ADVANCE_PC 1 4661 GOTO_NEXT_R %edx 4662 4663 4664/* ------------------------------ */ 4665 .balign 64 4666.L_OP_SUB_INT_2ADDR: /* 0xb1 */ 4667/* File: x86/OP_SUB_INT_2ADDR.S */ 4668/* File: x86/binop2addr.S */ 4669 /* 4670 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 4671 * that specifies an instruction that performs "result = r0 op r1". 4672 * This could be an ARM instruction or a function call. (If the result 4673 * comes back in a register other than r0, you can override "result".) 4674 * 4675 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4676 * vCC (r1). Useful for integer division and modulus. 4677 * 4678 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 4679 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 4680 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 4681 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 4682 */ 4683 /* binop/2addr vA, vB */ 4684 movzx rINSTbl,%ecx # ecx<- A+ 4685 sarl $4,rINST # rINST<- B 4686 GET_VREG_R %eax rINST # eax<- vB 4687 FETCH_INST_OPCODE 1 %edx 4688 andb $0xf,%cl # ecx<- A 4689 subl %eax,(rFP,%ecx,4) # for ex: addl %eax,(rFP,%ecx,4) 4690 ADVANCE_PC 1 4691 GOTO_NEXT_R %edx 4692 4693 4694/* ------------------------------ */ 4695 .balign 64 4696.L_OP_MUL_INT_2ADDR: /* 0xb2 */ 4697/* File: x86/OP_MUL_INT_2ADDR.S */ 4698 /* mul vA, vB */ 4699 movzx rINSTbl,%ecx # ecx<- A+ 4700 sarl $4,rINST # rINST<- B 4701 GET_VREG_R %eax rINST # eax<- vB 4702 andb $0xf,%cl # ecx<- A 4703 imull (rFP,%ecx,4),%eax 4704 FETCH_INST_OPCODE 1 %edx 4705 SET_VREG %eax %ecx 4706 ADVANCE_PC 1 4707 GOTO_NEXT_R %edx 4708 4709/* ------------------------------ */ 4710 .balign 64 4711.L_OP_DIV_INT_2ADDR: /* 0xb3 */ 4712/* File: x86/OP_DIV_INT_2ADDR.S */ 4713/* File: x86/bindiv2addr.S */ 4714 /* 4715 * 32-bit binary div/rem operation. Handles special case of op0=minint and 4716 * op1=-1. 4717 */ 4718 /* div/rem/2addr vA, vB */ 4719 movzx rINSTbl,%ecx # eax<- BA 4720 sarl $4,%ecx # ecx<- B 4721 GET_VREG_R %ecx %ecx # eax<- vBB 4722 andb $0xf,rINSTbl # rINST<- A 4723 GET_VREG_R %eax rINST # eax<- vBB 4724 cmpl $0,%ecx 4725 je common_errDivideByZero 4726 cmpl $-1,%ecx 4727 jne .LOP_DIV_INT_2ADDR_continue_div2addr 4728 cmpl $0x80000000,%eax 4729 jne .LOP_DIV_INT_2ADDR_continue_div2addr 4730 movl $0x80000000,%eax 4731 jmp .LOP_DIV_INT_2ADDR_finish_div2addr 4732 4733 4734 4735/* ------------------------------ */ 4736 .balign 64 4737.L_OP_REM_INT_2ADDR: /* 0xb4 */ 4738/* File: x86/OP_REM_INT_2ADDR.S */ 4739/* File: x86/bindiv2addr.S */ 4740 /* 4741 * 32-bit binary div/rem operation. Handles special case of op0=minint and 4742 * op1=-1. 4743 */ 4744 /* div/rem/2addr vA, vB */ 4745 movzx rINSTbl,%ecx # eax<- BA 4746 sarl $4,%ecx # ecx<- B 4747 GET_VREG_R %ecx %ecx # eax<- vBB 4748 andb $0xf,rINSTbl # rINST<- A 4749 GET_VREG_R %eax rINST # eax<- vBB 4750 cmpl $0,%ecx 4751 je common_errDivideByZero 4752 cmpl $-1,%ecx 4753 jne .LOP_REM_INT_2ADDR_continue_div2addr 4754 cmpl $0x80000000,%eax 4755 jne .LOP_REM_INT_2ADDR_continue_div2addr 4756 movl $0,%edx 4757 jmp .LOP_REM_INT_2ADDR_finish_div2addr 4758 4759 4760 4761/* ------------------------------ */ 4762 .balign 64 4763.L_OP_AND_INT_2ADDR: /* 0xb5 */ 4764/* File: x86/OP_AND_INT_2ADDR.S */ 4765/* File: x86/binop2addr.S */ 4766 /* 4767 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 4768 * that specifies an instruction that performs "result = r0 op r1". 4769 * This could be an ARM instruction or a function call. (If the result 4770 * comes back in a register other than r0, you can override "result".) 4771 * 4772 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4773 * vCC (r1). Useful for integer division and modulus. 4774 * 4775 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 4776 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 4777 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 4778 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 4779 */ 4780 /* binop/2addr vA, vB */ 4781 movzx rINSTbl,%ecx # ecx<- A+ 4782 sarl $4,rINST # rINST<- B 4783 GET_VREG_R %eax rINST # eax<- vB 4784 FETCH_INST_OPCODE 1 %edx 4785 andb $0xf,%cl # ecx<- A 4786 andl %eax,(rFP,%ecx,4) # for ex: addl %eax,(rFP,%ecx,4) 4787 ADVANCE_PC 1 4788 GOTO_NEXT_R %edx 4789 4790 4791/* ------------------------------ */ 4792 .balign 64 4793.L_OP_OR_INT_2ADDR: /* 0xb6 */ 4794/* File: x86/OP_OR_INT_2ADDR.S */ 4795/* File: x86/binop2addr.S */ 4796 /* 4797 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 4798 * that specifies an instruction that performs "result = r0 op r1". 4799 * This could be an ARM instruction or a function call. (If the result 4800 * comes back in a register other than r0, you can override "result".) 4801 * 4802 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4803 * vCC (r1). Useful for integer division and modulus. 4804 * 4805 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 4806 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 4807 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 4808 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 4809 */ 4810 /* binop/2addr vA, vB */ 4811 movzx rINSTbl,%ecx # ecx<- A+ 4812 sarl $4,rINST # rINST<- B 4813 GET_VREG_R %eax rINST # eax<- vB 4814 FETCH_INST_OPCODE 1 %edx 4815 andb $0xf,%cl # ecx<- A 4816 orl %eax,(rFP,%ecx,4) # for ex: addl %eax,(rFP,%ecx,4) 4817 ADVANCE_PC 1 4818 GOTO_NEXT_R %edx 4819 4820 4821/* ------------------------------ */ 4822 .balign 64 4823.L_OP_XOR_INT_2ADDR: /* 0xb7 */ 4824/* File: x86/OP_XOR_INT_2ADDR.S */ 4825/* File: x86/binop2addr.S */ 4826 /* 4827 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 4828 * that specifies an instruction that performs "result = r0 op r1". 4829 * This could be an ARM instruction or a function call. (If the result 4830 * comes back in a register other than r0, you can override "result".) 4831 * 4832 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4833 * vCC (r1). Useful for integer division and modulus. 4834 * 4835 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 4836 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 4837 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 4838 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 4839 */ 4840 /* binop/2addr vA, vB */ 4841 movzx rINSTbl,%ecx # ecx<- A+ 4842 sarl $4,rINST # rINST<- B 4843 GET_VREG_R %eax rINST # eax<- vB 4844 FETCH_INST_OPCODE 1 %edx 4845 andb $0xf,%cl # ecx<- A 4846 xorl %eax,(rFP,%ecx,4) # for ex: addl %eax,(rFP,%ecx,4) 4847 ADVANCE_PC 1 4848 GOTO_NEXT_R %edx 4849 4850 4851/* ------------------------------ */ 4852 .balign 64 4853.L_OP_SHL_INT_2ADDR: /* 0xb8 */ 4854/* File: x86/OP_SHL_INT_2ADDR.S */ 4855/* File: x86/shop2addr.S */ 4856 /* 4857 * Generic 32-bit "shift/2addr" operation. 4858 */ 4859 /* shift/2addr vA, vB */ 4860 movzx rINSTbl,%ecx # eax<- BA 4861 sarl $4,%ecx # ecx<- B 4862 GET_VREG_R %ecx %ecx # eax<- vBB 4863 andb $0xf,rINSTbl # rINST<- A 4864 GET_VREG_R %eax rINST # eax<- vAA 4865 sall %cl,%eax # ex: sarl %cl,%eax 4866 FETCH_INST_OPCODE 1 %edx 4867 SET_VREG %eax rINST 4868 ADVANCE_PC 1 4869 GOTO_NEXT_R %edx 4870 4871 4872/* ------------------------------ */ 4873 .balign 64 4874.L_OP_SHR_INT_2ADDR: /* 0xb9 */ 4875/* File: x86/OP_SHR_INT_2ADDR.S */ 4876/* File: x86/shop2addr.S */ 4877 /* 4878 * Generic 32-bit "shift/2addr" operation. 4879 */ 4880 /* shift/2addr vA, vB */ 4881 movzx rINSTbl,%ecx # eax<- BA 4882 sarl $4,%ecx # ecx<- B 4883 GET_VREG_R %ecx %ecx # eax<- vBB 4884 andb $0xf,rINSTbl # rINST<- A 4885 GET_VREG_R %eax rINST # eax<- vAA 4886 sarl %cl,%eax # ex: sarl %cl,%eax 4887 FETCH_INST_OPCODE 1 %edx 4888 SET_VREG %eax rINST 4889 ADVANCE_PC 1 4890 GOTO_NEXT_R %edx 4891 4892 4893/* ------------------------------ */ 4894 .balign 64 4895.L_OP_USHR_INT_2ADDR: /* 0xba */ 4896/* File: x86/OP_USHR_INT_2ADDR.S */ 4897/* File: x86/shop2addr.S */ 4898 /* 4899 * Generic 32-bit "shift/2addr" operation. 4900 */ 4901 /* shift/2addr vA, vB */ 4902 movzx rINSTbl,%ecx # eax<- BA 4903 sarl $4,%ecx # ecx<- B 4904 GET_VREG_R %ecx %ecx # eax<- vBB 4905 andb $0xf,rINSTbl # rINST<- A 4906 GET_VREG_R %eax rINST # eax<- vAA 4907 shrl %cl,%eax # ex: sarl %cl,%eax 4908 FETCH_INST_OPCODE 1 %edx 4909 SET_VREG %eax rINST 4910 ADVANCE_PC 1 4911 GOTO_NEXT_R %edx 4912 4913 4914/* ------------------------------ */ 4915 .balign 64 4916.L_OP_ADD_LONG_2ADDR: /* 0xbb */ 4917/* File: x86/OP_ADD_LONG_2ADDR.S */ 4918/* File: x86/binopWide2addr.S */ 4919 /* 4920 * Generic 64-bit binary operation. 4921 */ 4922 /* binop/2addr vA, vB */ 4923 movzbl rINSTbl,%ecx # ecx<- BA 4924 sarl $4,%ecx # ecx<- B 4925 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 4926 GET_VREG_WORD %ecx %ecx 1 # eax<- v[B+1] 4927 andb $0xF,rINSTbl # rINST<- A 4928 addl %eax,(rFP,rINST,4) # example: addl %eax,(rFP,rINST,4) 4929 adcl %ecx,4(rFP,rINST,4) # example: adcl %ecx,4(rFP,rINST,4) 4930 FETCH_INST_OPCODE 1 %edx 4931 ADVANCE_PC 1 4932 GOTO_NEXT_R %edx 4933 4934 4935/* ------------------------------ */ 4936 .balign 64 4937.L_OP_SUB_LONG_2ADDR: /* 0xbc */ 4938/* File: x86/OP_SUB_LONG_2ADDR.S */ 4939/* File: x86/binopWide2addr.S */ 4940 /* 4941 * Generic 64-bit binary operation. 4942 */ 4943 /* binop/2addr vA, vB */ 4944 movzbl rINSTbl,%ecx # ecx<- BA 4945 sarl $4,%ecx # ecx<- B 4946 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 4947 GET_VREG_WORD %ecx %ecx 1 # eax<- v[B+1] 4948 andb $0xF,rINSTbl # rINST<- A 4949 subl %eax,(rFP,rINST,4) # example: addl %eax,(rFP,rINST,4) 4950 sbbl %ecx,4(rFP,rINST,4) # example: adcl %ecx,4(rFP,rINST,4) 4951 FETCH_INST_OPCODE 1 %edx 4952 ADVANCE_PC 1 4953 GOTO_NEXT_R %edx 4954 4955 4956/* ------------------------------ */ 4957 .balign 64 4958.L_OP_MUL_LONG_2ADDR: /* 0xbd */ 4959/* File: x86/OP_MUL_LONG_2ADDR.S */ 4960 /* 4961 * Signed 64-bit integer multiply, 2-addr version 4962 * 4963 * We could definately use more free registers for 4964 * this code. We must spill %edx (edx) because it 4965 * is used by imul. We'll also spill rINST (ebx), 4966 * giving us eax, ebc, ecx and edx as computational 4967 * temps. On top of that, we'll spill %esi (edi) 4968 * for use as the vA pointer and rFP (esi) for use 4969 * as the vB pointer. Yuck. 4970 */ 4971 /* mul-long/2addr vA, vB */ 4972 movzbl rINSTbl,%eax # eax<- BA 4973 andb $0xf,%al # eax<- A 4974 sarl $4,rINST # rINST<- B 4975 SPILL_TMP2(%esi) 4976 SPILL(rFP) 4977 leal (rFP,%eax,4),%esi # %esi<- &v[A] 4978 leal (rFP,rINST,4),rFP # rFP<- &v[B] 4979 movl 4(%esi),%ecx # ecx<- Amsw 4980 imull (rFP),%ecx # ecx<- (Amsw*Blsw) 4981 movl 4(rFP),%eax # eax<- Bmsw 4982 imull (%esi),%eax # eax<- (Bmsw*Alsw) 4983 addl %eax,%ecx # ecx<- (Amsw*Blsw)+(Bmsw*Alsw) 4984 movl (rFP),%eax # eax<- Blsw 4985 mull (%esi) # eax<- (Blsw*Alsw) 4986 jmp .LOP_MUL_LONG_2ADDR_continue 4987 4988/* ------------------------------ */ 4989 .balign 64 4990.L_OP_DIV_LONG_2ADDR: /* 0xbe */ 4991/* File: x86/OP_DIV_LONG_2ADDR.S */ 4992 /* div/2addr vA, vB */ 4993 movzbl rINSTbl,%eax 4994 shrl $4,%eax # eax<- B 4995 andb $0xf,rINSTbl # rINST<- A 4996 GET_VREG_WORD %edx %eax 0 4997 GET_VREG_WORD %eax %eax 1 4998 movl %edx,OUT_ARG2(%esp) 4999 testl %eax,%eax 5000 je .LOP_DIV_LONG_2ADDR_check_zero 5001 cmpl $-1,%eax 5002 je .LOP_DIV_LONG_2ADDR_check_neg1 5003.LOP_DIV_LONG_2ADDR_notSpecial: 5004 GET_VREG_WORD %edx rINST 0 5005 GET_VREG_WORD %ecx rINST 1 5006.LOP_DIV_LONG_2ADDR_notSpecial1: 5007 jmp .LOP_DIV_LONG_2ADDR_continue 5008 5009/* ------------------------------ */ 5010 .balign 64 5011.L_OP_REM_LONG_2ADDR: /* 0xbf */ 5012/* File: x86/OP_REM_LONG_2ADDR.S */ 5013/* File: x86/OP_DIV_LONG_2ADDR.S */ 5014 /* div/2addr vA, vB */ 5015 movzbl rINSTbl,%eax 5016 shrl $4,%eax # eax<- B 5017 andb $0xf,rINSTbl # rINST<- A 5018 GET_VREG_WORD %edx %eax 0 5019 GET_VREG_WORD %eax %eax 1 5020 movl %edx,OUT_ARG2(%esp) 5021 testl %eax,%eax 5022 je .LOP_REM_LONG_2ADDR_check_zero 5023 cmpl $-1,%eax 5024 je .LOP_REM_LONG_2ADDR_check_neg1 5025.LOP_REM_LONG_2ADDR_notSpecial: 5026 GET_VREG_WORD %edx rINST 0 5027 GET_VREG_WORD %ecx rINST 1 5028.LOP_REM_LONG_2ADDR_notSpecial1: 5029 jmp .LOP_REM_LONG_2ADDR_continue 5030 5031 5032/* ------------------------------ */ 5033 .balign 64 5034.L_OP_AND_LONG_2ADDR: /* 0xc0 */ 5035/* File: x86/OP_AND_LONG_2ADDR.S */ 5036/* File: x86/binopWide2addr.S */ 5037 /* 5038 * Generic 64-bit binary operation. 5039 */ 5040 /* binop/2addr vA, vB */ 5041 movzbl rINSTbl,%ecx # ecx<- BA 5042 sarl $4,%ecx # ecx<- B 5043 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 5044 GET_VREG_WORD %ecx %ecx 1 # eax<- v[B+1] 5045 andb $0xF,rINSTbl # rINST<- A 5046 andl %eax,(rFP,rINST,4) # example: addl %eax,(rFP,rINST,4) 5047 andl %ecx,4(rFP,rINST,4) # example: adcl %ecx,4(rFP,rINST,4) 5048 FETCH_INST_OPCODE 1 %edx 5049 ADVANCE_PC 1 5050 GOTO_NEXT_R %edx 5051 5052 5053/* ------------------------------ */ 5054 .balign 64 5055.L_OP_OR_LONG_2ADDR: /* 0xc1 */ 5056/* File: x86/OP_OR_LONG_2ADDR.S */ 5057/* File: x86/binopWide2addr.S */ 5058 /* 5059 * Generic 64-bit binary operation. 5060 */ 5061 /* binop/2addr vA, vB */ 5062 movzbl rINSTbl,%ecx # ecx<- BA 5063 sarl $4,%ecx # ecx<- B 5064 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 5065 GET_VREG_WORD %ecx %ecx 1 # eax<- v[B+1] 5066 andb $0xF,rINSTbl # rINST<- A 5067 orl %eax,(rFP,rINST,4) # example: addl %eax,(rFP,rINST,4) 5068 orl %ecx,4(rFP,rINST,4) # example: adcl %ecx,4(rFP,rINST,4) 5069 FETCH_INST_OPCODE 1 %edx 5070 ADVANCE_PC 1 5071 GOTO_NEXT_R %edx 5072 5073 5074/* ------------------------------ */ 5075 .balign 64 5076.L_OP_XOR_LONG_2ADDR: /* 0xc2 */ 5077/* File: x86/OP_XOR_LONG_2ADDR.S */ 5078/* File: x86/binopWide2addr.S */ 5079 /* 5080 * Generic 64-bit binary operation. 5081 */ 5082 /* binop/2addr vA, vB */ 5083 movzbl rINSTbl,%ecx # ecx<- BA 5084 sarl $4,%ecx # ecx<- B 5085 GET_VREG_WORD %eax %ecx 0 # eax<- v[B+0] 5086 GET_VREG_WORD %ecx %ecx 1 # eax<- v[B+1] 5087 andb $0xF,rINSTbl # rINST<- A 5088 xorl %eax,(rFP,rINST,4) # example: addl %eax,(rFP,rINST,4) 5089 xorl %ecx,4(rFP,rINST,4) # example: adcl %ecx,4(rFP,rINST,4) 5090 FETCH_INST_OPCODE 1 %edx 5091 ADVANCE_PC 1 5092 GOTO_NEXT_R %edx 5093 5094 5095/* ------------------------------ */ 5096 .balign 64 5097.L_OP_SHL_LONG_2ADDR: /* 0xc3 */ 5098/* File: x86/OP_SHL_LONG_2ADDR.S */ 5099 /* 5100 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5101 * 32-bit shift distance. 5102 */ 5103 /* shl-long/2addr vA, vB */ 5104 /* ecx gets shift count */ 5105 /* Need to spill edx */ 5106 /* rINSTw gets AA */ 5107 movzbl rINSTbl,%ecx # ecx<- BA 5108 andb $0xf,rINSTbl # rINST<- A 5109 GET_VREG_WORD %eax rINST 0 # eax<- v[AA+0] 5110 sarl $4,%ecx # ecx<- B 5111 GET_VREG_WORD %edx rINST 1 # edx<- v[AA+1] 5112 GET_VREG_R %ecx %ecx # ecx<- vBB 5113 shldl %eax,%edx 5114 sall %cl,%eax 5115 testb $32,%cl 5116 je 2f 5117 movl %eax,%edx 5118 xorl %eax,%eax 51192: 5120 SET_VREG_WORD %edx rINST 1 # v[AA+1]<- edx 5121 jmp .LOP_SHL_LONG_2ADDR_finish 5122 5123/* ------------------------------ */ 5124 .balign 64 5125.L_OP_SHR_LONG_2ADDR: /* 0xc4 */ 5126/* File: x86/OP_SHR_LONG_2ADDR.S */ 5127 /* 5128 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5129 * 32-bit shift distance. 5130 */ 5131 /* shl-long/2addr vA, vB */ 5132 /* ecx gets shift count */ 5133 /* Need to spill edx */ 5134 /* rINSTw gets AA */ 5135 movzbl rINSTbl,%ecx # ecx<- BA 5136 andb $0xf,rINSTbl # rINST<- A 5137 GET_VREG_WORD %eax rINST 0 # eax<- v[AA+0] 5138 sarl $4,%ecx # ecx<- B 5139 GET_VREG_WORD %edx rINST 1 # edx<- v[AA+1] 5140 GET_VREG_R %ecx %ecx # ecx<- vBB 5141 shrdl %edx,%eax 5142 sarl %cl,%edx 5143 testb $32,%cl 5144 je 2f 5145 movl %edx,%eax 5146 sarl $31,%edx 51472: 5148 SET_VREG_WORD %edx rINST 1 # v[AA+1]<- edx 5149 jmp .LOP_SHR_LONG_2ADDR_finish 5150 5151/* ------------------------------ */ 5152 .balign 64 5153.L_OP_USHR_LONG_2ADDR: /* 0xc5 */ 5154/* File: x86/OP_USHR_LONG_2ADDR.S */ 5155 /* 5156 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5157 * 32-bit shift distance. 5158 */ 5159 /* shl-long/2addr vA, vB */ 5160 /* ecx gets shift count */ 5161 /* Need to spill edx */ 5162 /* rINSTw gets AA */ 5163 movzbl rINSTbl,%ecx # ecx<- BA 5164 andb $0xf,rINSTbl # rINST<- A 5165 GET_VREG_WORD %eax rINST 0 # eax<- v[AA+0] 5166 sarl $4,%ecx # ecx<- B 5167 GET_VREG_WORD %edx rINST 1 # edx<- v[AA+1] 5168 GET_VREG_R %ecx %ecx # ecx<- vBB 5169 shrdl %edx,%eax 5170 shrl %cl,%edx 5171 testb $32,%cl 5172 je 2f 5173 movl %edx,%eax 5174 xorl %edx,%edx 51752: 5176 SET_VREG_WORD %edx rINST 1 # v[AA+1]<- edx 5177 jmp .LOP_USHR_LONG_2ADDR_finish 5178 5179/* ------------------------------ */ 5180 .balign 64 5181.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */ 5182/* File: x86/OP_ADD_FLOAT_2ADDR.S */ 5183/* File: x86/binflop2addr.S */ 5184 /* 5185 * Generic 32-bit binary float operation. 5186 * 5187 * For: add-fp, sub-fp, mul-fp, div-fp 5188 */ 5189 5190 /* binop/2addr vA, vB */ 5191 movzx rINSTbl,%ecx # ecx<- A+ 5192 andb $0xf,%cl # ecx<- A 5193 flds (rFP,%ecx,4) # vAA to fp stack 5194 sarl $4,rINST # rINST<- B 5195 fadds (rFP,rINST,4) # ex: faddp 5196 FETCH_INST_OPCODE 1 %edx 5197 ADVANCE_PC 1 5198 fstps (rFP,%ecx,4) # %st to vA 5199 GOTO_NEXT_R %edx 5200 5201 5202/* ------------------------------ */ 5203 .balign 64 5204.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */ 5205/* File: x86/OP_SUB_FLOAT_2ADDR.S */ 5206/* File: x86/binflop2addr.S */ 5207 /* 5208 * Generic 32-bit binary float operation. 5209 * 5210 * For: add-fp, sub-fp, mul-fp, div-fp 5211 */ 5212 5213 /* binop/2addr vA, vB */ 5214 movzx rINSTbl,%ecx # ecx<- A+ 5215 andb $0xf,%cl # ecx<- A 5216 flds (rFP,%ecx,4) # vAA to fp stack 5217 sarl $4,rINST # rINST<- B 5218 fsubs (rFP,rINST,4) # ex: faddp 5219 FETCH_INST_OPCODE 1 %edx 5220 ADVANCE_PC 1 5221 fstps (rFP,%ecx,4) # %st to vA 5222 GOTO_NEXT_R %edx 5223 5224 5225/* ------------------------------ */ 5226 .balign 64 5227.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */ 5228/* File: x86/OP_MUL_FLOAT_2ADDR.S */ 5229/* File: x86/binflop2addr.S */ 5230 /* 5231 * Generic 32-bit binary float operation. 5232 * 5233 * For: add-fp, sub-fp, mul-fp, div-fp 5234 */ 5235 5236 /* binop/2addr vA, vB */ 5237 movzx rINSTbl,%ecx # ecx<- A+ 5238 andb $0xf,%cl # ecx<- A 5239 flds (rFP,%ecx,4) # vAA to fp stack 5240 sarl $4,rINST # rINST<- B 5241 fmuls (rFP,rINST,4) # ex: faddp 5242 FETCH_INST_OPCODE 1 %edx 5243 ADVANCE_PC 1 5244 fstps (rFP,%ecx,4) # %st to vA 5245 GOTO_NEXT_R %edx 5246 5247 5248/* ------------------------------ */ 5249 .balign 64 5250.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */ 5251/* File: x86/OP_DIV_FLOAT_2ADDR.S */ 5252/* File: x86/binflop2addr.S */ 5253 /* 5254 * Generic 32-bit binary float operation. 5255 * 5256 * For: add-fp, sub-fp, mul-fp, div-fp 5257 */ 5258 5259 /* binop/2addr vA, vB */ 5260 movzx rINSTbl,%ecx # ecx<- A+ 5261 andb $0xf,%cl # ecx<- A 5262 flds (rFP,%ecx,4) # vAA to fp stack 5263 sarl $4,rINST # rINST<- B 5264 fdivs (rFP,rINST,4) # ex: faddp 5265 FETCH_INST_OPCODE 1 %edx 5266 ADVANCE_PC 1 5267 fstps (rFP,%ecx,4) # %st to vA 5268 GOTO_NEXT_R %edx 5269 5270 5271/* ------------------------------ */ 5272 .balign 64 5273.L_OP_REM_FLOAT_2ADDR: /* 0xca */ 5274/* File: x86/OP_REM_FLOAT_2ADDR.S */ 5275 /* rem_float/2addr vA, vB */ 5276 movzx rINSTbl,%ecx # ecx<- A+ 5277 sarl $4,rINST # rINST<- B 5278 flds (rFP,rINST,4) # vBB to fp stack 5279 andb $0xf,%cl # ecx<- A 5280 flds (rFP,%ecx,4) # vAA to fp stack 5281 FETCH_INST_OPCODE 1 %edx 52821: 5283 fprem 5284 fstsw %ax 5285 sahf 5286 jp 1b 5287 fstp %st(1) 5288 ADVANCE_PC 1 5289 fstps (rFP,%ecx,4) # %st to vA 5290 GOTO_NEXT_R %edx 5291 5292/* ------------------------------ */ 5293 .balign 64 5294.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */ 5295/* File: x86/OP_ADD_DOUBLE_2ADDR.S */ 5296/* File: x86/binflop2addr.S */ 5297 /* 5298 * Generic 32-bit binary float operation. 5299 * 5300 * For: add-fp, sub-fp, mul-fp, div-fp 5301 */ 5302 5303 /* binop/2addr vA, vB */ 5304 movzx rINSTbl,%ecx # ecx<- A+ 5305 andb $0xf,%cl # ecx<- A 5306 fldl (rFP,%ecx,4) # vAA to fp stack 5307 sarl $4,rINST # rINST<- B 5308 faddl (rFP,rINST,4) # ex: faddp 5309 FETCH_INST_OPCODE 1 %edx 5310 ADVANCE_PC 1 5311 fstpl (rFP,%ecx,4) # %st to vA 5312 GOTO_NEXT_R %edx 5313 5314 5315/* ------------------------------ */ 5316 .balign 64 5317.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */ 5318/* File: x86/OP_SUB_DOUBLE_2ADDR.S */ 5319/* File: x86/binflop2addr.S */ 5320 /* 5321 * Generic 32-bit binary float operation. 5322 * 5323 * For: add-fp, sub-fp, mul-fp, div-fp 5324 */ 5325 5326 /* binop/2addr vA, vB */ 5327 movzx rINSTbl,%ecx # ecx<- A+ 5328 andb $0xf,%cl # ecx<- A 5329 fldl (rFP,%ecx,4) # vAA to fp stack 5330 sarl $4,rINST # rINST<- B 5331 fsubl (rFP,rINST,4) # ex: faddp 5332 FETCH_INST_OPCODE 1 %edx 5333 ADVANCE_PC 1 5334 fstpl (rFP,%ecx,4) # %st to vA 5335 GOTO_NEXT_R %edx 5336 5337 5338/* ------------------------------ */ 5339 .balign 64 5340.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */ 5341/* File: x86/OP_MUL_DOUBLE_2ADDR.S */ 5342/* File: x86/binflop2addr.S */ 5343 /* 5344 * Generic 32-bit binary float operation. 5345 * 5346 * For: add-fp, sub-fp, mul-fp, div-fp 5347 */ 5348 5349 /* binop/2addr vA, vB */ 5350 movzx rINSTbl,%ecx # ecx<- A+ 5351 andb $0xf,%cl # ecx<- A 5352 fldl (rFP,%ecx,4) # vAA to fp stack 5353 sarl $4,rINST # rINST<- B 5354 fmull (rFP,rINST,4) # ex: faddp 5355 FETCH_INST_OPCODE 1 %edx 5356 ADVANCE_PC 1 5357 fstpl (rFP,%ecx,4) # %st to vA 5358 GOTO_NEXT_R %edx 5359 5360 5361/* ------------------------------ */ 5362 .balign 64 5363.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */ 5364/* File: x86/OP_DIV_DOUBLE_2ADDR.S */ 5365/* File: x86/binflop2addr.S */ 5366 /* 5367 * Generic 32-bit binary float operation. 5368 * 5369 * For: add-fp, sub-fp, mul-fp, div-fp 5370 */ 5371 5372 /* binop/2addr vA, vB */ 5373 movzx rINSTbl,%ecx # ecx<- A+ 5374 andb $0xf,%cl # ecx<- A 5375 fldl (rFP,%ecx,4) # vAA to fp stack 5376 sarl $4,rINST # rINST<- B 5377 fdivl (rFP,rINST,4) # ex: faddp 5378 FETCH_INST_OPCODE 1 %edx 5379 ADVANCE_PC 1 5380 fstpl (rFP,%ecx,4) # %st to vA 5381 GOTO_NEXT_R %edx 5382 5383 5384/* ------------------------------ */ 5385 .balign 64 5386.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */ 5387/* File: x86/OP_REM_DOUBLE_2ADDR.S */ 5388 /* rem_float/2addr vA, vB */ 5389 movzx rINSTbl,%ecx # ecx<- A+ 5390 sarl $4,rINST # rINST<- B 5391 fldl (rFP,rINST,4) # vBB to fp stack 5392 andb $0xf,%cl # ecx<- A 5393 fldl (rFP,%ecx,4) # vAA to fp stack 5394 FETCH_INST_OPCODE 1 %edx 53951: 5396 fprem 5397 fstsw %ax 5398 sahf 5399 jp 1b 5400 fstp %st(1) 5401 ADVANCE_PC 1 5402 fstpl (rFP,%ecx,4) # %st to vA 5403 GOTO_NEXT_R %edx 5404 5405/* ------------------------------ */ 5406 .balign 64 5407.L_OP_ADD_INT_LIT16: /* 0xd0 */ 5408/* File: x86/OP_ADD_INT_LIT16.S */ 5409/* File: x86/binopLit16.S */ 5410 /* 5411 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 5412 * that specifies an instruction that performs "result = eax op ecx". 5413 * This could be an x86 instruction or a function call. (If the result 5414 * comes back in a register other than eax, you can override "result".) 5415 * 5416 * For: add-int/lit16, rsub-int, 5417 * and-int/lit16, or-int/lit16, xor-int/lit16 5418 */ 5419 /* binop/lit16 vA, vB, #+CCCC */ 5420 movzbl rINSTbl,%eax # eax<- 000000BA 5421 sarl $4,%eax # eax<- B 5422 GET_VREG_R %eax %eax # eax<- vB 5423 movswl 2(rPC),%ecx # ecx<- ssssCCCC 5424 andb $0xf,rINSTbl # rINST<- A 5425 addl %ecx,%eax # for example: addl %ecx, %eax 5426 SET_VREG %eax rINST 5427 FETCH_INST_OPCODE 2 %edx 5428 ADVANCE_PC 2 5429 GOTO_NEXT_R %edx 5430 5431 5432/* ------------------------------ */ 5433 .balign 64 5434.L_OP_RSUB_INT: /* 0xd1 */ 5435/* File: x86/OP_RSUB_INT.S */ 5436/* File: x86/binopLit16.S */ 5437 /* 5438 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 5439 * that specifies an instruction that performs "result = eax op ecx". 5440 * This could be an x86 instruction or a function call. (If the result 5441 * comes back in a register other than eax, you can override "result".) 5442 * 5443 * For: add-int/lit16, rsub-int, 5444 * and-int/lit16, or-int/lit16, xor-int/lit16 5445 */ 5446 /* binop/lit16 vA, vB, #+CCCC */ 5447 movzbl rINSTbl,%eax # eax<- 000000BA 5448 sarl $4,%eax # eax<- B 5449 GET_VREG_R %eax %eax # eax<- vB 5450 movswl 2(rPC),%ecx # ecx<- ssssCCCC 5451 andb $0xf,rINSTbl # rINST<- A 5452 subl %eax,%ecx # for example: addl %ecx, %eax 5453 SET_VREG %ecx rINST 5454 FETCH_INST_OPCODE 2 %edx 5455 ADVANCE_PC 2 5456 GOTO_NEXT_R %edx 5457 5458 5459/* ------------------------------ */ 5460 .balign 64 5461.L_OP_MUL_INT_LIT16: /* 0xd2 */ 5462/* File: x86/OP_MUL_INT_LIT16.S */ 5463 /* mul/lit16 vA, vB, #+CCCC */ 5464 /* Need A in rINST, ssssCCCC in ecx, vB in eax */ 5465 movzbl rINSTbl,%eax # eax<- 000000BA 5466 sarl $4,%eax # eax<- B 5467 GET_VREG_R %eax %eax # eax<- vB 5468 movswl 2(rPC),%ecx # ecx<- ssssCCCC 5469 andb $0xf,rINSTbl # rINST<- A 5470 imull %ecx,%eax # trashes edx 5471 FETCH_INST_OPCODE 2 %edx 5472 ADVANCE_PC 2 5473 SET_VREG %eax rINST 5474 GOTO_NEXT_R %edx 5475 5476/* ------------------------------ */ 5477 .balign 64 5478.L_OP_DIV_INT_LIT16: /* 0xd3 */ 5479/* File: x86/OP_DIV_INT_LIT16.S */ 5480/* File: x86/bindivLit16.S */ 5481 /* 5482 * 32-bit binary div/rem operation. Handles special case of op0=minint and 5483 * op1=-1. 5484 */ 5485 /* div/rem/lit16 vA, vB, #+CCCC */ 5486 /* Need A in rINST, ssssCCCC in ecx, vB in eax */ 5487 movzbl rINSTbl,%eax # eax<- 000000BA 5488 sarl $4,%eax # eax<- B 5489 GET_VREG_R %eax %eax # eax<- vB 5490 movswl 2(rPC),%ecx # ecx<- ssssCCCC 5491 andb $0xf,rINSTbl # rINST<- A 5492 cmpl $0,%ecx 5493 je common_errDivideByZero 5494 cmpl $-1,%ecx 5495 jne .LOP_DIV_INT_LIT16_continue_div 5496 cmpl $0x80000000,%eax 5497 jne .LOP_DIV_INT_LIT16_continue_div 5498 movl $0x80000000,%eax 5499 jmp .LOP_DIV_INT_LIT16_finish_div 5500 5501 5502 5503/* ------------------------------ */ 5504 .balign 64 5505.L_OP_REM_INT_LIT16: /* 0xd4 */ 5506/* File: x86/OP_REM_INT_LIT16.S */ 5507/* File: x86/bindivLit16.S */ 5508 /* 5509 * 32-bit binary div/rem operation. Handles special case of op0=minint and 5510 * op1=-1. 5511 */ 5512 /* div/rem/lit16 vA, vB, #+CCCC */ 5513 /* Need A in rINST, ssssCCCC in ecx, vB in eax */ 5514 movzbl rINSTbl,%eax # eax<- 000000BA 5515 sarl $4,%eax # eax<- B 5516 GET_VREG_R %eax %eax # eax<- vB 5517 movswl 2(rPC),%ecx # ecx<- ssssCCCC 5518 andb $0xf,rINSTbl # rINST<- A 5519 cmpl $0,%ecx 5520 je common_errDivideByZero 5521 cmpl $-1,%ecx 5522 jne .LOP_REM_INT_LIT16_continue_div 5523 cmpl $0x80000000,%eax 5524 jne .LOP_REM_INT_LIT16_continue_div 5525 movl $0,%edx 5526 jmp .LOP_REM_INT_LIT16_finish_div 5527 5528 5529 5530/* ------------------------------ */ 5531 .balign 64 5532.L_OP_AND_INT_LIT16: /* 0xd5 */ 5533/* File: x86/OP_AND_INT_LIT16.S */ 5534/* File: x86/binopLit16.S */ 5535 /* 5536 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 5537 * that specifies an instruction that performs "result = eax op ecx". 5538 * This could be an x86 instruction or a function call. (If the result 5539 * comes back in a register other than eax, you can override "result".) 5540 * 5541 * For: add-int/lit16, rsub-int, 5542 * and-int/lit16, or-int/lit16, xor-int/lit16 5543 */ 5544 /* binop/lit16 vA, vB, #+CCCC */ 5545 movzbl rINSTbl,%eax # eax<- 000000BA 5546 sarl $4,%eax # eax<- B 5547 GET_VREG_R %eax %eax # eax<- vB 5548 movswl 2(rPC),%ecx # ecx<- ssssCCCC 5549 andb $0xf,rINSTbl # rINST<- A 5550 andl %ecx,%eax # for example: addl %ecx, %eax 5551 SET_VREG %eax rINST 5552 FETCH_INST_OPCODE 2 %edx 5553 ADVANCE_PC 2 5554 GOTO_NEXT_R %edx 5555 5556 5557/* ------------------------------ */ 5558 .balign 64 5559.L_OP_OR_INT_LIT16: /* 0xd6 */ 5560/* File: x86/OP_OR_INT_LIT16.S */ 5561/* File: x86/binopLit16.S */ 5562 /* 5563 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 5564 * that specifies an instruction that performs "result = eax op ecx". 5565 * This could be an x86 instruction or a function call. (If the result 5566 * comes back in a register other than eax, you can override "result".) 5567 * 5568 * For: add-int/lit16, rsub-int, 5569 * and-int/lit16, or-int/lit16, xor-int/lit16 5570 */ 5571 /* binop/lit16 vA, vB, #+CCCC */ 5572 movzbl rINSTbl,%eax # eax<- 000000BA 5573 sarl $4,%eax # eax<- B 5574 GET_VREG_R %eax %eax # eax<- vB 5575 movswl 2(rPC),%ecx # ecx<- ssssCCCC 5576 andb $0xf,rINSTbl # rINST<- A 5577 orl %ecx,%eax # for example: addl %ecx, %eax 5578 SET_VREG %eax rINST 5579 FETCH_INST_OPCODE 2 %edx 5580 ADVANCE_PC 2 5581 GOTO_NEXT_R %edx 5582 5583 5584/* ------------------------------ */ 5585 .balign 64 5586.L_OP_XOR_INT_LIT16: /* 0xd7 */ 5587/* File: x86/OP_XOR_INT_LIT16.S */ 5588/* File: x86/binopLit16.S */ 5589 /* 5590 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 5591 * that specifies an instruction that performs "result = eax op ecx". 5592 * This could be an x86 instruction or a function call. (If the result 5593 * comes back in a register other than eax, you can override "result".) 5594 * 5595 * For: add-int/lit16, rsub-int, 5596 * and-int/lit16, or-int/lit16, xor-int/lit16 5597 */ 5598 /* binop/lit16 vA, vB, #+CCCC */ 5599 movzbl rINSTbl,%eax # eax<- 000000BA 5600 sarl $4,%eax # eax<- B 5601 GET_VREG_R %eax %eax # eax<- vB 5602 movswl 2(rPC),%ecx # ecx<- ssssCCCC 5603 andb $0xf,rINSTbl # rINST<- A 5604 xor %ecx,%eax # for example: addl %ecx, %eax 5605 SET_VREG %eax rINST 5606 FETCH_INST_OPCODE 2 %edx 5607 ADVANCE_PC 2 5608 GOTO_NEXT_R %edx 5609 5610 5611/* ------------------------------ */ 5612 .balign 64 5613.L_OP_ADD_INT_LIT8: /* 0xd8 */ 5614/* File: x86/OP_ADD_INT_LIT8.S */ 5615/* File: x86/binopLit8.S */ 5616 /* 5617 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 5618 * that specifies an instruction that performs "result = eax op ecx". 5619 * This could be an x86 instruction or a function call. (If the result 5620 * comes back in a register other than r0, you can override "result".) 5621 * 5622 * For: add-int/lit8, rsub-int/lit8 5623 * and-int/lit8, or-int/lit8, xor-int/lit8, 5624 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 5625 */ 5626 /* binop/lit8 vAA, vBB, #+CC */ 5627 movzbl 2(rPC),%eax # eax<- BB 5628 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5629 GET_VREG_R %eax %eax # eax<- rBB 5630 addl %ecx,%eax # ex: addl %ecx,%eax 5631 FETCH_INST_OPCODE 2 %edx 5632 SET_VREG %eax rINST 5633 ADVANCE_PC 2 5634 GOTO_NEXT_R %edx 5635 5636 5637/* ------------------------------ */ 5638 .balign 64 5639.L_OP_RSUB_INT_LIT8: /* 0xd9 */ 5640/* File: x86/OP_RSUB_INT_LIT8.S */ 5641/* File: x86/binopLit8.S */ 5642 /* 5643 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 5644 * that specifies an instruction that performs "result = eax op ecx". 5645 * This could be an x86 instruction or a function call. (If the result 5646 * comes back in a register other than r0, you can override "result".) 5647 * 5648 * For: add-int/lit8, rsub-int/lit8 5649 * and-int/lit8, or-int/lit8, xor-int/lit8, 5650 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 5651 */ 5652 /* binop/lit8 vAA, vBB, #+CC */ 5653 movzbl 2(rPC),%eax # eax<- BB 5654 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5655 GET_VREG_R %eax %eax # eax<- rBB 5656 subl %eax,%ecx # ex: addl %ecx,%eax 5657 FETCH_INST_OPCODE 2 %edx 5658 SET_VREG %ecx rINST 5659 ADVANCE_PC 2 5660 GOTO_NEXT_R %edx 5661 5662 5663/* ------------------------------ */ 5664 .balign 64 5665.L_OP_MUL_INT_LIT8: /* 0xda */ 5666/* File: x86/OP_MUL_INT_LIT8.S */ 5667 /* mul/lit8 vAA, vBB, #+CC */ 5668 movzbl 2(rPC),%eax # eax<- BB 5669 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5670 GET_VREG_R %eax %eax # eax<- rBB 5671 imull %ecx,%eax # trashes edx 5672 FETCH_INST_OPCODE 2 %edx 5673 ADVANCE_PC 2 5674 SET_VREG %eax rINST 5675 GOTO_NEXT_R %edx 5676 5677/* ------------------------------ */ 5678 .balign 64 5679.L_OP_DIV_INT_LIT8: /* 0xdb */ 5680/* File: x86/OP_DIV_INT_LIT8.S */ 5681/* File: x86/bindivLit8.S */ 5682 /* 5683 * 32-bit div/rem "lit8" binary operation. Handles special case of 5684 * op0=minint & op1=-1 5685 */ 5686 /* div/rem/lit8 vAA, vBB, #+CC */ 5687 movzbl 2(rPC),%eax # eax<- BB 5688 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5689 GET_VREG_R %eax %eax # eax<- rBB 5690 cmpl $0,%ecx 5691 je common_errDivideByZero 5692 cmpl $0x80000000,%eax 5693 jne .LOP_DIV_INT_LIT8_continue_div 5694 cmpl $-1,%ecx 5695 jne .LOP_DIV_INT_LIT8_continue_div 5696 movl $0x80000000,%eax 5697 jmp .LOP_DIV_INT_LIT8_finish_div 5698 5699 5700 5701/* ------------------------------ */ 5702 .balign 64 5703.L_OP_REM_INT_LIT8: /* 0xdc */ 5704/* File: x86/OP_REM_INT_LIT8.S */ 5705/* File: x86/bindivLit8.S */ 5706 /* 5707 * 32-bit div/rem "lit8" binary operation. Handles special case of 5708 * op0=minint & op1=-1 5709 */ 5710 /* div/rem/lit8 vAA, vBB, #+CC */ 5711 movzbl 2(rPC),%eax # eax<- BB 5712 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5713 GET_VREG_R %eax %eax # eax<- rBB 5714 cmpl $0,%ecx 5715 je common_errDivideByZero 5716 cmpl $0x80000000,%eax 5717 jne .LOP_REM_INT_LIT8_continue_div 5718 cmpl $-1,%ecx 5719 jne .LOP_REM_INT_LIT8_continue_div 5720 movl $0,%edx 5721 jmp .LOP_REM_INT_LIT8_finish_div 5722 5723 5724 5725/* ------------------------------ */ 5726 .balign 64 5727.L_OP_AND_INT_LIT8: /* 0xdd */ 5728/* File: x86/OP_AND_INT_LIT8.S */ 5729/* File: x86/binopLit8.S */ 5730 /* 5731 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 5732 * that specifies an instruction that performs "result = eax op ecx". 5733 * This could be an x86 instruction or a function call. (If the result 5734 * comes back in a register other than r0, you can override "result".) 5735 * 5736 * For: add-int/lit8, rsub-int/lit8 5737 * and-int/lit8, or-int/lit8, xor-int/lit8, 5738 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 5739 */ 5740 /* binop/lit8 vAA, vBB, #+CC */ 5741 movzbl 2(rPC),%eax # eax<- BB 5742 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5743 GET_VREG_R %eax %eax # eax<- rBB 5744 andl %ecx,%eax # ex: addl %ecx,%eax 5745 FETCH_INST_OPCODE 2 %edx 5746 SET_VREG %eax rINST 5747 ADVANCE_PC 2 5748 GOTO_NEXT_R %edx 5749 5750 5751/* ------------------------------ */ 5752 .balign 64 5753.L_OP_OR_INT_LIT8: /* 0xde */ 5754/* File: x86/OP_OR_INT_LIT8.S */ 5755/* File: x86/binopLit8.S */ 5756 /* 5757 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 5758 * that specifies an instruction that performs "result = eax op ecx". 5759 * This could be an x86 instruction or a function call. (If the result 5760 * comes back in a register other than r0, you can override "result".) 5761 * 5762 * For: add-int/lit8, rsub-int/lit8 5763 * and-int/lit8, or-int/lit8, xor-int/lit8, 5764 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 5765 */ 5766 /* binop/lit8 vAA, vBB, #+CC */ 5767 movzbl 2(rPC),%eax # eax<- BB 5768 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5769 GET_VREG_R %eax %eax # eax<- rBB 5770 orl %ecx,%eax # ex: addl %ecx,%eax 5771 FETCH_INST_OPCODE 2 %edx 5772 SET_VREG %eax rINST 5773 ADVANCE_PC 2 5774 GOTO_NEXT_R %edx 5775 5776 5777/* ------------------------------ */ 5778 .balign 64 5779.L_OP_XOR_INT_LIT8: /* 0xdf */ 5780/* File: x86/OP_XOR_INT_LIT8.S */ 5781/* File: x86/binopLit8.S */ 5782 /* 5783 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 5784 * that specifies an instruction that performs "result = eax op ecx". 5785 * This could be an x86 instruction or a function call. (If the result 5786 * comes back in a register other than r0, you can override "result".) 5787 * 5788 * For: add-int/lit8, rsub-int/lit8 5789 * and-int/lit8, or-int/lit8, xor-int/lit8, 5790 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 5791 */ 5792 /* binop/lit8 vAA, vBB, #+CC */ 5793 movzbl 2(rPC),%eax # eax<- BB 5794 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5795 GET_VREG_R %eax %eax # eax<- rBB 5796 xor %ecx,%eax # ex: addl %ecx,%eax 5797 FETCH_INST_OPCODE 2 %edx 5798 SET_VREG %eax rINST 5799 ADVANCE_PC 2 5800 GOTO_NEXT_R %edx 5801 5802 5803/* ------------------------------ */ 5804 .balign 64 5805.L_OP_SHL_INT_LIT8: /* 0xe0 */ 5806/* File: x86/OP_SHL_INT_LIT8.S */ 5807/* File: x86/binopLit8.S */ 5808 /* 5809 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 5810 * that specifies an instruction that performs "result = eax op ecx". 5811 * This could be an x86 instruction or a function call. (If the result 5812 * comes back in a register other than r0, you can override "result".) 5813 * 5814 * For: add-int/lit8, rsub-int/lit8 5815 * and-int/lit8, or-int/lit8, xor-int/lit8, 5816 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 5817 */ 5818 /* binop/lit8 vAA, vBB, #+CC */ 5819 movzbl 2(rPC),%eax # eax<- BB 5820 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5821 GET_VREG_R %eax %eax # eax<- rBB 5822 sall %cl,%eax # ex: addl %ecx,%eax 5823 FETCH_INST_OPCODE 2 %edx 5824 SET_VREG %eax rINST 5825 ADVANCE_PC 2 5826 GOTO_NEXT_R %edx 5827 5828 5829/* ------------------------------ */ 5830 .balign 64 5831.L_OP_SHR_INT_LIT8: /* 0xe1 */ 5832/* File: x86/OP_SHR_INT_LIT8.S */ 5833/* File: x86/binopLit8.S */ 5834 /* 5835 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 5836 * that specifies an instruction that performs "result = eax op ecx". 5837 * This could be an x86 instruction or a function call. (If the result 5838 * comes back in a register other than r0, you can override "result".) 5839 * 5840 * For: add-int/lit8, rsub-int/lit8 5841 * and-int/lit8, or-int/lit8, xor-int/lit8, 5842 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 5843 */ 5844 /* binop/lit8 vAA, vBB, #+CC */ 5845 movzbl 2(rPC),%eax # eax<- BB 5846 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5847 GET_VREG_R %eax %eax # eax<- rBB 5848 sarl %cl,%eax # ex: addl %ecx,%eax 5849 FETCH_INST_OPCODE 2 %edx 5850 SET_VREG %eax rINST 5851 ADVANCE_PC 2 5852 GOTO_NEXT_R %edx 5853 5854 5855/* ------------------------------ */ 5856 .balign 64 5857.L_OP_USHR_INT_LIT8: /* 0xe2 */ 5858/* File: x86/OP_USHR_INT_LIT8.S */ 5859/* File: x86/binopLit8.S */ 5860 /* 5861 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 5862 * that specifies an instruction that performs "result = eax op ecx". 5863 * This could be an x86 instruction or a function call. (If the result 5864 * comes back in a register other than r0, you can override "result".) 5865 * 5866 * For: add-int/lit8, rsub-int/lit8 5867 * and-int/lit8, or-int/lit8, xor-int/lit8, 5868 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 5869 */ 5870 /* binop/lit8 vAA, vBB, #+CC */ 5871 movzbl 2(rPC),%eax # eax<- BB 5872 movsbl 3(rPC),%ecx # ecx<- ssssssCC 5873 GET_VREG_R %eax %eax # eax<- rBB 5874 shrl %cl,%eax # ex: addl %ecx,%eax 5875 FETCH_INST_OPCODE 2 %edx 5876 SET_VREG %eax rINST 5877 ADVANCE_PC 2 5878 GOTO_NEXT_R %edx 5879 5880 5881/* ------------------------------ */ 5882 .balign 64 5883.L_OP_IGET_VOLATILE: /* 0xe3 */ 5884/* File: x86/OP_IGET_VOLATILE.S */ 5885/* File: x86/OP_IGET.S */ 5886 /* 5887 * General 32-bit instance field get. 5888 * 5889 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 5890 */ 5891 /* op vA, vB, field@CCCC */ 5892 movl rGLUE,%ecx 5893 movzwl 2(rPC),%edx # edx<- 0000CCCC 5894 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 5895 movzbl rINSTbl,%ecx # ecx<- BA 5896 sarl $4,%ecx # ecx<- B 5897 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 5898 andb $0xf,rINSTbl # rINST<- A 5899 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 5900 movl (%eax,%edx,4),%eax # resolved entry 5901 testl %eax,%eax # is resolved entry null? 5902 jne .LOP_IGET_VOLATILE_finish # no, already resolved 5903 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 5904 movl rGLUE,%edx 5905 jmp .LOP_IGET_VOLATILE_resolve 5906 5907 5908/* ------------------------------ */ 5909 .balign 64 5910.L_OP_IPUT_VOLATILE: /* 0xe4 */ 5911/* File: x86/OP_IPUT_VOLATILE.S */ 5912/* File: x86/OP_IPUT.S */ 5913 5914 /* 5915 * General 32-bit instance field put. 5916 * 5917 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 5918 */ 5919 /* op vA, vB, field@CCCC */ 5920 movl rGLUE,%ecx 5921 movzwl 2(rPC),%edx # %edx<- 0000CCCC 5922 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 5923 movzbl rINSTbl,%ecx # ecx<- BA 5924 sarl $4,%ecx # ecx<- B 5925 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 5926 andb $0xf,rINSTbl # rINST<- A 5927 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 5928 movl (%eax,%edx,4),%eax # resolved entry 5929 testl %eax,%eax # is resolved entry null? 5930 jne .LOP_IPUT_VOLATILE_finish # no, already resolved 5931 movl %edx,OUT_ARG1(%esp) 5932 movl rGLUE,%edx 5933 jmp .LOP_IPUT_VOLATILE_resolve 5934 5935 5936/* ------------------------------ */ 5937 .balign 64 5938.L_OP_SGET_VOLATILE: /* 0xe5 */ 5939/* File: x86/OP_SGET_VOLATILE.S */ 5940/* File: x86/OP_SGET.S */ 5941 /* 5942 * General 32-bit SGET handler. 5943 * 5944 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 5945 */ 5946 /* op vAA, field@BBBB */ 5947 movl rGLUE,%ecx 5948 movzwl 2(rPC),%eax # eax<- field ref BBBB 5949 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 5950 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 5951 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 5952 testl %eax,%eax # resolved entry null? 5953 je .LOP_SGET_VOLATILE_resolve # if not, make it so 5954.LOP_SGET_VOLATILE_finish: # field ptr in eax 5955 movl offStaticField_value(%eax),%eax 5956 FETCH_INST_OPCODE 2 %edx 5957 ADVANCE_PC 2 5958 SET_VREG %eax rINST 5959 GOTO_NEXT_R %edx 5960 5961 5962/* ------------------------------ */ 5963 .balign 64 5964.L_OP_SPUT_VOLATILE: /* 0xe6 */ 5965/* File: x86/OP_SPUT_VOLATILE.S */ 5966/* File: x86/OP_SPUT.S */ 5967 /* 5968 * General 32-bit SPUT handler. 5969 * 5970 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 5971 */ 5972 /* op vAA, field@BBBB */ 5973 movl rGLUE,%ecx 5974 movzwl 2(rPC),%eax # eax<- field ref BBBB 5975 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 5976 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 5977 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 5978 testl %eax,%eax # resolved entry null? 5979 je .LOP_SPUT_VOLATILE_resolve # if not, make it so 5980.LOP_SPUT_VOLATILE_finish: # field ptr in eax 5981 GET_VREG_R %ecx rINST 5982 FETCH_INST_OPCODE 2 %edx 5983 ADVANCE_PC 2 5984 movl %ecx,offStaticField_value(%eax) 5985 GOTO_NEXT_R %edx 5986 5987 5988/* ------------------------------ */ 5989 .balign 64 5990.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */ 5991/* File: x86/OP_IGET_OBJECT_VOLATILE.S */ 5992/* File: x86/OP_IGET.S */ 5993 /* 5994 * General 32-bit instance field get. 5995 * 5996 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 5997 */ 5998 /* op vA, vB, field@CCCC */ 5999 movl rGLUE,%ecx 6000 movzwl 2(rPC),%edx # edx<- 0000CCCC 6001 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 6002 movzbl rINSTbl,%ecx # ecx<- BA 6003 sarl $4,%ecx # ecx<- B 6004 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6005 andb $0xf,rINSTbl # rINST<- A 6006 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 6007 movl (%eax,%edx,4),%eax # resolved entry 6008 testl %eax,%eax # is resolved entry null? 6009 jne .LOP_IGET_OBJECT_VOLATILE_finish # no, already resolved 6010 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 6011 movl rGLUE,%edx 6012 jmp .LOP_IGET_OBJECT_VOLATILE_resolve 6013 6014 6015/* ------------------------------ */ 6016 .balign 64 6017.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */ 6018 /* (stub) */ 6019 SAVE_PC_FP_TO_GLUE %ecx # leaves rGLUE in %ecx 6020 movl %ecx,OUT_ARG0(%esp) # glue is first arg to function 6021 call dvmMterp_OP_IGET_WIDE_VOLATILE # do the real work 6022 mov rGLUE,%ecx 6023 LOAD_PC_FP_FROM_GLUE # retrieve updated values 6024 FETCH_INST 6025 GOTO_NEXT 6026/* ------------------------------ */ 6027 .balign 64 6028.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */ 6029 /* (stub) */ 6030 SAVE_PC_FP_TO_GLUE %ecx # leaves rGLUE in %ecx 6031 movl %ecx,OUT_ARG0(%esp) # glue is first arg to function 6032 call dvmMterp_OP_IPUT_WIDE_VOLATILE # do the real work 6033 mov rGLUE,%ecx 6034 LOAD_PC_FP_FROM_GLUE # retrieve updated values 6035 FETCH_INST 6036 GOTO_NEXT 6037/* ------------------------------ */ 6038 .balign 64 6039.L_OP_SGET_WIDE_VOLATILE: /* 0xea */ 6040 /* (stub) */ 6041 SAVE_PC_FP_TO_GLUE %ecx # leaves rGLUE in %ecx 6042 movl %ecx,OUT_ARG0(%esp) # glue is first arg to function 6043 call dvmMterp_OP_SGET_WIDE_VOLATILE # do the real work 6044 mov rGLUE,%ecx 6045 LOAD_PC_FP_FROM_GLUE # retrieve updated values 6046 FETCH_INST 6047 GOTO_NEXT 6048/* ------------------------------ */ 6049 .balign 64 6050.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */ 6051 /* (stub) */ 6052 SAVE_PC_FP_TO_GLUE %ecx # leaves rGLUE in %ecx 6053 movl %ecx,OUT_ARG0(%esp) # glue is first arg to function 6054 call dvmMterp_OP_SPUT_WIDE_VOLATILE # do the real work 6055 mov rGLUE,%ecx 6056 LOAD_PC_FP_FROM_GLUE # retrieve updated values 6057 FETCH_INST 6058 GOTO_NEXT 6059/* ------------------------------ */ 6060 .balign 64 6061.L_OP_BREAKPOINT: /* 0xec */ 6062/* File: x86/OP_BREAKPOINT.S */ 6063/* File: x86/unused.S */ 6064 jmp common_abort 6065 6066 6067/* ------------------------------ */ 6068 .balign 64 6069.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */ 6070/* File: x86/OP_THROW_VERIFICATION_ERROR.S */ 6071 /* 6072 * Handle a throw-verification-error instruction. This throws an 6073 * exception for an error discovered during verification. The 6074 * exception is indicated by AA, with some detail provided by BBBB. 6075 */ 6076 /* op AA, ref@BBBB */ 6077 movl rGLUE,%ecx 6078 movzwl 2(rPC),%eax # eax<- BBBB 6079 movl offGlue_method(%ecx),%ecx # ecx<- glue->method 6080 EXPORT_PC 6081 movl %eax,OUT_ARG2(%esp) # arg2<- BBBB 6082 movl rINST,OUT_ARG1(%esp) # arg1<- AA 6083 movl %ecx,OUT_ARG0(%esp) # arg0<- method 6084 call dvmThrowVerificationError # call(method, kind, ref) 6085 jmp common_exceptionThrown # handle exception 6086 6087/* ------------------------------ */ 6088 .balign 64 6089.L_OP_EXECUTE_INLINE: /* 0xee */ 6090/* File: x86/OP_EXECUTE_INLINE.S */ 6091 /* 6092 * Execute a "native inline" instruction. 6093 * 6094 * We will be calling through a function table: 6095 * 6096 * (*gDvmInlineOpsTable[opIndex].func)(arg0, arg1, arg2, arg3, pResult) 6097 * 6098 * Ignores argument count - always loads 4. 6099 * 6100 */ 6101 /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */ 6102 movl rGLUE,%ecx 6103 EXPORT_PC 6104 movzwl 2(rPC),%eax # eax<- BBBB 6105 leal offGlue_retval(%ecx),%ecx # ecx<- & glue->retval 6106 movl %ecx,OUT_ARG4(%esp) 6107 call .LOP_EXECUTE_INLINE_continue # make call; will return after 6108 testl %eax,%eax # successful? 6109 FETCH_INST_OPCODE 3 %edx 6110 je common_exceptionThrown # no, handle exception 6111 ADVANCE_PC 3 6112 GOTO_NEXT_R %edx 6113 6114/* ------------------------------ */ 6115 .balign 64 6116.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */ 6117 /* (stub) */ 6118 SAVE_PC_FP_TO_GLUE %ecx # leaves rGLUE in %ecx 6119 movl %ecx,OUT_ARG0(%esp) # glue is first arg to function 6120 call dvmMterp_OP_EXECUTE_INLINE_RANGE # do the real work 6121 mov rGLUE,%ecx 6122 LOAD_PC_FP_FROM_GLUE # retrieve updated values 6123 FETCH_INST 6124 GOTO_NEXT 6125/* ------------------------------ */ 6126 .balign 64 6127.L_OP_INVOKE_OBJECT_INIT: /* 0xf0 */ 6128/* File: x86/OP_INVOKE_OBJECT_INIT.S */ 6129 /* 6130 * invoke-object-init is a no-op in a "standard" interpreter. 6131 */ 6132 FETCH_INST_WORD 3 6133 ADVANCE_PC 3 6134 GOTO_NEXT 6135 6136/* ------------------------------ */ 6137 .balign 64 6138.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */ 6139 /* (stub) */ 6140 SAVE_PC_FP_TO_GLUE %ecx # leaves rGLUE in %ecx 6141 movl %ecx,OUT_ARG0(%esp) # glue is first arg to function 6142 call dvmMterp_OP_RETURN_VOID_BARRIER # do the real work 6143 mov rGLUE,%ecx 6144 LOAD_PC_FP_FROM_GLUE # retrieve updated values 6145 FETCH_INST 6146 GOTO_NEXT 6147/* ------------------------------ */ 6148 .balign 64 6149.L_OP_IGET_QUICK: /* 0xf2 */ 6150/* File: x86/OP_IGET_QUICK.S */ 6151 /* For: iget-quick, iget-object-quick */ 6152 /* op vA, vB, offset@CCCC */ 6153 movzbl rINSTbl,%ecx # ecx<- BA 6154 sarl $4,%ecx # ecx<- B 6155 GET_VREG_R %ecx %ecx # vB (object we're operating on) 6156 movzwl 2(rPC),%eax # eax<- field byte offset 6157 cmpl $0,%ecx # is object null? 6158 je common_errNullObject 6159 movl (%ecx,%eax,1),%eax 6160 FETCH_INST_OPCODE 2 %edx 6161 ADVANCE_PC 2 6162 andb $0xf,rINSTbl # rINST<- A 6163 SET_VREG %eax rINST # fp[A]<- result 6164 GOTO_NEXT_R %edx 6165 6166/* ------------------------------ */ 6167 .balign 64 6168.L_OP_IGET_WIDE_QUICK: /* 0xf3 */ 6169/* File: x86/OP_IGET_WIDE_QUICK.S */ 6170 /* For: iget-wide-quick */ 6171 /* op vA, vB, offset@CCCC */ 6172 movzbl rINSTbl,%ecx # ecx<- BA 6173 sarl $4,%ecx # ecx<- B 6174 GET_VREG_R %ecx %ecx # vB (object we're operating on) 6175 movzwl 2(rPC),%eax # eax<- field byte offset 6176 cmpl $0,%ecx # is object null? 6177 je common_errNullObject 6178 leal (%ecx,%eax,1),%eax # eax<- address of 64-bit source 6179 movl (%eax),%ecx # ecx<- lsw 6180 movl 4(%eax),%eax # eax<- msw 6181 andb $0xf,rINSTbl # rINST<- A 6182 FETCH_INST_OPCODE 2 %edx 6183 SET_VREG_WORD %ecx rINST 0 # v[A+0]<- lsw 6184 SET_VREG_WORD %eax rINST 1 # v[A+1]<- msw 6185 ADVANCE_PC 2 6186 GOTO_NEXT_R %edx 6187 6188/* ------------------------------ */ 6189 .balign 64 6190.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */ 6191/* File: x86/OP_IGET_OBJECT_QUICK.S */ 6192/* File: x86/OP_IGET_QUICK.S */ 6193 /* For: iget-quick, iget-object-quick */ 6194 /* op vA, vB, offset@CCCC */ 6195 movzbl rINSTbl,%ecx # ecx<- BA 6196 sarl $4,%ecx # ecx<- B 6197 GET_VREG_R %ecx %ecx # vB (object we're operating on) 6198 movzwl 2(rPC),%eax # eax<- field byte offset 6199 cmpl $0,%ecx # is object null? 6200 je common_errNullObject 6201 movl (%ecx,%eax,1),%eax 6202 FETCH_INST_OPCODE 2 %edx 6203 ADVANCE_PC 2 6204 andb $0xf,rINSTbl # rINST<- A 6205 SET_VREG %eax rINST # fp[A]<- result 6206 GOTO_NEXT_R %edx 6207 6208 6209/* ------------------------------ */ 6210 .balign 64 6211.L_OP_IPUT_QUICK: /* 0xf5 */ 6212/* File: x86/OP_IPUT_QUICK.S */ 6213 /* For: iput-quick */ 6214 /* op vA, vB, offset@CCCC */ 6215 movzbl rINSTbl,%ecx # ecx<- BA 6216 sarl $4,%ecx # ecx<- B 6217 GET_VREG_R %ecx %ecx # vB (object we're operating on) 6218 andb $0xf,rINSTbl # rINST<- A 6219 GET_VREG_R rINST,rINST # rINST<- v[A] 6220 movzwl 2(rPC),%eax # eax<- field byte offset 6221 testl %ecx,%ecx # is object null? 6222 FETCH_INST_OPCODE 2 %edx 6223 je common_errNullObject 6224 movl rINST,(%ecx,%eax,1) 6225 ADVANCE_PC 2 6226 GOTO_NEXT_R %edx 6227 6228/* ------------------------------ */ 6229 .balign 64 6230.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */ 6231/* File: x86/OP_IPUT_WIDE_QUICK.S */ 6232 /* For: iput-wide-quick */ 6233 /* op vA, vB, offset@CCCC */ 6234 movzbl rINSTbl,%ecx # ecx<- BA 6235 sarl $4,%ecx # ecx<- B 6236 GET_VREG_R %ecx %ecx # vB (object we're operating on) 6237 movzwl 2(rPC),%eax # eax<- field byte offset 6238 testl %ecx,%ecx # is object null? 6239 je common_errNullObject 6240 leal (%ecx,%eax,1),%ecx # ecx<- Address of 64-bit target 6241 andb $0xf,rINSTbl # rINST<- A 6242 GET_VREG_WORD %eax rINST 0 # eax<- lsw 6243 GET_VREG_WORD rINST rINST 1 # rINST<- msw 6244 FETCH_INST_OPCODE 2 %edx 6245 movl %eax,(%ecx) 6246 movl rINST,4(%ecx) 6247 ADVANCE_PC 2 6248 GOTO_NEXT_R %edx 6249 6250/* ------------------------------ */ 6251 .balign 64 6252.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */ 6253/* File: x86/OP_IPUT_OBJECT_QUICK.S */ 6254 /* For: iput-object-quick */ 6255 /* op vA, vB, offset@CCCC */ 6256 movzbl rINSTbl,%ecx # ecx<- BA 6257 sarl $4,%ecx # ecx<- B 6258 GET_VREG_R %ecx %ecx # vB (object we're operating on) 6259 andb $0xf,rINSTbl # rINST<- A 6260 GET_VREG_R rINST rINST # rINST<- v[A] 6261 movzwl 2(rPC),%eax # eax<- field byte offset 6262 testl %ecx,%ecx # is object null? 6263 je common_errNullObject 6264 movl rINST,(%ecx,%eax,1) 6265 movl rGLUE,%eax 6266 jmp .LOP_IPUT_OBJECT_QUICK_finish 6267 6268/* ------------------------------ */ 6269 .balign 64 6270.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */ 6271/* File: x86/OP_INVOKE_VIRTUAL_QUICK.S */ 6272 /* 6273 * Handle an optimized virtual method call. 6274 * 6275 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 6276 */ 6277 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 6278 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 6279 movzwl 4(rPC),%eax # eax<- FEDC or CCCC 6280 movzwl 2(rPC),%ecx # ecx<- BBBB 6281 .if (!0) 6282 andl $0xf,%eax # eax<- C (or stays CCCC) 6283 .endif 6284 GET_VREG_R %eax %eax # eax<- vC ("this" ptr) 6285 testl %eax,%eax # null? 6286 je common_errNullObject # yep, throw exception 6287 movl offObject_clazz(%eax),%eax # eax<- thisPtr->clazz 6288 movl offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable 6289 EXPORT_PC # might throw later - get ready 6290 movl (%eax,%ecx,4),%eax # eax<- vtable[BBBB] 6291 jmp common_invokeMethodNoRange 6292 6293/* ------------------------------ */ 6294 .balign 64 6295.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */ 6296/* File: x86/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */ 6297/* File: x86/OP_INVOKE_VIRTUAL_QUICK.S */ 6298 /* 6299 * Handle an optimized virtual method call. 6300 * 6301 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 6302 */ 6303 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 6304 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 6305 movzwl 4(rPC),%eax # eax<- FEDC or CCCC 6306 movzwl 2(rPC),%ecx # ecx<- BBBB 6307 .if (!1) 6308 andl $0xf,%eax # eax<- C (or stays CCCC) 6309 .endif 6310 GET_VREG_R %eax %eax # eax<- vC ("this" ptr) 6311 testl %eax,%eax # null? 6312 je common_errNullObject # yep, throw exception 6313 movl offObject_clazz(%eax),%eax # eax<- thisPtr->clazz 6314 movl offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable 6315 EXPORT_PC # might throw later - get ready 6316 movl (%eax,%ecx,4),%eax # eax<- vtable[BBBB] 6317 jmp common_invokeMethodRange 6318 6319 6320/* ------------------------------ */ 6321 .balign 64 6322.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */ 6323/* File: x86/OP_INVOKE_SUPER_QUICK.S */ 6324 /* 6325 * Handle an optimized "super" method call. 6326 * 6327 * for: [opt] invoke-super-quick, invoke-super-quick/range 6328 */ 6329 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 6330 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 6331 movl rGLUE,%ecx 6332 movzwl 4(rPC),%eax # eax<- GFED or CCCC 6333 movl offGlue_method(%ecx),%ecx # ecx<- current method 6334 .if (!0) 6335 andl $0xf,%eax # eax<- D (or stays CCCC) 6336 .endif 6337 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 6338 GET_VREG_R %eax %eax # eax<- "this" 6339 movl offClassObject_super(%ecx),%ecx # ecx<- method->clazz->super 6340 testl %eax,%eax # null "this"? 6341 je common_errNullObject # "this" is null, throw exception 6342 movzwl 2(rPC),%eax # eax<- BBBB 6343 movl offClassObject_vtable(%ecx),%ecx # ecx<- vtable 6344 EXPORT_PC 6345 movl (%ecx,%eax,4),%eax # eax<- super->vtable[BBBB] 6346 jmp common_invokeMethodNoRange 6347 6348/* ------------------------------ */ 6349 .balign 64 6350.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */ 6351/* File: x86/OP_INVOKE_SUPER_QUICK_RANGE.S */ 6352/* File: x86/OP_INVOKE_SUPER_QUICK.S */ 6353 /* 6354 * Handle an optimized "super" method call. 6355 * 6356 * for: [opt] invoke-super-quick, invoke-super-quick/range 6357 */ 6358 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 6359 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 6360 movl rGLUE,%ecx 6361 movzwl 4(rPC),%eax # eax<- GFED or CCCC 6362 movl offGlue_method(%ecx),%ecx # ecx<- current method 6363 .if (!1) 6364 andl $0xf,%eax # eax<- D (or stays CCCC) 6365 .endif 6366 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 6367 GET_VREG_R %eax %eax # eax<- "this" 6368 movl offClassObject_super(%ecx),%ecx # ecx<- method->clazz->super 6369 testl %eax,%eax # null "this"? 6370 je common_errNullObject # "this" is null, throw exception 6371 movzwl 2(rPC),%eax # eax<- BBBB 6372 movl offClassObject_vtable(%ecx),%ecx # ecx<- vtable 6373 EXPORT_PC 6374 movl (%ecx,%eax,4),%eax # eax<- super->vtable[BBBB] 6375 jmp common_invokeMethodRange 6376 6377 6378/* ------------------------------ */ 6379 .balign 64 6380.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */ 6381/* File: x86/OP_IPUT_OBJECT_VOLATILE.S */ 6382/* File: x86/OP_IPUT_OBJECT.S */ 6383 /* 6384 * Object field put. 6385 * 6386 * for: iput-object 6387 */ 6388 /* op vA, vB, field@CCCC */ 6389 movl rGLUE,%ecx 6390 movzwl 2(rPC),%edx # edx<- 0000CCCC 6391 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 6392 movzbl rINSTbl,%ecx # ecx<- BA 6393 sarl $4,%ecx # ecx<- B 6394 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6395 andb $0xf,rINSTbl # rINST<- A 6396 GET_VREG_R %ecx %ecx # ecx<- fp[B], the object ptr 6397 movl (%eax,%edx,4),%eax # resolved entry 6398 testl %eax,%eax # is resolved entry null? 6399 jne .LOP_IPUT_OBJECT_VOLATILE_finish # no, already resolved 6400 movl %edx,OUT_ARG1(%esp) 6401 movl rGLUE,%edx 6402 jmp .LOP_IPUT_OBJECT_VOLATILE_resolve 6403 6404 6405/* ------------------------------ */ 6406 .balign 64 6407.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */ 6408/* File: x86/OP_SGET_OBJECT_VOLATILE.S */ 6409/* File: x86/OP_SGET.S */ 6410 /* 6411 * General 32-bit SGET handler. 6412 * 6413 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 6414 */ 6415 /* op vAA, field@BBBB */ 6416 movl rGLUE,%ecx 6417 movzwl 2(rPC),%eax # eax<- field ref BBBB 6418 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 6419 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 6420 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 6421 testl %eax,%eax # resolved entry null? 6422 je .LOP_SGET_OBJECT_VOLATILE_resolve # if not, make it so 6423.LOP_SGET_OBJECT_VOLATILE_finish: # field ptr in eax 6424 movl offStaticField_value(%eax),%eax 6425 FETCH_INST_OPCODE 2 %edx 6426 ADVANCE_PC 2 6427 SET_VREG %eax rINST 6428 GOTO_NEXT_R %edx 6429 6430 6431/* ------------------------------ */ 6432 .balign 64 6433.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */ 6434/* File: x86/OP_SPUT_OBJECT_VOLATILE.S */ 6435/* File: x86/OP_SPUT_OBJECT.S */ 6436 /* 6437 * SPUT object handler. 6438 */ 6439 /* op vAA, field@BBBB */ 6440 movl rGLUE,%ecx 6441 movzwl 2(rPC),%eax # eax<- field ref BBBB 6442 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 6443 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 6444 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField 6445 testl %eax,%eax # resolved entry null? 6446 je .LOP_SPUT_OBJECT_VOLATILE_resolve # if not, make it so 6447.LOP_SPUT_OBJECT_VOLATILE_finish: # field ptr in eax 6448 movzbl rINSTbl,%ecx # ecx<- AA 6449 GET_VREG_R %ecx %ecx 6450 jmp .LOP_SPUT_OBJECT_VOLATILE_continue 6451 6452 6453/* ------------------------------ */ 6454 .balign 64 6455.L_OP_DISPATCH_FF: /* 0xff */ 6456/* File: x86/OP_DISPATCH_FF.S */ 6457 leal 256(rINST),%edx 6458 GOTO_NEXT_JUMBO_R %edx 6459 6460/* ------------------------------ */ 6461 .balign 64 6462.L_OP_CONST_CLASS_JUMBO: /* 0x100 */ 6463/* File: x86/OP_CONST_CLASS_JUMBO.S */ 6464 /* const-class/jumbo vBBBB, Class@AAAAAAAA */ 6465 movl rGLUE,%ecx 6466 movl 2(rPC),%eax # eax<- AAAAAAAA 6467 movl offGlue_methodClassDex(%ecx),%ecx# ecx<- glue->methodClassDex 6468 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- dvmDex->pResClasses 6469 movl (%ecx,%eax,4),%eax # eax<- rResClasses[AAAAAAAA] 6470 FETCH_INST_OPCODE 4 %edx 6471 testl %eax,%eax # resolved yet? 6472 je .LOP_CONST_CLASS_JUMBO_resolve 6473 SET_VREG %eax rINST # vBBBB<- rResClasses[AAAAAAAA] 6474 ADVANCE_PC 4 6475 GOTO_NEXT_R %edx 6476 6477/* ------------------------------ */ 6478 .balign 64 6479.L_OP_CHECK_CAST_JUMBO: /* 0x101 */ 6480/* File: x86/OP_CHECK_CAST_JUMBO.S */ 6481 /* 6482 * Check to see if a cast from one class to another is allowed. 6483 */ 6484 /* check-cast/jumbo vBBBB, class@AAAAAAAA */ 6485 movl rGLUE,%ecx 6486 GET_VREG_R rINST,rINST # rINST<- vBBBB (object) 6487 movl 2(rPC),%eax # eax<- AAAAAAAA 6488 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 6489 testl rINST,rINST # is oject null? 6490 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 6491 je .LOP_CHECK_CAST_JUMBO_okay # null obj, cast always succeeds 6492 movl (%ecx,%eax,4),%eax # eax<- resolved class 6493 movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz 6494 testl %eax,%eax # have we resolved this before? 6495 je .LOP_CHECK_CAST_JUMBO_resolve # no, go do it now 6496.LOP_CHECK_CAST_JUMBO_resolved: 6497 cmpl %eax,%ecx # same class (trivial success)? 6498 jne .LOP_CHECK_CAST_JUMBO_fullcheck # no, do full check 6499.LOP_CHECK_CAST_JUMBO_okay: 6500 FETCH_INST_OPCODE 4 %edx 6501 ADVANCE_PC 4 6502 GOTO_NEXT_R %edx 6503 6504/* ------------------------------ */ 6505 .balign 64 6506.L_OP_INSTANCE_OF_JUMBO: /* 0x102 */ 6507/* File: x86/OP_INSTANCE_OF_JUMBO.S */ 6508 /* 6509 * Check to see if an object reference is an instance of a class. 6510 * 6511 * Most common situation is a non-null object, being compared against 6512 * an already-resolved class. 6513 */ 6514 /* instance-of/jumbo vBBBB, vCCCC, class@AAAAAAAA */ 6515 movzwl 8(rPC),%eax # eax<- CCCC 6516 GET_VREG_R %eax %eax # eax<- vCCCC (obj) 6517 movl rGLUE,%ecx 6518 testl %eax,%eax # object null? 6519 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 6520 je .LOP_INSTANCE_OF_JUMBO_store # null obj, not instance, store it 6521 movl 2(rPC),%edx # edx<- AAAAAAAA 6522 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 6523 movl (%ecx,%edx,4),%ecx # ecx<- resolved class 6524 movl offObject_clazz(%eax),%eax # eax<- obj->clazz 6525 testl %ecx,%ecx # have we resolved this before? 6526 je .LOP_INSTANCE_OF_JUMBO_resolve # not resolved, do it now 6527.LOP_INSTANCE_OF_JUMBO_resolved: # eax<- obj->clazz, ecx<- resolved class 6528 cmpl %eax,%ecx # same class (trivial success)? 6529 je .LOP_INSTANCE_OF_JUMBO_trivial # yes, trivial finish 6530 jmp .LOP_INSTANCE_OF_JUMBO_fullcheck # no, do full check 6531 6532/* ------------------------------ */ 6533 .balign 64 6534.L_OP_NEW_INSTANCE_JUMBO: /* 0x103 */ 6535/* File: x86/OP_NEW_INSTANCE_JUMBO.S */ 6536 /* 6537 * Create a new instance of a class. 6538 */ 6539 /* new-instance/jumbo vBBBB, class@AAAAAAAA */ 6540 movl rGLUE,%ecx 6541 movl 2(rPC),%eax # eax<- AAAAAAAA 6542 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 6543 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 6544 EXPORT_PC 6545 movl (%ecx,%eax,4),%ecx # ecx<- resolved class 6546 testl %ecx,%ecx # resolved? 6547 je .LOP_NEW_INSTANCE_JUMBO_resolve # no, go do it 6548.LOP_NEW_INSTANCE_JUMBO_resolved: # on entry, ecx<- class 6549 cmpb $CLASS_INITIALIZED,offClassObject_status(%ecx) 6550 je .LOP_NEW_INSTANCE_JUMBO_initialized 6551 jmp .LOP_NEW_INSTANCE_JUMBO_needinit 6552 6553/* ------------------------------ */ 6554 .balign 64 6555.L_OP_NEW_ARRAY_JUMBO: /* 0x104 */ 6556/* File: x86/OP_NEW_ARRAY_JUMBO.S */ 6557 /* 6558 * Allocate an array of objects, specified with the array class 6559 * and a count. 6560 * 6561 * The verifier guarantees that this is an array class, so we don't 6562 * check for it here. 6563 */ 6564 /* new-array/jumbo vBBBB, vCCCC, class@AAAAAAAA */ 6565 movl rGLUE,%ecx 6566 EXPORT_PC 6567 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 6568 movl 2(rPC),%eax # eax<- AAAAAAAA 6569 movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 6570 movl (%ecx,%eax,4),%ecx # ecx<- resolved class 6571 movzwl 8(rPC),%eax # eax<- CCCC 6572 GET_VREG_R %eax %eax # eax<- vCCCC (array length) 6573 testl %eax,%eax 6574 js common_errNegativeArraySize # bail 6575 testl %ecx,%ecx # already resolved? 6576 jne .LOP_NEW_ARRAY_JUMBO_finish # yes, fast path 6577 jmp .LOP_NEW_ARRAY_JUMBO_resolve # resolve now 6578 6579/* ------------------------------ */ 6580 .balign 64 6581.L_OP_FILLED_NEW_ARRAY_JUMBO: /* 0x105 */ 6582/* File: x86/OP_FILLED_NEW_ARRAY_JUMBO.S */ 6583 /* 6584 * Create a new array with elements filled from registers. 6585 */ 6586 /* filled-new-array/jumbo {vCCCC..v(CCCC+BBBB-1)}, type@AAAAAAAA */ 6587 movl rGLUE,%eax 6588 movl offGlue_methodClassDex(%eax),%eax # eax<- pDvmDex 6589 movl 2(rPC),%ecx # ecx<- AAAAAAAA 6590 movl offDvmDex_pResClasses(%eax),%eax # eax<- pDvmDex->pResClasses 6591 movl (%eax,%ecx,4),%eax # eax<- resolved class 6592 EXPORT_PC 6593 testl %eax,%eax # already resolved? 6594 jne .LOP_FILLED_NEW_ARRAY_JUMBO_continue # yes, continue 6595 # less frequent path, so we'll redo some work 6596 movl rGLUE,%eax 6597 movl $0,OUT_ARG2(%esp) # arg2<- false 6598 movl %ecx,OUT_ARG1(%esp) # arg1<- AAAAAAAA 6599 movl offGlue_method(%eax),%eax # eax<- glue->method 6600 jmp .LOP_FILLED_NEW_ARRAY_JUMBO_more 6601 6602/* ------------------------------ */ 6603 .balign 64 6604.L_OP_IGET_JUMBO: /* 0x106 */ 6605/* File: x86/OP_IGET_JUMBO.S */ 6606 /* 6607 * Jumbo 32-bit instance field get. 6608 * 6609 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 6610 * iget-char/jumbo, iget-short/jumbo 6611 */ 6612 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6613 movl rGLUE,%ecx 6614 movl 2(rPC),%edx # edx<- AAAAAAAA 6615 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 6616 movzwl 8(rPC),%ecx # ecx<- CCCC 6617 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6618 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6619 movl (%eax,%edx,4),%eax # resolved entry 6620 testl %eax,%eax # is resolved entry null? 6621 jne .LOP_IGET_JUMBO_finish # no, already resolved 6622 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 6623 movl rGLUE,%edx 6624 jmp .LOP_IGET_JUMBO_resolve 6625 6626/* ------------------------------ */ 6627 .balign 64 6628.L_OP_IGET_WIDE_JUMBO: /* 0x107 */ 6629/* File: x86/OP_IGET_WIDE_JUMBO.S */ 6630 /* 6631 * Jumbo 64-bit instance field get. 6632 */ 6633 /* iget-wide/jumbo vBBBB, vCCCC, field@AAAA */ 6634 movl rGLUE,%ecx 6635 movl 2(rPC),%edx # edx<- AAAAAAAA 6636 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 6637 movzwl 8(rPC),%ecx # ecx<- CCCC 6638 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6639 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6640 movl (%eax,%edx,4),%eax # resolved entry 6641 testl %eax,%eax # is resolved entry null? 6642 jne .LOP_IGET_WIDE_JUMBO_finish # no, already resolved 6643 movl %edx,OUT_ARG1(%esp) # for dvmResolveInstField 6644 movl rGLUE,%edx 6645 jmp .LOP_IGET_WIDE_JUMBO_resolve 6646 6647/* ------------------------------ */ 6648 .balign 64 6649.L_OP_IGET_OBJECT_JUMBO: /* 0x108 */ 6650/* File: x86/OP_IGET_OBJECT_JUMBO.S */ 6651/* File: x86/OP_IGET_JUMBO.S */ 6652 /* 6653 * Jumbo 32-bit instance field get. 6654 * 6655 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 6656 * iget-char/jumbo, iget-short/jumbo 6657 */ 6658 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6659 movl rGLUE,%ecx 6660 movl 2(rPC),%edx # edx<- AAAAAAAA 6661 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 6662 movzwl 8(rPC),%ecx # ecx<- CCCC 6663 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6664 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6665 movl (%eax,%edx,4),%eax # resolved entry 6666 testl %eax,%eax # is resolved entry null? 6667 jne .LOP_IGET_OBJECT_JUMBO_finish # no, already resolved 6668 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 6669 movl rGLUE,%edx 6670 jmp .LOP_IGET_OBJECT_JUMBO_resolve 6671 6672 6673/* ------------------------------ */ 6674 .balign 64 6675.L_OP_IGET_BOOLEAN_JUMBO: /* 0x109 */ 6676/* File: x86/OP_IGET_BOOLEAN_JUMBO.S */ 6677/* File: x86/OP_IGET_JUMBO.S */ 6678 /* 6679 * Jumbo 32-bit instance field get. 6680 * 6681 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 6682 * iget-char/jumbo, iget-short/jumbo 6683 */ 6684 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6685 movl rGLUE,%ecx 6686 movl 2(rPC),%edx # edx<- AAAAAAAA 6687 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 6688 movzwl 8(rPC),%ecx # ecx<- CCCC 6689 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6690 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6691 movl (%eax,%edx,4),%eax # resolved entry 6692 testl %eax,%eax # is resolved entry null? 6693 jne .LOP_IGET_BOOLEAN_JUMBO_finish # no, already resolved 6694 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 6695 movl rGLUE,%edx 6696 jmp .LOP_IGET_BOOLEAN_JUMBO_resolve 6697 6698 6699/* ------------------------------ */ 6700 .balign 64 6701.L_OP_IGET_BYTE_JUMBO: /* 0x10a */ 6702/* File: x86/OP_IGET_BYTE_JUMBO.S */ 6703/* File: x86/OP_IGET_JUMBO.S */ 6704 /* 6705 * Jumbo 32-bit instance field get. 6706 * 6707 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 6708 * iget-char/jumbo, iget-short/jumbo 6709 */ 6710 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6711 movl rGLUE,%ecx 6712 movl 2(rPC),%edx # edx<- AAAAAAAA 6713 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 6714 movzwl 8(rPC),%ecx # ecx<- CCCC 6715 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6716 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6717 movl (%eax,%edx,4),%eax # resolved entry 6718 testl %eax,%eax # is resolved entry null? 6719 jne .LOP_IGET_BYTE_JUMBO_finish # no, already resolved 6720 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 6721 movl rGLUE,%edx 6722 jmp .LOP_IGET_BYTE_JUMBO_resolve 6723 6724 6725/* ------------------------------ */ 6726 .balign 64 6727.L_OP_IGET_CHAR_JUMBO: /* 0x10b */ 6728/* File: x86/OP_IGET_CHAR_JUMBO.S */ 6729/* File: x86/OP_IGET_JUMBO.S */ 6730 /* 6731 * Jumbo 32-bit instance field get. 6732 * 6733 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 6734 * iget-char/jumbo, iget-short/jumbo 6735 */ 6736 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6737 movl rGLUE,%ecx 6738 movl 2(rPC),%edx # edx<- AAAAAAAA 6739 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 6740 movzwl 8(rPC),%ecx # ecx<- CCCC 6741 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6742 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6743 movl (%eax,%edx,4),%eax # resolved entry 6744 testl %eax,%eax # is resolved entry null? 6745 jne .LOP_IGET_CHAR_JUMBO_finish # no, already resolved 6746 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 6747 movl rGLUE,%edx 6748 jmp .LOP_IGET_CHAR_JUMBO_resolve 6749 6750 6751/* ------------------------------ */ 6752 .balign 64 6753.L_OP_IGET_SHORT_JUMBO: /* 0x10c */ 6754/* File: x86/OP_IGET_SHORT_JUMBO.S */ 6755/* File: x86/OP_IGET_JUMBO.S */ 6756 /* 6757 * Jumbo 32-bit instance field get. 6758 * 6759 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 6760 * iget-char/jumbo, iget-short/jumbo 6761 */ 6762 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6763 movl rGLUE,%ecx 6764 movl 2(rPC),%edx # edx<- AAAAAAAA 6765 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 6766 movzwl 8(rPC),%ecx # ecx<- CCCC 6767 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6768 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6769 movl (%eax,%edx,4),%eax # resolved entry 6770 testl %eax,%eax # is resolved entry null? 6771 jne .LOP_IGET_SHORT_JUMBO_finish # no, already resolved 6772 movl %edx,OUT_ARG1(%esp) # needed by dvmResolveInstField 6773 movl rGLUE,%edx 6774 jmp .LOP_IGET_SHORT_JUMBO_resolve 6775 6776 6777/* ------------------------------ */ 6778 .balign 64 6779.L_OP_IPUT_JUMBO: /* 0x10d */ 6780/* File: x86/OP_IPUT_JUMBO.S */ 6781 /* 6782 * Jumbo 32-bit instance field put. 6783 * 6784 * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo, 6785 iput-char/jumbo, iput-short/jumbo 6786 */ 6787 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6788 movl rGLUE,%ecx 6789 movl 2(rPC),%edx # edx<- AAAAAAAA 6790 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 6791 movzwl 8(rPC),%ecx # ecx<- CCCC 6792 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6793 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6794 movl (%eax,%edx,4),%eax # resolved entry 6795 testl %eax,%eax # is resolved entry null? 6796 jne .LOP_IPUT_JUMBO_finish # no, already resolved 6797 movl %edx,OUT_ARG1(%esp) 6798 movl rGLUE,%edx 6799 jmp .LOP_IPUT_JUMBO_resolve 6800 6801/* ------------------------------ */ 6802 .balign 64 6803.L_OP_IPUT_WIDE_JUMBO: /* 0x10e */ 6804/* File: x86/OP_IPUT_WIDE_JUMBO.S */ 6805 /* 6806 * Jumbo 64-bit instance field put. 6807 */ 6808 /* iput-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */ 6809 movl rGLUE,%ecx 6810 movl 2(rPC),%edx # edx<- AAAAAAAA 6811 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 6812 movzwl 8(rPC),%ecx # ecx<- CCCC 6813 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6814 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6815 movl (%eax,%edx,4),%eax # resolved entry 6816 testl %eax,%eax # is resolved entry null? 6817 jne .LOP_IPUT_WIDE_JUMBO_finish # no, already resolved 6818 movl %edx,OUT_ARG1(%esp) 6819 movl rGLUE,%edx 6820 jmp .LOP_IPUT_WIDE_JUMBO_resolve 6821 6822/* ------------------------------ */ 6823 .balign 64 6824.L_OP_IPUT_OBJECT_JUMBO: /* 0x10f */ 6825/* File: x86/OP_IPUT_OBJECT_JUMBO.S */ 6826 /* 6827 * Jumbo object field put. 6828 */ 6829 /* iput-object/jumbo vBBBB, vCCCC, field@AAAAAAAA */ 6830 movl rGLUE,%ecx 6831 movl 2(rPC),%edx # edx<- AAAAAAAA 6832 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 6833 movzwl 8(rPC),%ecx # ecx<- CCCC 6834 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6835 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6836 movl (%eax,%edx,4),%eax # resolved entry 6837 testl %eax,%eax # is resolved entry null? 6838 jne .LOP_IPUT_OBJECT_JUMBO_finish # no, already resolved 6839 movl %edx,OUT_ARG1(%esp) 6840 movl rGLUE,%edx 6841 jmp .LOP_IPUT_OBJECT_JUMBO_resolve 6842 6843/* ------------------------------ */ 6844 .balign 64 6845.L_OP_IPUT_BOOLEAN_JUMBO: /* 0x110 */ 6846/* File: x86/OP_IPUT_BOOLEAN_JUMBO.S */ 6847/* File: x86/OP_IPUT_JUMBO.S */ 6848 /* 6849 * Jumbo 32-bit instance field put. 6850 * 6851 * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo, 6852 iput-char/jumbo, iput-short/jumbo 6853 */ 6854 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6855 movl rGLUE,%ecx 6856 movl 2(rPC),%edx # edx<- AAAAAAAA 6857 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 6858 movzwl 8(rPC),%ecx # ecx<- CCCC 6859 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6860 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6861 movl (%eax,%edx,4),%eax # resolved entry 6862 testl %eax,%eax # is resolved entry null? 6863 jne .LOP_IPUT_BOOLEAN_JUMBO_finish # no, already resolved 6864 movl %edx,OUT_ARG1(%esp) 6865 movl rGLUE,%edx 6866 jmp .LOP_IPUT_BOOLEAN_JUMBO_resolve 6867 6868 6869/* ------------------------------ */ 6870 .balign 64 6871.L_OP_IPUT_BYTE_JUMBO: /* 0x111 */ 6872/* File: x86/OP_IPUT_BYTE_JUMBO.S */ 6873/* File: x86/OP_IPUT_JUMBO.S */ 6874 /* 6875 * Jumbo 32-bit instance field put. 6876 * 6877 * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo, 6878 iput-char/jumbo, iput-short/jumbo 6879 */ 6880 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6881 movl rGLUE,%ecx 6882 movl 2(rPC),%edx # edx<- AAAAAAAA 6883 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 6884 movzwl 8(rPC),%ecx # ecx<- CCCC 6885 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6886 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6887 movl (%eax,%edx,4),%eax # resolved entry 6888 testl %eax,%eax # is resolved entry null? 6889 jne .LOP_IPUT_BYTE_JUMBO_finish # no, already resolved 6890 movl %edx,OUT_ARG1(%esp) 6891 movl rGLUE,%edx 6892 jmp .LOP_IPUT_BYTE_JUMBO_resolve 6893 6894 6895/* ------------------------------ */ 6896 .balign 64 6897.L_OP_IPUT_CHAR_JUMBO: /* 0x112 */ 6898/* File: x86/OP_IPUT_CHAR_JUMBO.S */ 6899/* File: x86/OP_IPUT_JUMBO.S */ 6900 /* 6901 * Jumbo 32-bit instance field put. 6902 * 6903 * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo, 6904 iput-char/jumbo, iput-short/jumbo 6905 */ 6906 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6907 movl rGLUE,%ecx 6908 movl 2(rPC),%edx # edx<- AAAAAAAA 6909 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 6910 movzwl 8(rPC),%ecx # ecx<- CCCC 6911 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6912 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6913 movl (%eax,%edx,4),%eax # resolved entry 6914 testl %eax,%eax # is resolved entry null? 6915 jne .LOP_IPUT_CHAR_JUMBO_finish # no, already resolved 6916 movl %edx,OUT_ARG1(%esp) 6917 movl rGLUE,%edx 6918 jmp .LOP_IPUT_CHAR_JUMBO_resolve 6919 6920 6921/* ------------------------------ */ 6922 .balign 64 6923.L_OP_IPUT_SHORT_JUMBO: /* 0x113 */ 6924/* File: x86/OP_IPUT_SHORT_JUMBO.S */ 6925/* File: x86/OP_IPUT_JUMBO.S */ 6926 /* 6927 * Jumbo 32-bit instance field put. 6928 * 6929 * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo, 6930 iput-char/jumbo, iput-short/jumbo 6931 */ 6932 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 6933 movl rGLUE,%ecx 6934 movl 2(rPC),%edx # edx<- AAAAAAAA 6935 movl offGlue_methodClassDex(%ecx),%eax # eax<- DvmDex 6936 movzwl 8(rPC),%ecx # ecx<- CCCC 6937 movl offDvmDex_pResFields(%eax),%eax # eax<- pDvmDex->pResFields 6938 GET_VREG_R %ecx %ecx # ecx<- fp[CCCC], the object ptr 6939 movl (%eax,%edx,4),%eax # resolved entry 6940 testl %eax,%eax # is resolved entry null? 6941 jne .LOP_IPUT_SHORT_JUMBO_finish # no, already resolved 6942 movl %edx,OUT_ARG1(%esp) 6943 movl rGLUE,%edx 6944 jmp .LOP_IPUT_SHORT_JUMBO_resolve 6945 6946 6947/* ------------------------------ */ 6948 .balign 64 6949.L_OP_SGET_JUMBO: /* 0x114 */ 6950/* File: x86/OP_SGET_JUMBO.S */ 6951 /* 6952 * Jumbo 32-bit SGET handler. 6953 * 6954 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 6955 * sget-char/jumbo, sget-short/jumbo 6956 */ 6957 /* exop vBBBB, field@AAAAAAAA */ 6958 movl rGLUE,%ecx 6959 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 6960 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 6961 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 6962 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 6963 testl %eax,%eax # resolved entry null? 6964 je .LOP_SGET_JUMBO_resolve # if not, make it so 6965.LOP_SGET_JUMBO_finish: # field ptr in eax 6966 movl offStaticField_value(%eax),%eax 6967 FETCH_INST_OPCODE 4 %edx 6968 ADVANCE_PC 4 6969 SET_VREG %eax rINST 6970 GOTO_NEXT_R %edx 6971 6972/* ------------------------------ */ 6973 .balign 64 6974.L_OP_SGET_WIDE_JUMBO: /* 0x115 */ 6975/* File: x86/OP_SGET_WIDE_JUMBO.S */ 6976 /* 6977 * Jumbo 64-bit SGET handler. 6978 * 6979 */ 6980 /* sget-wide/jumbo vBBBB, field@AAAAAAAA */ 6981 movl rGLUE,%ecx 6982 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 6983 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 6984 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 6985 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 6986 testl %eax,%eax # resolved entry null? 6987 je .LOP_SGET_WIDE_JUMBO_resolve # if not, make it so 6988.LOP_SGET_WIDE_JUMBO_finish: # field ptr in eax 6989 movl offStaticField_value(%eax),%ecx # ecx<- lsw 6990 movl 4+offStaticField_value(%eax),%eax # eax<- msw 6991 FETCH_INST_OPCODE 2 %edx 6992 ADVANCE_PC 2 6993 SET_VREG_WORD %ecx rINST 0 6994 SET_VREG_WORD %eax rINST 1 6995 GOTO_NEXT_R %edx 6996 6997/* ------------------------------ */ 6998 .balign 64 6999.L_OP_SGET_OBJECT_JUMBO: /* 0x116 */ 7000/* File: x86/OP_SGET_OBJECT_JUMBO.S */ 7001/* File: x86/OP_SGET_JUMBO.S */ 7002 /* 7003 * Jumbo 32-bit SGET handler. 7004 * 7005 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 7006 * sget-char/jumbo, sget-short/jumbo 7007 */ 7008 /* exop vBBBB, field@AAAAAAAA */ 7009 movl rGLUE,%ecx 7010 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7011 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7012 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7013 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7014 testl %eax,%eax # resolved entry null? 7015 je .LOP_SGET_OBJECT_JUMBO_resolve # if not, make it so 7016.LOP_SGET_OBJECT_JUMBO_finish: # field ptr in eax 7017 movl offStaticField_value(%eax),%eax 7018 FETCH_INST_OPCODE 4 %edx 7019 ADVANCE_PC 4 7020 SET_VREG %eax rINST 7021 GOTO_NEXT_R %edx 7022 7023 7024/* ------------------------------ */ 7025 .balign 64 7026.L_OP_SGET_BOOLEAN_JUMBO: /* 0x117 */ 7027/* File: x86/OP_SGET_BOOLEAN_JUMBO.S */ 7028/* File: x86/OP_SGET_JUMBO.S */ 7029 /* 7030 * Jumbo 32-bit SGET handler. 7031 * 7032 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 7033 * sget-char/jumbo, sget-short/jumbo 7034 */ 7035 /* exop vBBBB, field@AAAAAAAA */ 7036 movl rGLUE,%ecx 7037 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7038 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7039 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7040 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7041 testl %eax,%eax # resolved entry null? 7042 je .LOP_SGET_BOOLEAN_JUMBO_resolve # if not, make it so 7043.LOP_SGET_BOOLEAN_JUMBO_finish: # field ptr in eax 7044 movl offStaticField_value(%eax),%eax 7045 FETCH_INST_OPCODE 4 %edx 7046 ADVANCE_PC 4 7047 SET_VREG %eax rINST 7048 GOTO_NEXT_R %edx 7049 7050 7051/* ------------------------------ */ 7052 .balign 64 7053.L_OP_SGET_BYTE_JUMBO: /* 0x118 */ 7054/* File: x86/OP_SGET_BYTE_JUMBO.S */ 7055/* File: x86/OP_SGET_JUMBO.S */ 7056 /* 7057 * Jumbo 32-bit SGET handler. 7058 * 7059 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 7060 * sget-char/jumbo, sget-short/jumbo 7061 */ 7062 /* exop vBBBB, field@AAAAAAAA */ 7063 movl rGLUE,%ecx 7064 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7065 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7066 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7067 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7068 testl %eax,%eax # resolved entry null? 7069 je .LOP_SGET_BYTE_JUMBO_resolve # if not, make it so 7070.LOP_SGET_BYTE_JUMBO_finish: # field ptr in eax 7071 movl offStaticField_value(%eax),%eax 7072 FETCH_INST_OPCODE 4 %edx 7073 ADVANCE_PC 4 7074 SET_VREG %eax rINST 7075 GOTO_NEXT_R %edx 7076 7077 7078/* ------------------------------ */ 7079 .balign 64 7080.L_OP_SGET_CHAR_JUMBO: /* 0x119 */ 7081/* File: x86/OP_SGET_CHAR_JUMBO.S */ 7082/* File: x86/OP_SGET_JUMBO.S */ 7083 /* 7084 * Jumbo 32-bit SGET handler. 7085 * 7086 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 7087 * sget-char/jumbo, sget-short/jumbo 7088 */ 7089 /* exop vBBBB, field@AAAAAAAA */ 7090 movl rGLUE,%ecx 7091 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7092 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7093 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7094 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7095 testl %eax,%eax # resolved entry null? 7096 je .LOP_SGET_CHAR_JUMBO_resolve # if not, make it so 7097.LOP_SGET_CHAR_JUMBO_finish: # field ptr in eax 7098 movl offStaticField_value(%eax),%eax 7099 FETCH_INST_OPCODE 4 %edx 7100 ADVANCE_PC 4 7101 SET_VREG %eax rINST 7102 GOTO_NEXT_R %edx 7103 7104 7105/* ------------------------------ */ 7106 .balign 64 7107.L_OP_SGET_SHORT_JUMBO: /* 0x11a */ 7108/* File: x86/OP_SGET_SHORT_JUMBO.S */ 7109/* File: x86/OP_SGET_JUMBO.S */ 7110 /* 7111 * Jumbo 32-bit SGET handler. 7112 * 7113 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 7114 * sget-char/jumbo, sget-short/jumbo 7115 */ 7116 /* exop vBBBB, field@AAAAAAAA */ 7117 movl rGLUE,%ecx 7118 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7119 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7120 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7121 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7122 testl %eax,%eax # resolved entry null? 7123 je .LOP_SGET_SHORT_JUMBO_resolve # if not, make it so 7124.LOP_SGET_SHORT_JUMBO_finish: # field ptr in eax 7125 movl offStaticField_value(%eax),%eax 7126 FETCH_INST_OPCODE 4 %edx 7127 ADVANCE_PC 4 7128 SET_VREG %eax rINST 7129 GOTO_NEXT_R %edx 7130 7131 7132/* ------------------------------ */ 7133 .balign 64 7134.L_OP_SPUT_JUMBO: /* 0x11b */ 7135/* File: x86/OP_SPUT_JUMBO.S */ 7136 /* 7137 * Jumbo 32-bit SPUT handler. 7138 * 7139 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 7140 * sput-short/jumbo 7141 */ 7142 /* exop vBBBB, field@AAAAAAAA */ 7143 movl rGLUE,%ecx 7144 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7145 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7146 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7147 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7148 testl %eax,%eax # resolved entry null? 7149 je .LOP_SPUT_JUMBO_resolve # if not, make it so 7150.LOP_SPUT_JUMBO_finish: # field ptr in eax 7151 GET_VREG_R %ecx rINST 7152 FETCH_INST_OPCODE 4 %edx 7153 ADVANCE_PC 4 7154 movl %ecx,offStaticField_value(%eax) 7155 GOTO_NEXT_R %edx 7156 7157/* ------------------------------ */ 7158 .balign 64 7159.L_OP_SPUT_WIDE_JUMBO: /* 0x11c */ 7160/* File: x86/OP_SPUT_WIDE_JUMBO.S */ 7161 /* 7162 * Jumbo 64-bit SPUT handler. 7163 */ 7164 /* sput-wide/jumbo vBBBB, field@AAAAAAAA */ 7165 movl rGLUE,%ecx 7166 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7167 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7168 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7169 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7170 testl %eax,%eax # resolved entry null? 7171 je .LOP_SPUT_WIDE_JUMBO_resolve # if not, make it so 7172.LOP_SPUT_WIDE_JUMBO_finish: # field ptr in eax 7173 GET_VREG_WORD %ecx rINST 0 # ecx<- lsw 7174 GET_VREG_WORD rINST rINST 1 # rINST<- msw 7175 FETCH_INST_OPCODE 4 %edx 7176 ADVANCE_PC 4 7177 movl %ecx,offStaticField_value(%eax) 7178 movl rINST,4+offStaticField_value(%eax) 7179 GOTO_NEXT_R %edx 7180 7181/* ------------------------------ */ 7182 .balign 64 7183.L_OP_SPUT_OBJECT_JUMBO: /* 0x11d */ 7184/* File: x86/OP_SPUT_OBJECT_JUMBO.S */ 7185 /* 7186 * Jumbo SPUT object handler. 7187 */ 7188 /* sput-object/jumbo vBBBB, field@AAAAAAAA */ 7189 movl rGLUE,%ecx 7190 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7191 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7192 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7193 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField 7194 testl %eax,%eax # resolved entry null? 7195 je .LOP_SPUT_OBJECT_JUMBO_resolve # if not, make it so 7196.LOP_SPUT_OBJECT_JUMBO_finish: # field ptr in eax 7197 GET_VREG_R %ecx rINST 7198 jmp .LOP_SPUT_OBJECT_JUMBO_continue 7199 7200/* ------------------------------ */ 7201 .balign 64 7202.L_OP_SPUT_BOOLEAN_JUMBO: /* 0x11e */ 7203/* File: x86/OP_SPUT_BOOLEAN_JUMBO.S */ 7204/* File: x86/OP_SPUT_JUMBO.S */ 7205 /* 7206 * Jumbo 32-bit SPUT handler. 7207 * 7208 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 7209 * sput-short/jumbo 7210 */ 7211 /* exop vBBBB, field@AAAAAAAA */ 7212 movl rGLUE,%ecx 7213 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7214 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7215 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7216 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7217 testl %eax,%eax # resolved entry null? 7218 je .LOP_SPUT_BOOLEAN_JUMBO_resolve # if not, make it so 7219.LOP_SPUT_BOOLEAN_JUMBO_finish: # field ptr in eax 7220 GET_VREG_R %ecx rINST 7221 FETCH_INST_OPCODE 4 %edx 7222 ADVANCE_PC 4 7223 movl %ecx,offStaticField_value(%eax) 7224 GOTO_NEXT_R %edx 7225 7226 7227/* ------------------------------ */ 7228 .balign 64 7229.L_OP_SPUT_BYTE_JUMBO: /* 0x11f */ 7230/* File: x86/OP_SPUT_BYTE_JUMBO.S */ 7231/* File: x86/OP_SPUT_JUMBO.S */ 7232 /* 7233 * Jumbo 32-bit SPUT handler. 7234 * 7235 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 7236 * sput-short/jumbo 7237 */ 7238 /* exop vBBBB, field@AAAAAAAA */ 7239 movl rGLUE,%ecx 7240 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7241 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7242 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7243 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7244 testl %eax,%eax # resolved entry null? 7245 je .LOP_SPUT_BYTE_JUMBO_resolve # if not, make it so 7246.LOP_SPUT_BYTE_JUMBO_finish: # field ptr in eax 7247 GET_VREG_R %ecx rINST 7248 FETCH_INST_OPCODE 4 %edx 7249 ADVANCE_PC 4 7250 movl %ecx,offStaticField_value(%eax) 7251 GOTO_NEXT_R %edx 7252 7253 7254/* ------------------------------ */ 7255 .balign 64 7256.L_OP_SPUT_CHAR_JUMBO: /* 0x120 */ 7257/* File: x86/OP_SPUT_CHAR_JUMBO.S */ 7258/* File: x86/OP_SPUT_JUMBO.S */ 7259 /* 7260 * Jumbo 32-bit SPUT handler. 7261 * 7262 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 7263 * sput-short/jumbo 7264 */ 7265 /* exop vBBBB, field@AAAAAAAA */ 7266 movl rGLUE,%ecx 7267 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7268 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7269 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7270 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7271 testl %eax,%eax # resolved entry null? 7272 je .LOP_SPUT_CHAR_JUMBO_resolve # if not, make it so 7273.LOP_SPUT_CHAR_JUMBO_finish: # field ptr in eax 7274 GET_VREG_R %ecx rINST 7275 FETCH_INST_OPCODE 4 %edx 7276 ADVANCE_PC 4 7277 movl %ecx,offStaticField_value(%eax) 7278 GOTO_NEXT_R %edx 7279 7280 7281/* ------------------------------ */ 7282 .balign 64 7283.L_OP_SPUT_SHORT_JUMBO: /* 0x121 */ 7284/* File: x86/OP_SPUT_SHORT_JUMBO.S */ 7285/* File: x86/OP_SPUT_JUMBO.S */ 7286 /* 7287 * Jumbo 32-bit SPUT handler. 7288 * 7289 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 7290 * sput-short/jumbo 7291 */ 7292 /* exop vBBBB, field@AAAAAAAA */ 7293 movl rGLUE,%ecx 7294 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex 7295 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 7296 movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields 7297 movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr 7298 testl %eax,%eax # resolved entry null? 7299 je .LOP_SPUT_SHORT_JUMBO_resolve # if not, make it so 7300.LOP_SPUT_SHORT_JUMBO_finish: # field ptr in eax 7301 GET_VREG_R %ecx rINST 7302 FETCH_INST_OPCODE 4 %edx 7303 ADVANCE_PC 4 7304 movl %ecx,offStaticField_value(%eax) 7305 GOTO_NEXT_R %edx 7306 7307 7308/* ------------------------------ */ 7309 .balign 64 7310.L_OP_INVOKE_VIRTUAL_JUMBO: /* 0x122 */ 7311/* File: x86/OP_INVOKE_VIRTUAL_JUMBO.S */ 7312 /* 7313 * Handle a jumbo virtual method call. 7314 */ 7315 /* invoke-virtual/jumbo vBBBB, {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 7316 movl rGLUE,%eax 7317 movl 2(rPC),%ecx # ecx<- AAAAAAAA 7318 movl offGlue_methodClassDex(%eax),%eax # eax<- pDvmDex 7319 EXPORT_PC 7320 movl offDvmDex_pResMethods(%eax),%eax # eax<- pDvmDex->pResMethods 7321 movl (%eax,%ecx,4),%eax # eax<- resolved baseMethod 7322 testl %eax,%eax # already resolved? 7323 jne .LOP_INVOKE_VIRTUAL_JUMBO_continue # yes, continue 7324 movl rGLUE,%eax 7325 movl %ecx,OUT_ARG1(%esp) # arg1<- ref 7326 movl offGlue_method(%eax),%eax # eax<- glue->method 7327 jmp .LOP_INVOKE_VIRTUAL_JUMBO_more 7328 7329/* ------------------------------ */ 7330 .balign 64 7331.L_OP_INVOKE_SUPER_JUMBO: /* 0x123 */ 7332/* File: x86/OP_INVOKE_SUPER_JUMBO.S */ 7333 /* 7334 * Handle a jumbo "super" method call. 7335 */ 7336 /* invoke-super/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 7337 movl rGLUE,rINST 7338 movl 2(rPC),%eax # eax<- AAAAAAAA 7339 movl offGlue_methodClassDex(rINST),%ecx # ecx<- pDvmDex 7340 EXPORT_PC 7341 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 7342 movl (%ecx,%eax,4),%ecx # ecx<- resolved baseMethod 7343 movl offGlue_method(rINST),%eax # eax<- method 7344 movzwl 8(rPC),rINST # rINST<- CCCC 7345 GET_VREG_R rINST rINST # rINST<- "this" ptr 7346 testl rINST,rINST # null "this"? 7347 je common_errNullObject # yes, throw 7348 movl offMethod_clazz(%eax),%eax # eax<- method->clazz 7349 testl %ecx,%ecx # already resolved? 7350 jne .LOP_INVOKE_SUPER_JUMBO_continue # yes - go on 7351 jmp .LOP_INVOKE_SUPER_JUMBO_resolve 7352 7353/* ------------------------------ */ 7354 .balign 64 7355.L_OP_INVOKE_DIRECT_JUMBO: /* 0x124 */ 7356/* File: x86/OP_INVOKE_DIRECT_JUMBO.S */ 7357 /* 7358 * Handle a jumbo direct method call. 7359 * 7360 * (We could defer the "is 'this' pointer null" test to the common 7361 * method invocation code, and use a flag to indicate that static 7362 * calls don't count. If we do this as part of copying the arguments 7363 * out we could avoiding loading the first arg twice.) 7364 */ 7365 /* invoke-direct/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 7366 movl rGLUE,%ecx 7367 movl 2(rPC),%eax # eax<- AAAAAAAA 7368 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 7369 EXPORT_PC 7370 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 7371 movzwl 8(rPC),%edx # edx<- CCCC 7372 movl (%ecx,%eax,4),%eax # eax<- resolved methodToCall 7373 testl %eax,%eax # already resolved? 7374 GET_VREG_R %ecx %edx # ecx<- "this" ptr 7375 je .LOP_INVOKE_DIRECT_JUMBO_resolve # not resolved, do it now 7376.LOP_INVOKE_DIRECT_JUMBO_finish: 7377 testl %ecx,%ecx # null "this"? 7378 jne common_invokeMethodJumbo # no, continue on 7379 jmp common_errNullObject 7380 7381/* ------------------------------ */ 7382 .balign 64 7383.L_OP_INVOKE_STATIC_JUMBO: /* 0x125 */ 7384/* File: x86/OP_INVOKE_STATIC_JUMBO.S */ 7385 /* 7386 * Handle a jumbo static method call. 7387 */ 7388 /* invoke-static/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 7389 movl rGLUE,%ecx 7390 movl 2(rPC),%eax # eax<- AAAAAAAA 7391 movl offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 7392 EXPORT_PC 7393 movl offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods 7394 movl (%ecx,%eax,4),%eax # eax<- resolved methodToCall 7395 testl %eax,%eax 7396 jne common_invokeMethodJumbo 7397 movl rGLUE,%ecx 7398 movl offGlue_method(%ecx),%ecx # ecx<- glue->method 7399 movl 2(rPC),%eax # eax<- AAAAAAAA 7400 movl offMethod_clazz(%ecx),%ecx# ecx<- method->clazz 7401 movl %eax,OUT_ARG1(%esp) # arg1<- AAAAAAAA 7402 movl %ecx,OUT_ARG0(%esp) # arg0<- clazz 7403 jmp .LOP_INVOKE_STATIC_JUMBO_continue 7404 7405/* ------------------------------ */ 7406 .balign 64 7407.L_OP_INVOKE_INTERFACE_JUMBO: /* 0x126 */ 7408/* File: x86/OP_INVOKE_INTERFACE_JUMBO.S */ 7409 /* 7410 * Handle a jumbo interface method call. 7411 */ 7412 /* invoke-interface/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 7413 movzwl 8(rPC),%eax # eax<- CCCC 7414 movl rGLUE,%ecx 7415 GET_VREG_R %eax %eax # eax<- "this" 7416 EXPORT_PC 7417 testl %eax,%eax # null this? 7418 je common_errNullObject # yes, fail 7419 movl offObject_clazz(%eax),%eax# eax<- thisPtr->clazz 7420 movl %eax,OUT_ARG0(%esp) # arg0<- class 7421 movl offGlue_methodClassDex(%ecx),%eax # eax<- methodClassDex 7422 movl offGlue_method(%ecx),%ecx # ecx<- method 7423 movl %eax,OUT_ARG3(%esp) # arg3<- dex 7424 movl 2(rPC),%eax # eax<- AAAAAAAA 7425 movl %ecx,OUT_ARG2(%esp) # arg2<- method 7426 movl %eax,OUT_ARG1(%esp) # arg1<- AAAAAAAA 7427 jmp .LOP_INVOKE_INTERFACE_JUMBO_continue 7428 7429/* ------------------------------ */ 7430 .balign 64 7431.L_OP_UNUSED_27FF: /* 0x127 */ 7432/* File: x86/OP_UNUSED_27FF.S */ 7433/* File: x86/unused.S */ 7434 jmp common_abort 7435 7436 7437/* ------------------------------ */ 7438 .balign 64 7439.L_OP_UNUSED_28FF: /* 0x128 */ 7440/* File: x86/OP_UNUSED_28FF.S */ 7441/* File: x86/unused.S */ 7442 jmp common_abort 7443 7444 7445/* ------------------------------ */ 7446 .balign 64 7447.L_OP_UNUSED_29FF: /* 0x129 */ 7448/* File: x86/OP_UNUSED_29FF.S */ 7449/* File: x86/unused.S */ 7450 jmp common_abort 7451 7452 7453/* ------------------------------ */ 7454 .balign 64 7455.L_OP_UNUSED_2AFF: /* 0x12a */ 7456/* File: x86/OP_UNUSED_2AFF.S */ 7457/* File: x86/unused.S */ 7458 jmp common_abort 7459 7460 7461/* ------------------------------ */ 7462 .balign 64 7463.L_OP_UNUSED_2BFF: /* 0x12b */ 7464/* File: x86/OP_UNUSED_2BFF.S */ 7465/* File: x86/unused.S */ 7466 jmp common_abort 7467 7468 7469/* ------------------------------ */ 7470 .balign 64 7471.L_OP_UNUSED_2CFF: /* 0x12c */ 7472/* File: x86/OP_UNUSED_2CFF.S */ 7473/* File: x86/unused.S */ 7474 jmp common_abort 7475 7476 7477/* ------------------------------ */ 7478 .balign 64 7479.L_OP_UNUSED_2DFF: /* 0x12d */ 7480/* File: x86/OP_UNUSED_2DFF.S */ 7481/* File: x86/unused.S */ 7482 jmp common_abort 7483 7484 7485/* ------------------------------ */ 7486 .balign 64 7487.L_OP_UNUSED_2EFF: /* 0x12e */ 7488/* File: x86/OP_UNUSED_2EFF.S */ 7489/* File: x86/unused.S */ 7490 jmp common_abort 7491 7492 7493/* ------------------------------ */ 7494 .balign 64 7495.L_OP_UNUSED_2FFF: /* 0x12f */ 7496/* File: x86/OP_UNUSED_2FFF.S */ 7497/* File: x86/unused.S */ 7498 jmp common_abort 7499 7500 7501/* ------------------------------ */ 7502 .balign 64 7503.L_OP_UNUSED_30FF: /* 0x130 */ 7504/* File: x86/OP_UNUSED_30FF.S */ 7505/* File: x86/unused.S */ 7506 jmp common_abort 7507 7508 7509/* ------------------------------ */ 7510 .balign 64 7511.L_OP_UNUSED_31FF: /* 0x131 */ 7512/* File: x86/OP_UNUSED_31FF.S */ 7513/* File: x86/unused.S */ 7514 jmp common_abort 7515 7516 7517/* ------------------------------ */ 7518 .balign 64 7519.L_OP_UNUSED_32FF: /* 0x132 */ 7520/* File: x86/OP_UNUSED_32FF.S */ 7521/* File: x86/unused.S */ 7522 jmp common_abort 7523 7524 7525/* ------------------------------ */ 7526 .balign 64 7527.L_OP_UNUSED_33FF: /* 0x133 */ 7528/* File: x86/OP_UNUSED_33FF.S */ 7529/* File: x86/unused.S */ 7530 jmp common_abort 7531 7532 7533/* ------------------------------ */ 7534 .balign 64 7535.L_OP_UNUSED_34FF: /* 0x134 */ 7536/* File: x86/OP_UNUSED_34FF.S */ 7537/* File: x86/unused.S */ 7538 jmp common_abort 7539 7540 7541/* ------------------------------ */ 7542 .balign 64 7543.L_OP_UNUSED_35FF: /* 0x135 */ 7544/* File: x86/OP_UNUSED_35FF.S */ 7545/* File: x86/unused.S */ 7546 jmp common_abort 7547 7548 7549/* ------------------------------ */ 7550 .balign 64 7551.L_OP_UNUSED_36FF: /* 0x136 */ 7552/* File: x86/OP_UNUSED_36FF.S */ 7553/* File: x86/unused.S */ 7554 jmp common_abort 7555 7556 7557/* ------------------------------ */ 7558 .balign 64 7559.L_OP_UNUSED_37FF: /* 0x137 */ 7560/* File: x86/OP_UNUSED_37FF.S */ 7561/* File: x86/unused.S */ 7562 jmp common_abort 7563 7564 7565/* ------------------------------ */ 7566 .balign 64 7567.L_OP_UNUSED_38FF: /* 0x138 */ 7568/* File: x86/OP_UNUSED_38FF.S */ 7569/* File: x86/unused.S */ 7570 jmp common_abort 7571 7572 7573/* ------------------------------ */ 7574 .balign 64 7575.L_OP_UNUSED_39FF: /* 0x139 */ 7576/* File: x86/OP_UNUSED_39FF.S */ 7577/* File: x86/unused.S */ 7578 jmp common_abort 7579 7580 7581/* ------------------------------ */ 7582 .balign 64 7583.L_OP_UNUSED_3AFF: /* 0x13a */ 7584/* File: x86/OP_UNUSED_3AFF.S */ 7585/* File: x86/unused.S */ 7586 jmp common_abort 7587 7588 7589/* ------------------------------ */ 7590 .balign 64 7591.L_OP_UNUSED_3BFF: /* 0x13b */ 7592/* File: x86/OP_UNUSED_3BFF.S */ 7593/* File: x86/unused.S */ 7594 jmp common_abort 7595 7596 7597/* ------------------------------ */ 7598 .balign 64 7599.L_OP_UNUSED_3CFF: /* 0x13c */ 7600/* File: x86/OP_UNUSED_3CFF.S */ 7601/* File: x86/unused.S */ 7602 jmp common_abort 7603 7604 7605/* ------------------------------ */ 7606 .balign 64 7607.L_OP_UNUSED_3DFF: /* 0x13d */ 7608/* File: x86/OP_UNUSED_3DFF.S */ 7609/* File: x86/unused.S */ 7610 jmp common_abort 7611 7612 7613/* ------------------------------ */ 7614 .balign 64 7615.L_OP_UNUSED_3EFF: /* 0x13e */ 7616/* File: x86/OP_UNUSED_3EFF.S */ 7617/* File: x86/unused.S */ 7618 jmp common_abort 7619 7620 7621/* ------------------------------ */ 7622 .balign 64 7623.L_OP_UNUSED_3FFF: /* 0x13f */ 7624/* File: x86/OP_UNUSED_3FFF.S */ 7625/* File: x86/unused.S */ 7626 jmp common_abort 7627 7628 7629/* ------------------------------ */ 7630 .balign 64 7631.L_OP_UNUSED_40FF: /* 0x140 */ 7632/* File: x86/OP_UNUSED_40FF.S */ 7633/* File: x86/unused.S */ 7634 jmp common_abort 7635 7636 7637/* ------------------------------ */ 7638 .balign 64 7639.L_OP_UNUSED_41FF: /* 0x141 */ 7640/* File: x86/OP_UNUSED_41FF.S */ 7641/* File: x86/unused.S */ 7642 jmp common_abort 7643 7644 7645/* ------------------------------ */ 7646 .balign 64 7647.L_OP_UNUSED_42FF: /* 0x142 */ 7648/* File: x86/OP_UNUSED_42FF.S */ 7649/* File: x86/unused.S */ 7650 jmp common_abort 7651 7652 7653/* ------------------------------ */ 7654 .balign 64 7655.L_OP_UNUSED_43FF: /* 0x143 */ 7656/* File: x86/OP_UNUSED_43FF.S */ 7657/* File: x86/unused.S */ 7658 jmp common_abort 7659 7660 7661/* ------------------------------ */ 7662 .balign 64 7663.L_OP_UNUSED_44FF: /* 0x144 */ 7664/* File: x86/OP_UNUSED_44FF.S */ 7665/* File: x86/unused.S */ 7666 jmp common_abort 7667 7668 7669/* ------------------------------ */ 7670 .balign 64 7671.L_OP_UNUSED_45FF: /* 0x145 */ 7672/* File: x86/OP_UNUSED_45FF.S */ 7673/* File: x86/unused.S */ 7674 jmp common_abort 7675 7676 7677/* ------------------------------ */ 7678 .balign 64 7679.L_OP_UNUSED_46FF: /* 0x146 */ 7680/* File: x86/OP_UNUSED_46FF.S */ 7681/* File: x86/unused.S */ 7682 jmp common_abort 7683 7684 7685/* ------------------------------ */ 7686 .balign 64 7687.L_OP_UNUSED_47FF: /* 0x147 */ 7688/* File: x86/OP_UNUSED_47FF.S */ 7689/* File: x86/unused.S */ 7690 jmp common_abort 7691 7692 7693/* ------------------------------ */ 7694 .balign 64 7695.L_OP_UNUSED_48FF: /* 0x148 */ 7696/* File: x86/OP_UNUSED_48FF.S */ 7697/* File: x86/unused.S */ 7698 jmp common_abort 7699 7700 7701/* ------------------------------ */ 7702 .balign 64 7703.L_OP_UNUSED_49FF: /* 0x149 */ 7704/* File: x86/OP_UNUSED_49FF.S */ 7705/* File: x86/unused.S */ 7706 jmp common_abort 7707 7708 7709/* ------------------------------ */ 7710 .balign 64 7711.L_OP_UNUSED_4AFF: /* 0x14a */ 7712/* File: x86/OP_UNUSED_4AFF.S */ 7713/* File: x86/unused.S */ 7714 jmp common_abort 7715 7716 7717/* ------------------------------ */ 7718 .balign 64 7719.L_OP_UNUSED_4BFF: /* 0x14b */ 7720/* File: x86/OP_UNUSED_4BFF.S */ 7721/* File: x86/unused.S */ 7722 jmp common_abort 7723 7724 7725/* ------------------------------ */ 7726 .balign 64 7727.L_OP_UNUSED_4CFF: /* 0x14c */ 7728/* File: x86/OP_UNUSED_4CFF.S */ 7729/* File: x86/unused.S */ 7730 jmp common_abort 7731 7732 7733/* ------------------------------ */ 7734 .balign 64 7735.L_OP_UNUSED_4DFF: /* 0x14d */ 7736/* File: x86/OP_UNUSED_4DFF.S */ 7737/* File: x86/unused.S */ 7738 jmp common_abort 7739 7740 7741/* ------------------------------ */ 7742 .balign 64 7743.L_OP_UNUSED_4EFF: /* 0x14e */ 7744/* File: x86/OP_UNUSED_4EFF.S */ 7745/* File: x86/unused.S */ 7746 jmp common_abort 7747 7748 7749/* ------------------------------ */ 7750 .balign 64 7751.L_OP_UNUSED_4FFF: /* 0x14f */ 7752/* File: x86/OP_UNUSED_4FFF.S */ 7753/* File: x86/unused.S */ 7754 jmp common_abort 7755 7756 7757/* ------------------------------ */ 7758 .balign 64 7759.L_OP_UNUSED_50FF: /* 0x150 */ 7760/* File: x86/OP_UNUSED_50FF.S */ 7761/* File: x86/unused.S */ 7762 jmp common_abort 7763 7764 7765/* ------------------------------ */ 7766 .balign 64 7767.L_OP_UNUSED_51FF: /* 0x151 */ 7768/* File: x86/OP_UNUSED_51FF.S */ 7769/* File: x86/unused.S */ 7770 jmp common_abort 7771 7772 7773/* ------------------------------ */ 7774 .balign 64 7775.L_OP_UNUSED_52FF: /* 0x152 */ 7776/* File: x86/OP_UNUSED_52FF.S */ 7777/* File: x86/unused.S */ 7778 jmp common_abort 7779 7780 7781/* ------------------------------ */ 7782 .balign 64 7783.L_OP_UNUSED_53FF: /* 0x153 */ 7784/* File: x86/OP_UNUSED_53FF.S */ 7785/* File: x86/unused.S */ 7786 jmp common_abort 7787 7788 7789/* ------------------------------ */ 7790 .balign 64 7791.L_OP_UNUSED_54FF: /* 0x154 */ 7792/* File: x86/OP_UNUSED_54FF.S */ 7793/* File: x86/unused.S */ 7794 jmp common_abort 7795 7796 7797/* ------------------------------ */ 7798 .balign 64 7799.L_OP_UNUSED_55FF: /* 0x155 */ 7800/* File: x86/OP_UNUSED_55FF.S */ 7801/* File: x86/unused.S */ 7802 jmp common_abort 7803 7804 7805/* ------------------------------ */ 7806 .balign 64 7807.L_OP_UNUSED_56FF: /* 0x156 */ 7808/* File: x86/OP_UNUSED_56FF.S */ 7809/* File: x86/unused.S */ 7810 jmp common_abort 7811 7812 7813/* ------------------------------ */ 7814 .balign 64 7815.L_OP_UNUSED_57FF: /* 0x157 */ 7816/* File: x86/OP_UNUSED_57FF.S */ 7817/* File: x86/unused.S */ 7818 jmp common_abort 7819 7820 7821/* ------------------------------ */ 7822 .balign 64 7823.L_OP_UNUSED_58FF: /* 0x158 */ 7824/* File: x86/OP_UNUSED_58FF.S */ 7825/* File: x86/unused.S */ 7826 jmp common_abort 7827 7828 7829/* ------------------------------ */ 7830 .balign 64 7831.L_OP_UNUSED_59FF: /* 0x159 */ 7832/* File: x86/OP_UNUSED_59FF.S */ 7833/* File: x86/unused.S */ 7834 jmp common_abort 7835 7836 7837/* ------------------------------ */ 7838 .balign 64 7839.L_OP_UNUSED_5AFF: /* 0x15a */ 7840/* File: x86/OP_UNUSED_5AFF.S */ 7841/* File: x86/unused.S */ 7842 jmp common_abort 7843 7844 7845/* ------------------------------ */ 7846 .balign 64 7847.L_OP_UNUSED_5BFF: /* 0x15b */ 7848/* File: x86/OP_UNUSED_5BFF.S */ 7849/* File: x86/unused.S */ 7850 jmp common_abort 7851 7852 7853/* ------------------------------ */ 7854 .balign 64 7855.L_OP_UNUSED_5CFF: /* 0x15c */ 7856/* File: x86/OP_UNUSED_5CFF.S */ 7857/* File: x86/unused.S */ 7858 jmp common_abort 7859 7860 7861/* ------------------------------ */ 7862 .balign 64 7863.L_OP_UNUSED_5DFF: /* 0x15d */ 7864/* File: x86/OP_UNUSED_5DFF.S */ 7865/* File: x86/unused.S */ 7866 jmp common_abort 7867 7868 7869/* ------------------------------ */ 7870 .balign 64 7871.L_OP_UNUSED_5EFF: /* 0x15e */ 7872/* File: x86/OP_UNUSED_5EFF.S */ 7873/* File: x86/unused.S */ 7874 jmp common_abort 7875 7876 7877/* ------------------------------ */ 7878 .balign 64 7879.L_OP_UNUSED_5FFF: /* 0x15f */ 7880/* File: x86/OP_UNUSED_5FFF.S */ 7881/* File: x86/unused.S */ 7882 jmp common_abort 7883 7884 7885/* ------------------------------ */ 7886 .balign 64 7887.L_OP_UNUSED_60FF: /* 0x160 */ 7888/* File: x86/OP_UNUSED_60FF.S */ 7889/* File: x86/unused.S */ 7890 jmp common_abort 7891 7892 7893/* ------------------------------ */ 7894 .balign 64 7895.L_OP_UNUSED_61FF: /* 0x161 */ 7896/* File: x86/OP_UNUSED_61FF.S */ 7897/* File: x86/unused.S */ 7898 jmp common_abort 7899 7900 7901/* ------------------------------ */ 7902 .balign 64 7903.L_OP_UNUSED_62FF: /* 0x162 */ 7904/* File: x86/OP_UNUSED_62FF.S */ 7905/* File: x86/unused.S */ 7906 jmp common_abort 7907 7908 7909/* ------------------------------ */ 7910 .balign 64 7911.L_OP_UNUSED_63FF: /* 0x163 */ 7912/* File: x86/OP_UNUSED_63FF.S */ 7913/* File: x86/unused.S */ 7914 jmp common_abort 7915 7916 7917/* ------------------------------ */ 7918 .balign 64 7919.L_OP_UNUSED_64FF: /* 0x164 */ 7920/* File: x86/OP_UNUSED_64FF.S */ 7921/* File: x86/unused.S */ 7922 jmp common_abort 7923 7924 7925/* ------------------------------ */ 7926 .balign 64 7927.L_OP_UNUSED_65FF: /* 0x165 */ 7928/* File: x86/OP_UNUSED_65FF.S */ 7929/* File: x86/unused.S */ 7930 jmp common_abort 7931 7932 7933/* ------------------------------ */ 7934 .balign 64 7935.L_OP_UNUSED_66FF: /* 0x166 */ 7936/* File: x86/OP_UNUSED_66FF.S */ 7937/* File: x86/unused.S */ 7938 jmp common_abort 7939 7940 7941/* ------------------------------ */ 7942 .balign 64 7943.L_OP_UNUSED_67FF: /* 0x167 */ 7944/* File: x86/OP_UNUSED_67FF.S */ 7945/* File: x86/unused.S */ 7946 jmp common_abort 7947 7948 7949/* ------------------------------ */ 7950 .balign 64 7951.L_OP_UNUSED_68FF: /* 0x168 */ 7952/* File: x86/OP_UNUSED_68FF.S */ 7953/* File: x86/unused.S */ 7954 jmp common_abort 7955 7956 7957/* ------------------------------ */ 7958 .balign 64 7959.L_OP_UNUSED_69FF: /* 0x169 */ 7960/* File: x86/OP_UNUSED_69FF.S */ 7961/* File: x86/unused.S */ 7962 jmp common_abort 7963 7964 7965/* ------------------------------ */ 7966 .balign 64 7967.L_OP_UNUSED_6AFF: /* 0x16a */ 7968/* File: x86/OP_UNUSED_6AFF.S */ 7969/* File: x86/unused.S */ 7970 jmp common_abort 7971 7972 7973/* ------------------------------ */ 7974 .balign 64 7975.L_OP_UNUSED_6BFF: /* 0x16b */ 7976/* File: x86/OP_UNUSED_6BFF.S */ 7977/* File: x86/unused.S */ 7978 jmp common_abort 7979 7980 7981/* ------------------------------ */ 7982 .balign 64 7983.L_OP_UNUSED_6CFF: /* 0x16c */ 7984/* File: x86/OP_UNUSED_6CFF.S */ 7985/* File: x86/unused.S */ 7986 jmp common_abort 7987 7988 7989/* ------------------------------ */ 7990 .balign 64 7991.L_OP_UNUSED_6DFF: /* 0x16d */ 7992/* File: x86/OP_UNUSED_6DFF.S */ 7993/* File: x86/unused.S */ 7994 jmp common_abort 7995 7996 7997/* ------------------------------ */ 7998 .balign 64 7999.L_OP_UNUSED_6EFF: /* 0x16e */ 8000/* File: x86/OP_UNUSED_6EFF.S */ 8001/* File: x86/unused.S */ 8002 jmp common_abort 8003 8004 8005/* ------------------------------ */ 8006 .balign 64 8007.L_OP_UNUSED_6FFF: /* 0x16f */ 8008/* File: x86/OP_UNUSED_6FFF.S */ 8009/* File: x86/unused.S */ 8010 jmp common_abort 8011 8012 8013/* ------------------------------ */ 8014 .balign 64 8015.L_OP_UNUSED_70FF: /* 0x170 */ 8016/* File: x86/OP_UNUSED_70FF.S */ 8017/* File: x86/unused.S */ 8018 jmp common_abort 8019 8020 8021/* ------------------------------ */ 8022 .balign 64 8023.L_OP_UNUSED_71FF: /* 0x171 */ 8024/* File: x86/OP_UNUSED_71FF.S */ 8025/* File: x86/unused.S */ 8026 jmp common_abort 8027 8028 8029/* ------------------------------ */ 8030 .balign 64 8031.L_OP_UNUSED_72FF: /* 0x172 */ 8032/* File: x86/OP_UNUSED_72FF.S */ 8033/* File: x86/unused.S */ 8034 jmp common_abort 8035 8036 8037/* ------------------------------ */ 8038 .balign 64 8039.L_OP_UNUSED_73FF: /* 0x173 */ 8040/* File: x86/OP_UNUSED_73FF.S */ 8041/* File: x86/unused.S */ 8042 jmp common_abort 8043 8044 8045/* ------------------------------ */ 8046 .balign 64 8047.L_OP_UNUSED_74FF: /* 0x174 */ 8048/* File: x86/OP_UNUSED_74FF.S */ 8049/* File: x86/unused.S */ 8050 jmp common_abort 8051 8052 8053/* ------------------------------ */ 8054 .balign 64 8055.L_OP_UNUSED_75FF: /* 0x175 */ 8056/* File: x86/OP_UNUSED_75FF.S */ 8057/* File: x86/unused.S */ 8058 jmp common_abort 8059 8060 8061/* ------------------------------ */ 8062 .balign 64 8063.L_OP_UNUSED_76FF: /* 0x176 */ 8064/* File: x86/OP_UNUSED_76FF.S */ 8065/* File: x86/unused.S */ 8066 jmp common_abort 8067 8068 8069/* ------------------------------ */ 8070 .balign 64 8071.L_OP_UNUSED_77FF: /* 0x177 */ 8072/* File: x86/OP_UNUSED_77FF.S */ 8073/* File: x86/unused.S */ 8074 jmp common_abort 8075 8076 8077/* ------------------------------ */ 8078 .balign 64 8079.L_OP_UNUSED_78FF: /* 0x178 */ 8080/* File: x86/OP_UNUSED_78FF.S */ 8081/* File: x86/unused.S */ 8082 jmp common_abort 8083 8084 8085/* ------------------------------ */ 8086 .balign 64 8087.L_OP_UNUSED_79FF: /* 0x179 */ 8088/* File: x86/OP_UNUSED_79FF.S */ 8089/* File: x86/unused.S */ 8090 jmp common_abort 8091 8092 8093/* ------------------------------ */ 8094 .balign 64 8095.L_OP_UNUSED_7AFF: /* 0x17a */ 8096/* File: x86/OP_UNUSED_7AFF.S */ 8097/* File: x86/unused.S */ 8098 jmp common_abort 8099 8100 8101/* ------------------------------ */ 8102 .balign 64 8103.L_OP_UNUSED_7BFF: /* 0x17b */ 8104/* File: x86/OP_UNUSED_7BFF.S */ 8105/* File: x86/unused.S */ 8106 jmp common_abort 8107 8108 8109/* ------------------------------ */ 8110 .balign 64 8111.L_OP_UNUSED_7CFF: /* 0x17c */ 8112/* File: x86/OP_UNUSED_7CFF.S */ 8113/* File: x86/unused.S */ 8114 jmp common_abort 8115 8116 8117/* ------------------------------ */ 8118 .balign 64 8119.L_OP_UNUSED_7DFF: /* 0x17d */ 8120/* File: x86/OP_UNUSED_7DFF.S */ 8121/* File: x86/unused.S */ 8122 jmp common_abort 8123 8124 8125/* ------------------------------ */ 8126 .balign 64 8127.L_OP_UNUSED_7EFF: /* 0x17e */ 8128/* File: x86/OP_UNUSED_7EFF.S */ 8129/* File: x86/unused.S */ 8130 jmp common_abort 8131 8132 8133/* ------------------------------ */ 8134 .balign 64 8135.L_OP_UNUSED_7FFF: /* 0x17f */ 8136/* File: x86/OP_UNUSED_7FFF.S */ 8137/* File: x86/unused.S */ 8138 jmp common_abort 8139 8140 8141/* ------------------------------ */ 8142 .balign 64 8143.L_OP_UNUSED_80FF: /* 0x180 */ 8144/* File: x86/OP_UNUSED_80FF.S */ 8145/* File: x86/unused.S */ 8146 jmp common_abort 8147 8148 8149/* ------------------------------ */ 8150 .balign 64 8151.L_OP_UNUSED_81FF: /* 0x181 */ 8152/* File: x86/OP_UNUSED_81FF.S */ 8153/* File: x86/unused.S */ 8154 jmp common_abort 8155 8156 8157/* ------------------------------ */ 8158 .balign 64 8159.L_OP_UNUSED_82FF: /* 0x182 */ 8160/* File: x86/OP_UNUSED_82FF.S */ 8161/* File: x86/unused.S */ 8162 jmp common_abort 8163 8164 8165/* ------------------------------ */ 8166 .balign 64 8167.L_OP_UNUSED_83FF: /* 0x183 */ 8168/* File: x86/OP_UNUSED_83FF.S */ 8169/* File: x86/unused.S */ 8170 jmp common_abort 8171 8172 8173/* ------------------------------ */ 8174 .balign 64 8175.L_OP_UNUSED_84FF: /* 0x184 */ 8176/* File: x86/OP_UNUSED_84FF.S */ 8177/* File: x86/unused.S */ 8178 jmp common_abort 8179 8180 8181/* ------------------------------ */ 8182 .balign 64 8183.L_OP_UNUSED_85FF: /* 0x185 */ 8184/* File: x86/OP_UNUSED_85FF.S */ 8185/* File: x86/unused.S */ 8186 jmp common_abort 8187 8188 8189/* ------------------------------ */ 8190 .balign 64 8191.L_OP_UNUSED_86FF: /* 0x186 */ 8192/* File: x86/OP_UNUSED_86FF.S */ 8193/* File: x86/unused.S */ 8194 jmp common_abort 8195 8196 8197/* ------------------------------ */ 8198 .balign 64 8199.L_OP_UNUSED_87FF: /* 0x187 */ 8200/* File: x86/OP_UNUSED_87FF.S */ 8201/* File: x86/unused.S */ 8202 jmp common_abort 8203 8204 8205/* ------------------------------ */ 8206 .balign 64 8207.L_OP_UNUSED_88FF: /* 0x188 */ 8208/* File: x86/OP_UNUSED_88FF.S */ 8209/* File: x86/unused.S */ 8210 jmp common_abort 8211 8212 8213/* ------------------------------ */ 8214 .balign 64 8215.L_OP_UNUSED_89FF: /* 0x189 */ 8216/* File: x86/OP_UNUSED_89FF.S */ 8217/* File: x86/unused.S */ 8218 jmp common_abort 8219 8220 8221/* ------------------------------ */ 8222 .balign 64 8223.L_OP_UNUSED_8AFF: /* 0x18a */ 8224/* File: x86/OP_UNUSED_8AFF.S */ 8225/* File: x86/unused.S */ 8226 jmp common_abort 8227 8228 8229/* ------------------------------ */ 8230 .balign 64 8231.L_OP_UNUSED_8BFF: /* 0x18b */ 8232/* File: x86/OP_UNUSED_8BFF.S */ 8233/* File: x86/unused.S */ 8234 jmp common_abort 8235 8236 8237/* ------------------------------ */ 8238 .balign 64 8239.L_OP_UNUSED_8CFF: /* 0x18c */ 8240/* File: x86/OP_UNUSED_8CFF.S */ 8241/* File: x86/unused.S */ 8242 jmp common_abort 8243 8244 8245/* ------------------------------ */ 8246 .balign 64 8247.L_OP_UNUSED_8DFF: /* 0x18d */ 8248/* File: x86/OP_UNUSED_8DFF.S */ 8249/* File: x86/unused.S */ 8250 jmp common_abort 8251 8252 8253/* ------------------------------ */ 8254 .balign 64 8255.L_OP_UNUSED_8EFF: /* 0x18e */ 8256/* File: x86/OP_UNUSED_8EFF.S */ 8257/* File: x86/unused.S */ 8258 jmp common_abort 8259 8260 8261/* ------------------------------ */ 8262 .balign 64 8263.L_OP_UNUSED_8FFF: /* 0x18f */ 8264/* File: x86/OP_UNUSED_8FFF.S */ 8265/* File: x86/unused.S */ 8266 jmp common_abort 8267 8268 8269/* ------------------------------ */ 8270 .balign 64 8271.L_OP_UNUSED_90FF: /* 0x190 */ 8272/* File: x86/OP_UNUSED_90FF.S */ 8273/* File: x86/unused.S */ 8274 jmp common_abort 8275 8276 8277/* ------------------------------ */ 8278 .balign 64 8279.L_OP_UNUSED_91FF: /* 0x191 */ 8280/* File: x86/OP_UNUSED_91FF.S */ 8281/* File: x86/unused.S */ 8282 jmp common_abort 8283 8284 8285/* ------------------------------ */ 8286 .balign 64 8287.L_OP_UNUSED_92FF: /* 0x192 */ 8288/* File: x86/OP_UNUSED_92FF.S */ 8289/* File: x86/unused.S */ 8290 jmp common_abort 8291 8292 8293/* ------------------------------ */ 8294 .balign 64 8295.L_OP_UNUSED_93FF: /* 0x193 */ 8296/* File: x86/OP_UNUSED_93FF.S */ 8297/* File: x86/unused.S */ 8298 jmp common_abort 8299 8300 8301/* ------------------------------ */ 8302 .balign 64 8303.L_OP_UNUSED_94FF: /* 0x194 */ 8304/* File: x86/OP_UNUSED_94FF.S */ 8305/* File: x86/unused.S */ 8306 jmp common_abort 8307 8308 8309/* ------------------------------ */ 8310 .balign 64 8311.L_OP_UNUSED_95FF: /* 0x195 */ 8312/* File: x86/OP_UNUSED_95FF.S */ 8313/* File: x86/unused.S */ 8314 jmp common_abort 8315 8316 8317/* ------------------------------ */ 8318 .balign 64 8319.L_OP_UNUSED_96FF: /* 0x196 */ 8320/* File: x86/OP_UNUSED_96FF.S */ 8321/* File: x86/unused.S */ 8322 jmp common_abort 8323 8324 8325/* ------------------------------ */ 8326 .balign 64 8327.L_OP_UNUSED_97FF: /* 0x197 */ 8328/* File: x86/OP_UNUSED_97FF.S */ 8329/* File: x86/unused.S */ 8330 jmp common_abort 8331 8332 8333/* ------------------------------ */ 8334 .balign 64 8335.L_OP_UNUSED_98FF: /* 0x198 */ 8336/* File: x86/OP_UNUSED_98FF.S */ 8337/* File: x86/unused.S */ 8338 jmp common_abort 8339 8340 8341/* ------------------------------ */ 8342 .balign 64 8343.L_OP_UNUSED_99FF: /* 0x199 */ 8344/* File: x86/OP_UNUSED_99FF.S */ 8345/* File: x86/unused.S */ 8346 jmp common_abort 8347 8348 8349/* ------------------------------ */ 8350 .balign 64 8351.L_OP_UNUSED_9AFF: /* 0x19a */ 8352/* File: x86/OP_UNUSED_9AFF.S */ 8353/* File: x86/unused.S */ 8354 jmp common_abort 8355 8356 8357/* ------------------------------ */ 8358 .balign 64 8359.L_OP_UNUSED_9BFF: /* 0x19b */ 8360/* File: x86/OP_UNUSED_9BFF.S */ 8361/* File: x86/unused.S */ 8362 jmp common_abort 8363 8364 8365/* ------------------------------ */ 8366 .balign 64 8367.L_OP_UNUSED_9CFF: /* 0x19c */ 8368/* File: x86/OP_UNUSED_9CFF.S */ 8369/* File: x86/unused.S */ 8370 jmp common_abort 8371 8372 8373/* ------------------------------ */ 8374 .balign 64 8375.L_OP_UNUSED_9DFF: /* 0x19d */ 8376/* File: x86/OP_UNUSED_9DFF.S */ 8377/* File: x86/unused.S */ 8378 jmp common_abort 8379 8380 8381/* ------------------------------ */ 8382 .balign 64 8383.L_OP_UNUSED_9EFF: /* 0x19e */ 8384/* File: x86/OP_UNUSED_9EFF.S */ 8385/* File: x86/unused.S */ 8386 jmp common_abort 8387 8388 8389/* ------------------------------ */ 8390 .balign 64 8391.L_OP_UNUSED_9FFF: /* 0x19f */ 8392/* File: x86/OP_UNUSED_9FFF.S */ 8393/* File: x86/unused.S */ 8394 jmp common_abort 8395 8396 8397/* ------------------------------ */ 8398 .balign 64 8399.L_OP_UNUSED_A0FF: /* 0x1a0 */ 8400/* File: x86/OP_UNUSED_A0FF.S */ 8401/* File: x86/unused.S */ 8402 jmp common_abort 8403 8404 8405/* ------------------------------ */ 8406 .balign 64 8407.L_OP_UNUSED_A1FF: /* 0x1a1 */ 8408/* File: x86/OP_UNUSED_A1FF.S */ 8409/* File: x86/unused.S */ 8410 jmp common_abort 8411 8412 8413/* ------------------------------ */ 8414 .balign 64 8415.L_OP_UNUSED_A2FF: /* 0x1a2 */ 8416/* File: x86/OP_UNUSED_A2FF.S */ 8417/* File: x86/unused.S */ 8418 jmp common_abort 8419 8420 8421/* ------------------------------ */ 8422 .balign 64 8423.L_OP_UNUSED_A3FF: /* 0x1a3 */ 8424/* File: x86/OP_UNUSED_A3FF.S */ 8425/* File: x86/unused.S */ 8426 jmp common_abort 8427 8428 8429/* ------------------------------ */ 8430 .balign 64 8431.L_OP_UNUSED_A4FF: /* 0x1a4 */ 8432/* File: x86/OP_UNUSED_A4FF.S */ 8433/* File: x86/unused.S */ 8434 jmp common_abort 8435 8436 8437/* ------------------------------ */ 8438 .balign 64 8439.L_OP_UNUSED_A5FF: /* 0x1a5 */ 8440/* File: x86/OP_UNUSED_A5FF.S */ 8441/* File: x86/unused.S */ 8442 jmp common_abort 8443 8444 8445/* ------------------------------ */ 8446 .balign 64 8447.L_OP_UNUSED_A6FF: /* 0x1a6 */ 8448/* File: x86/OP_UNUSED_A6FF.S */ 8449/* File: x86/unused.S */ 8450 jmp common_abort 8451 8452 8453/* ------------------------------ */ 8454 .balign 64 8455.L_OP_UNUSED_A7FF: /* 0x1a7 */ 8456/* File: x86/OP_UNUSED_A7FF.S */ 8457/* File: x86/unused.S */ 8458 jmp common_abort 8459 8460 8461/* ------------------------------ */ 8462 .balign 64 8463.L_OP_UNUSED_A8FF: /* 0x1a8 */ 8464/* File: x86/OP_UNUSED_A8FF.S */ 8465/* File: x86/unused.S */ 8466 jmp common_abort 8467 8468 8469/* ------------------------------ */ 8470 .balign 64 8471.L_OP_UNUSED_A9FF: /* 0x1a9 */ 8472/* File: x86/OP_UNUSED_A9FF.S */ 8473/* File: x86/unused.S */ 8474 jmp common_abort 8475 8476 8477/* ------------------------------ */ 8478 .balign 64 8479.L_OP_UNUSED_AAFF: /* 0x1aa */ 8480/* File: x86/OP_UNUSED_AAFF.S */ 8481/* File: x86/unused.S */ 8482 jmp common_abort 8483 8484 8485/* ------------------------------ */ 8486 .balign 64 8487.L_OP_UNUSED_ABFF: /* 0x1ab */ 8488/* File: x86/OP_UNUSED_ABFF.S */ 8489/* File: x86/unused.S */ 8490 jmp common_abort 8491 8492 8493/* ------------------------------ */ 8494 .balign 64 8495.L_OP_UNUSED_ACFF: /* 0x1ac */ 8496/* File: x86/OP_UNUSED_ACFF.S */ 8497/* File: x86/unused.S */ 8498 jmp common_abort 8499 8500 8501/* ------------------------------ */ 8502 .balign 64 8503.L_OP_UNUSED_ADFF: /* 0x1ad */ 8504/* File: x86/OP_UNUSED_ADFF.S */ 8505/* File: x86/unused.S */ 8506 jmp common_abort 8507 8508 8509/* ------------------------------ */ 8510 .balign 64 8511.L_OP_UNUSED_AEFF: /* 0x1ae */ 8512/* File: x86/OP_UNUSED_AEFF.S */ 8513/* File: x86/unused.S */ 8514 jmp common_abort 8515 8516 8517/* ------------------------------ */ 8518 .balign 64 8519.L_OP_UNUSED_AFFF: /* 0x1af */ 8520/* File: x86/OP_UNUSED_AFFF.S */ 8521/* File: x86/unused.S */ 8522 jmp common_abort 8523 8524 8525/* ------------------------------ */ 8526 .balign 64 8527.L_OP_UNUSED_B0FF: /* 0x1b0 */ 8528/* File: x86/OP_UNUSED_B0FF.S */ 8529/* File: x86/unused.S */ 8530 jmp common_abort 8531 8532 8533/* ------------------------------ */ 8534 .balign 64 8535.L_OP_UNUSED_B1FF: /* 0x1b1 */ 8536/* File: x86/OP_UNUSED_B1FF.S */ 8537/* File: x86/unused.S */ 8538 jmp common_abort 8539 8540 8541/* ------------------------------ */ 8542 .balign 64 8543.L_OP_UNUSED_B2FF: /* 0x1b2 */ 8544/* File: x86/OP_UNUSED_B2FF.S */ 8545/* File: x86/unused.S */ 8546 jmp common_abort 8547 8548 8549/* ------------------------------ */ 8550 .balign 64 8551.L_OP_UNUSED_B3FF: /* 0x1b3 */ 8552/* File: x86/OP_UNUSED_B3FF.S */ 8553/* File: x86/unused.S */ 8554 jmp common_abort 8555 8556 8557/* ------------------------------ */ 8558 .balign 64 8559.L_OP_UNUSED_B4FF: /* 0x1b4 */ 8560/* File: x86/OP_UNUSED_B4FF.S */ 8561/* File: x86/unused.S */ 8562 jmp common_abort 8563 8564 8565/* ------------------------------ */ 8566 .balign 64 8567.L_OP_UNUSED_B5FF: /* 0x1b5 */ 8568/* File: x86/OP_UNUSED_B5FF.S */ 8569/* File: x86/unused.S */ 8570 jmp common_abort 8571 8572 8573/* ------------------------------ */ 8574 .balign 64 8575.L_OP_UNUSED_B6FF: /* 0x1b6 */ 8576/* File: x86/OP_UNUSED_B6FF.S */ 8577/* File: x86/unused.S */ 8578 jmp common_abort 8579 8580 8581/* ------------------------------ */ 8582 .balign 64 8583.L_OP_UNUSED_B7FF: /* 0x1b7 */ 8584/* File: x86/OP_UNUSED_B7FF.S */ 8585/* File: x86/unused.S */ 8586 jmp common_abort 8587 8588 8589/* ------------------------------ */ 8590 .balign 64 8591.L_OP_UNUSED_B8FF: /* 0x1b8 */ 8592/* File: x86/OP_UNUSED_B8FF.S */ 8593/* File: x86/unused.S */ 8594 jmp common_abort 8595 8596 8597/* ------------------------------ */ 8598 .balign 64 8599.L_OP_UNUSED_B9FF: /* 0x1b9 */ 8600/* File: x86/OP_UNUSED_B9FF.S */ 8601/* File: x86/unused.S */ 8602 jmp common_abort 8603 8604 8605/* ------------------------------ */ 8606 .balign 64 8607.L_OP_UNUSED_BAFF: /* 0x1ba */ 8608/* File: x86/OP_UNUSED_BAFF.S */ 8609/* File: x86/unused.S */ 8610 jmp common_abort 8611 8612 8613/* ------------------------------ */ 8614 .balign 64 8615.L_OP_UNUSED_BBFF: /* 0x1bb */ 8616/* File: x86/OP_UNUSED_BBFF.S */ 8617/* File: x86/unused.S */ 8618 jmp common_abort 8619 8620 8621/* ------------------------------ */ 8622 .balign 64 8623.L_OP_UNUSED_BCFF: /* 0x1bc */ 8624/* File: x86/OP_UNUSED_BCFF.S */ 8625/* File: x86/unused.S */ 8626 jmp common_abort 8627 8628 8629/* ------------------------------ */ 8630 .balign 64 8631.L_OP_UNUSED_BDFF: /* 0x1bd */ 8632/* File: x86/OP_UNUSED_BDFF.S */ 8633/* File: x86/unused.S */ 8634 jmp common_abort 8635 8636 8637/* ------------------------------ */ 8638 .balign 64 8639.L_OP_UNUSED_BEFF: /* 0x1be */ 8640/* File: x86/OP_UNUSED_BEFF.S */ 8641/* File: x86/unused.S */ 8642 jmp common_abort 8643 8644 8645/* ------------------------------ */ 8646 .balign 64 8647.L_OP_UNUSED_BFFF: /* 0x1bf */ 8648/* File: x86/OP_UNUSED_BFFF.S */ 8649/* File: x86/unused.S */ 8650 jmp common_abort 8651 8652 8653/* ------------------------------ */ 8654 .balign 64 8655.L_OP_UNUSED_C0FF: /* 0x1c0 */ 8656/* File: x86/OP_UNUSED_C0FF.S */ 8657/* File: x86/unused.S */ 8658 jmp common_abort 8659 8660 8661/* ------------------------------ */ 8662 .balign 64 8663.L_OP_UNUSED_C1FF: /* 0x1c1 */ 8664/* File: x86/OP_UNUSED_C1FF.S */ 8665/* File: x86/unused.S */ 8666 jmp common_abort 8667 8668 8669/* ------------------------------ */ 8670 .balign 64 8671.L_OP_UNUSED_C2FF: /* 0x1c2 */ 8672/* File: x86/OP_UNUSED_C2FF.S */ 8673/* File: x86/unused.S */ 8674 jmp common_abort 8675 8676 8677/* ------------------------------ */ 8678 .balign 64 8679.L_OP_UNUSED_C3FF: /* 0x1c3 */ 8680/* File: x86/OP_UNUSED_C3FF.S */ 8681/* File: x86/unused.S */ 8682 jmp common_abort 8683 8684 8685/* ------------------------------ */ 8686 .balign 64 8687.L_OP_UNUSED_C4FF: /* 0x1c4 */ 8688/* File: x86/OP_UNUSED_C4FF.S */ 8689/* File: x86/unused.S */ 8690 jmp common_abort 8691 8692 8693/* ------------------------------ */ 8694 .balign 64 8695.L_OP_UNUSED_C5FF: /* 0x1c5 */ 8696/* File: x86/OP_UNUSED_C5FF.S */ 8697/* File: x86/unused.S */ 8698 jmp common_abort 8699 8700 8701/* ------------------------------ */ 8702 .balign 64 8703.L_OP_UNUSED_C6FF: /* 0x1c6 */ 8704/* File: x86/OP_UNUSED_C6FF.S */ 8705/* File: x86/unused.S */ 8706 jmp common_abort 8707 8708 8709/* ------------------------------ */ 8710 .balign 64 8711.L_OP_UNUSED_C7FF: /* 0x1c7 */ 8712/* File: x86/OP_UNUSED_C7FF.S */ 8713/* File: x86/unused.S */ 8714 jmp common_abort 8715 8716 8717/* ------------------------------ */ 8718 .balign 64 8719.L_OP_UNUSED_C8FF: /* 0x1c8 */ 8720/* File: x86/OP_UNUSED_C8FF.S */ 8721/* File: x86/unused.S */ 8722 jmp common_abort 8723 8724 8725/* ------------------------------ */ 8726 .balign 64 8727.L_OP_UNUSED_C9FF: /* 0x1c9 */ 8728/* File: x86/OP_UNUSED_C9FF.S */ 8729/* File: x86/unused.S */ 8730 jmp common_abort 8731 8732 8733/* ------------------------------ */ 8734 .balign 64 8735.L_OP_UNUSED_CAFF: /* 0x1ca */ 8736/* File: x86/OP_UNUSED_CAFF.S */ 8737/* File: x86/unused.S */ 8738 jmp common_abort 8739 8740 8741/* ------------------------------ */ 8742 .balign 64 8743.L_OP_UNUSED_CBFF: /* 0x1cb */ 8744/* File: x86/OP_UNUSED_CBFF.S */ 8745/* File: x86/unused.S */ 8746 jmp common_abort 8747 8748 8749/* ------------------------------ */ 8750 .balign 64 8751.L_OP_UNUSED_CCFF: /* 0x1cc */ 8752/* File: x86/OP_UNUSED_CCFF.S */ 8753/* File: x86/unused.S */ 8754 jmp common_abort 8755 8756 8757/* ------------------------------ */ 8758 .balign 64 8759.L_OP_UNUSED_CDFF: /* 0x1cd */ 8760/* File: x86/OP_UNUSED_CDFF.S */ 8761/* File: x86/unused.S */ 8762 jmp common_abort 8763 8764 8765/* ------------------------------ */ 8766 .balign 64 8767.L_OP_UNUSED_CEFF: /* 0x1ce */ 8768/* File: x86/OP_UNUSED_CEFF.S */ 8769/* File: x86/unused.S */ 8770 jmp common_abort 8771 8772 8773/* ------------------------------ */ 8774 .balign 64 8775.L_OP_UNUSED_CFFF: /* 0x1cf */ 8776/* File: x86/OP_UNUSED_CFFF.S */ 8777/* File: x86/unused.S */ 8778 jmp common_abort 8779 8780 8781/* ------------------------------ */ 8782 .balign 64 8783.L_OP_UNUSED_D0FF: /* 0x1d0 */ 8784/* File: x86/OP_UNUSED_D0FF.S */ 8785/* File: x86/unused.S */ 8786 jmp common_abort 8787 8788 8789/* ------------------------------ */ 8790 .balign 64 8791.L_OP_UNUSED_D1FF: /* 0x1d1 */ 8792/* File: x86/OP_UNUSED_D1FF.S */ 8793/* File: x86/unused.S */ 8794 jmp common_abort 8795 8796 8797/* ------------------------------ */ 8798 .balign 64 8799.L_OP_UNUSED_D2FF: /* 0x1d2 */ 8800/* File: x86/OP_UNUSED_D2FF.S */ 8801/* File: x86/unused.S */ 8802 jmp common_abort 8803 8804 8805/* ------------------------------ */ 8806 .balign 64 8807.L_OP_UNUSED_D3FF: /* 0x1d3 */ 8808/* File: x86/OP_UNUSED_D3FF.S */ 8809/* File: x86/unused.S */ 8810 jmp common_abort 8811 8812 8813/* ------------------------------ */ 8814 .balign 64 8815.L_OP_UNUSED_D4FF: /* 0x1d4 */ 8816/* File: x86/OP_UNUSED_D4FF.S */ 8817/* File: x86/unused.S */ 8818 jmp common_abort 8819 8820 8821/* ------------------------------ */ 8822 .balign 64 8823.L_OP_UNUSED_D5FF: /* 0x1d5 */ 8824/* File: x86/OP_UNUSED_D5FF.S */ 8825/* File: x86/unused.S */ 8826 jmp common_abort 8827 8828 8829/* ------------------------------ */ 8830 .balign 64 8831.L_OP_UNUSED_D6FF: /* 0x1d6 */ 8832/* File: x86/OP_UNUSED_D6FF.S */ 8833/* File: x86/unused.S */ 8834 jmp common_abort 8835 8836 8837/* ------------------------------ */ 8838 .balign 64 8839.L_OP_UNUSED_D7FF: /* 0x1d7 */ 8840/* File: x86/OP_UNUSED_D7FF.S */ 8841/* File: x86/unused.S */ 8842 jmp common_abort 8843 8844 8845/* ------------------------------ */ 8846 .balign 64 8847.L_OP_UNUSED_D8FF: /* 0x1d8 */ 8848/* File: x86/OP_UNUSED_D8FF.S */ 8849/* File: x86/unused.S */ 8850 jmp common_abort 8851 8852 8853/* ------------------------------ */ 8854 .balign 64 8855.L_OP_UNUSED_D9FF: /* 0x1d9 */ 8856/* File: x86/OP_UNUSED_D9FF.S */ 8857/* File: x86/unused.S */ 8858 jmp common_abort 8859 8860 8861/* ------------------------------ */ 8862 .balign 64 8863.L_OP_UNUSED_DAFF: /* 0x1da */ 8864/* File: x86/OP_UNUSED_DAFF.S */ 8865/* File: x86/unused.S */ 8866 jmp common_abort 8867 8868 8869/* ------------------------------ */ 8870 .balign 64 8871.L_OP_UNUSED_DBFF: /* 0x1db */ 8872/* File: x86/OP_UNUSED_DBFF.S */ 8873/* File: x86/unused.S */ 8874 jmp common_abort 8875 8876 8877/* ------------------------------ */ 8878 .balign 64 8879.L_OP_UNUSED_DCFF: /* 0x1dc */ 8880/* File: x86/OP_UNUSED_DCFF.S */ 8881/* File: x86/unused.S */ 8882 jmp common_abort 8883 8884 8885/* ------------------------------ */ 8886 .balign 64 8887.L_OP_UNUSED_DDFF: /* 0x1dd */ 8888/* File: x86/OP_UNUSED_DDFF.S */ 8889/* File: x86/unused.S */ 8890 jmp common_abort 8891 8892 8893/* ------------------------------ */ 8894 .balign 64 8895.L_OP_UNUSED_DEFF: /* 0x1de */ 8896/* File: x86/OP_UNUSED_DEFF.S */ 8897/* File: x86/unused.S */ 8898 jmp common_abort 8899 8900 8901/* ------------------------------ */ 8902 .balign 64 8903.L_OP_UNUSED_DFFF: /* 0x1df */ 8904/* File: x86/OP_UNUSED_DFFF.S */ 8905/* File: x86/unused.S */ 8906 jmp common_abort 8907 8908 8909/* ------------------------------ */ 8910 .balign 64 8911.L_OP_UNUSED_E0FF: /* 0x1e0 */ 8912/* File: x86/OP_UNUSED_E0FF.S */ 8913/* File: x86/unused.S */ 8914 jmp common_abort 8915 8916 8917/* ------------------------------ */ 8918 .balign 64 8919.L_OP_UNUSED_E1FF: /* 0x1e1 */ 8920/* File: x86/OP_UNUSED_E1FF.S */ 8921/* File: x86/unused.S */ 8922 jmp common_abort 8923 8924 8925/* ------------------------------ */ 8926 .balign 64 8927.L_OP_UNUSED_E2FF: /* 0x1e2 */ 8928/* File: x86/OP_UNUSED_E2FF.S */ 8929/* File: x86/unused.S */ 8930 jmp common_abort 8931 8932 8933/* ------------------------------ */ 8934 .balign 64 8935.L_OP_UNUSED_E3FF: /* 0x1e3 */ 8936/* File: x86/OP_UNUSED_E3FF.S */ 8937/* File: x86/unused.S */ 8938 jmp common_abort 8939 8940 8941/* ------------------------------ */ 8942 .balign 64 8943.L_OP_UNUSED_E4FF: /* 0x1e4 */ 8944/* File: x86/OP_UNUSED_E4FF.S */ 8945/* File: x86/unused.S */ 8946 jmp common_abort 8947 8948 8949/* ------------------------------ */ 8950 .balign 64 8951.L_OP_UNUSED_E5FF: /* 0x1e5 */ 8952/* File: x86/OP_UNUSED_E5FF.S */ 8953/* File: x86/unused.S */ 8954 jmp common_abort 8955 8956 8957/* ------------------------------ */ 8958 .balign 64 8959.L_OP_UNUSED_E6FF: /* 0x1e6 */ 8960/* File: x86/OP_UNUSED_E6FF.S */ 8961/* File: x86/unused.S */ 8962 jmp common_abort 8963 8964 8965/* ------------------------------ */ 8966 .balign 64 8967.L_OP_UNUSED_E7FF: /* 0x1e7 */ 8968/* File: x86/OP_UNUSED_E7FF.S */ 8969/* File: x86/unused.S */ 8970 jmp common_abort 8971 8972 8973/* ------------------------------ */ 8974 .balign 64 8975.L_OP_UNUSED_E8FF: /* 0x1e8 */ 8976/* File: x86/OP_UNUSED_E8FF.S */ 8977/* File: x86/unused.S */ 8978 jmp common_abort 8979 8980 8981/* ------------------------------ */ 8982 .balign 64 8983.L_OP_UNUSED_E9FF: /* 0x1e9 */ 8984/* File: x86/OP_UNUSED_E9FF.S */ 8985/* File: x86/unused.S */ 8986 jmp common_abort 8987 8988 8989/* ------------------------------ */ 8990 .balign 64 8991.L_OP_UNUSED_EAFF: /* 0x1ea */ 8992/* File: x86/OP_UNUSED_EAFF.S */ 8993/* File: x86/unused.S */ 8994 jmp common_abort 8995 8996 8997/* ------------------------------ */ 8998 .balign 64 8999.L_OP_UNUSED_EBFF: /* 0x1eb */ 9000/* File: x86/OP_UNUSED_EBFF.S */ 9001/* File: x86/unused.S */ 9002 jmp common_abort 9003 9004 9005/* ------------------------------ */ 9006 .balign 64 9007.L_OP_UNUSED_ECFF: /* 0x1ec */ 9008/* File: x86/OP_UNUSED_ECFF.S */ 9009/* File: x86/unused.S */ 9010 jmp common_abort 9011 9012 9013/* ------------------------------ */ 9014 .balign 64 9015.L_OP_UNUSED_EDFF: /* 0x1ed */ 9016/* File: x86/OP_UNUSED_EDFF.S */ 9017/* File: x86/unused.S */ 9018 jmp common_abort 9019 9020 9021/* ------------------------------ */ 9022 .balign 64 9023.L_OP_UNUSED_EEFF: /* 0x1ee */ 9024/* File: x86/OP_UNUSED_EEFF.S */ 9025/* File: x86/unused.S */ 9026 jmp common_abort 9027 9028 9029/* ------------------------------ */ 9030 .balign 64 9031.L_OP_UNUSED_EFFF: /* 0x1ef */ 9032/* File: x86/OP_UNUSED_EFFF.S */ 9033/* File: x86/unused.S */ 9034 jmp common_abort 9035 9036 9037/* ------------------------------ */ 9038 .balign 64 9039.L_OP_UNUSED_F0FF: /* 0x1f0 */ 9040/* File: x86/OP_UNUSED_F0FF.S */ 9041/* File: x86/unused.S */ 9042 jmp common_abort 9043 9044 9045/* ------------------------------ */ 9046 .balign 64 9047.L_OP_UNUSED_F1FF: /* 0x1f1 */ 9048/* File: x86/OP_UNUSED_F1FF.S */ 9049/* File: x86/unused.S */ 9050 jmp common_abort 9051 9052 9053/* ------------------------------ */ 9054 .balign 64 9055.L_OP_UNUSED_F2FF: /* 0x1f2 */ 9056/* File: x86/OP_UNUSED_F2FF.S */ 9057/* File: x86/unused.S */ 9058 jmp common_abort 9059 9060 9061/* ------------------------------ */ 9062 .balign 64 9063.L_OP_UNUSED_F3FF: /* 0x1f3 */ 9064/* File: x86/OP_UNUSED_F3FF.S */ 9065/* File: x86/unused.S */ 9066 jmp common_abort 9067 9068 9069/* ------------------------------ */ 9070 .balign 64 9071.L_OP_UNUSED_F4FF: /* 0x1f4 */ 9072/* File: x86/OP_UNUSED_F4FF.S */ 9073/* File: x86/unused.S */ 9074 jmp common_abort 9075 9076 9077/* ------------------------------ */ 9078 .balign 64 9079.L_OP_UNUSED_F5FF: /* 0x1f5 */ 9080/* File: x86/OP_UNUSED_F5FF.S */ 9081/* File: x86/unused.S */ 9082 jmp common_abort 9083 9084 9085/* ------------------------------ */ 9086 .balign 64 9087.L_OP_UNUSED_F6FF: /* 0x1f6 */ 9088/* File: x86/OP_UNUSED_F6FF.S */ 9089/* File: x86/unused.S */ 9090 jmp common_abort 9091 9092 9093/* ------------------------------ */ 9094 .balign 64 9095.L_OP_UNUSED_F7FF: /* 0x1f7 */ 9096/* File: x86/OP_UNUSED_F7FF.S */ 9097/* File: x86/unused.S */ 9098 jmp common_abort 9099 9100 9101/* ------------------------------ */ 9102 .balign 64 9103.L_OP_UNUSED_F8FF: /* 0x1f8 */ 9104/* File: x86/OP_UNUSED_F8FF.S */ 9105/* File: x86/unused.S */ 9106 jmp common_abort 9107 9108 9109/* ------------------------------ */ 9110 .balign 64 9111.L_OP_UNUSED_F9FF: /* 0x1f9 */ 9112/* File: x86/OP_UNUSED_F9FF.S */ 9113/* File: x86/unused.S */ 9114 jmp common_abort 9115 9116 9117/* ------------------------------ */ 9118 .balign 64 9119.L_OP_UNUSED_FAFF: /* 0x1fa */ 9120/* File: x86/OP_UNUSED_FAFF.S */ 9121/* File: x86/unused.S */ 9122 jmp common_abort 9123 9124 9125/* ------------------------------ */ 9126 .balign 64 9127.L_OP_UNUSED_FBFF: /* 0x1fb */ 9128/* File: x86/OP_UNUSED_FBFF.S */ 9129/* File: x86/unused.S */ 9130 jmp common_abort 9131 9132 9133/* ------------------------------ */ 9134 .balign 64 9135.L_OP_UNUSED_FCFF: /* 0x1fc */ 9136/* File: x86/OP_UNUSED_FCFF.S */ 9137/* File: x86/unused.S */ 9138 jmp common_abort 9139 9140 9141/* ------------------------------ */ 9142 .balign 64 9143.L_OP_UNUSED_FDFF: /* 0x1fd */ 9144/* File: x86/OP_UNUSED_FDFF.S */ 9145/* File: x86/unused.S */ 9146 jmp common_abort 9147 9148 9149/* ------------------------------ */ 9150 .balign 64 9151.L_OP_UNUSED_FEFF: /* 0x1fe */ 9152/* File: x86/OP_UNUSED_FEFF.S */ 9153/* File: x86/unused.S */ 9154 jmp common_abort 9155 9156 9157/* ------------------------------ */ 9158 .balign 64 9159.L_OP_THROW_VERIFICATION_ERROR_JUMBO: /* 0x1ff */ 9160/* File: x86/OP_THROW_VERIFICATION_ERROR_JUMBO.S */ 9161 /* 9162 * Handle a jumbo throw-verification-error instruction. This throws an 9163 * exception for an error discovered during verification. The 9164 * exception is indicated by BBBB, with some detail provided by AAAAAAAA. 9165 */ 9166 /* exop BBBB, ref@AAAAAAAA */ 9167 movl rGLUE,%ecx 9168 movl 2(rPC),%eax # eax<- AAAAAAAA 9169 movl offGlue_method(%ecx),%ecx # ecx<- glue->method 9170 EXPORT_PC 9171 movl %eax,OUT_ARG2(%esp) # arg2<- AAAAAAAA 9172 movl rINST,OUT_ARG1(%esp) # arg1<- BBBB 9173 movl %ecx,OUT_ARG0(%esp) # arg0<- method 9174 call dvmThrowVerificationError # call(method, kind, ref) 9175 jmp common_exceptionThrown # handle exception 9176 9177 9178 .balign 64 9179 .size dvmAsmInstructionStart, .-dvmAsmInstructionStart 9180 .global dvmAsmInstructionEnd 9181dvmAsmInstructionEnd: 9182 9183/* 9184 * =========================================================================== 9185 * Sister implementations 9186 * =========================================================================== 9187 */ 9188 .global dvmAsmSisterStart 9189 .type dvmAsmSisterStart, %function 9190 .text 9191 .balign 4 9192dvmAsmSisterStart: 9193 9194/* continuation for OP_CONST_STRING */ 9195 9196/* This is the less common path, so we'll redo some work 9197 here rather than force spills on the common path */ 9198.LOP_CONST_STRING_resolve: 9199 movl rGLUE,%eax 9200 movl %ecx,rINST # rINST<- AA 9201 EXPORT_PC 9202 movl offGlue_method(%eax),%eax # eax<- glue->method 9203 movzwl 2(rPC),%ecx # ecx<- BBBB 9204 movl offMethod_clazz(%eax),%eax 9205 movl %ecx,OUT_ARG1(%esp) 9206 movl %eax,OUT_ARG0(%esp) 9207 call dvmResolveString # go resolve 9208 testl %eax,%eax # failed? 9209 je common_exceptionThrown 9210 SET_VREG %eax rINST 9211 FETCH_INST_OPCODE 2 %edx 9212 ADVANCE_PC 2 9213 GOTO_NEXT_R %edx 9214 9215/* continuation for OP_CONST_STRING_JUMBO */ 9216 9217/* This is the less common path, so we'll redo some work 9218 here rather than force spills on the common path */ 9219.LOP_CONST_STRING_JUMBO_resolve: 9220 movl rGLUE,%eax 9221 movl %ecx,rINST # rINST<- AA 9222 EXPORT_PC 9223 movl offGlue_method(%eax),%eax # eax<- glue->method 9224 movl 2(rPC),%ecx # ecx<- BBBBBBBB 9225 movl offMethod_clazz(%eax),%eax 9226 movl %ecx,OUT_ARG1(%esp) 9227 movl %eax,OUT_ARG0(%esp) 9228 call dvmResolveString # go resolve 9229 testl %eax,%eax # failed? 9230 je common_exceptionThrown 9231 SET_VREG %eax rINST 9232 FETCH_INST_OPCODE 3 %edx 9233 ADVANCE_PC 3 9234 GOTO_NEXT_R %edx 9235 9236/* continuation for OP_CONST_CLASS */ 9237 9238/* This is the less common path, so we'll redo some work 9239 here rather than force spills on the common path */ 9240.LOP_CONST_CLASS_resolve: 9241 movl rGLUE,%eax 9242 movl %ecx,rINST # rINST<- AA 9243 EXPORT_PC 9244 movl offGlue_method(%eax),%eax # eax<- glue->method 9245 movl $1,OUT_ARG2(%esp) # true 9246 movzwl 2(rPC),%ecx # ecx<- BBBB 9247 movl offMethod_clazz(%eax),%eax 9248 movl %ecx,OUT_ARG1(%esp) 9249 movl %eax,OUT_ARG0(%esp) 9250 call dvmResolveClass # go resolve 9251 testl %eax,%eax # failed? 9252 je common_exceptionThrown 9253 SET_VREG %eax rINST 9254 FETCH_INST_OPCODE 2 %edx 9255 ADVANCE_PC 2 9256 GOTO_NEXT_R %edx 9257 9258/* continuation for OP_MONITOR_ENTER */ 9259 9260.LOP_MONITOR_ENTER_continue: 9261 movl %ecx,OUT_ARG0(%esp) 9262 movl %eax,OUT_ARG1(%esp) 9263 call dvmLockObject # dvmLockObject(self,object) 9264 ADVANCE_PC 1 9265 GOTO_NEXT 9266 9267/* continuation for OP_MONITOR_EXIT */ 9268 9269.LOP_MONITOR_EXIT_continue: 9270 call dvmUnlockObject # unlock(self,obj) 9271 FETCH_INST_OPCODE 1 %edx 9272 testl %eax,%eax # success? 9273 ADVANCE_PC 1 9274 je common_exceptionThrown # no, exception pending 9275 GOTO_NEXT_R %edx 9276.LOP_MONITOR_EXIT_errNullObject: 9277 ADVANCE_PC 1 # advance before throw 9278 jmp common_errNullObject 9279 9280/* continuation for OP_CHECK_CAST */ 9281 9282 /* 9283 * Trivial test failed, need to perform full check. This is common. 9284 * ecx holds obj->clazz 9285 * eax holds class resolved from BBBB 9286 * rINST holds object 9287 */ 9288.LOP_CHECK_CAST_fullcheck: 9289 movl %eax,sReg0 # we'll need the desired class on failure 9290 movl %eax,OUT_ARG1(%esp) 9291 movl %ecx,OUT_ARG0(%esp) 9292 call dvmInstanceofNonTrivial # eax<- boolean result 9293 testl %eax,%eax # failed? 9294 jne .LOP_CHECK_CAST_okay # no, success 9295 9296 # A cast has failed. We need to throw a ClassCastException. 9297 EXPORT_PC 9298 movl offObject_clazz(rINST),%eax 9299 movl %eax,OUT_ARG0(%esp) # arg0<- obj->clazz 9300 movl sReg0,%ecx 9301 movl %ecx,OUT_ARG1(%esp) # arg1<- desired class 9302 call dvmThrowClassCastException 9303 jmp common_exceptionThrown 9304 9305 /* 9306 * Resolution required. This is the least-likely path, and we're 9307 * going to have to recreate some data. 9308 * 9309 * rINST holds object 9310 */ 9311.LOP_CHECK_CAST_resolve: 9312 movl rGLUE,%ecx 9313 EXPORT_PC 9314 movzwl 2(rPC),%eax # eax<- BBBB 9315 movl offGlue_method(%ecx),%ecx # ecx<- glue->method 9316 movl %eax,OUT_ARG1(%esp) # arg1<- BBBB 9317 movl offMethod_clazz(%ecx),%ecx # ecx<- metho->clazz 9318 movl $0,OUT_ARG2(%esp) # arg2<- false 9319 movl %ecx,OUT_ARG0(%esp) # arg0<- method->clazz 9320 call dvmResolveClass # eax<- resolved ClassObject ptr 9321 testl %eax,%eax # got null? 9322 je common_exceptionThrown # yes, handle exception 9323 movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz 9324 jmp .LOP_CHECK_CAST_resolved # pick up where we left off 9325 9326/* continuation for OP_INSTANCE_OF */ 9327 9328 /* 9329 * Trivial test failed, need to perform full check. This is common. 9330 * eax holds obj->clazz 9331 * ecx holds class resolved from BBBB 9332 * rINST has BA 9333 */ 9334.LOP_INSTANCE_OF_fullcheck: 9335 movl %eax,OUT_ARG0(%esp) 9336 movl %ecx,OUT_ARG1(%esp) 9337 call dvmInstanceofNonTrivial # eax<- boolean result 9338 # fall through to OP_INSTANCE_OF_store 9339 9340 /* 9341 * eax holds boolean result 9342 * rINST holds BA 9343 */ 9344.LOP_INSTANCE_OF_store: 9345 FETCH_INST_OPCODE 2 %edx 9346 andb $0xf,rINSTbl # <- A 9347 ADVANCE_PC 2 9348 SET_VREG %eax rINST # vA<- eax 9349 GOTO_NEXT_R %edx 9350 9351 /* 9352 * Trivial test succeeded, save and bail. 9353 * r9 holds A 9354 */ 9355.LOP_INSTANCE_OF_trivial: 9356 FETCH_INST_OPCODE 2 %edx 9357 andb $0xf,rINSTbl # <- A 9358 ADVANCE_PC 2 9359 movl $1,%eax 9360 SET_VREG %eax rINST # vA<- true 9361 GOTO_NEXT_R %edx 9362 9363 /* 9364 * Resolution required. This is the least-likely path. 9365 * 9366 * edx holds BBBB 9367 * rINST holds BA 9368 */ 9369.LOP_INSTANCE_OF_resolve: 9370 movl %edx,OUT_ARG1(%esp) # arg1<- BBBB 9371 movl rGLUE,%ecx 9372 movl offGlue_method(%ecx),%ecx 9373 movl $1,OUT_ARG2(%esp) # arg2<- true 9374 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 9375 EXPORT_PC 9376 movl %ecx,OUT_ARG0(%esp) # arg0<- method->clazz 9377 call dvmResolveClass # eax<- resolved ClassObject ptr 9378 testl %eax,%eax # success? 9379 je common_exceptionThrown # no, handle exception 9380/* Now, we need to sync up with fast path. We need eax to 9381 * hold the obj->clazz, and ecx to hold the resolved class 9382 */ 9383 movl %eax,%ecx # ecx<- resolved class 9384 movl rINST,%eax # eax<- BA 9385 sarl $4,%eax # eax<- B 9386 GET_VREG_R %eax %eax # eax<- vB (obj) 9387 movl offObject_clazz(%eax),%eax # eax<- obj->clazz 9388 jmp .LOP_INSTANCE_OF_resolved 9389 9390/* continuation for OP_NEW_INSTANCE */ 9391 9392.LOP_NEW_INSTANCE_initialized: # on entry, ecx<- class 9393 /* TODO: remove test for interface/abstract, now done in verifier */ 9394 testl $(ACC_INTERFACE|ACC_ABSTRACT),offClassObject_accessFlags(%ecx) 9395 movl $ALLOC_DONT_TRACK,OUT_ARG1(%esp) 9396 jne .LOP_NEW_INSTANCE_abstract 9397.LOP_NEW_INSTANCE_finish: # ecx=class 9398 movl %ecx,OUT_ARG0(%esp) 9399 call dvmAllocObject # eax<- new object 9400 FETCH_INST_OPCODE 2 %edx 9401 testl %eax,%eax # success? 9402 je common_exceptionThrown # no, bail out 9403 SET_VREG %eax rINST 9404 ADVANCE_PC 2 9405 GOTO_NEXT_R %edx 9406 9407 /* 9408 * Class initialization required. 9409 * 9410 * ecx holds class object 9411 */ 9412.LOP_NEW_INSTANCE_needinit: 9413 SPILL_TMP1(%ecx) # save object 9414 movl %ecx,OUT_ARG0(%esp) 9415 call dvmInitClass # initialize class 9416 UNSPILL_TMP1(%ecx) # restore object 9417 testl %eax,%eax # success? 9418 jne .LOP_NEW_INSTANCE_initialized # success, continue 9419 jmp common_exceptionThrown # go deal with init exception 9420 9421 /* 9422 * Resolution required. This is the least-likely path. 9423 * 9424 */ 9425.LOP_NEW_INSTANCE_resolve: 9426 movl rGLUE,%ecx 9427 movzwl 2(rPC),%eax 9428 movl offGlue_method(%ecx),%ecx # ecx<- glue->method 9429 movl %eax,OUT_ARG1(%esp) 9430 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 9431 movl $0,OUT_ARG2(%esp) 9432 movl %ecx,OUT_ARG0(%esp) 9433 call dvmResolveClass # call(clazz,off,flags) 9434 movl %eax,%ecx # ecx<- resolved ClassObject ptr 9435 testl %ecx,%ecx # success? 9436 jne .LOP_NEW_INSTANCE_resolved # good to go 9437 jmp common_exceptionThrown # no, handle exception 9438 9439 /* 9440 * TODO: remove this 9441 * We can't instantiate an abstract class or interface, so throw an 9442 * InstantiationError with the class descriptor as the message. 9443 * 9444 * ecx holds class object 9445 */ 9446.LOP_NEW_INSTANCE_abstract: 9447 movl offClassObject_descriptor(%ecx),%eax 9448 movl $.LstrInstantiationError,OUT_ARG0(%esp) 9449 movl %eax,OUT_ARG1(%esp) 9450 call dvmThrowExceptionWithClassMessage 9451 jmp common_exceptionThrown 9452 9453/* continuation for OP_NEW_ARRAY */ 9454 9455 /* 9456 * Resolve class. (This is an uncommon case.) 9457 * ecx holds class (null here) 9458 * eax holds array length (vB) 9459 */ 9460.LOP_NEW_ARRAY_resolve: 9461 movl rGLUE,%ecx 9462 SPILL_TMP1(%eax) # save array length 9463 movl offGlue_method(%ecx),%ecx # ecx<- glue->method 9464 movzwl 2(rPC),%eax # eax<- CCCC 9465 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 9466 movl %eax,OUT_ARG1(%esp) 9467 movl $0,OUT_ARG2(%esp) 9468 movl %ecx,OUT_ARG0(%esp) 9469 call dvmResolveClass # eax<- call(clazz,ref,flag) 9470 movl %eax,%ecx 9471 UNSPILL_TMP1(%eax) 9472 testl %ecx,%ecx # successful resolution? 9473 je common_exceptionThrown # no, bail. 9474# fall through to OP_NEW_ARRAY_finish 9475 9476 /* 9477 * Finish allocation 9478 * 9479 * ecx holds class 9480 * eax holds array length (vB) 9481 */ 9482.LOP_NEW_ARRAY_finish: 9483 movl %ecx,OUT_ARG0(%esp) 9484 movl %eax,OUT_ARG1(%esp) 9485 movl $ALLOC_DONT_TRACK,OUT_ARG2(%esp) 9486 call dvmAllocArrayByClass # eax<- call(clazz,length,flags) 9487 FETCH_INST_OPCODE 2 %edx 9488 testl %eax,%eax # failed? 9489 je common_exceptionThrown # yup - go handle 9490 SET_VREG %eax rINST 9491 ADVANCE_PC 2 9492 GOTO_NEXT_R %edx 9493 9494/* continuation for OP_FILLED_NEW_ARRAY */ 9495 9496.LOP_FILLED_NEW_ARRAY_more: 9497 movl offMethod_clazz(%eax),%eax # eax<- method->clazz 9498 movl %eax,OUT_ARG0(%esp) # arg0<- clazz 9499 call dvmResolveClass # eax<- call(clazz,ref,flag) 9500 testl %eax,%eax # null? 9501 je common_exceptionThrown # yes, handle it 9502 9503 # note: fall through to .LOP_FILLED_NEW_ARRAY_continue 9504 9505 /* 9506 * On entry: 9507 * eax holds array class [r0] 9508 * rINST holds AA or BB [r10] 9509 * ecx is scratch 9510 */ 9511.LOP_FILLED_NEW_ARRAY_continue: 9512 movl offClassObject_descriptor(%eax),%ecx # ecx<- arrayClass->descriptor 9513 movl $ALLOC_DONT_TRACK,OUT_ARG2(%esp) # arg2<- flags 9514 movzbl 1(%ecx),%ecx # ecx<- descriptor[1] 9515 movl %eax,OUT_ARG0(%esp) # arg0<- arrayClass 9516 movl rGLUE,%eax 9517 cmpb $'I',%cl # supported? 9518 je 1f 9519 cmpb $'L',%cl 9520 je 1f 9521 cmpb $'[',%cl 9522 jne .LOP_FILLED_NEW_ARRAY_notimpl # no, not handled yet 95231: 9524 movl %ecx,offGlue_retval+4(%eax) # save type 9525 .if (!0) 9526 SPILL_TMP1(rINST) # save copy, need "B" later 9527 sarl $4,rINST 9528 .endif 9529 movl rINST,OUT_ARG1(%esp) # arg1<- A or AA (length) 9530 call dvmAllocArrayByClass # eax<- call(arrayClass, length, flags) 9531 movl rGLUE,%ecx 9532 testl %eax,%eax # alloc successful? 9533 je common_exceptionThrown # no, handle exception 9534 movl %eax,offGlue_retval(%ecx) # retval.l<- new array 9535 movzwl 4(rPC),%ecx # ecx<- FEDC or CCCC 9536 leal offArrayObject_contents(%eax),%eax # eax<- newArray->contents 9537 9538/* at this point: 9539 * eax is pointer to tgt 9540 * rINST is length 9541 * ecx is FEDC or CCCC 9542 * TMP_SPILL1 is BA 9543 * We now need to copy values from registers into the array 9544 */ 9545 9546 .if 0 9547 # set up src pointer 9548 SPILL_TMP2(%esi) 9549 SPILL_TMP3(%edi) 9550 leal (rFP,%ecx,4),%esi # set up src ptr 9551 movl %eax,%edi # set up dst ptr 9552 movl rINST,%ecx # load count register 9553 rep 9554 movsd 9555 UNSPILL_TMP2(%esi) 9556 UNSPILL_TMP3(%edi) 9557 movl rGLUE,%ecx 9558 movl offGlue_retval+4(%ecx),%eax # eax<- type 9559 FETCH_INST_OPCODE 3 %edx 9560 .else 9561 testl rINST,rINST 9562 je 4f 9563 UNSPILL_TMP1(%edx) # restore "BA" 9564 andl $0x0f,%edx # edx<- 0000000A 9565 sall $16,%edx # edx<- 000A0000 9566 orl %ecx,%edx # edx<- 000AFEDC 95673: 9568 movl $0xf,%ecx 9569 andl %edx,%ecx # ecx<- next reg to load 9570 GET_VREG_R %ecx %ecx 9571 shrl $4,%edx 9572 leal 4(%eax),%eax 9573 movl %ecx,-4(%eax) 9574 sub $1,rINST 9575 jne 3b 95764: 9577 movl rGLUE,%ecx 9578 movl offGlue_retval+4(%ecx),%eax # eax<- type 9579 FETCH_INST_OPCODE 3 %edx 9580 .endif 9581 9582 cmpb $'I',%al # Int array? 9583 je 5f # skip card mark if so 9584 movl offGlue_retval(%ecx),%eax # eax<- object head 9585 movl offGlue_cardTable(%ecx),%ecx # card table base 9586 shrl $GC_CARD_SHIFT,%eax # convert to card num 9587 movb %cl,(%ecx,%eax) # mark card based on object head 95885: 9589 ADVANCE_PC 3 9590 GOTO_NEXT_R %edx 9591 9592 9593 /* 9594 * Throw an exception indicating that we have not implemented this 9595 * mode of filled-new-array. 9596 */ 9597.LOP_FILLED_NEW_ARRAY_notimpl: 9598 movl $.LstrInternalErrorA,%eax 9599 movl %eax,OUT_ARG0(%esp) 9600 movl $.LstrFilledNewArrayNotImplA,%eax 9601 movl %eax,OUT_ARG1(%esp) 9602 call dvmThrowException 9603 jmp common_exceptionThrown 9604 9605/* continuation for OP_FILLED_NEW_ARRAY_RANGE */ 9606 9607.LOP_FILLED_NEW_ARRAY_RANGE_more: 9608 movl offMethod_clazz(%eax),%eax # eax<- method->clazz 9609 movl %eax,OUT_ARG0(%esp) # arg0<- clazz 9610 call dvmResolveClass # eax<- call(clazz,ref,flag) 9611 testl %eax,%eax # null? 9612 je common_exceptionThrown # yes, handle it 9613 9614 # note: fall through to .LOP_FILLED_NEW_ARRAY_RANGE_continue 9615 9616 /* 9617 * On entry: 9618 * eax holds array class [r0] 9619 * rINST holds AA or BB [r10] 9620 * ecx is scratch 9621 */ 9622.LOP_FILLED_NEW_ARRAY_RANGE_continue: 9623 movl offClassObject_descriptor(%eax),%ecx # ecx<- arrayClass->descriptor 9624 movl $ALLOC_DONT_TRACK,OUT_ARG2(%esp) # arg2<- flags 9625 movzbl 1(%ecx),%ecx # ecx<- descriptor[1] 9626 movl %eax,OUT_ARG0(%esp) # arg0<- arrayClass 9627 movl rGLUE,%eax 9628 cmpb $'I',%cl # supported? 9629 je 1f 9630 cmpb $'L',%cl 9631 je 1f 9632 cmpb $'[',%cl 9633 jne .LOP_FILLED_NEW_ARRAY_RANGE_notimpl # no, not handled yet 96341: 9635 movl %ecx,offGlue_retval+4(%eax) # save type 9636 .if (!1) 9637 SPILL_TMP1(rINST) # save copy, need "B" later 9638 sarl $4,rINST 9639 .endif 9640 movl rINST,OUT_ARG1(%esp) # arg1<- A or AA (length) 9641 call dvmAllocArrayByClass # eax<- call(arrayClass, length, flags) 9642 movl rGLUE,%ecx 9643 testl %eax,%eax # alloc successful? 9644 je common_exceptionThrown # no, handle exception 9645 movl %eax,offGlue_retval(%ecx) # retval.l<- new array 9646 movzwl 4(rPC),%ecx # ecx<- FEDC or CCCC 9647 leal offArrayObject_contents(%eax),%eax # eax<- newArray->contents 9648 9649/* at this point: 9650 * eax is pointer to tgt 9651 * rINST is length 9652 * ecx is FEDC or CCCC 9653 * TMP_SPILL1 is BA 9654 * We now need to copy values from registers into the array 9655 */ 9656 9657 .if 1 9658 # set up src pointer 9659 SPILL_TMP2(%esi) 9660 SPILL_TMP3(%edi) 9661 leal (rFP,%ecx,4),%esi # set up src ptr 9662 movl %eax,%edi # set up dst ptr 9663 movl rINST,%ecx # load count register 9664 rep 9665 movsd 9666 UNSPILL_TMP2(%esi) 9667 UNSPILL_TMP3(%edi) 9668 movl rGLUE,%ecx 9669 movl offGlue_retval+4(%ecx),%eax # eax<- type 9670 FETCH_INST_OPCODE 3 %edx 9671 .else 9672 testl rINST,rINST 9673 je 4f 9674 UNSPILL_TMP1(%edx) # restore "BA" 9675 andl $0x0f,%edx # edx<- 0000000A 9676 sall $16,%edx # edx<- 000A0000 9677 orl %ecx,%edx # edx<- 000AFEDC 96783: 9679 movl $0xf,%ecx 9680 andl %edx,%ecx # ecx<- next reg to load 9681 GET_VREG_R %ecx %ecx 9682 shrl $4,%edx 9683 leal 4(%eax),%eax 9684 movl %ecx,-4(%eax) 9685 sub $1,rINST 9686 jne 3b 96874: 9688 movl rGLUE,%ecx 9689 movl offGlue_retval+4(%ecx),%eax # eax<- type 9690 FETCH_INST_OPCODE 3 %edx 9691 .endif 9692 9693 cmpb $'I',%al # Int array? 9694 je 5f # skip card mark if so 9695 movl offGlue_retval(%ecx),%eax # eax<- object head 9696 movl offGlue_cardTable(%ecx),%ecx # card table base 9697 shrl $GC_CARD_SHIFT,%eax # convert to card num 9698 movb %cl,(%ecx,%eax) # mark card based on object head 96995: 9700 ADVANCE_PC 3 9701 GOTO_NEXT_R %edx 9702 9703 9704 /* 9705 * Throw an exception indicating that we have not implemented this 9706 * mode of filled-new-array. 9707 */ 9708.LOP_FILLED_NEW_ARRAY_RANGE_notimpl: 9709 movl $.LstrInternalErrorA,%eax 9710 movl %eax,OUT_ARG0(%esp) 9711 movl $.LstrFilledNewArrayNotImplA,%eax 9712 movl %eax,OUT_ARG1(%esp) 9713 call dvmThrowException 9714 jmp common_exceptionThrown 9715 9716/* continuation for OP_CMPL_FLOAT */ 9717 9718.LOP_CMPL_FLOAT_isNaN: 9719 movl $-1,%ecx 9720 jmp .LOP_CMPL_FLOAT_finish 9721 9722/* continuation for OP_CMPG_FLOAT */ 9723 9724.LOP_CMPG_FLOAT_isNaN: 9725 movl $1,%ecx 9726 jmp .LOP_CMPG_FLOAT_finish 9727 9728/* continuation for OP_CMPL_DOUBLE */ 9729 9730.LOP_CMPL_DOUBLE_isNaN: 9731 movl $-1,%ecx 9732 jmp .LOP_CMPL_DOUBLE_finish 9733 9734/* continuation for OP_CMPG_DOUBLE */ 9735 9736.LOP_CMPG_DOUBLE_isNaN: 9737 movl $1,%ecx 9738 jmp .LOP_CMPG_DOUBLE_finish 9739 9740/* continuation for OP_CMP_LONG */ 9741 9742.LOP_CMP_LONG_bigger: 9743 movl $1,%ecx 9744 jmp .LOP_CMP_LONG_finish 9745.LOP_CMP_LONG_smaller: 9746 movl $-1,%ecx 9747.LOP_CMP_LONG_finish: 9748 SET_VREG %ecx rINST 9749 FETCH_INST_OPCODE 2 %edx 9750 ADVANCE_PC 2 9751 GOTO_NEXT_R %edx 9752 9753/* continuation for OP_AGET_WIDE */ 9754 9755.LOP_AGET_WIDE_finish: 9756 leal offArrayObject_contents(%eax,%ecx,8),%eax 9757 movl (%eax),%ecx 9758 movl 4(%eax),%eax 9759 SET_VREG_WORD %ecx rINST 0 9760 SET_VREG_WORD %eax rINST 1 9761 FETCH_INST_OPCODE 2 %edx 9762 ADVANCE_PC 2 9763 GOTO_NEXT_R %edx 9764 9765/* continuation for OP_APUT_WIDE */ 9766 9767.LOP_APUT_WIDE_finish: 9768 leal offArrayObject_contents(%eax,%ecx,8),%eax 9769 GET_VREG_WORD %ecx rINST 0 9770 GET_VREG_WORD rINST rINST 1 9771 movl rINST,4(%eax) 9772 FETCH_INST_OPCODE 2 %edx 9773 movl %ecx,(%eax) 9774 ADVANCE_PC 2 9775 GOTO_NEXT_R %edx 9776 9777/* continuation for OP_APUT_OBJECT */ 9778 9779 /* On entry: 9780 * eax<- array object 9781 * ecx<- index 9782 * rINST<- vAA 9783 */ 9784.LOP_APUT_OBJECT_continue: 9785 leal offArrayObject_contents(%eax,%ecx,4),%ecx 9786 testl rINST,rINST # storing null reference? 9787 je .LOP_APUT_OBJECT_skip_check 9788 SPILL_TMP1(%ecx) # save target address 9789 SPILL_TMP2(%eax) # save object head 9790 movl offObject_clazz(%eax),%eax # eax<- arrayObj->clazz 9791 movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz 9792 movl %eax,OUT_ARG1(%esp) 9793 movl %ecx,OUT_ARG0(%esp) 9794 movl %ecx,sReg0 # store the two classes for later 9795 movl %eax,sReg1 9796 call dvmCanPutArrayElement # test object type vs. array type 9797 UNSPILL_TMP1(%ecx) # recover target address 9798 testl %eax,%eax 9799 movl rGLUE,%eax 9800 jne .LOP_APUT_OBJECT_types_okay 9801 9802 # The types don't match. We need to throw an ArrayStoreException. 9803 EXPORT_PC 9804 movl sReg0,%eax # restore the two classes... 9805 movl %eax,OUT_ARG0(%esp) 9806 movl sReg1,%ecx 9807 movl %ecx,OUT_ARG1(%esp) 9808 call dvmThrowArrayStoreException # ...and throw 9809 jmp common_exceptionThrown 9810 9811.LOP_APUT_OBJECT_types_okay: 9812 movl offGlue_cardTable(%eax),%eax # get card table base 9813 movl rINST,(%ecx) # store into array 9814 UNSPILL_TMP2(%ecx) # recover object head 9815 FETCH_INST_OPCODE 2 %edx 9816 shrl $GC_CARD_SHIFT,%ecx # object head to card number 9817 movb %al,(%eax,%ecx) # mark card using object head 9818 ADVANCE_PC 2 9819 GOTO_NEXT_R %edx 9820 9821.LOP_APUT_OBJECT_skip_check: 9822 movl rINST,(%ecx) 9823 FETCH_INST_OPCODE 2 %edx 9824 ADVANCE_PC 2 9825 GOTO_NEXT_R %edx 9826 9827/* continuation for OP_IGET */ 9828 9829 9830.LOP_IGET_resolve: 9831 EXPORT_PC 9832 movl offGlue_method(%edx),%edx # edx<- current method 9833 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 9834 SPILL_TMP1(%ecx) # save obj pointer across call 9835 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 9836 call dvmResolveInstField # ... to dvmResolveInstField 9837 UNSPILL_TMP1(%ecx) 9838 testl %eax,%eax # returns InstrField ptr 9839 jne .LOP_IGET_finish 9840 jmp common_exceptionThrown 9841 9842.LOP_IGET_finish: 9843 /* 9844 * Currently: 9845 * eax holds resolved field 9846 * ecx holds object 9847 * rINST holds A 9848 */ 9849 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 9850 testl %ecx,%ecx # object null? 9851 je common_errNullObject # object was null 9852 movl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 9853 movl rINST,%eax # eax<- A 9854 FETCH_INST_OPCODE 2 %edx 9855 SET_VREG %ecx %eax 9856 ADVANCE_PC 2 9857 GOTO_NEXT_R %edx 9858 9859/* continuation for OP_IGET_WIDE */ 9860 9861 9862.LOP_IGET_WIDE_resolve: 9863 EXPORT_PC 9864 movl offGlue_method(%edx),%edx # edx<- current method 9865 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 9866 SPILL_TMP1(%ecx) # save objpointer across call 9867 movl rPC,OUT_ARG0(%esp) # pass in method->clazz 9868 call dvmResolveInstField # ... to dvmResolveInstField 9869 UNSPILL_TMP1(%ecx) 9870 testl %eax,%eax # returns InstrField ptr 9871 jne .LOP_IGET_WIDE_finish 9872 jmp common_exceptionThrown 9873 9874.LOP_IGET_WIDE_finish: 9875 /* 9876 * Currently: 9877 * eax holds resolved field 9878 * ecx holds object 9879 * rINST holds A 9880 */ 9881 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 9882 testl %ecx,%ecx # object null? 9883 je common_errNullObject # object was null 9884 leal (%ecx,%eax,1),%eax # eax<- address of field 9885 movl (%eax),%ecx # ecx<- lsw 9886 movl 4(%eax),%eax # eax<- msw 9887 FETCH_INST_OPCODE 2 %edx 9888 SET_VREG_WORD %ecx rINST 0 9889 SET_VREG_WORD %eax rINST 1 9890 ADVANCE_PC 2 9891 GOTO_NEXT_R %edx 9892 9893/* continuation for OP_IGET_OBJECT */ 9894 9895 9896.LOP_IGET_OBJECT_resolve: 9897 EXPORT_PC 9898 movl offGlue_method(%edx),%edx # edx<- current method 9899 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 9900 SPILL_TMP1(%ecx) # save obj pointer across call 9901 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 9902 call dvmResolveInstField # ... to dvmResolveInstField 9903 UNSPILL_TMP1(%ecx) 9904 testl %eax,%eax # returns InstrField ptr 9905 jne .LOP_IGET_OBJECT_finish 9906 jmp common_exceptionThrown 9907 9908.LOP_IGET_OBJECT_finish: 9909 /* 9910 * Currently: 9911 * eax holds resolved field 9912 * ecx holds object 9913 * rINST holds A 9914 */ 9915 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 9916 testl %ecx,%ecx # object null? 9917 je common_errNullObject # object was null 9918 movl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 9919 movl rINST,%eax # eax<- A 9920 FETCH_INST_OPCODE 2 %edx 9921 SET_VREG %ecx %eax 9922 ADVANCE_PC 2 9923 GOTO_NEXT_R %edx 9924 9925/* continuation for OP_IGET_BOOLEAN */ 9926 9927 9928.LOP_IGET_BOOLEAN_resolve: 9929 EXPORT_PC 9930 movl offGlue_method(%edx),%edx # edx<- current method 9931 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 9932 SPILL_TMP1(%ecx) # save obj pointer across call 9933 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 9934 call dvmResolveInstField # ... to dvmResolveInstField 9935 UNSPILL_TMP1(%ecx) 9936 testl %eax,%eax # returns InstrField ptr 9937 jne .LOP_IGET_BOOLEAN_finish 9938 jmp common_exceptionThrown 9939 9940.LOP_IGET_BOOLEAN_finish: 9941 /* 9942 * Currently: 9943 * eax holds resolved field 9944 * ecx holds object 9945 * rINST holds A 9946 */ 9947 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 9948 testl %ecx,%ecx # object null? 9949 je common_errNullObject # object was null 9950 movzbl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 9951 movl rINST,%eax # eax<- A 9952 FETCH_INST_OPCODE 2 %edx 9953 SET_VREG %ecx %eax 9954 ADVANCE_PC 2 9955 GOTO_NEXT_R %edx 9956 9957/* continuation for OP_IGET_BYTE */ 9958 9959 9960.LOP_IGET_BYTE_resolve: 9961 EXPORT_PC 9962 movl offGlue_method(%edx),%edx # edx<- current method 9963 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 9964 SPILL_TMP1(%ecx) # save obj pointer across call 9965 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 9966 call dvmResolveInstField # ... to dvmResolveInstField 9967 UNSPILL_TMP1(%ecx) 9968 testl %eax,%eax # returns InstrField ptr 9969 jne .LOP_IGET_BYTE_finish 9970 jmp common_exceptionThrown 9971 9972.LOP_IGET_BYTE_finish: 9973 /* 9974 * Currently: 9975 * eax holds resolved field 9976 * ecx holds object 9977 * rINST holds A 9978 */ 9979 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 9980 testl %ecx,%ecx # object null? 9981 je common_errNullObject # object was null 9982 movsbl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 9983 movl rINST,%eax # eax<- A 9984 FETCH_INST_OPCODE 2 %edx 9985 SET_VREG %ecx %eax 9986 ADVANCE_PC 2 9987 GOTO_NEXT_R %edx 9988 9989/* continuation for OP_IGET_CHAR */ 9990 9991 9992.LOP_IGET_CHAR_resolve: 9993 EXPORT_PC 9994 movl offGlue_method(%edx),%edx # edx<- current method 9995 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 9996 SPILL_TMP1(%ecx) # save obj pointer across call 9997 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 9998 call dvmResolveInstField # ... to dvmResolveInstField 9999 UNSPILL_TMP1(%ecx) 10000 testl %eax,%eax # returns InstrField ptr 10001 jne .LOP_IGET_CHAR_finish 10002 jmp common_exceptionThrown 10003 10004.LOP_IGET_CHAR_finish: 10005 /* 10006 * Currently: 10007 * eax holds resolved field 10008 * ecx holds object 10009 * rINST holds A 10010 */ 10011 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 10012 testl %ecx,%ecx # object null? 10013 je common_errNullObject # object was null 10014 movzwl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 10015 movl rINST,%eax # eax<- A 10016 FETCH_INST_OPCODE 2 %edx 10017 SET_VREG %ecx %eax 10018 ADVANCE_PC 2 10019 GOTO_NEXT_R %edx 10020 10021/* continuation for OP_IGET_SHORT */ 10022 10023 10024.LOP_IGET_SHORT_resolve: 10025 EXPORT_PC 10026 movl offGlue_method(%edx),%edx # edx<- current method 10027 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 10028 SPILL_TMP1(%ecx) # save obj pointer across call 10029 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 10030 call dvmResolveInstField # ... to dvmResolveInstField 10031 UNSPILL_TMP1(%ecx) 10032 testl %eax,%eax # returns InstrField ptr 10033 jne .LOP_IGET_SHORT_finish 10034 jmp common_exceptionThrown 10035 10036.LOP_IGET_SHORT_finish: 10037 /* 10038 * Currently: 10039 * eax holds resolved field 10040 * ecx holds object 10041 * rINST holds A 10042 */ 10043 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 10044 testl %ecx,%ecx # object null? 10045 je common_errNullObject # object was null 10046 movswl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 10047 movl rINST,%eax # eax<- A 10048 FETCH_INST_OPCODE 2 %edx 10049 SET_VREG %ecx %eax 10050 ADVANCE_PC 2 10051 GOTO_NEXT_R %edx 10052 10053/* continuation for OP_IPUT */ 10054 10055 10056.LOP_IPUT_resolve: 10057 EXPORT_PC 10058 movl offGlue_method(%edx),%edx # edx<- current method 10059 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 10060 SPILL_TMP1(%ecx) # save obj pointer across call 10061 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 10062 call dvmResolveInstField # ... to dvmResolveInstField 10063 UNSPILL_TMP1(%ecx) 10064 testl %eax,%eax # returns InstrField ptr 10065 jne .LOP_IPUT_finish 10066 jmp common_exceptionThrown 10067 10068.LOP_IPUT_finish: 10069 /* 10070 * Currently: 10071 * eax holds resolved field 10072 * ecx holds object 10073 * rINST holds A 10074 */ 10075 GET_VREG_R rINST rINST # rINST<- v[A] 10076 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 10077 testl %ecx,%ecx # object null? 10078 je common_errNullObject # object was null 10079 FETCH_INST_OPCODE 2 %edx 10080 movl rINST,(%ecx,%eax,1) # obj.field <- v[A](8/16/32 bits) 10081 ADVANCE_PC 2 10082 GOTO_NEXT_R %edx 10083 10084/* continuation for OP_IPUT_WIDE */ 10085 10086 10087.LOP_IPUT_WIDE_resolve: 10088 EXPORT_PC 10089 movl offGlue_method(%edx),%edx # edx<- current method 10090 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 10091 SPILL_TMP1(%ecx) # save obj pointer across call 10092 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 10093 call dvmResolveInstField # ... to dvmResolveInstField 10094 UNSPILL_TMP1(%ecx) 10095 testl %eax,%eax # ... which returns InstrField ptr 10096 jne .LOP_IPUT_WIDE_finish 10097 jmp common_exceptionThrown 10098 10099.LOP_IPUT_WIDE_finish: 10100 /* 10101 * Currently: 10102 * eax holds resolved field 10103 * ecx holds object 10104 * %edx is scratch, but needs to be unspilled 10105 * rINST holds A 10106 */ 10107 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 10108 testl %ecx,%ecx # object null? 10109 je common_errNullObject # object was null 10110 leal (%ecx,%eax,1),%eax # eax<- address of field 10111 GET_VREG_WORD %ecx rINST 0 # ecx<- lsw 10112 GET_VREG_WORD rINST rINST 1 # rINST<- msw 10113 FETCH_INST_OPCODE 2 %edx 10114 movl rINST,4(%eax) 10115 movl %ecx,(%eax) 10116 ADVANCE_PC 2 10117 GOTO_NEXT_R %edx 10118 10119/* continuation for OP_IPUT_OBJECT */ 10120 10121 10122.LOP_IPUT_OBJECT_resolve: 10123 EXPORT_PC 10124 movl offGlue_method(%edx),%edx # edx<- current method 10125 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 10126 SPILL_TMP1(%ecx) # save obj pointer across call 10127 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 10128 call dvmResolveInstField # ... to dvmResolveInstField 10129 UNSPILL_TMP1(%ecx) 10130 testl %eax,%eax # returns InstrField ptr 10131 jne .LOP_IPUT_OBJECT_finish 10132 jmp common_exceptionThrown 10133 10134.LOP_IPUT_OBJECT_finish: 10135 /* 10136 * Currently: 10137 * eax holds resolved field 10138 * ecx holds object 10139 * %edx is scratch, but needs to be unspilled 10140 * rINST holds A 10141 */ 10142 GET_VREG_R rINST rINST # rINST<- v[A] 10143 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 10144 testl %ecx,%ecx # object null? 10145 je common_errNullObject # object was null 10146 movl rINST,(%ecx,%eax) # obj.field <- v[A](8/16/32 bits) 10147 movl rGLUE,%eax 10148 testl rINST,rINST # stored a NULL? 10149 movl offGlue_cardTable(%eax),%eax # get card table base 10150 FETCH_INST_OPCODE 2 %edx 10151 je 1f # skip card mark if null store 10152 shrl $GC_CARD_SHIFT,%ecx # object head to card number 10153 movb %al,(%eax,%ecx) # mark card using object head 101541: 10155 ADVANCE_PC 2 10156 GOTO_NEXT_R %edx 10157 10158/* continuation for OP_IPUT_BOOLEAN */ 10159 10160 10161.LOP_IPUT_BOOLEAN_resolve: 10162 EXPORT_PC 10163 movl offGlue_method(%edx),%edx # edx<- current method 10164 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 10165 SPILL_TMP1(%ecx) # save obj pointer across call 10166 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 10167 call dvmResolveInstField # ... to dvmResolveInstField 10168 UNSPILL_TMP1(%ecx) 10169 testl %eax,%eax # returns InstrField ptr 10170 jne .LOP_IPUT_BOOLEAN_finish 10171 jmp common_exceptionThrown 10172 10173.LOP_IPUT_BOOLEAN_finish: 10174 /* 10175 * Currently: 10176 * eax holds resolved field 10177 * ecx holds object 10178 * rINST holds A 10179 */ 10180 GET_VREG_R rINST rINST # rINST<- v[A] 10181 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 10182 testl %ecx,%ecx # object null? 10183 je common_errNullObject # object was null 10184 FETCH_INST_OPCODE 2 %edx 10185 movb rINSTbl,(%ecx,%eax,1) # obj.field <- v[A](8/16/32 bits) 10186 ADVANCE_PC 2 10187 GOTO_NEXT_R %edx 10188 10189/* continuation for OP_IPUT_BYTE */ 10190 10191 10192.LOP_IPUT_BYTE_resolve: 10193 EXPORT_PC 10194 movl offGlue_method(%edx),%edx # edx<- current method 10195 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 10196 SPILL_TMP1(%ecx) # save obj pointer across call 10197 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 10198 call dvmResolveInstField # ... to dvmResolveInstField 10199 UNSPILL_TMP1(%ecx) 10200 testl %eax,%eax # returns InstrField ptr 10201 jne .LOP_IPUT_BYTE_finish 10202 jmp common_exceptionThrown 10203 10204.LOP_IPUT_BYTE_finish: 10205 /* 10206 * Currently: 10207 * eax holds resolved field 10208 * ecx holds object 10209 * rINST holds A 10210 */ 10211 GET_VREG_R rINST rINST # rINST<- v[A] 10212 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 10213 testl %ecx,%ecx # object null? 10214 je common_errNullObject # object was null 10215 FETCH_INST_OPCODE 2 %edx 10216 movb rINSTbl,(%ecx,%eax,1) # obj.field <- v[A](8/16/32 bits) 10217 ADVANCE_PC 2 10218 GOTO_NEXT_R %edx 10219 10220/* continuation for OP_IPUT_CHAR */ 10221 10222 10223.LOP_IPUT_CHAR_resolve: 10224 EXPORT_PC 10225 movl offGlue_method(%edx),%edx # edx<- current method 10226 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 10227 SPILL_TMP1(%ecx) # save obj pointer across call 10228 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 10229 call dvmResolveInstField # ... to dvmResolveInstField 10230 UNSPILL_TMP1(%ecx) 10231 testl %eax,%eax # returns InstrField ptr 10232 jne .LOP_IPUT_CHAR_finish 10233 jmp common_exceptionThrown 10234 10235.LOP_IPUT_CHAR_finish: 10236 /* 10237 * Currently: 10238 * eax holds resolved field 10239 * ecx holds object 10240 * rINST holds A 10241 */ 10242 GET_VREG_R rINST rINST # rINST<- v[A] 10243 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 10244 testl %ecx,%ecx # object null? 10245 je common_errNullObject # object was null 10246 FETCH_INST_OPCODE 2 %edx 10247 movw rINSTw,(%ecx,%eax,1) # obj.field <- v[A](8/16/32 bits) 10248 ADVANCE_PC 2 10249 GOTO_NEXT_R %edx 10250 10251/* continuation for OP_IPUT_SHORT */ 10252 10253 10254.LOP_IPUT_SHORT_resolve: 10255 EXPORT_PC 10256 movl offGlue_method(%edx),%edx # edx<- current method 10257 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 10258 SPILL_TMP1(%ecx) # save obj pointer across call 10259 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 10260 call dvmResolveInstField # ... to dvmResolveInstField 10261 UNSPILL_TMP1(%ecx) 10262 testl %eax,%eax # returns InstrField ptr 10263 jne .LOP_IPUT_SHORT_finish 10264 jmp common_exceptionThrown 10265 10266.LOP_IPUT_SHORT_finish: 10267 /* 10268 * Currently: 10269 * eax holds resolved field 10270 * ecx holds object 10271 * rINST holds A 10272 */ 10273 GET_VREG_R rINST rINST # rINST<- v[A] 10274 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 10275 testl %ecx,%ecx # object null? 10276 je common_errNullObject # object was null 10277 FETCH_INST_OPCODE 2 %edx 10278 movw rINSTw,(%ecx,%eax,1) # obj.field <- v[A](8/16/32 bits) 10279 ADVANCE_PC 2 10280 GOTO_NEXT_R %edx 10281 10282/* continuation for OP_SGET */ 10283 10284 /* 10285 * Go resolve the field 10286 */ 10287.LOP_SGET_resolve: 10288 movl rGLUE,%ecx 10289 movzwl 2(rPC),%eax # eax<- field ref BBBB 10290 movl offGlue_method(%ecx),%ecx # ecx<- current method 10291 EXPORT_PC # could throw, need to export 10292 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10293 movl %eax,OUT_ARG1(%esp) 10294 movl %ecx,OUT_ARG0(%esp) 10295 call dvmResolveStaticField # eax<- resolved StaticField ptr 10296 testl %eax,%eax 10297 jne .LOP_SGET_finish # success, continue 10298 jmp common_exceptionThrown # no, handle exception 10299 10300/* continuation for OP_SGET_WIDE */ 10301 10302 /* 10303 * Go resolve the field 10304 */ 10305.LOP_SGET_WIDE_resolve: 10306 movl rGLUE,%ecx 10307 movzwl 2(rPC),%eax # eax<- field ref BBBB 10308 movl offGlue_method(%ecx),%ecx # ecx<- current method 10309 EXPORT_PC # could throw, need to export 10310 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10311 movl %eax,OUT_ARG1(%esp) 10312 movl %ecx,OUT_ARG0(%esp) 10313 call dvmResolveStaticField # eax<- resolved StaticField ptr 10314 testl %eax,%eax 10315 jne .LOP_SGET_WIDE_finish # success, continue 10316 jmp common_exceptionThrown # no, handle exception 10317 10318/* continuation for OP_SGET_OBJECT */ 10319 10320 /* 10321 * Go resolve the field 10322 */ 10323.LOP_SGET_OBJECT_resolve: 10324 movl rGLUE,%ecx 10325 movzwl 2(rPC),%eax # eax<- field ref BBBB 10326 movl offGlue_method(%ecx),%ecx # ecx<- current method 10327 EXPORT_PC # could throw, need to export 10328 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10329 movl %eax,OUT_ARG1(%esp) 10330 movl %ecx,OUT_ARG0(%esp) 10331 call dvmResolveStaticField # eax<- resolved StaticField ptr 10332 testl %eax,%eax 10333 jne .LOP_SGET_OBJECT_finish # success, continue 10334 jmp common_exceptionThrown # no, handle exception 10335 10336/* continuation for OP_SGET_BOOLEAN */ 10337 10338 /* 10339 * Go resolve the field 10340 */ 10341.LOP_SGET_BOOLEAN_resolve: 10342 movl rGLUE,%ecx 10343 movzwl 2(rPC),%eax # eax<- field ref BBBB 10344 movl offGlue_method(%ecx),%ecx # ecx<- current method 10345 EXPORT_PC # could throw, need to export 10346 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10347 movl %eax,OUT_ARG1(%esp) 10348 movl %ecx,OUT_ARG0(%esp) 10349 call dvmResolveStaticField # eax<- resolved StaticField ptr 10350 testl %eax,%eax 10351 jne .LOP_SGET_BOOLEAN_finish # success, continue 10352 jmp common_exceptionThrown # no, handle exception 10353 10354/* continuation for OP_SGET_BYTE */ 10355 10356 /* 10357 * Go resolve the field 10358 */ 10359.LOP_SGET_BYTE_resolve: 10360 movl rGLUE,%ecx 10361 movzwl 2(rPC),%eax # eax<- field ref BBBB 10362 movl offGlue_method(%ecx),%ecx # ecx<- current method 10363 EXPORT_PC # could throw, need to export 10364 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10365 movl %eax,OUT_ARG1(%esp) 10366 movl %ecx,OUT_ARG0(%esp) 10367 call dvmResolveStaticField # eax<- resolved StaticField ptr 10368 testl %eax,%eax 10369 jne .LOP_SGET_BYTE_finish # success, continue 10370 jmp common_exceptionThrown # no, handle exception 10371 10372/* continuation for OP_SGET_CHAR */ 10373 10374 /* 10375 * Go resolve the field 10376 */ 10377.LOP_SGET_CHAR_resolve: 10378 movl rGLUE,%ecx 10379 movzwl 2(rPC),%eax # eax<- field ref BBBB 10380 movl offGlue_method(%ecx),%ecx # ecx<- current method 10381 EXPORT_PC # could throw, need to export 10382 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10383 movl %eax,OUT_ARG1(%esp) 10384 movl %ecx,OUT_ARG0(%esp) 10385 call dvmResolveStaticField # eax<- resolved StaticField ptr 10386 testl %eax,%eax 10387 jne .LOP_SGET_CHAR_finish # success, continue 10388 jmp common_exceptionThrown # no, handle exception 10389 10390/* continuation for OP_SGET_SHORT */ 10391 10392 /* 10393 * Go resolve the field 10394 */ 10395.LOP_SGET_SHORT_resolve: 10396 movl rGLUE,%ecx 10397 movzwl 2(rPC),%eax # eax<- field ref BBBB 10398 movl offGlue_method(%ecx),%ecx # ecx<- current method 10399 EXPORT_PC # could throw, need to export 10400 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10401 movl %eax,OUT_ARG1(%esp) 10402 movl %ecx,OUT_ARG0(%esp) 10403 call dvmResolveStaticField # eax<- resolved StaticField ptr 10404 testl %eax,%eax 10405 jne .LOP_SGET_SHORT_finish # success, continue 10406 jmp common_exceptionThrown # no, handle exception 10407 10408/* continuation for OP_SPUT */ 10409 10410 /* 10411 * Go resolve the field 10412 */ 10413.LOP_SPUT_resolve: 10414 movl rGLUE,%ecx 10415 movzwl 2(rPC),%eax # eax<- field ref BBBB 10416 movl offGlue_method(%ecx),%ecx # ecx<- current method 10417 EXPORT_PC # could throw, need to export 10418 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10419 movl %eax,OUT_ARG1(%esp) 10420 movl %ecx,OUT_ARG0(%esp) 10421 call dvmResolveStaticField # eax<- resolved StaticField ptr 10422 testl %eax,%eax 10423 jne .LOP_SPUT_finish # success, continue 10424 jmp common_exceptionThrown # no, handle exception 10425 10426/* continuation for OP_SPUT_WIDE */ 10427 10428 /* 10429 * Go resolve the field 10430 */ 10431.LOP_SPUT_WIDE_resolve: 10432 movl rGLUE,%ecx 10433 movzwl 2(rPC),%eax # eax<- field ref BBBB 10434 movl offGlue_method(%ecx),%ecx # ecx<- current method 10435 EXPORT_PC # could throw, need to export 10436 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10437 movl %eax,OUT_ARG1(%esp) 10438 movl %ecx,OUT_ARG0(%esp) 10439 call dvmResolveStaticField # eax<- resolved StaticField ptr 10440 testl %eax,%eax 10441 jne .LOP_SPUT_WIDE_finish # success, continue 10442 jmp common_exceptionThrown # no, handle exception 10443 10444/* continuation for OP_SPUT_OBJECT */ 10445 10446 10447.LOP_SPUT_OBJECT_continue: 10448 movl %ecx,offStaticField_value(%eax) # do the store 10449 testl %ecx,%ecx # stored null object ptr? 10450 FETCH_INST_OPCODE 2 %edx 10451 je 1f # skip card mark if null 10452 movl rGLUE,%ecx 10453 movl offField_clazz(%eax),%eax # eax<- method->clazz 10454 movl offGlue_cardTable(%ecx),%ecx # get card table base 10455 shrl $GC_CARD_SHIFT,%eax # head to card number 10456 movb %cl,(%ecx,%eax) # mark card 104571: 10458 ADVANCE_PC 2 10459 GOTO_NEXT_R %edx 10460 10461.LOP_SPUT_OBJECT_resolve: 10462 movl rGLUE,%ecx 10463 movzwl 2(rPC),%eax # eax<- field ref BBBB 10464 movl offGlue_method(%ecx),%ecx # ecx<- current method 10465 EXPORT_PC # could throw, need to export 10466 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10467 movl %eax,OUT_ARG1(%esp) 10468 movl %ecx,OUT_ARG0(%esp) 10469 call dvmResolveStaticField # eax<- resolved StaticField ptr 10470 testl %eax,%eax 10471 jne .LOP_SPUT_OBJECT_finish # success, continue 10472 jmp common_exceptionThrown # no, handle exception 10473 10474/* continuation for OP_SPUT_BOOLEAN */ 10475 10476 /* 10477 * Go resolve the field 10478 */ 10479.LOP_SPUT_BOOLEAN_resolve: 10480 movl rGLUE,%ecx 10481 movzwl 2(rPC),%eax # eax<- field ref BBBB 10482 movl offGlue_method(%ecx),%ecx # ecx<- current method 10483 EXPORT_PC # could throw, need to export 10484 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10485 movl %eax,OUT_ARG1(%esp) 10486 movl %ecx,OUT_ARG0(%esp) 10487 call dvmResolveStaticField # eax<- resolved StaticField ptr 10488 testl %eax,%eax 10489 jne .LOP_SPUT_BOOLEAN_finish # success, continue 10490 jmp common_exceptionThrown # no, handle exception 10491 10492/* continuation for OP_SPUT_BYTE */ 10493 10494 /* 10495 * Go resolve the field 10496 */ 10497.LOP_SPUT_BYTE_resolve: 10498 movl rGLUE,%ecx 10499 movzwl 2(rPC),%eax # eax<- field ref BBBB 10500 movl offGlue_method(%ecx),%ecx # ecx<- current method 10501 EXPORT_PC # could throw, need to export 10502 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10503 movl %eax,OUT_ARG1(%esp) 10504 movl %ecx,OUT_ARG0(%esp) 10505 call dvmResolveStaticField # eax<- resolved StaticField ptr 10506 testl %eax,%eax 10507 jne .LOP_SPUT_BYTE_finish # success, continue 10508 jmp common_exceptionThrown # no, handle exception 10509 10510/* continuation for OP_SPUT_CHAR */ 10511 10512 /* 10513 * Go resolve the field 10514 */ 10515.LOP_SPUT_CHAR_resolve: 10516 movl rGLUE,%ecx 10517 movzwl 2(rPC),%eax # eax<- field ref BBBB 10518 movl offGlue_method(%ecx),%ecx # ecx<- current method 10519 EXPORT_PC # could throw, need to export 10520 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10521 movl %eax,OUT_ARG1(%esp) 10522 movl %ecx,OUT_ARG0(%esp) 10523 call dvmResolveStaticField # eax<- resolved StaticField ptr 10524 testl %eax,%eax 10525 jne .LOP_SPUT_CHAR_finish # success, continue 10526 jmp common_exceptionThrown # no, handle exception 10527 10528/* continuation for OP_SPUT_SHORT */ 10529 10530 /* 10531 * Go resolve the field 10532 */ 10533.LOP_SPUT_SHORT_resolve: 10534 movl rGLUE,%ecx 10535 movzwl 2(rPC),%eax # eax<- field ref BBBB 10536 movl offGlue_method(%ecx),%ecx # ecx<- current method 10537 EXPORT_PC # could throw, need to export 10538 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10539 movl %eax,OUT_ARG1(%esp) 10540 movl %ecx,OUT_ARG0(%esp) 10541 call dvmResolveStaticField # eax<- resolved StaticField ptr 10542 testl %eax,%eax 10543 jne .LOP_SPUT_SHORT_finish # success, continue 10544 jmp common_exceptionThrown # no, handle exception 10545 10546/* continuation for OP_INVOKE_VIRTUAL */ 10547 10548 10549.LOP_INVOKE_VIRTUAL_more: 10550 movl offMethod_clazz(%eax),%eax # ecx<- method->clazz 10551 movl %eax,OUT_ARG0(%esp) # arg0<- clazz 10552 movl $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags 10553 call dvmResolveMethod # eax<- call(clazz, ref, flags) 10554 testl %eax,%eax # got null? 10555 jne .LOP_INVOKE_VIRTUAL_continue # no, continue 10556 jmp common_exceptionThrown # yes, handle exception 10557 10558 /* At this point: 10559 * eax = resolved base method 10560 * ecx = scratch 10561 */ 10562.LOP_INVOKE_VIRTUAL_continue: 10563 movzwl 4(rPC),%ecx # ecx<- GFED or CCCC 10564 .if (!0) 10565 andl $0xf,%ecx # ecx<- D (or stays CCCC) 10566 .endif 10567 GET_VREG_R %ecx %ecx # ecx<- "this" 10568 movzwl offMethod_methodIndex(%eax),%eax # eax<- baseMethod->methodIndex 10569 testl %ecx,%ecx # null this? 10570 je common_errNullObject # go if so 10571 movl offObject_clazz(%ecx),%ecx # ecx<- thisPtr->clazz 10572 movl offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable 10573 movl (%ecx,%eax,4),%eax # eax<- vtable[methodIndex] 10574 jmp common_invokeMethodNoRange 10575 10576/* continuation for OP_INVOKE_SUPER */ 10577 10578 /* 10579 * At this point: 10580 * ecx = resolved base method [r0] 10581 * eax = method->clazz [r9] 10582 */ 10583.LOP_INVOKE_SUPER_continue: 10584 movl offClassObject_super(%eax),%eax # eax<- method->clazz->super 10585 movzwl offMethod_methodIndex(%ecx),%ecx # ecx<- baseMthod->methodIndex 10586 cmpl offClassObject_vtableCount(%eax),%ecx # compare(methodIndex,vtableCount) 10587 jae .LOP_INVOKE_SUPER_nsm # method not present in superclass 10588 movl offClassObject_vtable(%eax),%eax # eax<- ...clazz->super->vtable 10589 movl (%eax,%ecx,4),%eax # eax<- vtable[methodIndex] 10590 jmp common_invokeMethodNoRange 10591 10592 10593 /* At this point: 10594 * ecx = null (needs to be resolved base method) 10595 * eax = method->clazz 10596 */ 10597.LOP_INVOKE_SUPER_resolve: 10598 SPILL_TMP1(%eax) # method->clazz 10599 movl %eax,OUT_ARG0(%esp) # arg0<- method->clazz 10600 movzwl 2(rPC),%ecx # ecx<- BBBB 10601 movl $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- resolver method type 10602 movl %ecx,OUT_ARG1(%esp) # arg1<- ref 10603 call dvmResolveMethod # eax<- call(clazz, ref, flags) 10604 testl %eax,%eax # got null? 10605 movl %eax,%ecx # ecx<- resolved base method 10606 UNSPILL_TMP1(%eax) # restore method->clazz 10607 jne .LOP_INVOKE_SUPER_continue # good to go - continue 10608 jmp common_exceptionThrown # handle exception 10609 10610 /* 10611 * Throw a NoSuchMethodError with the method name as the message. 10612 * ecx = resolved base method 10613 */ 10614.LOP_INVOKE_SUPER_nsm: 10615 movl offMethod_name(%ecx),%eax 10616 mov %eax,OUT_ARG1(%esp) 10617 jmp common_errNoSuchMethod 10618 10619/* continuation for OP_INVOKE_DIRECT */ 10620 10621 /* 10622 * On entry: 10623 * TMP_SPILL <- "this" register 10624 * Things a bit ugly on this path, but it's the less 10625 * frequent one. We'll have to do some reloading. 10626 */ 10627.LOP_INVOKE_DIRECT_resolve: 10628 SPILL_TMP1(%ecx) 10629 movl rGLUE,%ecx 10630 movl offGlue_method(%ecx),%ecx # ecx<- glue->method 10631 movzwl 2(rPC),%eax # reference (BBBB or CCCC) 10632 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10633 movl $METHOD_DIRECT,OUT_ARG2(%esp) 10634 movl %eax,OUT_ARG1(%esp) 10635 movl %ecx,OUT_ARG0(%esp) 10636 call dvmResolveMethod # eax<- call(clazz, ref, flags) 10637 UNSPILL_TMP1(%ecx) 10638 testl %eax,%eax 10639 jne .LOP_INVOKE_DIRECT_finish 10640 jmp common_exceptionThrown 10641 10642/* continuation for OP_INVOKE_STATIC */ 10643 10644.LOP_INVOKE_STATIC_continue: 10645 movl $METHOD_STATIC,%eax 10646 movl %eax,OUT_ARG2(%esp) # arg2<- flags 10647 call dvmResolveMethod # call(clazz,ref,flags) 10648 testl %eax,%eax # got null? 10649 jne common_invokeMethodNoRange 10650 jmp common_exceptionThrown 10651 10652/* continuation for OP_INVOKE_INTERFACE */ 10653 10654.LOP_INVOKE_INTERFACE_continue: 10655 call dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex) 10656 testl %eax,%eax 10657 je common_exceptionThrown 10658 jmp common_invokeMethodNoRange 10659 10660/* continuation for OP_INVOKE_VIRTUAL_RANGE */ 10661 10662 10663.LOP_INVOKE_VIRTUAL_RANGE_more: 10664 movl offMethod_clazz(%eax),%eax # ecx<- method->clazz 10665 movl %eax,OUT_ARG0(%esp) # arg0<- clazz 10666 movl $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags 10667 call dvmResolveMethod # eax<- call(clazz, ref, flags) 10668 testl %eax,%eax # got null? 10669 jne .LOP_INVOKE_VIRTUAL_RANGE_continue # no, continue 10670 jmp common_exceptionThrown # yes, handle exception 10671 10672 /* At this point: 10673 * eax = resolved base method 10674 * ecx = scratch 10675 */ 10676.LOP_INVOKE_VIRTUAL_RANGE_continue: 10677 movzwl 4(rPC),%ecx # ecx<- GFED or CCCC 10678 .if (!1) 10679 andl $0xf,%ecx # ecx<- D (or stays CCCC) 10680 .endif 10681 GET_VREG_R %ecx %ecx # ecx<- "this" 10682 movzwl offMethod_methodIndex(%eax),%eax # eax<- baseMethod->methodIndex 10683 testl %ecx,%ecx # null this? 10684 je common_errNullObject # go if so 10685 movl offObject_clazz(%ecx),%ecx # ecx<- thisPtr->clazz 10686 movl offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable 10687 movl (%ecx,%eax,4),%eax # eax<- vtable[methodIndex] 10688 jmp common_invokeMethodRange 10689 10690/* continuation for OP_INVOKE_SUPER_RANGE */ 10691 10692 /* 10693 * At this point: 10694 * ecx = resolved base method [r0] 10695 * eax = method->clazz [r9] 10696 */ 10697.LOP_INVOKE_SUPER_RANGE_continue: 10698 movl offClassObject_super(%eax),%eax # eax<- method->clazz->super 10699 movzwl offMethod_methodIndex(%ecx),%ecx # ecx<- baseMthod->methodIndex 10700 cmpl offClassObject_vtableCount(%eax),%ecx # compare(methodIndex,vtableCount) 10701 jae .LOP_INVOKE_SUPER_RANGE_nsm # method not present in superclass 10702 movl offClassObject_vtable(%eax),%eax # eax<- ...clazz->super->vtable 10703 movl (%eax,%ecx,4),%eax # eax<- vtable[methodIndex] 10704 jmp common_invokeMethodRange 10705 10706 10707 /* At this point: 10708 * ecx = null (needs to be resolved base method) 10709 * eax = method->clazz 10710 */ 10711.LOP_INVOKE_SUPER_RANGE_resolve: 10712 SPILL_TMP1(%eax) # method->clazz 10713 movl %eax,OUT_ARG0(%esp) # arg0<- method->clazz 10714 movzwl 2(rPC),%ecx # ecx<- BBBB 10715 movl $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- resolver method type 10716 movl %ecx,OUT_ARG1(%esp) # arg1<- ref 10717 call dvmResolveMethod # eax<- call(clazz, ref, flags) 10718 testl %eax,%eax # got null? 10719 movl %eax,%ecx # ecx<- resolved base method 10720 UNSPILL_TMP1(%eax) # restore method->clazz 10721 jne .LOP_INVOKE_SUPER_RANGE_continue # good to go - continue 10722 jmp common_exceptionThrown # handle exception 10723 10724 /* 10725 * Throw a NoSuchMethodError with the method name as the message. 10726 * ecx = resolved base method 10727 */ 10728.LOP_INVOKE_SUPER_RANGE_nsm: 10729 movl offMethod_name(%ecx),%eax 10730 mov %eax,OUT_ARG1(%esp) 10731 jmp common_errNoSuchMethod 10732 10733/* continuation for OP_INVOKE_DIRECT_RANGE */ 10734 10735 /* 10736 * On entry: 10737 * TMP_SPILL <- "this" register 10738 * Things a bit ugly on this path, but it's the less 10739 * frequent one. We'll have to do some reloading. 10740 */ 10741.LOP_INVOKE_DIRECT_RANGE_resolve: 10742 SPILL_TMP1(%ecx) 10743 movl rGLUE,%ecx 10744 movl offGlue_method(%ecx),%ecx # ecx<- glue->method 10745 movzwl 2(rPC),%eax # reference (BBBB or CCCC) 10746 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 10747 movl $METHOD_DIRECT,OUT_ARG2(%esp) 10748 movl %eax,OUT_ARG1(%esp) 10749 movl %ecx,OUT_ARG0(%esp) 10750 call dvmResolveMethod # eax<- call(clazz, ref, flags) 10751 UNSPILL_TMP1(%ecx) 10752 testl %eax,%eax 10753 jne .LOP_INVOKE_DIRECT_RANGE_finish 10754 jmp common_exceptionThrown 10755 10756/* continuation for OP_INVOKE_STATIC_RANGE */ 10757 10758.LOP_INVOKE_STATIC_RANGE_continue: 10759 movl $METHOD_STATIC,%eax 10760 movl %eax,OUT_ARG2(%esp) # arg2<- flags 10761 call dvmResolveMethod # call(clazz,ref,flags) 10762 testl %eax,%eax # got null? 10763 jne common_invokeMethodRange 10764 jmp common_exceptionThrown 10765 10766/* continuation for OP_INVOKE_INTERFACE_RANGE */ 10767 10768.LOP_INVOKE_INTERFACE_RANGE_continue: 10769 call dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex) 10770 testl %eax,%eax 10771 je common_exceptionThrown 10772 jmp common_invokeMethodRange 10773 10774/* continuation for OP_FLOAT_TO_INT */ 10775 10776 10777.LOP_FLOAT_TO_INT_continue: 10778 .if 0 10779 movl $0x80000000,%eax 10780 xorl 4(rFP,%ecx,4),%eax 10781 orl (rFP,%ecx,4),%eax 10782 .else 10783 cmpl $0x80000000,(rFP,%ecx,4) 10784 .endif 10785 je .LOP_FLOAT_TO_INT_special_case # fix up result 10786 10787.LOP_FLOAT_TO_INT_finish: 10788 ADVANCE_PC 1 10789 GOTO_NEXT_R %edx 10790 10791.LOP_FLOAT_TO_INT_special_case: 10792 fnstsw %ax 10793 sahf 10794 jp .LOP_FLOAT_TO_INT_isNaN 10795 adcl $-1,(rFP,%ecx,4) 10796 .if 0 10797 adcl $-1,4(rFP,%ecx,4) 10798 .endif 10799 jmp .LOP_FLOAT_TO_INT_finish 10800.LOP_FLOAT_TO_INT_isNaN: 10801 movl $0,(rFP,%ecx,4) 10802 .if 0 10803 movl $0,4(rFP,%ecx,4) 10804 .endif 10805 jmp .LOP_FLOAT_TO_INT_finish 10806 10807/* continuation for OP_FLOAT_TO_LONG */ 10808 10809 10810.LOP_FLOAT_TO_LONG_continue: 10811 .if 1 10812 movl $0x80000000,%eax 10813 xorl 4(rFP,%ecx,4),%eax 10814 orl (rFP,%ecx,4),%eax 10815 .else 10816 cmpl $0x80000000,(rFP,%ecx,4) 10817 .endif 10818 je .LOP_FLOAT_TO_LONG_special_case # fix up result 10819 10820.LOP_FLOAT_TO_LONG_finish: 10821 ADVANCE_PC 1 10822 GOTO_NEXT_R %edx 10823 10824.LOP_FLOAT_TO_LONG_special_case: 10825 fnstsw %ax 10826 sahf 10827 jp .LOP_FLOAT_TO_LONG_isNaN 10828 adcl $-1,(rFP,%ecx,4) 10829 .if 1 10830 adcl $-1,4(rFP,%ecx,4) 10831 .endif 10832 jmp .LOP_FLOAT_TO_LONG_finish 10833.LOP_FLOAT_TO_LONG_isNaN: 10834 movl $0,(rFP,%ecx,4) 10835 .if 1 10836 movl $0,4(rFP,%ecx,4) 10837 .endif 10838 jmp .LOP_FLOAT_TO_LONG_finish 10839 10840/* continuation for OP_DOUBLE_TO_INT */ 10841 10842 10843.LOP_DOUBLE_TO_INT_continue: 10844 .if 0 10845 movl $0x80000000,%eax 10846 xorl 4(rFP,%ecx,4),%eax 10847 orl (rFP,%ecx,4),%eax 10848 .else 10849 cmpl $0x80000000,(rFP,%ecx,4) 10850 .endif 10851 je .LOP_DOUBLE_TO_INT_special_case # fix up result 10852 10853.LOP_DOUBLE_TO_INT_finish: 10854 ADVANCE_PC 1 10855 GOTO_NEXT_R %edx 10856 10857.LOP_DOUBLE_TO_INT_special_case: 10858 fnstsw %ax 10859 sahf 10860 jp .LOP_DOUBLE_TO_INT_isNaN 10861 adcl $-1,(rFP,%ecx,4) 10862 .if 0 10863 adcl $-1,4(rFP,%ecx,4) 10864 .endif 10865 jmp .LOP_DOUBLE_TO_INT_finish 10866.LOP_DOUBLE_TO_INT_isNaN: 10867 movl $0,(rFP,%ecx,4) 10868 .if 0 10869 movl $0,4(rFP,%ecx,4) 10870 .endif 10871 jmp .LOP_DOUBLE_TO_INT_finish 10872 10873/* continuation for OP_DOUBLE_TO_LONG */ 10874 10875 10876.LOP_DOUBLE_TO_LONG_continue: 10877 .if 1 10878 movl $0x80000000,%eax 10879 xorl 4(rFP,%ecx,4),%eax 10880 orl (rFP,%ecx,4),%eax 10881 .else 10882 cmpl $0x80000000,(rFP,%ecx,4) 10883 .endif 10884 je .LOP_DOUBLE_TO_LONG_special_case # fix up result 10885 10886.LOP_DOUBLE_TO_LONG_finish: 10887 ADVANCE_PC 1 10888 GOTO_NEXT_R %edx 10889 10890.LOP_DOUBLE_TO_LONG_special_case: 10891 fnstsw %ax 10892 sahf 10893 jp .LOP_DOUBLE_TO_LONG_isNaN 10894 adcl $-1,(rFP,%ecx,4) 10895 .if 1 10896 adcl $-1,4(rFP,%ecx,4) 10897 .endif 10898 jmp .LOP_DOUBLE_TO_LONG_finish 10899.LOP_DOUBLE_TO_LONG_isNaN: 10900 movl $0,(rFP,%ecx,4) 10901 .if 1 10902 movl $0,4(rFP,%ecx,4) 10903 .endif 10904 jmp .LOP_DOUBLE_TO_LONG_finish 10905 10906/* continuation for OP_DIV_INT */ 10907.LOP_DIV_INT_continue_div: 10908 cltd 10909 idivl %ecx 10910.LOP_DIV_INT_finish_div: 10911 SET_VREG %eax rINST 10912 FETCH_INST_OPCODE 2 %edx 10913 ADVANCE_PC 2 10914 GOTO_NEXT_R %edx 10915 10916/* continuation for OP_REM_INT */ 10917.LOP_REM_INT_continue_div: 10918 cltd 10919 idivl %ecx 10920.LOP_REM_INT_finish_div: 10921 SET_VREG %edx rINST 10922 FETCH_INST_OPCODE 2 %edx 10923 ADVANCE_PC 2 10924 GOTO_NEXT_R %edx 10925 10926/* continuation for OP_MUL_LONG */ 10927 10928.LOP_MUL_LONG_continue: 10929 leal (%ecx,%edx),%edx # full result now in %edx:%eax 10930 UNSPILL_TMP2(%esi) # Restore Dalvik PC 10931 FETCH_INST_OPCODE 2 %ecx # Fetch next instruction 10932 movl %edx,4(rFP,rINST,4) # v[B+1]<- %edx 10933 movl %eax,(rFP,rINST,4) # v[B]<- %eax 10934 ADVANCE_PC 2 10935 GOTO_NEXT_R %ecx 10936 10937/* continuation for OP_DIV_LONG */ 10938 10939.LOP_DIV_LONG_continue: 10940 call __divdi3 10941.LOP_DIV_LONG_finish: 10942 SET_VREG_WORD %edx rINST 1 10943 SET_VREG_WORD %eax rINST 0 10944 FETCH_INST_OPCODE 2 %edx 10945 ADVANCE_PC 2 10946 GOTO_NEXT_R %edx 10947 10948.LOP_DIV_LONG_check_zero: 10949 testl %edx,%edx 10950 jne .LOP_DIV_LONG_notSpecial 10951 jmp common_errDivideByZero 10952.LOP_DIV_LONG_check_neg1: 10953 testl %edx,%eax 10954 jne .LOP_DIV_LONG_notSpecial 10955 GET_VREG_WORD %edx %ecx 0 10956 GET_VREG_WORD %ecx %ecx 1 10957 testl %edx,%edx 10958 jne .LOP_DIV_LONG_notSpecial1 10959 cmpl $0x80000000,%ecx 10960 jne .LOP_DIV_LONG_notSpecial1 10961 /* minint / -1, return minint on div, 0 on rem */ 10962 xorl %eax,%eax 10963 movl $0x80000000,%edx 10964 jmp .LOP_DIV_LONG_finish 10965 10966/* continuation for OP_REM_LONG */ 10967 10968.LOP_REM_LONG_continue: 10969 call __moddi3 10970.LOP_REM_LONG_finish: 10971 SET_VREG_WORD %edx rINST 1 10972 SET_VREG_WORD %eax rINST 0 10973 FETCH_INST_OPCODE 2 %edx 10974 ADVANCE_PC 2 10975 GOTO_NEXT_R %edx 10976 10977.LOP_REM_LONG_check_zero: 10978 testl %edx,%edx 10979 jne .LOP_REM_LONG_notSpecial 10980 jmp common_errDivideByZero 10981.LOP_REM_LONG_check_neg1: 10982 testl %edx,%eax 10983 jne .LOP_REM_LONG_notSpecial 10984 GET_VREG_WORD %edx %ecx 0 10985 GET_VREG_WORD %ecx %ecx 1 10986 testl %edx,%edx 10987 jne .LOP_REM_LONG_notSpecial1 10988 cmpl $0x80000000,%ecx 10989 jne .LOP_REM_LONG_notSpecial1 10990 /* minint / -1, return minint on div, 0 on rem */ 10991 xorl %eax,%eax 10992 movl $0,%edx 10993 jmp .LOP_REM_LONG_finish 10994 10995/* continuation for OP_SHL_LONG */ 10996 10997.LOP_SHL_LONG_finish: 10998 SET_VREG_WORD %eax rINST 0 # v[AA+0]<- %eax 10999 ADVANCE_PC 2 11000 GOTO_NEXT_R %edx 11001 11002/* continuation for OP_SHR_LONG */ 11003 11004 11005.LOP_SHR_LONG_finish: 11006 SET_VREG_WORD %eax rINST 0 # v[AA+0]<- eax 11007 ADVANCE_PC 2 11008 GOTO_NEXT_R %edx 11009 11010/* continuation for OP_USHR_LONG */ 11011 11012 11013.LOP_USHR_LONG_finish: 11014 SET_VREG_WORD %eax rINST 0 # v[BB+0]<- eax 11015 ADVANCE_PC 2 11016 GOTO_NEXT_R %edx 11017 11018/* continuation for OP_DIV_INT_2ADDR */ 11019.LOP_DIV_INT_2ADDR_continue_div2addr: 11020 cltd 11021 idivl %ecx 11022.LOP_DIV_INT_2ADDR_finish_div2addr: 11023 SET_VREG %eax rINST 11024 FETCH_INST_OPCODE 1 %edx 11025 ADVANCE_PC 1 11026 GOTO_NEXT_R %edx 11027 11028/* continuation for OP_REM_INT_2ADDR */ 11029.LOP_REM_INT_2ADDR_continue_div2addr: 11030 cltd 11031 idivl %ecx 11032.LOP_REM_INT_2ADDR_finish_div2addr: 11033 SET_VREG %edx rINST 11034 FETCH_INST_OPCODE 1 %edx 11035 ADVANCE_PC 1 11036 GOTO_NEXT_R %edx 11037 11038/* continuation for OP_MUL_LONG_2ADDR */ 11039 11040.LOP_MUL_LONG_2ADDR_continue: 11041 leal (%ecx,%edx),%edx # full result now in %edx:%eax 11042 movl %edx,4(%esi) # v[A+1]<- %edx 11043 movl %eax,(%esi) # v[A]<- %eax 11044 UNSPILL_TMP2(%esi) 11045 FETCH_INST_OPCODE 1 %ecx 11046 UNSPILL(rFP) 11047 ADVANCE_PC 1 11048 GOTO_NEXT_R %ecx 11049 11050/* continuation for OP_DIV_LONG_2ADDR */ 11051 11052.LOP_DIV_LONG_2ADDR_continue: 11053 movl %eax,OUT_ARG3(%esp) 11054 movl %edx,OUT_ARG0(%esp) 11055 movl %ecx,OUT_ARG1(%esp) 11056 call __divdi3 11057.LOP_DIV_LONG_2ADDR_finish: 11058 SET_VREG_WORD %edx rINST 1 11059 SET_VREG_WORD %eax rINST 0 11060 FETCH_INST_OPCODE 1 %edx 11061 ADVANCE_PC 1 11062 GOTO_NEXT_R %edx 11063 11064.LOP_DIV_LONG_2ADDR_check_zero: 11065 testl %edx,%edx 11066 jne .LOP_DIV_LONG_2ADDR_notSpecial 11067 jmp common_errDivideByZero 11068.LOP_DIV_LONG_2ADDR_check_neg1: 11069 testl %edx,%eax 11070 jne .LOP_DIV_LONG_2ADDR_notSpecial 11071 GET_VREG_WORD %edx rINST 0 11072 GET_VREG_WORD %ecx rINST 1 11073 testl %edx,%edx 11074 jne .LOP_DIV_LONG_2ADDR_notSpecial1 11075 cmpl $0x80000000,%ecx 11076 jne .LOP_DIV_LONG_2ADDR_notSpecial1 11077 /* minint / -1, return minint on div, 0 on rem */ 11078 xorl %eax,%eax 11079 movl $0x80000000,%edx 11080 jmp .LOP_DIV_LONG_2ADDR_finish 11081 11082/* continuation for OP_REM_LONG_2ADDR */ 11083 11084.LOP_REM_LONG_2ADDR_continue: 11085 movl %eax,OUT_ARG3(%esp) 11086 movl %edx,OUT_ARG0(%esp) 11087 movl %ecx,OUT_ARG1(%esp) 11088 call __moddi3 11089.LOP_REM_LONG_2ADDR_finish: 11090 SET_VREG_WORD %edx rINST 1 11091 SET_VREG_WORD %eax rINST 0 11092 FETCH_INST_OPCODE 1 %edx 11093 ADVANCE_PC 1 11094 GOTO_NEXT_R %edx 11095 11096.LOP_REM_LONG_2ADDR_check_zero: 11097 testl %edx,%edx 11098 jne .LOP_REM_LONG_2ADDR_notSpecial 11099 jmp common_errDivideByZero 11100.LOP_REM_LONG_2ADDR_check_neg1: 11101 testl %edx,%eax 11102 jne .LOP_REM_LONG_2ADDR_notSpecial 11103 GET_VREG_WORD %edx rINST 0 11104 GET_VREG_WORD %ecx rINST 1 11105 testl %edx,%edx 11106 jne .LOP_REM_LONG_2ADDR_notSpecial1 11107 cmpl $0x80000000,%ecx 11108 jne .LOP_REM_LONG_2ADDR_notSpecial1 11109 /* minint / -1, return minint on div, 0 on rem */ 11110 xorl %eax,%eax 11111 movl $0,%edx 11112 jmp .LOP_REM_LONG_2ADDR_finish 11113 11114/* continuation for OP_SHL_LONG_2ADDR */ 11115 11116 11117.LOP_SHL_LONG_2ADDR_finish: 11118 FETCH_INST_OPCODE 1 %edx 11119 SET_VREG_WORD %eax rINST 0 # v[AA+0]<- eax 11120 ADVANCE_PC 1 11121 GOTO_NEXT_R %edx 11122 11123/* continuation for OP_SHR_LONG_2ADDR */ 11124 11125 11126.LOP_SHR_LONG_2ADDR_finish: 11127 FETCH_INST_OPCODE 1 %edx 11128 SET_VREG_WORD %eax rINST 0 # v[AA+0]<- eax 11129 ADVANCE_PC 1 11130 GOTO_NEXT_R %edx 11131 11132/* continuation for OP_USHR_LONG_2ADDR */ 11133 11134 11135.LOP_USHR_LONG_2ADDR_finish: 11136 FETCH_INST_OPCODE 1 %edx 11137 SET_VREG_WORD %eax rINST 0 # v[AA+0]<- eax 11138 ADVANCE_PC 1 11139 GOTO_NEXT_R %edx 11140 11141/* continuation for OP_DIV_INT_LIT16 */ 11142.LOP_DIV_INT_LIT16_continue_div: 11143 cltd 11144 idivl %ecx 11145.LOP_DIV_INT_LIT16_finish_div: 11146 SET_VREG %eax rINST 11147 FETCH_INST_OPCODE 2 %edx 11148 ADVANCE_PC 2 11149 GOTO_NEXT_R %edx 11150 11151/* continuation for OP_REM_INT_LIT16 */ 11152.LOP_REM_INT_LIT16_continue_div: 11153 cltd 11154 idivl %ecx 11155.LOP_REM_INT_LIT16_finish_div: 11156 SET_VREG %edx rINST 11157 FETCH_INST_OPCODE 2 %edx 11158 ADVANCE_PC 2 11159 GOTO_NEXT_R %edx 11160 11161/* continuation for OP_DIV_INT_LIT8 */ 11162.LOP_DIV_INT_LIT8_continue_div: 11163 cltd 11164 idivl %ecx 11165.LOP_DIV_INT_LIT8_finish_div: 11166 SET_VREG %eax rINST 11167 FETCH_INST_OPCODE 2 %edx 11168 ADVANCE_PC 2 11169 GOTO_NEXT_R %edx 11170 11171/* continuation for OP_REM_INT_LIT8 */ 11172.LOP_REM_INT_LIT8_continue_div: 11173 cltd 11174 idivl %ecx 11175.LOP_REM_INT_LIT8_finish_div: 11176 SET_VREG %edx rINST 11177 FETCH_INST_OPCODE 2 %edx 11178 ADVANCE_PC 2 11179 GOTO_NEXT_R %edx 11180 11181/* continuation for OP_IGET_VOLATILE */ 11182 11183 11184.LOP_IGET_VOLATILE_resolve: 11185 EXPORT_PC 11186 movl offGlue_method(%edx),%edx # edx<- current method 11187 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11188 SPILL_TMP1(%ecx) # save obj pointer across call 11189 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11190 call dvmResolveInstField # ... to dvmResolveInstField 11191 UNSPILL_TMP1(%ecx) 11192 testl %eax,%eax # returns InstrField ptr 11193 jne .LOP_IGET_VOLATILE_finish 11194 jmp common_exceptionThrown 11195 11196.LOP_IGET_VOLATILE_finish: 11197 /* 11198 * Currently: 11199 * eax holds resolved field 11200 * ecx holds object 11201 * rINST holds A 11202 */ 11203 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11204 testl %ecx,%ecx # object null? 11205 je common_errNullObject # object was null 11206 movl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 11207 movl rINST,%eax # eax<- A 11208 FETCH_INST_OPCODE 2 %edx 11209 SET_VREG %ecx %eax 11210 ADVANCE_PC 2 11211 GOTO_NEXT_R %edx 11212 11213/* continuation for OP_IPUT_VOLATILE */ 11214 11215 11216.LOP_IPUT_VOLATILE_resolve: 11217 EXPORT_PC 11218 movl offGlue_method(%edx),%edx # edx<- current method 11219 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11220 SPILL_TMP1(%ecx) # save obj pointer across call 11221 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11222 call dvmResolveInstField # ... to dvmResolveInstField 11223 UNSPILL_TMP1(%ecx) 11224 testl %eax,%eax # returns InstrField ptr 11225 jne .LOP_IPUT_VOLATILE_finish 11226 jmp common_exceptionThrown 11227 11228.LOP_IPUT_VOLATILE_finish: 11229 /* 11230 * Currently: 11231 * eax holds resolved field 11232 * ecx holds object 11233 * rINST holds A 11234 */ 11235 GET_VREG_R rINST rINST # rINST<- v[A] 11236 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11237 testl %ecx,%ecx # object null? 11238 je common_errNullObject # object was null 11239 FETCH_INST_OPCODE 2 %edx 11240 movl rINST,(%ecx,%eax,1) # obj.field <- v[A](8/16/32 bits) 11241 ADVANCE_PC 2 11242 GOTO_NEXT_R %edx 11243 11244/* continuation for OP_SGET_VOLATILE */ 11245 11246 /* 11247 * Go resolve the field 11248 */ 11249.LOP_SGET_VOLATILE_resolve: 11250 movl rGLUE,%ecx 11251 movzwl 2(rPC),%eax # eax<- field ref BBBB 11252 movl offGlue_method(%ecx),%ecx # ecx<- current method 11253 EXPORT_PC # could throw, need to export 11254 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 11255 movl %eax,OUT_ARG1(%esp) 11256 movl %ecx,OUT_ARG0(%esp) 11257 call dvmResolveStaticField # eax<- resolved StaticField ptr 11258 testl %eax,%eax 11259 jne .LOP_SGET_VOLATILE_finish # success, continue 11260 jmp common_exceptionThrown # no, handle exception 11261 11262/* continuation for OP_SPUT_VOLATILE */ 11263 11264 /* 11265 * Go resolve the field 11266 */ 11267.LOP_SPUT_VOLATILE_resolve: 11268 movl rGLUE,%ecx 11269 movzwl 2(rPC),%eax # eax<- field ref BBBB 11270 movl offGlue_method(%ecx),%ecx # ecx<- current method 11271 EXPORT_PC # could throw, need to export 11272 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 11273 movl %eax,OUT_ARG1(%esp) 11274 movl %ecx,OUT_ARG0(%esp) 11275 call dvmResolveStaticField # eax<- resolved StaticField ptr 11276 testl %eax,%eax 11277 jne .LOP_SPUT_VOLATILE_finish # success, continue 11278 jmp common_exceptionThrown # no, handle exception 11279 11280/* continuation for OP_IGET_OBJECT_VOLATILE */ 11281 11282 11283.LOP_IGET_OBJECT_VOLATILE_resolve: 11284 EXPORT_PC 11285 movl offGlue_method(%edx),%edx # edx<- current method 11286 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11287 SPILL_TMP1(%ecx) # save obj pointer across call 11288 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11289 call dvmResolveInstField # ... to dvmResolveInstField 11290 UNSPILL_TMP1(%ecx) 11291 testl %eax,%eax # returns InstrField ptr 11292 jne .LOP_IGET_OBJECT_VOLATILE_finish 11293 jmp common_exceptionThrown 11294 11295.LOP_IGET_OBJECT_VOLATILE_finish: 11296 /* 11297 * Currently: 11298 * eax holds resolved field 11299 * ecx holds object 11300 * rINST holds A 11301 */ 11302 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11303 testl %ecx,%ecx # object null? 11304 je common_errNullObject # object was null 11305 movl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 11306 movl rINST,%eax # eax<- A 11307 FETCH_INST_OPCODE 2 %edx 11308 SET_VREG %ecx %eax 11309 ADVANCE_PC 2 11310 GOTO_NEXT_R %edx 11311 11312/* continuation for OP_EXECUTE_INLINE */ 11313 11314.LOP_EXECUTE_INLINE_continue: 11315 /* 11316 * Extract args, call function. 11317 * ecx = #of args (0-4) 11318 * eax = call index 11319 * @esp = return addr 11320 * esp is -4 from normal 11321 * 11322 * Go ahead and load all 4 args, even if not used. 11323 */ 11324 movzwl 4(rPC),%edx 11325 11326 movl $0xf,%ecx 11327 andl %edx,%ecx 11328 GET_VREG_R %ecx %ecx 11329 sarl $4,%edx 11330 movl %ecx,4+OUT_ARG0(%esp) 11331 11332 movl $0xf,%ecx 11333 andl %edx,%ecx 11334 GET_VREG_R %ecx %ecx 11335 sarl $4,%edx 11336 movl %ecx,4+OUT_ARG1(%esp) 11337 11338 movl $0xf,%ecx 11339 andl %edx,%ecx 11340 GET_VREG_R %ecx %ecx 11341 sarl $4,%edx 11342 movl %ecx,4+OUT_ARG2(%esp) 11343 11344 movl $0xf,%ecx 11345 andl %edx,%ecx 11346 GET_VREG_R %ecx %ecx 11347 sarl $4,%edx 11348 movl %ecx,4+OUT_ARG3(%esp) 11349 11350 sall $4,%eax # index *= sizeof(table entry) 11351 jmp *gDvmInlineOpsTable(%eax) 11352 # will return to caller of .LOP_EXECUTE_INLINE_continue 11353 11354/* continuation for OP_IPUT_OBJECT_QUICK */ 11355 11356.LOP_IPUT_OBJECT_QUICK_finish: 11357 testl rINST,rINST # did we store null? 11358 FETCH_INST_OPCODE 2 %edx 11359 movl offGlue_cardTable(%eax),%eax # get card table base 11360 je 1f # skip card mark if null store 11361 shrl $GC_CARD_SHIFT,%ecx # object head to card number 11362 movb %al,(%eax,%ecx) # mark card based on object head 113631: 11364 ADVANCE_PC 2 11365 GOTO_NEXT_R %edx 11366 11367/* continuation for OP_IPUT_OBJECT_VOLATILE */ 11368 11369 11370.LOP_IPUT_OBJECT_VOLATILE_resolve: 11371 EXPORT_PC 11372 movl offGlue_method(%edx),%edx # edx<- current method 11373 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11374 SPILL_TMP1(%ecx) # save obj pointer across call 11375 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11376 call dvmResolveInstField # ... to dvmResolveInstField 11377 UNSPILL_TMP1(%ecx) 11378 testl %eax,%eax # returns InstrField ptr 11379 jne .LOP_IPUT_OBJECT_VOLATILE_finish 11380 jmp common_exceptionThrown 11381 11382.LOP_IPUT_OBJECT_VOLATILE_finish: 11383 /* 11384 * Currently: 11385 * eax holds resolved field 11386 * ecx holds object 11387 * %edx is scratch, but needs to be unspilled 11388 * rINST holds A 11389 */ 11390 GET_VREG_R rINST rINST # rINST<- v[A] 11391 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11392 testl %ecx,%ecx # object null? 11393 je common_errNullObject # object was null 11394 movl rINST,(%ecx,%eax) # obj.field <- v[A](8/16/32 bits) 11395 movl rGLUE,%eax 11396 testl rINST,rINST # stored a NULL? 11397 movl offGlue_cardTable(%eax),%eax # get card table base 11398 FETCH_INST_OPCODE 2 %edx 11399 je 1f # skip card mark if null store 11400 shrl $GC_CARD_SHIFT,%ecx # object head to card number 11401 movb %al,(%eax,%ecx) # mark card using object head 114021: 11403 ADVANCE_PC 2 11404 GOTO_NEXT_R %edx 11405 11406/* continuation for OP_SGET_OBJECT_VOLATILE */ 11407 11408 /* 11409 * Go resolve the field 11410 */ 11411.LOP_SGET_OBJECT_VOLATILE_resolve: 11412 movl rGLUE,%ecx 11413 movzwl 2(rPC),%eax # eax<- field ref BBBB 11414 movl offGlue_method(%ecx),%ecx # ecx<- current method 11415 EXPORT_PC # could throw, need to export 11416 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 11417 movl %eax,OUT_ARG1(%esp) 11418 movl %ecx,OUT_ARG0(%esp) 11419 call dvmResolveStaticField # eax<- resolved StaticField ptr 11420 testl %eax,%eax 11421 jne .LOP_SGET_OBJECT_VOLATILE_finish # success, continue 11422 jmp common_exceptionThrown # no, handle exception 11423 11424/* continuation for OP_SPUT_OBJECT_VOLATILE */ 11425 11426 11427.LOP_SPUT_OBJECT_VOLATILE_continue: 11428 movl %ecx,offStaticField_value(%eax) # do the store 11429 testl %ecx,%ecx # stored null object ptr? 11430 FETCH_INST_OPCODE 2 %edx 11431 je 1f # skip card mark if null 11432 movl rGLUE,%ecx 11433 movl offField_clazz(%eax),%eax # eax<- method->clazz 11434 movl offGlue_cardTable(%ecx),%ecx # get card table base 11435 shrl $GC_CARD_SHIFT,%eax # head to card number 11436 movb %cl,(%ecx,%eax) # mark card 114371: 11438 ADVANCE_PC 2 11439 GOTO_NEXT_R %edx 11440 11441.LOP_SPUT_OBJECT_VOLATILE_resolve: 11442 movl rGLUE,%ecx 11443 movzwl 2(rPC),%eax # eax<- field ref BBBB 11444 movl offGlue_method(%ecx),%ecx # ecx<- current method 11445 EXPORT_PC # could throw, need to export 11446 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 11447 movl %eax,OUT_ARG1(%esp) 11448 movl %ecx,OUT_ARG0(%esp) 11449 call dvmResolveStaticField # eax<- resolved StaticField ptr 11450 testl %eax,%eax 11451 jne .LOP_SPUT_OBJECT_VOLATILE_finish # success, continue 11452 jmp common_exceptionThrown # no, handle exception 11453 11454/* continuation for OP_CONST_CLASS_JUMBO */ 11455 11456/* This is the less common path, so we'll redo some work 11457 here rather than force spills on the common path */ 11458.LOP_CONST_CLASS_JUMBO_resolve: 11459 movl rGLUE,%eax 11460 EXPORT_PC 11461 movl offGlue_method(%eax),%eax # eax<- glue->method 11462 movl $1,OUT_ARG2(%esp) # true 11463 movl 2(rPC),%ecx # ecx<- AAAAAAAA 11464 movl offMethod_clazz(%eax),%eax 11465 movl %ecx,OUT_ARG1(%esp) 11466 movl %eax,OUT_ARG0(%esp) 11467 call dvmResolveClass # go resolve 11468 testl %eax,%eax # failed? 11469 je common_exceptionThrown 11470 SET_VREG %eax rINST 11471 FETCH_INST_OPCODE 4 %edx 11472 ADVANCE_PC 4 11473 GOTO_NEXT_R %edx 11474 11475/* continuation for OP_CHECK_CAST_JUMBO */ 11476 11477 /* 11478 * Trivial test failed, need to perform full check. This is common. 11479 * ecx holds obj->clazz 11480 * eax holds class resolved from AAAAAAAA 11481 * rINST holds object 11482 */ 11483.LOP_CHECK_CAST_JUMBO_fullcheck: 11484 movl %eax,sReg0 # we'll need the desired class on failure 11485 movl %eax,OUT_ARG1(%esp) 11486 movl %ecx,OUT_ARG0(%esp) 11487 call dvmInstanceofNonTrivial # eax<- boolean result 11488 testl %eax,%eax # failed? 11489 jne .LOP_CHECK_CAST_JUMBO_okay # no, success 11490 11491 # A cast has failed. We need to throw a ClassCastException. 11492 EXPORT_PC 11493 movl offObject_clazz(rINST),%eax 11494 movl %eax,OUT_ARG0(%esp) # arg0<- obj->clazz 11495 movl sReg0,%ecx 11496 movl %ecx,OUT_ARG1(%esp) # arg1<- desired class 11497 call dvmThrowClassCastException 11498 jmp common_exceptionThrown 11499 11500 /* 11501 * Resolution required. This is the least-likely path, and we're 11502 * going to have to recreate some data. 11503 * 11504 * rINST holds object 11505 */ 11506.LOP_CHECK_CAST_JUMBO_resolve: 11507 movl rGLUE,%ecx 11508 EXPORT_PC 11509 movl 2(rPC),%eax # eax<- AAAAAAAA 11510 movl offGlue_method(%ecx),%ecx # ecx<- glue->method 11511 movl %eax,OUT_ARG1(%esp) # arg1<- AAAAAAAA 11512 movl offMethod_clazz(%ecx),%ecx # ecx<- metho->clazz 11513 movl $0,OUT_ARG2(%esp) # arg2<- false 11514 movl %ecx,OUT_ARG0(%esp) # arg0<- method->clazz 11515 call dvmResolveClass # eax<- resolved ClassObject ptr 11516 testl %eax,%eax # got null? 11517 je common_exceptionThrown # yes, handle exception 11518 movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz 11519 jmp .LOP_CHECK_CAST_JUMBO_resolved # pick up where we left off 11520 11521/* continuation for OP_INSTANCE_OF_JUMBO */ 11522 11523 /* 11524 * Trivial test failed, need to perform full check. This is common. 11525 * eax holds obj->clazz 11526 * ecx holds class resolved from BBBB 11527 * rINST has BA 11528 */ 11529.LOP_INSTANCE_OF_JUMBO_fullcheck: 11530 movl %eax,OUT_ARG0(%esp) 11531 movl %ecx,OUT_ARG1(%esp) 11532 call dvmInstanceofNonTrivial # eax<- boolean result 11533 # fall through to OP_INSTANCE_OF_JUMBO_store 11534 11535 /* 11536 * eax holds boolean result 11537 * rINST holds BBBB 11538 */ 11539.LOP_INSTANCE_OF_JUMBO_store: 11540 FETCH_INST_OPCODE 5 %edx 11541 ADVANCE_PC 5 11542 SET_VREG %eax rINST # vBBBB<- eax 11543 GOTO_NEXT_R %edx 11544 11545 /* 11546 * Trivial test succeeded, save and bail. 11547 * r9 holds BBBB 11548 */ 11549.LOP_INSTANCE_OF_JUMBO_trivial: 11550 FETCH_INST_OPCODE 5 %edx 11551 ADVANCE_PC 5 11552 movl $1,%eax 11553 SET_VREG %eax rINST # vBBBB<- true 11554 GOTO_NEXT_R %edx 11555 11556 /* 11557 * Resolution required. This is the least-likely path. 11558 * 11559 * edx holds AAAAAAAA 11560 */ 11561.LOP_INSTANCE_OF_JUMBO_resolve: 11562 movl %edx,OUT_ARG1(%esp) # arg1<- AAAAAAAA 11563 movl rGLUE,%ecx 11564 movl offGlue_method(%ecx),%ecx 11565 movl $1,OUT_ARG2(%esp) # arg2<- true 11566 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 11567 EXPORT_PC 11568 movl %ecx,OUT_ARG0(%esp) # arg0<- method->clazz 11569 call dvmResolveClass # eax<- resolved ClassObject ptr 11570 testl %eax,%eax # success? 11571 je common_exceptionThrown # no, handle exception 11572/* Now, we need to sync up with fast path. We need eax to 11573 * hold the obj->clazz, and ecx to hold the resolved class 11574 */ 11575 movl %eax,%ecx # ecx<- resolved class 11576 movzwl 8(rPC),%eax # eax<- CCCC 11577 GET_VREG_R %eax %eax # eax<- vCCCC (obj) 11578 movl offObject_clazz(%eax),%eax # eax<- obj->clazz 11579 jmp .LOP_INSTANCE_OF_JUMBO_resolved 11580 11581/* continuation for OP_NEW_INSTANCE_JUMBO */ 11582 11583.LOP_NEW_INSTANCE_JUMBO_initialized: # on entry, ecx<- class 11584 /* TODO: remove test for interface/abstract, now done in verifier */ 11585 testl $(ACC_INTERFACE|ACC_ABSTRACT),offClassObject_accessFlags(%ecx) 11586 movl $ALLOC_DONT_TRACK,OUT_ARG1(%esp) 11587 jne .LOP_NEW_INSTANCE_JUMBO_abstract 11588.LOP_NEW_INSTANCE_JUMBO_finish: # ecx=class 11589 movl %ecx,OUT_ARG0(%esp) 11590 call dvmAllocObject # eax<- new object 11591 FETCH_INST_OPCODE 4 %edx 11592 testl %eax,%eax # success? 11593 je common_exceptionThrown # no, bail out 11594 SET_VREG %eax rINST 11595 ADVANCE_PC 4 11596 GOTO_NEXT_R %edx 11597 11598 /* 11599 * Class initialization required. 11600 * 11601 * ecx holds class object 11602 */ 11603.LOP_NEW_INSTANCE_JUMBO_needinit: 11604 SPILL_TMP1(%ecx) # save object 11605 movl %ecx,OUT_ARG0(%esp) 11606 call dvmInitClass # initialize class 11607 UNSPILL_TMP1(%ecx) # restore object 11608 testl %eax,%eax # success? 11609 jne .LOP_NEW_INSTANCE_JUMBO_initialized # success, continue 11610 jmp common_exceptionThrown # go deal with init exception 11611 11612 /* 11613 * Resolution required. This is the least-likely path. 11614 * 11615 */ 11616.LOP_NEW_INSTANCE_JUMBO_resolve: 11617 movl rGLUE,%ecx 11618 movl 2(rPC),%eax # eax<- AAAAAAAA 11619 movl offGlue_method(%ecx),%ecx # ecx<- glue->method 11620 movl %eax,OUT_ARG1(%esp) 11621 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 11622 movl $0,OUT_ARG2(%esp) 11623 movl %ecx,OUT_ARG0(%esp) 11624 call dvmResolveClass # call(clazz,off,flags) 11625 movl %eax,%ecx # ecx<- resolved ClassObject ptr 11626 testl %ecx,%ecx # success? 11627 jne .LOP_NEW_INSTANCE_JUMBO_resolved # good to go 11628 jmp common_exceptionThrown # no, handle exception 11629 11630 /* 11631 * TODO: remove this 11632 * We can't instantiate an abstract class or interface, so throw an 11633 * InstantiationError with the class descriptor as the message. 11634 * 11635 * ecx holds class object 11636 */ 11637.LOP_NEW_INSTANCE_JUMBO_abstract: 11638 movl offClassObject_descriptor(%ecx),%eax 11639 movl $.LstrInstantiationError,OUT_ARG0(%esp) 11640 movl %eax,OUT_ARG1(%esp) 11641 call dvmThrowExceptionWithClassMessage 11642 jmp common_exceptionThrown 11643 11644/* continuation for OP_NEW_ARRAY_JUMBO */ 11645 11646 /* 11647 * Resolve class. (This is an uncommon case.) 11648 * ecx holds class (null here) 11649 * eax holds array length (vCCCC) 11650 */ 11651.LOP_NEW_ARRAY_JUMBO_resolve: 11652 movl rGLUE,%ecx 11653 SPILL_TMP1(%eax) # save array length 11654 movl offGlue_method(%ecx),%ecx # ecx<- glue->method 11655 movl 2(rPC),%eax # eax<- AAAAAAAA 11656 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 11657 movl %eax,OUT_ARG1(%esp) 11658 movl $0,OUT_ARG2(%esp) 11659 movl %ecx,OUT_ARG0(%esp) 11660 call dvmResolveClass # eax<- call(clazz,ref,flag) 11661 movl %eax,%ecx 11662 UNSPILL_TMP1(%eax) 11663 testl %ecx,%ecx # successful resolution? 11664 je common_exceptionThrown # no, bail. 11665# fall through to OP_NEW_ARRAY_JUMBO_finish 11666 11667 /* 11668 * Finish allocation 11669 * 11670 * ecx holds class 11671 * eax holds array length (vCCCC) 11672 */ 11673.LOP_NEW_ARRAY_JUMBO_finish: 11674 movl %ecx,OUT_ARG0(%esp) 11675 movl %eax,OUT_ARG1(%esp) 11676 movl $ALLOC_DONT_TRACK,OUT_ARG2(%esp) 11677 call dvmAllocArrayByClass # eax<- call(clazz,length,flags) 11678 FETCH_INST_OPCODE 5 %edx 11679 testl %eax,%eax # failed? 11680 je common_exceptionThrown # yup - go handle 11681 SET_VREG %eax rINST 11682 ADVANCE_PC 5 11683 GOTO_NEXT_R %edx 11684 11685/* continuation for OP_FILLED_NEW_ARRAY_JUMBO */ 11686 11687.LOP_FILLED_NEW_ARRAY_JUMBO_more: 11688 movl offMethod_clazz(%eax),%eax # eax<- method->clazz 11689 movl %eax,OUT_ARG0(%esp) # arg0<- clazz 11690 call dvmResolveClass # eax<- call(clazz,ref,flag) 11691 testl %eax,%eax # null? 11692 je common_exceptionThrown # yes, handle it 11693 11694 # note: fall through to .LOP_FILLED_NEW_ARRAY_JUMBO_continue 11695 11696 /* 11697 * On entry: 11698 * eax holds array class [r0] 11699 * ecx is scratch 11700 */ 11701.LOP_FILLED_NEW_ARRAY_JUMBO_continue: 11702 movl offClassObject_descriptor(%eax),%ecx # ecx<- arrayClass->descriptor 11703 movl $ALLOC_DONT_TRACK,OUT_ARG2(%esp) # arg2<- flags 11704 movzbl 1(%ecx),%ecx # ecx<- descriptor[1] 11705 movl %eax,OUT_ARG0(%esp) # arg0<- arrayClass 11706 movl rGLUE,%eax 11707 cmpb $'I',%cl # supported? 11708 je 1f 11709 cmpb $'L',%cl 11710 je 1f 11711 cmpb $'[',%cl 11712 jne .LOP_FILLED_NEW_ARRAY_JUMBO_notimpl # no, not handled yet 117131: 11714 movl %ecx,offGlue_retval+4(%eax) # save type 11715 movl rINST,OUT_ARG1(%esp) # arg1<- BBBB (length) 11716 call dvmAllocArrayByClass # eax<- call(arrayClass, length, flags) 11717 movl rGLUE,%ecx 11718 testl %eax,%eax # alloc successful? 11719 je common_exceptionThrown # no, handle exception 11720 movl %eax,offGlue_retval(%ecx) # retval.l<- new array 11721 movzwl 8(rPC),%ecx # ecx<- CCCC 11722 leal offArrayObject_contents(%eax),%eax # eax<- newArray->contents 11723 11724/* at this point: 11725 * eax is pointer to tgt 11726 * rINST is length 11727 * ecx is CCCC 11728 * We now need to copy values from registers into the array 11729 */ 11730 11731 # set up src pointer 11732 SPILL_TMP2(%esi) 11733 SPILL_TMP3(%edi) 11734 leal (rFP,%ecx,4),%esi # set up src ptr 11735 movl %eax,%edi # set up dst ptr 11736 movl rINST,%ecx # load count register 11737 rep 11738 movsd 11739 UNSPILL_TMP2(%esi) 11740 UNSPILL_TMP3(%edi) 11741 movl rGLUE,%ecx 11742 movl offGlue_retval+4(%ecx),%eax # eax<- type 11743 FETCH_INST_OPCODE 5 %edx 11744 11745 cmpb $'I',%al # Int array? 11746 je 5f # skip card mark if so 11747 movl offGlue_retval(%ecx),%eax # eax<- object head 11748 movl offGlue_cardTable(%ecx),%ecx # card table base 11749 shrl $GC_CARD_SHIFT,%eax # convert to card num 11750 movb %cl,(%ecx,%eax) # mark card based on object head 117515: 11752 ADVANCE_PC 5 11753 GOTO_NEXT_R %edx 11754 11755 11756 /* 11757 * Throw an exception indicating that we have not implemented this 11758 * mode of filled-new-array. 11759 */ 11760.LOP_FILLED_NEW_ARRAY_JUMBO_notimpl: 11761 movl $.LstrInternalErrorA,%eax 11762 movl %eax,OUT_ARG0(%esp) 11763 movl $.LstrFilledNewArrayNotImplA,%eax 11764 movl %eax,OUT_ARG1(%esp) 11765 call dvmThrowException 11766 jmp common_exceptionThrown 11767 11768/* continuation for OP_IGET_JUMBO */ 11769 11770 11771.LOP_IGET_JUMBO_resolve: 11772 EXPORT_PC 11773 movl offGlue_method(%edx),%edx # edx<- current method 11774 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11775 SPILL_TMP1(%ecx) # save obj pointer across call 11776 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11777 call dvmResolveInstField # ... to dvmResolveInstField 11778 UNSPILL_TMP1(%ecx) 11779 testl %eax,%eax # returns InstrField ptr 11780 jne .LOP_IGET_JUMBO_finish 11781 jmp common_exceptionThrown 11782 11783.LOP_IGET_JUMBO_finish: 11784 /* 11785 * Currently: 11786 * eax holds resolved field 11787 * ecx holds object 11788 * rINST holds BBBB 11789 */ 11790 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11791 testl %ecx,%ecx # object null? 11792 je common_errNullObject # object was null 11793 movl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 11794 movl rINST,%eax # eax<- BBBB 11795 FETCH_INST_OPCODE 5 %edx 11796 SET_VREG %ecx %eax 11797 ADVANCE_PC 5 11798 GOTO_NEXT_R %edx 11799 11800/* continuation for OP_IGET_WIDE_JUMBO */ 11801 11802 11803.LOP_IGET_WIDE_JUMBO_resolve: 11804 EXPORT_PC 11805 movl offGlue_method(%edx),%edx # edx<- current method 11806 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11807 SPILL_TMP1(%ecx) # save objpointer across call 11808 movl rPC,OUT_ARG0(%esp) # pass in method->clazz 11809 call dvmResolveInstField # ... to dvmResolveInstField 11810 UNSPILL_TMP1(%ecx) 11811 testl %eax,%eax # returns InstrField ptr 11812 jne .LOP_IGET_WIDE_JUMBO_finish 11813 jmp common_exceptionThrown 11814 11815.LOP_IGET_WIDE_JUMBO_finish: 11816 /* 11817 * Currently: 11818 * eax holds resolved field 11819 * ecx holds object 11820 * rINST holds BBBB 11821 */ 11822 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11823 testl %ecx,%ecx # object null? 11824 je common_errNullObject # object was null 11825 leal (%ecx,%eax,1),%eax # eax<- address of field 11826 movl (%eax),%ecx # ecx<- lsw 11827 movl 4(%eax),%eax # eax<- msw 11828 FETCH_INST_OPCODE 5 %edx 11829 SET_VREG_WORD %ecx rINST 0 11830 SET_VREG_WORD %eax rINST 1 11831 ADVANCE_PC 5 11832 GOTO_NEXT_R %edx 11833 11834/* continuation for OP_IGET_OBJECT_JUMBO */ 11835 11836 11837.LOP_IGET_OBJECT_JUMBO_resolve: 11838 EXPORT_PC 11839 movl offGlue_method(%edx),%edx # edx<- current method 11840 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11841 SPILL_TMP1(%ecx) # save obj pointer across call 11842 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11843 call dvmResolveInstField # ... to dvmResolveInstField 11844 UNSPILL_TMP1(%ecx) 11845 testl %eax,%eax # returns InstrField ptr 11846 jne .LOP_IGET_OBJECT_JUMBO_finish 11847 jmp common_exceptionThrown 11848 11849.LOP_IGET_OBJECT_JUMBO_finish: 11850 /* 11851 * Currently: 11852 * eax holds resolved field 11853 * ecx holds object 11854 * rINST holds BBBB 11855 */ 11856 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11857 testl %ecx,%ecx # object null? 11858 je common_errNullObject # object was null 11859 movl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 11860 movl rINST,%eax # eax<- BBBB 11861 FETCH_INST_OPCODE 5 %edx 11862 SET_VREG %ecx %eax 11863 ADVANCE_PC 5 11864 GOTO_NEXT_R %edx 11865 11866/* continuation for OP_IGET_BOOLEAN_JUMBO */ 11867 11868 11869.LOP_IGET_BOOLEAN_JUMBO_resolve: 11870 EXPORT_PC 11871 movl offGlue_method(%edx),%edx # edx<- current method 11872 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11873 SPILL_TMP1(%ecx) # save obj pointer across call 11874 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11875 call dvmResolveInstField # ... to dvmResolveInstField 11876 UNSPILL_TMP1(%ecx) 11877 testl %eax,%eax # returns InstrField ptr 11878 jne .LOP_IGET_BOOLEAN_JUMBO_finish 11879 jmp common_exceptionThrown 11880 11881.LOP_IGET_BOOLEAN_JUMBO_finish: 11882 /* 11883 * Currently: 11884 * eax holds resolved field 11885 * ecx holds object 11886 * rINST holds BBBB 11887 */ 11888 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11889 testl %ecx,%ecx # object null? 11890 je common_errNullObject # object was null 11891 movzbl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 11892 movl rINST,%eax # eax<- BBBB 11893 FETCH_INST_OPCODE 5 %edx 11894 SET_VREG %ecx %eax 11895 ADVANCE_PC 5 11896 GOTO_NEXT_R %edx 11897 11898/* continuation for OP_IGET_BYTE_JUMBO */ 11899 11900 11901.LOP_IGET_BYTE_JUMBO_resolve: 11902 EXPORT_PC 11903 movl offGlue_method(%edx),%edx # edx<- current method 11904 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11905 SPILL_TMP1(%ecx) # save obj pointer across call 11906 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11907 call dvmResolveInstField # ... to dvmResolveInstField 11908 UNSPILL_TMP1(%ecx) 11909 testl %eax,%eax # returns InstrField ptr 11910 jne .LOP_IGET_BYTE_JUMBO_finish 11911 jmp common_exceptionThrown 11912 11913.LOP_IGET_BYTE_JUMBO_finish: 11914 /* 11915 * Currently: 11916 * eax holds resolved field 11917 * ecx holds object 11918 * rINST holds BBBB 11919 */ 11920 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11921 testl %ecx,%ecx # object null? 11922 je common_errNullObject # object was null 11923 movsbl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 11924 movl rINST,%eax # eax<- BBBB 11925 FETCH_INST_OPCODE 5 %edx 11926 SET_VREG %ecx %eax 11927 ADVANCE_PC 5 11928 GOTO_NEXT_R %edx 11929 11930/* continuation for OP_IGET_CHAR_JUMBO */ 11931 11932 11933.LOP_IGET_CHAR_JUMBO_resolve: 11934 EXPORT_PC 11935 movl offGlue_method(%edx),%edx # edx<- current method 11936 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11937 SPILL_TMP1(%ecx) # save obj pointer across call 11938 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11939 call dvmResolveInstField # ... to dvmResolveInstField 11940 UNSPILL_TMP1(%ecx) 11941 testl %eax,%eax # returns InstrField ptr 11942 jne .LOP_IGET_CHAR_JUMBO_finish 11943 jmp common_exceptionThrown 11944 11945.LOP_IGET_CHAR_JUMBO_finish: 11946 /* 11947 * Currently: 11948 * eax holds resolved field 11949 * ecx holds object 11950 * rINST holds BBBB 11951 */ 11952 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11953 testl %ecx,%ecx # object null? 11954 je common_errNullObject # object was null 11955 movzwl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 11956 movl rINST,%eax # eax<- BBBB 11957 FETCH_INST_OPCODE 5 %edx 11958 SET_VREG %ecx %eax 11959 ADVANCE_PC 5 11960 GOTO_NEXT_R %edx 11961 11962/* continuation for OP_IGET_SHORT_JUMBO */ 11963 11964 11965.LOP_IGET_SHORT_JUMBO_resolve: 11966 EXPORT_PC 11967 movl offGlue_method(%edx),%edx # edx<- current method 11968 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 11969 SPILL_TMP1(%ecx) # save obj pointer across call 11970 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 11971 call dvmResolveInstField # ... to dvmResolveInstField 11972 UNSPILL_TMP1(%ecx) 11973 testl %eax,%eax # returns InstrField ptr 11974 jne .LOP_IGET_SHORT_JUMBO_finish 11975 jmp common_exceptionThrown 11976 11977.LOP_IGET_SHORT_JUMBO_finish: 11978 /* 11979 * Currently: 11980 * eax holds resolved field 11981 * ecx holds object 11982 * rINST holds BBBB 11983 */ 11984 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 11985 testl %ecx,%ecx # object null? 11986 je common_errNullObject # object was null 11987 movswl (%ecx,%eax,1),%ecx # ecx<- obj.field (8/16/32 bits) 11988 movl rINST,%eax # eax<- BBBB 11989 FETCH_INST_OPCODE 5 %edx 11990 SET_VREG %ecx %eax 11991 ADVANCE_PC 5 11992 GOTO_NEXT_R %edx 11993 11994/* continuation for OP_IPUT_JUMBO */ 11995 11996 11997.LOP_IPUT_JUMBO_resolve: 11998 EXPORT_PC 11999 movl offGlue_method(%edx),%edx # edx<- current method 12000 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 12001 SPILL_TMP1(%ecx) # save obj pointer across call 12002 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 12003 call dvmResolveInstField # ... to dvmResolveInstField 12004 UNSPILL_TMP1(%ecx) 12005 testl %eax,%eax # returns InstrField ptr 12006 jne .LOP_IPUT_JUMBO_finish 12007 jmp common_exceptionThrown 12008 12009.LOP_IPUT_JUMBO_finish: 12010 /* 12011 * Currently: 12012 * eax holds resolved field 12013 * ecx holds object 12014 * rINST holds BBBB 12015 */ 12016 GET_VREG_R rINST rINST # rINST<- v[BBBB] 12017 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 12018 testl %ecx,%ecx # object null? 12019 je common_errNullObject # object was null 12020 FETCH_INST_OPCODE 5 %edx 12021 movl rINST,(%ecx,%eax,1) # obj.field <- v[BBBB](8/16/32 bits) 12022 ADVANCE_PC 5 12023 GOTO_NEXT_R %edx 12024 12025/* continuation for OP_IPUT_WIDE_JUMBO */ 12026 12027 12028.LOP_IPUT_WIDE_JUMBO_resolve: 12029 EXPORT_PC 12030 movl offGlue_method(%edx),%edx # edx<- current method 12031 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 12032 SPILL_TMP1(%ecx) # save obj pointer across call 12033 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 12034 call dvmResolveInstField # ... to dvmResolveInstField 12035 UNSPILL_TMP1(%ecx) 12036 testl %eax,%eax # ... which returns InstrField ptr 12037 jne .LOP_IPUT_WIDE_JUMBO_finish 12038 jmp common_exceptionThrown 12039 12040.LOP_IPUT_WIDE_JUMBO_finish: 12041 /* 12042 * Currently: 12043 * eax holds resolved field 12044 * ecx holds object 12045 * %edx is scratch, but needs to be unspilled 12046 * rINST holds BBBB 12047 */ 12048 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 12049 testl %ecx,%ecx # object null? 12050 je common_errNullObject # object was null 12051 leal (%ecx,%eax,1),%eax # eax<- address of field 12052 GET_VREG_WORD %ecx rINST 0 # ecx<- lsw 12053 GET_VREG_WORD rINST rINST 1 # rINST<- msw 12054 FETCH_INST_OPCODE 5 %edx 12055 movl rINST,4(%eax) 12056 movl %ecx,(%eax) 12057 ADVANCE_PC 5 12058 GOTO_NEXT_R %edx 12059 12060/* continuation for OP_IPUT_OBJECT_JUMBO */ 12061 12062 12063.LOP_IPUT_OBJECT_JUMBO_resolve: 12064 EXPORT_PC 12065 movl offGlue_method(%edx),%edx # edx<- current method 12066 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 12067 SPILL_TMP1(%ecx) # save obj pointer across call 12068 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 12069 call dvmResolveInstField # ... to dvmResolveInstField 12070 UNSPILL_TMP1(%ecx) 12071 testl %eax,%eax # returns InstrField ptr 12072 jne .LOP_IPUT_OBJECT_JUMBO_finish 12073 jmp common_exceptionThrown 12074 12075.LOP_IPUT_OBJECT_JUMBO_finish: 12076 /* 12077 * Currently: 12078 * eax holds resolved field 12079 * ecx holds object 12080 * %edx is scratch, but needs to be unspilled 12081 * rINST holds BBBB 12082 */ 12083 GET_VREG_R rINST rINST # rINST<- v[BBBB] 12084 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 12085 testl %ecx,%ecx # object null? 12086 je common_errNullObject # object was null 12087 movl rINST,(%ecx,%eax) # obj.field <- v[BBBB](8/16/32 bits) 12088 movl rGLUE,%eax 12089 testl rINST,rINST # stored a NULL? 12090 movl offGlue_cardTable(%eax),%eax # get card table base 12091 FETCH_INST_OPCODE 5 %edx 12092 je 1f # skip card mark if null store 12093 shrl $GC_CARD_SHIFT,%ecx # object head to card number 12094 movb %al,(%eax,%ecx) # mark card using object head 120951: 12096 ADVANCE_PC 5 12097 GOTO_NEXT_R %edx 12098 12099/* continuation for OP_IPUT_BOOLEAN_JUMBO */ 12100 12101 12102.LOP_IPUT_BOOLEAN_JUMBO_resolve: 12103 EXPORT_PC 12104 movl offGlue_method(%edx),%edx # edx<- current method 12105 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 12106 SPILL_TMP1(%ecx) # save obj pointer across call 12107 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 12108 call dvmResolveInstField # ... to dvmResolveInstField 12109 UNSPILL_TMP1(%ecx) 12110 testl %eax,%eax # returns InstrField ptr 12111 jne .LOP_IPUT_BOOLEAN_JUMBO_finish 12112 jmp common_exceptionThrown 12113 12114.LOP_IPUT_BOOLEAN_JUMBO_finish: 12115 /* 12116 * Currently: 12117 * eax holds resolved field 12118 * ecx holds object 12119 * rINST holds BBBB 12120 */ 12121 GET_VREG_R rINST rINST # rINST<- v[BBBB] 12122 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 12123 testl %ecx,%ecx # object null? 12124 je common_errNullObject # object was null 12125 FETCH_INST_OPCODE 5 %edx 12126 movb rINSTbl,(%ecx,%eax,1) # obj.field <- v[BBBB](8/16/32 bits) 12127 ADVANCE_PC 5 12128 GOTO_NEXT_R %edx 12129 12130/* continuation for OP_IPUT_BYTE_JUMBO */ 12131 12132 12133.LOP_IPUT_BYTE_JUMBO_resolve: 12134 EXPORT_PC 12135 movl offGlue_method(%edx),%edx # edx<- current method 12136 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 12137 SPILL_TMP1(%ecx) # save obj pointer across call 12138 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 12139 call dvmResolveInstField # ... to dvmResolveInstField 12140 UNSPILL_TMP1(%ecx) 12141 testl %eax,%eax # returns InstrField ptr 12142 jne .LOP_IPUT_BYTE_JUMBO_finish 12143 jmp common_exceptionThrown 12144 12145.LOP_IPUT_BYTE_JUMBO_finish: 12146 /* 12147 * Currently: 12148 * eax holds resolved field 12149 * ecx holds object 12150 * rINST holds BBBB 12151 */ 12152 GET_VREG_R rINST rINST # rINST<- v[BBBB] 12153 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 12154 testl %ecx,%ecx # object null? 12155 je common_errNullObject # object was null 12156 FETCH_INST_OPCODE 5 %edx 12157 movb rINSTbl,(%ecx,%eax,1) # obj.field <- v[BBBB](8/16/32 bits) 12158 ADVANCE_PC 5 12159 GOTO_NEXT_R %edx 12160 12161/* continuation for OP_IPUT_CHAR_JUMBO */ 12162 12163 12164.LOP_IPUT_CHAR_JUMBO_resolve: 12165 EXPORT_PC 12166 movl offGlue_method(%edx),%edx # edx<- current method 12167 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 12168 SPILL_TMP1(%ecx) # save obj pointer across call 12169 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 12170 call dvmResolveInstField # ... to dvmResolveInstField 12171 UNSPILL_TMP1(%ecx) 12172 testl %eax,%eax # returns InstrField ptr 12173 jne .LOP_IPUT_CHAR_JUMBO_finish 12174 jmp common_exceptionThrown 12175 12176.LOP_IPUT_CHAR_JUMBO_finish: 12177 /* 12178 * Currently: 12179 * eax holds resolved field 12180 * ecx holds object 12181 * rINST holds BBBB 12182 */ 12183 GET_VREG_R rINST rINST # rINST<- v[BBBB] 12184 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 12185 testl %ecx,%ecx # object null? 12186 je common_errNullObject # object was null 12187 FETCH_INST_OPCODE 5 %edx 12188 movw rINSTw,(%ecx,%eax,1) # obj.field <- v[BBBB](8/16/32 bits) 12189 ADVANCE_PC 5 12190 GOTO_NEXT_R %edx 12191 12192/* continuation for OP_IPUT_SHORT_JUMBO */ 12193 12194 12195.LOP_IPUT_SHORT_JUMBO_resolve: 12196 EXPORT_PC 12197 movl offGlue_method(%edx),%edx # edx<- current method 12198 movl offMethod_clazz(%edx),%edx # edx<- method->clazz 12199 SPILL_TMP1(%ecx) # save obj pointer across call 12200 movl %edx,OUT_ARG0(%esp) # pass in method->clazz 12201 call dvmResolveInstField # ... to dvmResolveInstField 12202 UNSPILL_TMP1(%ecx) 12203 testl %eax,%eax # returns InstrField ptr 12204 jne .LOP_IPUT_SHORT_JUMBO_finish 12205 jmp common_exceptionThrown 12206 12207.LOP_IPUT_SHORT_JUMBO_finish: 12208 /* 12209 * Currently: 12210 * eax holds resolved field 12211 * ecx holds object 12212 * rINST holds BBBB 12213 */ 12214 GET_VREG_R rINST rINST # rINST<- v[BBBB] 12215 movl offInstField_byteOffset(%eax),%eax # eax<- byte offset of field 12216 testl %ecx,%ecx # object null? 12217 je common_errNullObject # object was null 12218 FETCH_INST_OPCODE 5 %edx 12219 movw rINSTw,(%ecx,%eax,1) # obj.field <- v[BBBB](8/16/32 bits) 12220 ADVANCE_PC 5 12221 GOTO_NEXT_R %edx 12222 12223/* continuation for OP_SGET_JUMBO */ 12224 12225 /* 12226 * Go resolve the field 12227 */ 12228.LOP_SGET_JUMBO_resolve: 12229 movl rGLUE,%ecx 12230 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12231 movl offGlue_method(%ecx),%ecx # ecx<- current method 12232 EXPORT_PC # could throw, need to export 12233 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12234 movl %eax,OUT_ARG1(%esp) 12235 movl %ecx,OUT_ARG0(%esp) 12236 call dvmResolveStaticField # eax<- resolved StaticField ptr 12237 testl %eax,%eax 12238 jne .LOP_SGET_JUMBO_finish # success, continue 12239 jmp common_exceptionThrown # no, handle exception 12240 12241/* continuation for OP_SGET_WIDE_JUMBO */ 12242 12243 /* 12244 * Go resolve the field 12245 */ 12246.LOP_SGET_WIDE_JUMBO_resolve: 12247 movl rGLUE,%ecx 12248 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12249 movl offGlue_method(%ecx),%ecx # ecx<- current method 12250 EXPORT_PC # could throw, need to export 12251 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12252 movl %eax,OUT_ARG1(%esp) 12253 movl %ecx,OUT_ARG0(%esp) 12254 call dvmResolveStaticField # eax<- resolved StaticField ptr 12255 testl %eax,%eax 12256 jne .LOP_SGET_WIDE_JUMBO_finish # success, continue 12257 jmp common_exceptionThrown # no, handle exception 12258 12259/* continuation for OP_SGET_OBJECT_JUMBO */ 12260 12261 /* 12262 * Go resolve the field 12263 */ 12264.LOP_SGET_OBJECT_JUMBO_resolve: 12265 movl rGLUE,%ecx 12266 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12267 movl offGlue_method(%ecx),%ecx # ecx<- current method 12268 EXPORT_PC # could throw, need to export 12269 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12270 movl %eax,OUT_ARG1(%esp) 12271 movl %ecx,OUT_ARG0(%esp) 12272 call dvmResolveStaticField # eax<- resolved StaticField ptr 12273 testl %eax,%eax 12274 jne .LOP_SGET_OBJECT_JUMBO_finish # success, continue 12275 jmp common_exceptionThrown # no, handle exception 12276 12277/* continuation for OP_SGET_BOOLEAN_JUMBO */ 12278 12279 /* 12280 * Go resolve the field 12281 */ 12282.LOP_SGET_BOOLEAN_JUMBO_resolve: 12283 movl rGLUE,%ecx 12284 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12285 movl offGlue_method(%ecx),%ecx # ecx<- current method 12286 EXPORT_PC # could throw, need to export 12287 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12288 movl %eax,OUT_ARG1(%esp) 12289 movl %ecx,OUT_ARG0(%esp) 12290 call dvmResolveStaticField # eax<- resolved StaticField ptr 12291 testl %eax,%eax 12292 jne .LOP_SGET_BOOLEAN_JUMBO_finish # success, continue 12293 jmp common_exceptionThrown # no, handle exception 12294 12295/* continuation for OP_SGET_BYTE_JUMBO */ 12296 12297 /* 12298 * Go resolve the field 12299 */ 12300.LOP_SGET_BYTE_JUMBO_resolve: 12301 movl rGLUE,%ecx 12302 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12303 movl offGlue_method(%ecx),%ecx # ecx<- current method 12304 EXPORT_PC # could throw, need to export 12305 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12306 movl %eax,OUT_ARG1(%esp) 12307 movl %ecx,OUT_ARG0(%esp) 12308 call dvmResolveStaticField # eax<- resolved StaticField ptr 12309 testl %eax,%eax 12310 jne .LOP_SGET_BYTE_JUMBO_finish # success, continue 12311 jmp common_exceptionThrown # no, handle exception 12312 12313/* continuation for OP_SGET_CHAR_JUMBO */ 12314 12315 /* 12316 * Go resolve the field 12317 */ 12318.LOP_SGET_CHAR_JUMBO_resolve: 12319 movl rGLUE,%ecx 12320 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12321 movl offGlue_method(%ecx),%ecx # ecx<- current method 12322 EXPORT_PC # could throw, need to export 12323 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12324 movl %eax,OUT_ARG1(%esp) 12325 movl %ecx,OUT_ARG0(%esp) 12326 call dvmResolveStaticField # eax<- resolved StaticField ptr 12327 testl %eax,%eax 12328 jne .LOP_SGET_CHAR_JUMBO_finish # success, continue 12329 jmp common_exceptionThrown # no, handle exception 12330 12331/* continuation for OP_SGET_SHORT_JUMBO */ 12332 12333 /* 12334 * Go resolve the field 12335 */ 12336.LOP_SGET_SHORT_JUMBO_resolve: 12337 movl rGLUE,%ecx 12338 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12339 movl offGlue_method(%ecx),%ecx # ecx<- current method 12340 EXPORT_PC # could throw, need to export 12341 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12342 movl %eax,OUT_ARG1(%esp) 12343 movl %ecx,OUT_ARG0(%esp) 12344 call dvmResolveStaticField # eax<- resolved StaticField ptr 12345 testl %eax,%eax 12346 jne .LOP_SGET_SHORT_JUMBO_finish # success, continue 12347 jmp common_exceptionThrown # no, handle exception 12348 12349/* continuation for OP_SPUT_JUMBO */ 12350 12351 /* 12352 * Go resolve the field 12353 */ 12354.LOP_SPUT_JUMBO_resolve: 12355 movl rGLUE,%ecx 12356 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12357 movl offGlue_method(%ecx),%ecx # ecx<- current method 12358 EXPORT_PC # could throw, need to export 12359 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12360 movl %eax,OUT_ARG1(%esp) 12361 movl %ecx,OUT_ARG0(%esp) 12362 call dvmResolveStaticField # eax<- resolved StaticField ptr 12363 testl %eax,%eax 12364 jne .LOP_SPUT_JUMBO_finish # success, continue 12365 jmp common_exceptionThrown # no, handle exception 12366 12367/* continuation for OP_SPUT_WIDE_JUMBO */ 12368 12369 /* 12370 * Go resolve the field 12371 */ 12372.LOP_SPUT_WIDE_JUMBO_resolve: 12373 movl rGLUE,%ecx 12374 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12375 movl offGlue_method(%ecx),%ecx # ecx<- current method 12376 EXPORT_PC # could throw, need to export 12377 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12378 movl %eax,OUT_ARG1(%esp) 12379 movl %ecx,OUT_ARG0(%esp) 12380 call dvmResolveStaticField # eax<- resolved StaticField ptr 12381 testl %eax,%eax 12382 jne .LOP_SPUT_WIDE_JUMBO_finish # success, continue 12383 jmp common_exceptionThrown # no, handle exception 12384 12385/* continuation for OP_SPUT_OBJECT_JUMBO */ 12386 12387 12388.LOP_SPUT_OBJECT_JUMBO_continue: 12389 movl %ecx,offStaticField_value(%eax) # do the store 12390 testl %ecx,%ecx # stored null object ptr? 12391 FETCH_INST_OPCODE 4 %edx 12392 je 1f # skip card mark if null 12393 movl rGLUE,%ecx 12394 movl offField_clazz(%eax),%eax # eax<- method->clazz 12395 movl offGlue_cardTable(%ecx),%ecx # get card table base 12396 shrl $GC_CARD_SHIFT,%eax # head to card number 12397 movb %cl,(%ecx,%eax) # mark card 123981: 12399 ADVANCE_PC 4 12400 GOTO_NEXT_R %edx 12401 12402.LOP_SPUT_OBJECT_JUMBO_resolve: 12403 movl rGLUE,%ecx 12404 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12405 movl offGlue_method(%ecx),%ecx # ecx<- current method 12406 EXPORT_PC # could throw, need to export 12407 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12408 movl %eax,OUT_ARG1(%esp) 12409 movl %ecx,OUT_ARG0(%esp) 12410 call dvmResolveStaticField # eax<- resolved StaticField ptr 12411 testl %eax,%eax 12412 jne .LOP_SPUT_OBJECT_JUMBO_finish # success, continue 12413 jmp common_exceptionThrown # no, handle exception 12414 12415/* continuation for OP_SPUT_BOOLEAN_JUMBO */ 12416 12417 /* 12418 * Go resolve the field 12419 */ 12420.LOP_SPUT_BOOLEAN_JUMBO_resolve: 12421 movl rGLUE,%ecx 12422 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12423 movl offGlue_method(%ecx),%ecx # ecx<- current method 12424 EXPORT_PC # could throw, need to export 12425 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12426 movl %eax,OUT_ARG1(%esp) 12427 movl %ecx,OUT_ARG0(%esp) 12428 call dvmResolveStaticField # eax<- resolved StaticField ptr 12429 testl %eax,%eax 12430 jne .LOP_SPUT_BOOLEAN_JUMBO_finish # success, continue 12431 jmp common_exceptionThrown # no, handle exception 12432 12433/* continuation for OP_SPUT_BYTE_JUMBO */ 12434 12435 /* 12436 * Go resolve the field 12437 */ 12438.LOP_SPUT_BYTE_JUMBO_resolve: 12439 movl rGLUE,%ecx 12440 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12441 movl offGlue_method(%ecx),%ecx # ecx<- current method 12442 EXPORT_PC # could throw, need to export 12443 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12444 movl %eax,OUT_ARG1(%esp) 12445 movl %ecx,OUT_ARG0(%esp) 12446 call dvmResolveStaticField # eax<- resolved StaticField ptr 12447 testl %eax,%eax 12448 jne .LOP_SPUT_BYTE_JUMBO_finish # success, continue 12449 jmp common_exceptionThrown # no, handle exception 12450 12451/* continuation for OP_SPUT_CHAR_JUMBO */ 12452 12453 /* 12454 * Go resolve the field 12455 */ 12456.LOP_SPUT_CHAR_JUMBO_resolve: 12457 movl rGLUE,%ecx 12458 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12459 movl offGlue_method(%ecx),%ecx # ecx<- current method 12460 EXPORT_PC # could throw, need to export 12461 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12462 movl %eax,OUT_ARG1(%esp) 12463 movl %ecx,OUT_ARG0(%esp) 12464 call dvmResolveStaticField # eax<- resolved StaticField ptr 12465 testl %eax,%eax 12466 jne .LOP_SPUT_CHAR_JUMBO_finish # success, continue 12467 jmp common_exceptionThrown # no, handle exception 12468 12469/* continuation for OP_SPUT_SHORT_JUMBO */ 12470 12471 /* 12472 * Go resolve the field 12473 */ 12474.LOP_SPUT_SHORT_JUMBO_resolve: 12475 movl rGLUE,%ecx 12476 movl 2(rPC),%eax # eax<- field ref AAAAAAAA 12477 movl offGlue_method(%ecx),%ecx # ecx<- current method 12478 EXPORT_PC # could throw, need to export 12479 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12480 movl %eax,OUT_ARG1(%esp) 12481 movl %ecx,OUT_ARG0(%esp) 12482 call dvmResolveStaticField # eax<- resolved StaticField ptr 12483 testl %eax,%eax 12484 jne .LOP_SPUT_SHORT_JUMBO_finish # success, continue 12485 jmp common_exceptionThrown # no, handle exception 12486 12487/* continuation for OP_INVOKE_VIRTUAL_JUMBO */ 12488 12489 12490.LOP_INVOKE_VIRTUAL_JUMBO_more: 12491 movl offMethod_clazz(%eax),%eax # ecx<- method->clazz 12492 movl %eax,OUT_ARG0(%esp) # arg0<- clazz 12493 movl $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags 12494 call dvmResolveMethod # eax<- call(clazz, ref, flags) 12495 testl %eax,%eax # got null? 12496 jne .LOP_INVOKE_VIRTUAL_JUMBO_continue # no, continue 12497 jmp common_exceptionThrown # yes, handle exception 12498 12499 /* At this point: 12500 * eax = resolved base method 12501 * ecx = scratch 12502 */ 12503.LOP_INVOKE_VIRTUAL_JUMBO_continue: 12504 movzwl 8(rPC),%ecx # ecx<- CCCC 12505 GET_VREG_R %ecx %ecx # ecx<- "this" 12506 movzwl offMethod_methodIndex(%eax),%eax # eax<- baseMethod->methodIndex 12507 testl %ecx,%ecx # null this? 12508 je common_errNullObject # go if so 12509 movl offObject_clazz(%ecx),%ecx # ecx<- thisPtr->clazz 12510 movl offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable 12511 movl (%ecx,%eax,4),%eax # eax<- vtable[methodIndex] 12512 jmp common_invokeMethodJumbo 12513 12514/* continuation for OP_INVOKE_SUPER_JUMBO */ 12515 12516 /* 12517 * At this point: 12518 * ecx = resolved base method [r0] 12519 * eax = method->clazz [r9] 12520 */ 12521.LOP_INVOKE_SUPER_JUMBO_continue: 12522 movl offClassObject_super(%eax),%eax # eax<- method->clazz->super 12523 movzwl offMethod_methodIndex(%ecx),%ecx # ecx<- baseMthod->methodIndex 12524 cmpl offClassObject_vtableCount(%eax),%ecx # compare(methodIndex,vtableCount) 12525 jae .LOP_INVOKE_SUPER_JUMBO_nsm # method not present in superclass 12526 movl offClassObject_vtable(%eax),%eax # eax<- ...clazz->super->vtable 12527 movl (%eax,%ecx,4),%eax # eax<- vtable[methodIndex] 12528 jmp common_invokeMethodJumbo 12529 12530 12531 /* At this point: 12532 * ecx = null (needs to be resolved base method) 12533 * eax = method->clazz 12534 */ 12535.LOP_INVOKE_SUPER_JUMBO_resolve: 12536 SPILL_TMP1(%eax) # method->clazz 12537 movl %eax,OUT_ARG0(%esp) # arg0<- method->clazz 12538 movl 2(rPC),%ecx # ecx<- AAAAAAAA 12539 movl $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- resolver method type 12540 movl %ecx,OUT_ARG1(%esp) # arg1<- ref 12541 call dvmResolveMethod # eax<- call(clazz, ref, flags) 12542 testl %eax,%eax # got null? 12543 movl %eax,%ecx # ecx<- resolved base method 12544 UNSPILL_TMP1(%eax) # restore method->clazz 12545 jne .LOP_INVOKE_SUPER_JUMBO_continue # good to go - continue 12546 jmp common_exceptionThrown # handle exception 12547 12548 /* 12549 * Throw a NoSuchMethodError with the method name as the message. 12550 * ecx = resolved base method 12551 */ 12552.LOP_INVOKE_SUPER_JUMBO_nsm: 12553 movl offMethod_name(%ecx),%eax 12554 mov %eax,OUT_ARG1(%esp) 12555 jmp common_errNoSuchMethod 12556 12557/* continuation for OP_INVOKE_DIRECT_JUMBO */ 12558 12559 /* 12560 * On entry: 12561 * TMP_SPILL <- "this" register 12562 * Things a bit ugly on this path, but it's the less 12563 * frequent one. We'll have to do some reloading. 12564 */ 12565.LOP_INVOKE_DIRECT_JUMBO_resolve: 12566 SPILL_TMP1(%ecx) 12567 movl rGLUE,%ecx 12568 movl offGlue_method(%ecx),%ecx # ecx<- glue->method 12569 movl 2(rPC),%eax # reference AAAAAAAA 12570 movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz 12571 movl $METHOD_DIRECT,OUT_ARG2(%esp) 12572 movl %eax,OUT_ARG1(%esp) 12573 movl %ecx,OUT_ARG0(%esp) 12574 call dvmResolveMethod # eax<- call(clazz, ref, flags) 12575 UNSPILL_TMP1(%ecx) 12576 testl %eax,%eax 12577 jne .LOP_INVOKE_DIRECT_JUMBO_finish 12578 jmp common_exceptionThrown 12579 12580/* continuation for OP_INVOKE_STATIC_JUMBO */ 12581 12582.LOP_INVOKE_STATIC_JUMBO_continue: 12583 movl $METHOD_STATIC,%eax 12584 movl %eax,OUT_ARG2(%esp) # arg2<- flags 12585 call dvmResolveMethod # call(clazz,ref,flags) 12586 testl %eax,%eax # got null? 12587 jne common_invokeMethodJumbo 12588 jmp common_exceptionThrown 12589 12590/* continuation for OP_INVOKE_INTERFACE_JUMBO */ 12591 12592.LOP_INVOKE_INTERFACE_JUMBO_continue: 12593 call dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex) 12594 testl %eax,%eax 12595 je common_exceptionThrown 12596 jmp common_invokeMethodJumbo 12597 12598 .size dvmAsmSisterStart, .-dvmAsmSisterStart 12599 .global dvmAsmSisterEnd 12600dvmAsmSisterEnd: 12601 12602/* File: x86/entry.S */ 12603/* 12604 * Copyright (C) 2008 The Android Open Source Project 12605 * 12606 * Licensed under the Apache License, Version 2.0 (the "License"); 12607 * you may not use this file except in compliance with the License. 12608 * You may obtain a copy of the License at 12609 * 12610 * http://www.apache.org/licenses/LICENSE-2.0 12611 * 12612 * Unless required by applicable law or agreed to in writing, software 12613 * distributed under the License is distributed on an "AS IS" BASIS, 12614 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12615 * See the License for the specific language governing permissions and 12616 * limitations under the License. 12617 */ 12618 12619 12620 .text 12621 .global dvmMterpStdRun 12622 .type dvmMterpStdRun, %function 12623/* 12624 * bool dvmMterpStdRun(MterpGlue* glue) 12625 * 12626 * Interpreter entry point. Returns changeInterp. 12627 * 12628 */ 12629dvmMterpStdRun: 12630 movl 4(%esp), %ecx # get incoming rGLUE 12631 push %ebp # save caller base pointer 12632 push %ecx # save rGLUE at (%ebp) 12633 movl %esp, %ebp # set our %ebp 12634/* 12635 * At this point we've allocated two slots on the stack 12636 * via push and stack is 8-byte aligned. Allocate space 12637 * for 8 spill slots, 3 local slots, 5 arg slots + 2 slots for 12638 * padding to bring us to 16-byte alignment 12639 */ 12640 subl $(FRAME_SIZE-8), %esp 12641 12642/* Spill callee save regs */ 12643 movl %edi,EDI_SPILL(%ebp) 12644 movl %esi,ESI_SPILL(%ebp) 12645 movl %ebx,EBX_SPILL(%ebp) 12646 12647/* Set up "named" registers */ 12648 movl offGlue_pc(%ecx),rPC 12649 movl offGlue_fp(%ecx),rFP 12650 12651/* Remember %esp for future "longjmp" */ 12652 movl %esp,offGlue_bailPtr(%ecx) 12653 12654/* How to start? */ 12655 movb offGlue_entryPoint(%ecx),%al 12656 12657/* Normal start? */ 12658 cmpb $kInterpEntryInstr,%al 12659 jne .Lnot_instr 12660 12661 /* Normal case: start executing the instruction at rPC */ 12662 FETCH_INST 12663 GOTO_NEXT 12664 12665.Lnot_instr: 12666 /* Reset to normal case */ 12667 movb $kInterpEntryInstr,offGlue_entryPoint(%ecx) 12668 cmpb $kInterpEntryReturn,%al 12669 je common_returnFromMethod 12670 cmpb $kInterpEntryThrow,%al 12671 je common_exceptionThrown 12672 movzx %al,%eax 12673 movl %eax,OUT_ARG1(%esp) 12674 movl $.LstrBadEntryPoint,OUT_ARG0(%esp) 12675 call printf 12676 call dvmAbort 12677 /* Not reached */ 12678 12679 12680 .global dvmMterpStdBail 12681 .type dvmMterpStdBail, %function 12682/* 12683 * void dvmMterpStdBail(MterpGlue* glue, bool changeInterp) 12684 * 12685 * Restore the stack pointer and PC from the save point established on entry. 12686 * This is essentially the same as a longjmp, but should be cheaper. The 12687 * last instruction causes us to return to whoever called dvmMterpStdRun. 12688 * 12689 * We're not going to build a standard frame here, so the arg accesses will 12690 * look a little strange. 12691 * 12692 * On entry: 12693 * esp+4 (arg0) MterpGlue* glue 12694 * esp+8 (arg1) bool changeInterp 12695 */ 12696dvmMterpStdBail: 12697 movl 4(%esp),%ecx # grab glue 12698 movl 8(%esp),%eax # changeInterp to return reg 12699 movl offGlue_bailPtr(%ecx),%esp # Restore "setjmp" esp 12700 movl %esp,%ebp 12701 addl $(FRAME_SIZE-8), %ebp # Restore %ebp at point of setjmp 12702 movl EDI_SPILL(%ebp),%edi 12703 movl ESI_SPILL(%ebp),%esi 12704 movl EBX_SPILL(%ebp),%ebx 12705 movl PREV_FP(%ebp),%ebp # restore caller's ebp 12706 addl $FRAME_SIZE,%esp # strip frame 12707 ret # return to dvmMterpStdRun's caller 12708 12709 12710/* 12711 * Strings 12712 */ 12713 .section .rodata 12714.LstrBadEntryPoint: 12715 .asciz "Bad entry point %d\n" 12716 12717 12718/* 12719 * FIXME: Should have the config/rebuild mechanism generate this 12720 * for targets that need it. 12721 */ 12722 12723/* Jump table */ 12724dvmAsmInstructionJmpTable = .LdvmAsmInstructionJmpTable 12725.LdvmAsmInstructionJmpTable: 12726.long .L_OP_NOP 12727.long .L_OP_MOVE 12728.long .L_OP_MOVE_FROM16 12729.long .L_OP_MOVE_16 12730.long .L_OP_MOVE_WIDE 12731.long .L_OP_MOVE_WIDE_FROM16 12732.long .L_OP_MOVE_WIDE_16 12733.long .L_OP_MOVE_OBJECT 12734.long .L_OP_MOVE_OBJECT_FROM16 12735.long .L_OP_MOVE_OBJECT_16 12736.long .L_OP_MOVE_RESULT 12737.long .L_OP_MOVE_RESULT_WIDE 12738.long .L_OP_MOVE_RESULT_OBJECT 12739.long .L_OP_MOVE_EXCEPTION 12740.long .L_OP_RETURN_VOID 12741.long .L_OP_RETURN 12742.long .L_OP_RETURN_WIDE 12743.long .L_OP_RETURN_OBJECT 12744.long .L_OP_CONST_4 12745.long .L_OP_CONST_16 12746.long .L_OP_CONST 12747.long .L_OP_CONST_HIGH16 12748.long .L_OP_CONST_WIDE_16 12749.long .L_OP_CONST_WIDE_32 12750.long .L_OP_CONST_WIDE 12751.long .L_OP_CONST_WIDE_HIGH16 12752.long .L_OP_CONST_STRING 12753.long .L_OP_CONST_STRING_JUMBO 12754.long .L_OP_CONST_CLASS 12755.long .L_OP_MONITOR_ENTER 12756.long .L_OP_MONITOR_EXIT 12757.long .L_OP_CHECK_CAST 12758.long .L_OP_INSTANCE_OF 12759.long .L_OP_ARRAY_LENGTH 12760.long .L_OP_NEW_INSTANCE 12761.long .L_OP_NEW_ARRAY 12762.long .L_OP_FILLED_NEW_ARRAY 12763.long .L_OP_FILLED_NEW_ARRAY_RANGE 12764.long .L_OP_FILL_ARRAY_DATA 12765.long .L_OP_THROW 12766.long .L_OP_GOTO 12767.long .L_OP_GOTO_16 12768.long .L_OP_GOTO_32 12769.long .L_OP_PACKED_SWITCH 12770.long .L_OP_SPARSE_SWITCH 12771.long .L_OP_CMPL_FLOAT 12772.long .L_OP_CMPG_FLOAT 12773.long .L_OP_CMPL_DOUBLE 12774.long .L_OP_CMPG_DOUBLE 12775.long .L_OP_CMP_LONG 12776.long .L_OP_IF_EQ 12777.long .L_OP_IF_NE 12778.long .L_OP_IF_LT 12779.long .L_OP_IF_GE 12780.long .L_OP_IF_GT 12781.long .L_OP_IF_LE 12782.long .L_OP_IF_EQZ 12783.long .L_OP_IF_NEZ 12784.long .L_OP_IF_LTZ 12785.long .L_OP_IF_GEZ 12786.long .L_OP_IF_GTZ 12787.long .L_OP_IF_LEZ 12788.long .L_OP_UNUSED_3E 12789.long .L_OP_UNUSED_3F 12790.long .L_OP_UNUSED_40 12791.long .L_OP_UNUSED_41 12792.long .L_OP_UNUSED_42 12793.long .L_OP_UNUSED_43 12794.long .L_OP_AGET 12795.long .L_OP_AGET_WIDE 12796.long .L_OP_AGET_OBJECT 12797.long .L_OP_AGET_BOOLEAN 12798.long .L_OP_AGET_BYTE 12799.long .L_OP_AGET_CHAR 12800.long .L_OP_AGET_SHORT 12801.long .L_OP_APUT 12802.long .L_OP_APUT_WIDE 12803.long .L_OP_APUT_OBJECT 12804.long .L_OP_APUT_BOOLEAN 12805.long .L_OP_APUT_BYTE 12806.long .L_OP_APUT_CHAR 12807.long .L_OP_APUT_SHORT 12808.long .L_OP_IGET 12809.long .L_OP_IGET_WIDE 12810.long .L_OP_IGET_OBJECT 12811.long .L_OP_IGET_BOOLEAN 12812.long .L_OP_IGET_BYTE 12813.long .L_OP_IGET_CHAR 12814.long .L_OP_IGET_SHORT 12815.long .L_OP_IPUT 12816.long .L_OP_IPUT_WIDE 12817.long .L_OP_IPUT_OBJECT 12818.long .L_OP_IPUT_BOOLEAN 12819.long .L_OP_IPUT_BYTE 12820.long .L_OP_IPUT_CHAR 12821.long .L_OP_IPUT_SHORT 12822.long .L_OP_SGET 12823.long .L_OP_SGET_WIDE 12824.long .L_OP_SGET_OBJECT 12825.long .L_OP_SGET_BOOLEAN 12826.long .L_OP_SGET_BYTE 12827.long .L_OP_SGET_CHAR 12828.long .L_OP_SGET_SHORT 12829.long .L_OP_SPUT 12830.long .L_OP_SPUT_WIDE 12831.long .L_OP_SPUT_OBJECT 12832.long .L_OP_SPUT_BOOLEAN 12833.long .L_OP_SPUT_BYTE 12834.long .L_OP_SPUT_CHAR 12835.long .L_OP_SPUT_SHORT 12836.long .L_OP_INVOKE_VIRTUAL 12837.long .L_OP_INVOKE_SUPER 12838.long .L_OP_INVOKE_DIRECT 12839.long .L_OP_INVOKE_STATIC 12840.long .L_OP_INVOKE_INTERFACE 12841.long .L_OP_UNUSED_73 12842.long .L_OP_INVOKE_VIRTUAL_RANGE 12843.long .L_OP_INVOKE_SUPER_RANGE 12844.long .L_OP_INVOKE_DIRECT_RANGE 12845.long .L_OP_INVOKE_STATIC_RANGE 12846.long .L_OP_INVOKE_INTERFACE_RANGE 12847.long .L_OP_UNUSED_79 12848.long .L_OP_UNUSED_7A 12849.long .L_OP_NEG_INT 12850.long .L_OP_NOT_INT 12851.long .L_OP_NEG_LONG 12852.long .L_OP_NOT_LONG 12853.long .L_OP_NEG_FLOAT 12854.long .L_OP_NEG_DOUBLE 12855.long .L_OP_INT_TO_LONG 12856.long .L_OP_INT_TO_FLOAT 12857.long .L_OP_INT_TO_DOUBLE 12858.long .L_OP_LONG_TO_INT 12859.long .L_OP_LONG_TO_FLOAT 12860.long .L_OP_LONG_TO_DOUBLE 12861.long .L_OP_FLOAT_TO_INT 12862.long .L_OP_FLOAT_TO_LONG 12863.long .L_OP_FLOAT_TO_DOUBLE 12864.long .L_OP_DOUBLE_TO_INT 12865.long .L_OP_DOUBLE_TO_LONG 12866.long .L_OP_DOUBLE_TO_FLOAT 12867.long .L_OP_INT_TO_BYTE 12868.long .L_OP_INT_TO_CHAR 12869.long .L_OP_INT_TO_SHORT 12870.long .L_OP_ADD_INT 12871.long .L_OP_SUB_INT 12872.long .L_OP_MUL_INT 12873.long .L_OP_DIV_INT 12874.long .L_OP_REM_INT 12875.long .L_OP_AND_INT 12876.long .L_OP_OR_INT 12877.long .L_OP_XOR_INT 12878.long .L_OP_SHL_INT 12879.long .L_OP_SHR_INT 12880.long .L_OP_USHR_INT 12881.long .L_OP_ADD_LONG 12882.long .L_OP_SUB_LONG 12883.long .L_OP_MUL_LONG 12884.long .L_OP_DIV_LONG 12885.long .L_OP_REM_LONG 12886.long .L_OP_AND_LONG 12887.long .L_OP_OR_LONG 12888.long .L_OP_XOR_LONG 12889.long .L_OP_SHL_LONG 12890.long .L_OP_SHR_LONG 12891.long .L_OP_USHR_LONG 12892.long .L_OP_ADD_FLOAT 12893.long .L_OP_SUB_FLOAT 12894.long .L_OP_MUL_FLOAT 12895.long .L_OP_DIV_FLOAT 12896.long .L_OP_REM_FLOAT 12897.long .L_OP_ADD_DOUBLE 12898.long .L_OP_SUB_DOUBLE 12899.long .L_OP_MUL_DOUBLE 12900.long .L_OP_DIV_DOUBLE 12901.long .L_OP_REM_DOUBLE 12902.long .L_OP_ADD_INT_2ADDR 12903.long .L_OP_SUB_INT_2ADDR 12904.long .L_OP_MUL_INT_2ADDR 12905.long .L_OP_DIV_INT_2ADDR 12906.long .L_OP_REM_INT_2ADDR 12907.long .L_OP_AND_INT_2ADDR 12908.long .L_OP_OR_INT_2ADDR 12909.long .L_OP_XOR_INT_2ADDR 12910.long .L_OP_SHL_INT_2ADDR 12911.long .L_OP_SHR_INT_2ADDR 12912.long .L_OP_USHR_INT_2ADDR 12913.long .L_OP_ADD_LONG_2ADDR 12914.long .L_OP_SUB_LONG_2ADDR 12915.long .L_OP_MUL_LONG_2ADDR 12916.long .L_OP_DIV_LONG_2ADDR 12917.long .L_OP_REM_LONG_2ADDR 12918.long .L_OP_AND_LONG_2ADDR 12919.long .L_OP_OR_LONG_2ADDR 12920.long .L_OP_XOR_LONG_2ADDR 12921.long .L_OP_SHL_LONG_2ADDR 12922.long .L_OP_SHR_LONG_2ADDR 12923.long .L_OP_USHR_LONG_2ADDR 12924.long .L_OP_ADD_FLOAT_2ADDR 12925.long .L_OP_SUB_FLOAT_2ADDR 12926.long .L_OP_MUL_FLOAT_2ADDR 12927.long .L_OP_DIV_FLOAT_2ADDR 12928.long .L_OP_REM_FLOAT_2ADDR 12929.long .L_OP_ADD_DOUBLE_2ADDR 12930.long .L_OP_SUB_DOUBLE_2ADDR 12931.long .L_OP_MUL_DOUBLE_2ADDR 12932.long .L_OP_DIV_DOUBLE_2ADDR 12933.long .L_OP_REM_DOUBLE_2ADDR 12934.long .L_OP_ADD_INT_LIT16 12935.long .L_OP_RSUB_INT 12936.long .L_OP_MUL_INT_LIT16 12937.long .L_OP_DIV_INT_LIT16 12938.long .L_OP_REM_INT_LIT16 12939.long .L_OP_AND_INT_LIT16 12940.long .L_OP_OR_INT_LIT16 12941.long .L_OP_XOR_INT_LIT16 12942.long .L_OP_ADD_INT_LIT8 12943.long .L_OP_RSUB_INT_LIT8 12944.long .L_OP_MUL_INT_LIT8 12945.long .L_OP_DIV_INT_LIT8 12946.long .L_OP_REM_INT_LIT8 12947.long .L_OP_AND_INT_LIT8 12948.long .L_OP_OR_INT_LIT8 12949.long .L_OP_XOR_INT_LIT8 12950.long .L_OP_SHL_INT_LIT8 12951.long .L_OP_SHR_INT_LIT8 12952.long .L_OP_USHR_INT_LIT8 12953.long .L_OP_IGET_VOLATILE 12954.long .L_OP_IPUT_VOLATILE 12955.long .L_OP_SGET_VOLATILE 12956.long .L_OP_SPUT_VOLATILE 12957.long .L_OP_IGET_OBJECT_VOLATILE 12958.long .L_OP_IGET_WIDE_VOLATILE 12959.long .L_OP_IPUT_WIDE_VOLATILE 12960.long .L_OP_SGET_WIDE_VOLATILE 12961.long .L_OP_SPUT_WIDE_VOLATILE 12962.long .L_OP_BREAKPOINT 12963.long .L_OP_THROW_VERIFICATION_ERROR 12964.long .L_OP_EXECUTE_INLINE 12965.long .L_OP_EXECUTE_INLINE_RANGE 12966.long .L_OP_INVOKE_OBJECT_INIT 12967.long .L_OP_RETURN_VOID_BARRIER 12968.long .L_OP_IGET_QUICK 12969.long .L_OP_IGET_WIDE_QUICK 12970.long .L_OP_IGET_OBJECT_QUICK 12971.long .L_OP_IPUT_QUICK 12972.long .L_OP_IPUT_WIDE_QUICK 12973.long .L_OP_IPUT_OBJECT_QUICK 12974.long .L_OP_INVOKE_VIRTUAL_QUICK 12975.long .L_OP_INVOKE_VIRTUAL_QUICK_RANGE 12976.long .L_OP_INVOKE_SUPER_QUICK 12977.long .L_OP_INVOKE_SUPER_QUICK_RANGE 12978.long .L_OP_IPUT_OBJECT_VOLATILE 12979.long .L_OP_SGET_OBJECT_VOLATILE 12980.long .L_OP_SPUT_OBJECT_VOLATILE 12981.long .L_OP_DISPATCH_FF 12982.long .L_OP_CONST_CLASS_JUMBO 12983.long .L_OP_CHECK_CAST_JUMBO 12984.long .L_OP_INSTANCE_OF_JUMBO 12985.long .L_OP_NEW_INSTANCE_JUMBO 12986.long .L_OP_NEW_ARRAY_JUMBO 12987.long .L_OP_FILLED_NEW_ARRAY_JUMBO 12988.long .L_OP_IGET_JUMBO 12989.long .L_OP_IGET_WIDE_JUMBO 12990.long .L_OP_IGET_OBJECT_JUMBO 12991.long .L_OP_IGET_BOOLEAN_JUMBO 12992.long .L_OP_IGET_BYTE_JUMBO 12993.long .L_OP_IGET_CHAR_JUMBO 12994.long .L_OP_IGET_SHORT_JUMBO 12995.long .L_OP_IPUT_JUMBO 12996.long .L_OP_IPUT_WIDE_JUMBO 12997.long .L_OP_IPUT_OBJECT_JUMBO 12998.long .L_OP_IPUT_BOOLEAN_JUMBO 12999.long .L_OP_IPUT_BYTE_JUMBO 13000.long .L_OP_IPUT_CHAR_JUMBO 13001.long .L_OP_IPUT_SHORT_JUMBO 13002.long .L_OP_SGET_JUMBO 13003.long .L_OP_SGET_WIDE_JUMBO 13004.long .L_OP_SGET_OBJECT_JUMBO 13005.long .L_OP_SGET_BOOLEAN_JUMBO 13006.long .L_OP_SGET_BYTE_JUMBO 13007.long .L_OP_SGET_CHAR_JUMBO 13008.long .L_OP_SGET_SHORT_JUMBO 13009.long .L_OP_SPUT_JUMBO 13010.long .L_OP_SPUT_WIDE_JUMBO 13011.long .L_OP_SPUT_OBJECT_JUMBO 13012.long .L_OP_SPUT_BOOLEAN_JUMBO 13013.long .L_OP_SPUT_BYTE_JUMBO 13014.long .L_OP_SPUT_CHAR_JUMBO 13015.long .L_OP_SPUT_SHORT_JUMBO 13016.long .L_OP_INVOKE_VIRTUAL_JUMBO 13017.long .L_OP_INVOKE_SUPER_JUMBO 13018.long .L_OP_INVOKE_DIRECT_JUMBO 13019.long .L_OP_INVOKE_STATIC_JUMBO 13020.long .L_OP_INVOKE_INTERFACE_JUMBO 13021.long .L_OP_UNUSED_27FF 13022.long .L_OP_UNUSED_28FF 13023.long .L_OP_UNUSED_29FF 13024.long .L_OP_UNUSED_2AFF 13025.long .L_OP_UNUSED_2BFF 13026.long .L_OP_UNUSED_2CFF 13027.long .L_OP_UNUSED_2DFF 13028.long .L_OP_UNUSED_2EFF 13029.long .L_OP_UNUSED_2FFF 13030.long .L_OP_UNUSED_30FF 13031.long .L_OP_UNUSED_31FF 13032.long .L_OP_UNUSED_32FF 13033.long .L_OP_UNUSED_33FF 13034.long .L_OP_UNUSED_34FF 13035.long .L_OP_UNUSED_35FF 13036.long .L_OP_UNUSED_36FF 13037.long .L_OP_UNUSED_37FF 13038.long .L_OP_UNUSED_38FF 13039.long .L_OP_UNUSED_39FF 13040.long .L_OP_UNUSED_3AFF 13041.long .L_OP_UNUSED_3BFF 13042.long .L_OP_UNUSED_3CFF 13043.long .L_OP_UNUSED_3DFF 13044.long .L_OP_UNUSED_3EFF 13045.long .L_OP_UNUSED_3FFF 13046.long .L_OP_UNUSED_40FF 13047.long .L_OP_UNUSED_41FF 13048.long .L_OP_UNUSED_42FF 13049.long .L_OP_UNUSED_43FF 13050.long .L_OP_UNUSED_44FF 13051.long .L_OP_UNUSED_45FF 13052.long .L_OP_UNUSED_46FF 13053.long .L_OP_UNUSED_47FF 13054.long .L_OP_UNUSED_48FF 13055.long .L_OP_UNUSED_49FF 13056.long .L_OP_UNUSED_4AFF 13057.long .L_OP_UNUSED_4BFF 13058.long .L_OP_UNUSED_4CFF 13059.long .L_OP_UNUSED_4DFF 13060.long .L_OP_UNUSED_4EFF 13061.long .L_OP_UNUSED_4FFF 13062.long .L_OP_UNUSED_50FF 13063.long .L_OP_UNUSED_51FF 13064.long .L_OP_UNUSED_52FF 13065.long .L_OP_UNUSED_53FF 13066.long .L_OP_UNUSED_54FF 13067.long .L_OP_UNUSED_55FF 13068.long .L_OP_UNUSED_56FF 13069.long .L_OP_UNUSED_57FF 13070.long .L_OP_UNUSED_58FF 13071.long .L_OP_UNUSED_59FF 13072.long .L_OP_UNUSED_5AFF 13073.long .L_OP_UNUSED_5BFF 13074.long .L_OP_UNUSED_5CFF 13075.long .L_OP_UNUSED_5DFF 13076.long .L_OP_UNUSED_5EFF 13077.long .L_OP_UNUSED_5FFF 13078.long .L_OP_UNUSED_60FF 13079.long .L_OP_UNUSED_61FF 13080.long .L_OP_UNUSED_62FF 13081.long .L_OP_UNUSED_63FF 13082.long .L_OP_UNUSED_64FF 13083.long .L_OP_UNUSED_65FF 13084.long .L_OP_UNUSED_66FF 13085.long .L_OP_UNUSED_67FF 13086.long .L_OP_UNUSED_68FF 13087.long .L_OP_UNUSED_69FF 13088.long .L_OP_UNUSED_6AFF 13089.long .L_OP_UNUSED_6BFF 13090.long .L_OP_UNUSED_6CFF 13091.long .L_OP_UNUSED_6DFF 13092.long .L_OP_UNUSED_6EFF 13093.long .L_OP_UNUSED_6FFF 13094.long .L_OP_UNUSED_70FF 13095.long .L_OP_UNUSED_71FF 13096.long .L_OP_UNUSED_72FF 13097.long .L_OP_UNUSED_73FF 13098.long .L_OP_UNUSED_74FF 13099.long .L_OP_UNUSED_75FF 13100.long .L_OP_UNUSED_76FF 13101.long .L_OP_UNUSED_77FF 13102.long .L_OP_UNUSED_78FF 13103.long .L_OP_UNUSED_79FF 13104.long .L_OP_UNUSED_7AFF 13105.long .L_OP_UNUSED_7BFF 13106.long .L_OP_UNUSED_7CFF 13107.long .L_OP_UNUSED_7DFF 13108.long .L_OP_UNUSED_7EFF 13109.long .L_OP_UNUSED_7FFF 13110.long .L_OP_UNUSED_80FF 13111.long .L_OP_UNUSED_81FF 13112.long .L_OP_UNUSED_82FF 13113.long .L_OP_UNUSED_83FF 13114.long .L_OP_UNUSED_84FF 13115.long .L_OP_UNUSED_85FF 13116.long .L_OP_UNUSED_86FF 13117.long .L_OP_UNUSED_87FF 13118.long .L_OP_UNUSED_88FF 13119.long .L_OP_UNUSED_89FF 13120.long .L_OP_UNUSED_8AFF 13121.long .L_OP_UNUSED_8BFF 13122.long .L_OP_UNUSED_8CFF 13123.long .L_OP_UNUSED_8DFF 13124.long .L_OP_UNUSED_8EFF 13125.long .L_OP_UNUSED_8FFF 13126.long .L_OP_UNUSED_90FF 13127.long .L_OP_UNUSED_91FF 13128.long .L_OP_UNUSED_92FF 13129.long .L_OP_UNUSED_93FF 13130.long .L_OP_UNUSED_94FF 13131.long .L_OP_UNUSED_95FF 13132.long .L_OP_UNUSED_96FF 13133.long .L_OP_UNUSED_97FF 13134.long .L_OP_UNUSED_98FF 13135.long .L_OP_UNUSED_99FF 13136.long .L_OP_UNUSED_9AFF 13137.long .L_OP_UNUSED_9BFF 13138.long .L_OP_UNUSED_9CFF 13139.long .L_OP_UNUSED_9DFF 13140.long .L_OP_UNUSED_9EFF 13141.long .L_OP_UNUSED_9FFF 13142.long .L_OP_UNUSED_A0FF 13143.long .L_OP_UNUSED_A1FF 13144.long .L_OP_UNUSED_A2FF 13145.long .L_OP_UNUSED_A3FF 13146.long .L_OP_UNUSED_A4FF 13147.long .L_OP_UNUSED_A5FF 13148.long .L_OP_UNUSED_A6FF 13149.long .L_OP_UNUSED_A7FF 13150.long .L_OP_UNUSED_A8FF 13151.long .L_OP_UNUSED_A9FF 13152.long .L_OP_UNUSED_AAFF 13153.long .L_OP_UNUSED_ABFF 13154.long .L_OP_UNUSED_ACFF 13155.long .L_OP_UNUSED_ADFF 13156.long .L_OP_UNUSED_AEFF 13157.long .L_OP_UNUSED_AFFF 13158.long .L_OP_UNUSED_B0FF 13159.long .L_OP_UNUSED_B1FF 13160.long .L_OP_UNUSED_B2FF 13161.long .L_OP_UNUSED_B3FF 13162.long .L_OP_UNUSED_B4FF 13163.long .L_OP_UNUSED_B5FF 13164.long .L_OP_UNUSED_B6FF 13165.long .L_OP_UNUSED_B7FF 13166.long .L_OP_UNUSED_B8FF 13167.long .L_OP_UNUSED_B9FF 13168.long .L_OP_UNUSED_BAFF 13169.long .L_OP_UNUSED_BBFF 13170.long .L_OP_UNUSED_BCFF 13171.long .L_OP_UNUSED_BDFF 13172.long .L_OP_UNUSED_BEFF 13173.long .L_OP_UNUSED_BFFF 13174.long .L_OP_UNUSED_C0FF 13175.long .L_OP_UNUSED_C1FF 13176.long .L_OP_UNUSED_C2FF 13177.long .L_OP_UNUSED_C3FF 13178.long .L_OP_UNUSED_C4FF 13179.long .L_OP_UNUSED_C5FF 13180.long .L_OP_UNUSED_C6FF 13181.long .L_OP_UNUSED_C7FF 13182.long .L_OP_UNUSED_C8FF 13183.long .L_OP_UNUSED_C9FF 13184.long .L_OP_UNUSED_CAFF 13185.long .L_OP_UNUSED_CBFF 13186.long .L_OP_UNUSED_CCFF 13187.long .L_OP_UNUSED_CDFF 13188.long .L_OP_UNUSED_CEFF 13189.long .L_OP_UNUSED_CFFF 13190.long .L_OP_UNUSED_D0FF 13191.long .L_OP_UNUSED_D1FF 13192.long .L_OP_UNUSED_D2FF 13193.long .L_OP_UNUSED_D3FF 13194.long .L_OP_UNUSED_D4FF 13195.long .L_OP_UNUSED_D5FF 13196.long .L_OP_UNUSED_D6FF 13197.long .L_OP_UNUSED_D7FF 13198.long .L_OP_UNUSED_D8FF 13199.long .L_OP_UNUSED_D9FF 13200.long .L_OP_UNUSED_DAFF 13201.long .L_OP_UNUSED_DBFF 13202.long .L_OP_UNUSED_DCFF 13203.long .L_OP_UNUSED_DDFF 13204.long .L_OP_UNUSED_DEFF 13205.long .L_OP_UNUSED_DFFF 13206.long .L_OP_UNUSED_E0FF 13207.long .L_OP_UNUSED_E1FF 13208.long .L_OP_UNUSED_E2FF 13209.long .L_OP_UNUSED_E3FF 13210.long .L_OP_UNUSED_E4FF 13211.long .L_OP_UNUSED_E5FF 13212.long .L_OP_UNUSED_E6FF 13213.long .L_OP_UNUSED_E7FF 13214.long .L_OP_UNUSED_E8FF 13215.long .L_OP_UNUSED_E9FF 13216.long .L_OP_UNUSED_EAFF 13217.long .L_OP_UNUSED_EBFF 13218.long .L_OP_UNUSED_ECFF 13219.long .L_OP_UNUSED_EDFF 13220.long .L_OP_UNUSED_EEFF 13221.long .L_OP_UNUSED_EFFF 13222.long .L_OP_UNUSED_F0FF 13223.long .L_OP_UNUSED_F1FF 13224.long .L_OP_UNUSED_F2FF 13225.long .L_OP_UNUSED_F3FF 13226.long .L_OP_UNUSED_F4FF 13227.long .L_OP_UNUSED_F5FF 13228.long .L_OP_UNUSED_F6FF 13229.long .L_OP_UNUSED_F7FF 13230.long .L_OP_UNUSED_F8FF 13231.long .L_OP_UNUSED_F9FF 13232.long .L_OP_UNUSED_FAFF 13233.long .L_OP_UNUSED_FBFF 13234.long .L_OP_UNUSED_FCFF 13235.long .L_OP_UNUSED_FDFF 13236.long .L_OP_UNUSED_FEFF 13237.long .L_OP_THROW_VERIFICATION_ERROR_JUMBO 13238 13239/* File: x86/footer.S */ 13240/* 13241 * Copyright (C) 2008 The Android Open Source Project 13242 * 13243 * Licensed under the Apache License, Version 2.0 (the "License"); 13244 * you may not use this file except in compliance with the License. 13245 * You may obtain a copy of the License at 13246 * 13247 * http://www.apache.org/licenses/LICENSE-2.0 13248 * 13249 * Unless required by applicable law or agreed to in writing, software 13250 * distributed under the License is distributed on an "AS IS" BASIS, 13251 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13252 * See the License for the specific language governing permissions and 13253 * limitations under the License. 13254 */ 13255/* 13256 * Common subroutines and data. 13257 */ 13258 13259#if defined(WITH_JIT) 13260/* 13261 * JIT-related re-entries into the interpreter. In general, if the 13262 * exit from a translation can at some point be chained, the entry 13263 * here requires that control arrived via a call, and that the "rp" 13264 * on TOS is actually a pointer to a 32-bit cell containing the Dalvik PC 13265 * of the next insn to handle. If no chaining will happen, the entry 13266 * should be reached via a direct jump and rPC set beforehand. 13267 */ 13268 13269 .global dvmJitToInterpPunt 13270/* 13271 * The compiler will generate a jump to this entry point when it is 13272 * having difficulty translating a Dalvik instruction. We must skip 13273 * the code cache lookup & prevent chaining to avoid bouncing between 13274 * the interpreter and code cache. rPC must be set on entry. 13275 */ 13276dvmJitToInterpPunt: 13277#if defined(WITH_JIT_TUNING) 13278 movl rPC, OUT_ARG0(%esp) 13279 call dvmBumpPunt 13280#endif 13281 FETCH_INST_R %edx 13282 GOTO_NEXT_R %edx 13283 13284 .global dvmJitToInterpSingleStep 13285/* 13286 * Return to the interpreter to handle a single instruction. 13287 * Should be reached via a call. 13288 * On entry: 13289 * 0(%esp) <= native return address within trace 13290 * rPC <= Dalvik PC of this instruction 13291 * OUT_ARG0+4(%esp) <= Dalvik PC of next instruction 13292 */ 13293dvmJitToInterpSingleStep: 13294 pop %eax 13295 movl rGLUE, %ecx 13296 movl OUT_ARG0(%esp), %edx 13297 movl %eax,offGlue_jitResumeNPC(%ecx) 13298 movl %edx,offGlue_jitResumeDPC(%ecx) 13299 movl $kInterpEntryInstr,offGlue_entryPoint(%ecx) 13300 movl $1,rINST # changeInterp <= true 13301 jmp common_gotoBail 13302 13303 .global dvmJitToInterpNoChainNoProfile 13304/* 13305 * Return from the translation cache to the interpreter to do method 13306 * invocation. Check if the translation exists for the callee, but don't 13307 * chain to it. rPC must be set on entry. 13308 */ 13309dvmJitToInterpNoChainNoProfile: 13310#if defined(WITH_JIT_TUNING) 13311 call dvmBumpNoChain 13312#endif 13313 movl rPC,OUT_ARG0(%esp) 13314 call dvmJitGetTraceAddr # is there a translation? 13315 movl rGLUE,%ecx 13316 movl offGlue_self(%ecx), %ecx # ecx <- glue->self 13317 movl %eax,offThread_inJitCodeCache(%ecx) # set inJitCodeCache flag 13318 cmpl $0, %eax 13319 jz 1f 13320 call *%eax # exec translation if we've got one 13321 # won't return 133221: 13323 FETCH_INST_R %edx 13324 GOTO_NEXT_R %edx 13325 13326/* 13327 * Return from the translation cache and immediately request a 13328 * translation fro the exit target, but don't attempt to chain. 13329 * rPC set on entry. 13330 */ 13331 .global dvmJitToInterpTraceSelectNoChain 13332dvmJitToInterpTraceSelectNoChain: 13333#if defined(WITH_JIT_TUNING) 13334 call dvmBumpNoChain 13335#endif 13336 movl rPC,OUT_ARG0(%esp) 13337 call dvmJitGetTraceAddr # is there a translation? 13338 movl rGLUE,%ecx 13339 movl offGlue_self(%ecx),%ecx 13340 cmpl $0,%eax 13341 movl %eax,offThread_inJitCodeCache(%ecx) # set inJitCodeCache flag 13342 jz 1f 13343 call *%eax # jump to tranlation 13344 # won't return 13345 13346/* No Translation - request one */ 133471: 13348 GET_JIT_PROF_TABLE %ecx %eax 13349 cmpl $0, %eax # JIT enabled? 13350 jnz 2f # Request one if so 13351 FETCH_INST_R %edx # Continue interpreting if not 13352 GOTO_NEXT_R %edx 133532: 13354 movl $kJitTSelectRequestHot,rINST # ask for trace select 13355 jmp common_selectTrace 13356 13357/* 13358 * Return from the translation cache and immediately request a 13359 * translation for the exit target. Reached via a call, and 13360 * (TOS)->rPC. 13361 */ 13362 .global dvmJitToInterpTraceSelect 13363dvmJitToInterpTraceSelect: 13364 pop rINST # save chain cell address in callee save reg 13365 movl (rINST),rPC 13366 movl rPC,OUT_ARG0(%esp) 13367 call dvmJitGetTraceAddr # is there a translation? 13368 cmpl $0,%eax 13369 jz 1b # no - ask for one 13370 movl %eax,OUT_ARG0(%esp) 13371# FIXME - need to adjust rINST to beginning of sequence 13372 movl rINST,OUT_ARG1(%esp) 13373 call dvmJitChain # Attempt dvmJitChain(codeAddr,chainAddr) 13374 cmpl $0,%eax # Success? 13375 jz toInterpreter # didn't chain - interpret 13376 call *%eax 13377 # won't return 13378 13379/* 13380 * Placeholder entries for x86 JIT 13381 */ 13382 .global dvmJitToInterpBackwardBranch 13383dvmJitToInterpBackwardBranch: 13384 .global dvmJitToInterpNormal 13385dvmJitToInterpNormal: 13386 .global dvmJitToInterpNoChain 13387dvmJitToInterpNoChain: 13388toInterpreter: 13389 jmp common_abort 13390#endif 13391 13392/* 13393 * Common code when a backwards branch is taken 13394 * 13395 * On entry: 13396 * ebx (a.k.a. rINST) -> PC adjustment in 16-bit words 13397 */ 13398common_backwardBranch: 13399 movl rGLUE,%ecx 13400 call common_periodicChecks # rPC and ecx/rGLUE preserved 13401#if defined(WITH_JIT) 13402 GET_JIT_PROF_TABLE %ecx %edx 13403 ADVANCE_PC_INDEXED rINST 13404 cmpl $0,%edx 13405 FETCH_INST 13406 jz 1f # Profiling off - continue 13407 .global updateProfile 13408updateProfile: 13409common_updateProfile: 13410 # quick & dirty hash 13411 movl rPC, %eax 13412 shrl $12, %eax 13413 xorl rPC, %eax 13414 andl $((1<<JIT_PROF_SIZE_LOG_2)-1),%eax 13415 decb (%edx,%eax) 13416 jz 2f 134171: 13418 GOTO_NEXT 134192: 13420/* 13421 * Here, we switch to the debug interpreter to request 13422 * trace selection. First, though, check to see if there 13423 * is already a native translation in place (and, if so, 13424 * jump to it now. 13425 */ 13426 GET_JIT_THRESHOLD %ecx rINST 13427 EXPORT_PC 13428 movb rINSTbl,(%edx,%eax) # reset counter 13429 movl offGlue_self(%ecx),rINST 13430 movl rPC,OUT_ARG0(%esp) 13431 call dvmJitGetTraceAddr # already have one? 13432 movl %eax,offThread_inJitCodeCache(rINST) # set the inJitCodeCache flag 13433 cmpl $0,%eax 13434 jz 1f 13435 call *%eax # FIXME: decide call vs/ jmp!. No return either way 134361: 13437 movl $kJitTSelectRequest,%eax 13438 # On entry, eax<- jitState, rPC valid 13439common_selectTrace: 13440 movl rGLUE,%ecx 13441 movl %eax,offGlue_jitState(%ecx) 13442 movl $kInterpEntryInstr,offGlue_entryPoint(%ecx) 13443 movl $1,rINST 13444 jmp common_gotoBail 13445#else 13446 ADVANCE_PC_INDEXED rINST 13447 FETCH_INST 13448 GOTO_NEXT 13449#endif 13450 13451 13452 13453/* 13454 * Common code for jumbo method invocation. 13455 * 13456 * On entry: 13457 * eax = Method* methodToCall 13458 * rINSTw trashed, must reload 13459 */ 13460 13461common_invokeMethodJumbo: 13462.LinvokeNewJumbo: 13463 13464 /* 13465 * prepare to copy args to "outs" area of current frame 13466 */ 13467 movzwl 6(rPC),rINST # rINST<- BBBB 13468 movzwl 8(rPC), %ecx # %ecx<- CCCC 13469 ADVANCE_PC 2 # adjust pc to make return similar 13470 SAVEAREA_FROM_FP %edx # %edx<- &StackSaveArea 13471 test rINST, rINST 13472 movl rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- BBBB 13473 jz .LinvokeArgsDone # no args; jump to args done 13474 jmp .LinvokeRangeArgs # handle args like invoke range 13475 13476/* 13477 * Common code for method invocation with range. 13478 * 13479 * On entry: 13480 * eax = Method* methodToCall 13481 * rINSTw trashed, must reload 13482 */ 13483 13484common_invokeMethodRange: 13485.LinvokeNewRange: 13486 13487 /* 13488 * prepare to copy args to "outs" area of current frame 13489 */ 13490 13491 movzbl 1(rPC),rINST # rINST<- AA 13492 movzwl 4(rPC), %ecx # %ecx<- CCCC 13493 SAVEAREA_FROM_FP %edx # %edx<- &StackSaveArea 13494 test rINST, rINST 13495 movl rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- AA 13496 jz .LinvokeArgsDone # no args; jump to args done 13497 13498 13499 /* 13500 * %eax=methodToCall, %ecx=CCCC, LOCAL0_OFFSET(%ebp)=count, %edx=&outs (&stackSaveArea) 13501 * (very few methods have > 10 args; could unroll for common cases) 13502 */ 13503 13504.LinvokeRangeArgs: 13505 movl %ebx, LOCAL1_OFFSET(%ebp) # LOCAL1_OFFSET(%ebp)<- save %ebx 13506 lea (rFP, %ecx, 4), %ecx # %ecx<- &vCCCC 13507 shll $2, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- offset 13508 subl LOCAL0_OFFSET(%ebp), %edx # %edx<- update &outs 13509 shrl $2, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- offset 135101: 13511 movl (%ecx), %ebx # %ebx<- vCCCC 13512 lea 4(%ecx), %ecx # %ecx<- &vCCCC++ 13513 subl $1, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET<- LOCAL0_OFFSET-- 13514 movl %ebx, (%edx) # *outs<- vCCCC 13515 lea 4(%edx), %edx # outs++ 13516 jne 1b # loop if count (LOCAL0_OFFSET(%ebp)) not zero 13517 movl LOCAL1_OFFSET(%ebp), %ebx # %ebx<- restore %ebx 13518 jmp .LinvokeArgsDone # continue 13519 13520 /* 13521 * %eax is "Method* methodToCall", the method we're trying to call 13522 * prepare to copy args to "outs" area of current frame 13523 */ 13524 13525common_invokeMethodNoRange: 13526.LinvokeNewNoRange: 13527 movzbl 1(rPC),rINST # rINST<- BA 13528 movl rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- BA 13529 shrl $4, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- B 13530 je .LinvokeArgsDone # no args; jump to args done 13531 movzwl 4(rPC), %ecx # %ecx<- GFED 13532 SAVEAREA_FROM_FP %edx # %edx<- &StackSaveArea 13533 13534 /* 13535 * %eax=methodToCall, %ecx=GFED, LOCAL0_OFFSET(%ebp)=count, %edx=outs 13536 */ 13537 13538.LinvokeNonRange: 13539 cmp $2, LOCAL0_OFFSET(%ebp) # compare LOCAL0_OFFSET(%ebp) to 2 13540 movl %ecx, LOCAL1_OFFSET(%ebp) # LOCAL1_OFFSET(%ebp)<- GFED 13541 jl 1f # handle 1 arg 13542 je 2f # handle 2 args 13543 cmp $4, LOCAL0_OFFSET(%ebp) # compare LOCAL0_OFFSET(%ebp) to 4 13544 jl 3f # handle 3 args 13545 je 4f # handle 4 args 135465: 13547 andl $15, rINST # rINSTw<- A 13548 lea -4(%edx), %edx # %edx<- update &outs; &outs-- 13549 movl (rFP, rINST, 4), %ecx # %ecx<- vA 13550 movl %ecx, (%edx) # *outs<- vA 13551 movl LOCAL1_OFFSET(%ebp), %ecx # %ecx<- GFED 135524: 13553 shr $12, %ecx # %ecx<- G 13554 lea -4(%edx), %edx # %edx<- update &outs; &outs-- 13555 movl (rFP, %ecx, 4), %ecx # %ecx<- vG 13556 movl %ecx, (%edx) # *outs<- vG 13557 movl LOCAL1_OFFSET(%ebp), %ecx # %ecx<- GFED 135583: 13559 and $0x0f00, %ecx # %ecx<- 0F00 13560 shr $8, %ecx # %ecx<- F 13561 lea -4(%edx), %edx # %edx<- update &outs; &outs-- 13562 movl (rFP, %ecx, 4), %ecx # %ecx<- vF 13563 movl %ecx, (%edx) # *outs<- vF 13564 movl LOCAL1_OFFSET(%ebp), %ecx # %ecx<- GFED 135652: 13566 and $0x00f0, %ecx # %ecx<- 00E0 13567 shr $4, %ecx # %ecx<- E 13568 lea -4(%edx), %edx # %edx<- update &outs; &outs-- 13569 movl (rFP, %ecx, 4), %ecx # %ecx<- vE 13570 movl %ecx, (%edx) # *outs<- vE 13571 movl LOCAL1_OFFSET(%ebp), %ecx # %ecx<- GFED 135721: 13573 and $0x000f, %ecx # %ecx<- 000D 13574 movl (rFP, %ecx, 4), %ecx # %ecx<- vD 13575 movl %ecx, -4(%edx) # *--outs<- vD 135760: 13577 13578 /* 13579 * %eax is "Method* methodToCall", the method we're trying to call 13580 * find space for the new stack frame, check for overflow 13581 */ 13582 13583.LinvokeArgsDone: 13584 movzwl offMethod_registersSize(%eax), %edx # %edx<- methodToCall->regsSize 13585 movzwl offMethod_outsSize(%eax), %ecx # %ecx<- methodToCall->outsSize 13586 movl %eax, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET<- methodToCall 13587 shl $2, %edx # %edx<- update offset 13588 SAVEAREA_FROM_FP %eax # %eax<- &StackSaveArea 13589 subl %edx, %eax # %eax<- newFP; (old savearea - regsSize) 13590 movl rGLUE,%edx # %edx<- pMterpGlue 13591 movl %eax, LOCAL1_OFFSET(%ebp) # LOCAL1_OFFSET(%ebp)<- &outs 13592 subl $sizeofStackSaveArea, %eax # %eax<- newSaveArea (stack save area using newFP) 13593 movl offGlue_interpStackEnd(%edx), %edx # %edx<- glue->interpStackEnd 13594 movl %edx, LOCAL2_OFFSET(%ebp) # LOCAL2_OFFSET<- glue->interpStackEnd 13595 shl $2, %ecx # %ecx<- update offset for outsSize 13596 movl %eax, %edx # %edx<- newSaveArea 13597 sub %ecx, %eax # %eax<- bottom; (newSaveArea - outsSize) 13598 cmp LOCAL2_OFFSET(%ebp), %eax # compare interpStackEnd and bottom 13599 movl LOCAL0_OFFSET(%ebp), %eax # %eax<- restore methodToCall 13600 jl .LstackOverflow # handle frame overflow 13601 13602 /* 13603 * set up newSaveArea 13604 */ 13605 13606#ifdef EASY_GDB 13607 SAVEAREA_FROM_FP %ecx # %ecx<- &StackSaveArea 13608 movl %ecx, offStackSaveArea_prevSave(%edx) # newSaveArea->prevSave<- &outs 13609#endif 13610 movl rFP, offStackSaveArea_prevFrame(%edx) # newSaveArea->prevFrame<- rFP 13611 movl rPC, offStackSaveArea_savedPc(%edx) # newSaveArea->savedPc<- rPC 13612 testl $ACC_NATIVE, offMethod_accessFlags(%eax) # check for native call 13613 movl %eax, offStackSaveArea_method(%edx) # newSaveArea->method<- method to call 13614 jne .LinvokeNative # handle native call 13615 13616 /* 13617 * Update "glue" values for the new method 13618 * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFp 13619 */ 13620 13621 movl offMethod_clazz(%eax), %edx # %edx<- method->clazz 13622 movl rGLUE,%ecx # %ecx<- pMterpGlue 13623 movl offClassObject_pDvmDex(%edx), %edx # %edx<- method->clazz->pDvmDex 13624 movl %eax, offGlue_method(%ecx) # glue->method<- methodToCall 13625 movl %edx, offGlue_methodClassDex(%ecx) # glue->methodClassDex<- method->clazz->pDvmDex 13626 movl offMethod_insns(%eax), rPC # rPC<- methodToCall->insns 13627 movl offGlue_self(%ecx), %eax # %eax<- glue->self 13628 movl LOCAL1_OFFSET(%ebp), rFP # rFP<- newFP 13629 movl rFP, offThread_curFrame(%eax) # glue->self->curFrame<- newFP 13630 FETCH_INST 13631 GOTO_NEXT # jump to methodToCall->insns 13632 13633 /* 13634 * Prep for the native call 13635 * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFP, %edx=newSaveArea 13636 */ 13637 13638.LinvokeNative: 13639 movl rGLUE,%ecx # %ecx<- pMterpGlue 13640 movl %eax, OUT_ARG1(%esp) # push parameter methodToCall 13641 movl offGlue_self(%ecx), %ecx # %ecx<- glue->self 13642 movl offThread_jniLocal_topCookie(%ecx), %eax # %eax<- self->localRef->... 13643 movl %eax, offStackSaveArea_localRefCookie(%edx) # newSaveArea->localRefCookie<- top 13644 movl %edx, OUT_ARG4(%esp) # save newSaveArea 13645 movl LOCAL1_OFFSET(%ebp), %edx # %edx<- newFP 13646 movl %edx, offThread_curFrame(%ecx) # glue->self->curFrame<- newFP 13647 movl %ecx, OUT_ARG3(%esp) # save glue->self 13648 movl %ecx, OUT_ARG2(%esp) # push parameter glue->self 13649 movl rGLUE,%ecx # %ecx<- pMterpGlue 13650 movl OUT_ARG1(%esp), %eax # %eax<- methodToCall 13651 lea offGlue_retval(%ecx), %ecx # %ecx<- &retval 13652 movl %ecx, OUT_ARG0(%esp) # push parameter pMterpGlue 13653 push %edx # push parameter newFP 13654 13655 call *offMethod_nativeFunc(%eax) # call methodToCall->nativeFunc 13656 lea 4(%esp), %esp 13657 movl OUT_ARG4(%esp), %ecx # %ecx<- newSaveArea 13658 movl OUT_ARG3(%esp), %eax # %eax<- glue->self 13659 movl offStackSaveArea_localRefCookie(%ecx), %edx # %edx<- old top 13660 cmp $0, offThread_exception(%eax) # check for exception 13661 movl rFP, offThread_curFrame(%eax) # glue->self->curFrame<- rFP 13662 movl %edx, offThread_jniLocal_topCookie(%eax) # new top <- old top 13663 jne common_exceptionThrown # handle exception 13664 FETCH_INST_OPCODE 3 %edx 13665 ADVANCE_PC 3 13666 GOTO_NEXT_R %edx # jump to next instruction 13667 13668.LstackOverflow: # eax=methodToCall 13669 movl %eax, OUT_ARG1(%esp) # push parameter methodToCall 13670 movl rGLUE,%eax # %eax<- pMterpGlue 13671 movl offGlue_self(%eax), %eax # %eax<- glue->self 13672 movl %eax, OUT_ARG0(%esp) # push parameter self 13673 call dvmHandleStackOverflow # call: (Thread* self, Method* meth) 13674 jmp common_exceptionThrown # handle exception 13675 13676 13677/* 13678 * Do we need the thread to be suspended or have debugger/profiling activity? 13679 * 13680 * On entry: 13681 * ebx -> PC adjustment in 16-bit words (must be preserved) 13682 * ecx -> GLUE pointer 13683 * reentry type, e.g. kInterpEntryInstr stored in rGLUE->entryPoint 13684 * 13685 * Note: A call will normally kill %eax and %ecx. To 13686 * streamline the normal case, this routine will preserve 13687 * %ecx in addition to the normal caller save regs. The save/restore 13688 * is a bit ugly, but will happen in the relatively uncommon path. 13689 * TODO: Basic-block style Jit will need a hook here as well. Fold it into 13690 * the suspendCount check so we can get both in 1 shot. 13691 * TUNING: Improve scheduling here & do initial single test for all. 13692 */ 13693common_periodicChecks: 13694 movl offGlue_pSelfSuspendCount(%ecx),%eax # eax <- &suspendCount 13695 cmpl $0,(%eax) 13696 jne 1f 13697 136986: 13699 movl offGlue_pInterpBreak(%ecx),%eax # eax <- &interpBreak 13700 cmpl $0,(%eax) # something interesting happening? 13701 jne 3f # yes - switch interpreters 13702 ret 13703 13704 /* Check for suspend */ 137051: 13706 /* At this point, the return pointer to the caller of 13707 * common_periodicChecks is on the top of stack. We need to preserve 13708 * GLUE(ecx). 13709 * The outgoing profile is: 13710 * bool dvmCheckSuspendPending(Thread* self) 13711 * Because we reached here via a call, go ahead and build a new frame. 13712 */ 13713 EXPORT_PC # need for precise GC 13714 movl offGlue_self(%ecx),%eax # eax<- glue->self 13715 push %ebp 13716 movl %esp,%ebp 13717 subl $24,%esp 13718 movl %eax,OUT_ARG0(%esp) 13719 call dvmCheckSuspendPending 13720 addl $24,%esp 13721 pop %ebp 13722 movl rGLUE,%ecx 13723 13724 /* 13725 * Need to check to see if debugger or profiler flags got set 13726 * while we were suspended. 13727 */ 13728 jmp 6b 13729 13730 /* Switch interpreters */ 13731 /* Note: %ebx contains the 16-bit word offset to be applied to rPC to 13732 * "complete" the interpretation of backwards branches. In effect, we 13733 * are completing the interpretation of the branch instruction here, 13734 * and the new interpreter will resume interpretation at the branch 13735 * target. However, a switch request recognized during the handling 13736 * of a return from method instruction results in an immediate abort, 13737 * and the new interpreter will resume by re-interpreting the return 13738 * instruction. 13739 */ 137403: 13741 leal (rPC,%ebx,2),rPC # adjust pc to show target 13742 movl rGLUE,%ecx # bail expect GLUE already loaded 13743 movl $1,rINST # set changeInterp to true 13744 jmp common_gotoBail 13745 13746 13747/* 13748 * Common code for handling a return instruction 13749 */ 13750common_returnFromMethod: 13751 movl rGLUE,%ecx 13752 /* Set entry mode in case we bail */ 13753 movb $kInterpEntryReturn,offGlue_entryPoint(%ecx) 13754 xorl rINST,rINST # zero offset in case we switch interps 13755 call common_periodicChecks # Note: expects %ecx to be preserved 13756 13757 SAVEAREA_FROM_FP %eax # eax<- saveArea (old) 13758 movl offStackSaveArea_prevFrame(%eax),rFP # rFP<- prevFrame 13759 movl (offStackSaveArea_method-sizeofStackSaveArea)(rFP),rINST 13760 cmpl $0,rINST # break? 13761 je common_gotoBail # break frame, bail out completely 13762 13763 movl offStackSaveArea_savedPc(%eax),rPC # pc<- saveArea->savedPC 13764 movl offGlue_self(%ecx),%eax # eax<- self 13765 movl rINST,offGlue_method(%ecx) # glue->method = newSave->meethod 13766 movl rFP,offThread_curFrame(%eax) # self->curFrame = fp 13767 movl offMethod_clazz(rINST),%eax # eax<- method->clazz 13768 FETCH_INST_OPCODE 3 %edx 13769 movl offClassObject_pDvmDex(%eax),%eax # eax<- method->clazz->pDvmDex 13770 ADVANCE_PC 3 13771 movl %eax,offGlue_methodClassDex(%ecx) 13772 /* not bailing - restore entry mode to default */ 13773 movb $kInterpEntryInstr,offGlue_entryPoint(%ecx) 13774 GOTO_NEXT_R %edx 13775 13776/* 13777 * Prepare to strip the current frame and "longjump" back to caller of 13778 * dvmMterpStdRun. 13779 * 13780 * on entry: 13781 * rINST holds changeInterp 13782 * ecx holds glue pointer 13783 * 13784 * expected profile: dvmMterpStdBail(MterpGlue *glue, bool changeInterp) 13785 */ 13786common_gotoBail: 13787 movl rPC,offGlue_pc(%ecx) # export state to glue 13788 movl rFP,offGlue_fp(%ecx) 13789 movl %ecx,OUT_ARG0(%esp) # glue in arg0 13790 movl rINST,OUT_ARG1(%esp) # changeInterp in arg1 13791 call dvmMterpStdBail # bail out.... 13792 13793 13794/* 13795 * After returning from a "glued" function, pull out the updated values 13796 * and start executing at the next instruction. 13797 */ 13798 common_resumeAfterGlueCall: 13799 LOAD_PC_FP_FROM_GLUE 13800 FETCH_INST 13801 GOTO_NEXT 13802 13803/* 13804 * Integer divide or mod by zero 13805 */ 13806common_errDivideByZero: 13807 EXPORT_PC 13808 movl $.LstrArithmeticException,%eax 13809 movl %eax,OUT_ARG0(%esp) 13810 movl $.LstrDivideByZero,%eax 13811 movl %eax,OUT_ARG1(%esp) 13812 call dvmThrowException 13813 jmp common_exceptionThrown 13814 13815/* 13816 * Attempt to allocate an array with a negative size. 13817 */ 13818common_errNegativeArraySize: 13819 EXPORT_PC 13820 movl $.LstrNegativeArraySizeException,%eax 13821 movl %eax,OUT_ARG0(%esp) 13822 xorl %eax,%eax 13823 movl %eax,OUT_ARG1(%esp) 13824 call dvmThrowException 13825 jmp common_exceptionThrown 13826 13827/* 13828 * Attempt to allocate an array with a negative size. 13829 */ 13830common_errNoSuchMethod: 13831 13832 EXPORT_PC 13833 movl $.LstrNoSuchMethodError,%eax 13834 movl %eax,OUT_ARG0(%esp) 13835 xorl %eax,%eax 13836 movl %eax,OUT_ARG1(%esp) 13837 call dvmThrowException 13838 jmp common_exceptionThrown 13839 13840/* 13841 * Hit a null object when we weren't expecting one. Export the PC, throw a 13842 * NullPointerException and goto the exception processing code. 13843 */ 13844common_errNullObject: 13845 EXPORT_PC 13846 movl $.LstrNullPointerException,%eax 13847 movl %eax,OUT_ARG0(%esp) 13848 xorl %eax,%eax 13849 movl %eax,OUT_ARG1(%esp) 13850 call dvmThrowException 13851 jmp common_exceptionThrown 13852 13853/* 13854 * Array index exceeds max. 13855 * On entry: 13856 * eax <- array object 13857 * ecx <- index 13858 */ 13859common_errArrayIndex: 13860 EXPORT_PC 13861 movl offArrayObject_length(%eax), %eax 13862 movl %ecx,OUT_ARG0(%esp) 13863 movl %eax,OUT_ARG1(%esp) 13864 call dvmThrowAIOOBE # dvmThrowAIOO(index, length) 13865 jmp common_exceptionThrown 13866 13867/* 13868 * Somebody has thrown an exception. Handle it. 13869 * 13870 * If the exception processing code returns to us (instead of falling 13871 * out of the interpreter), continue with whatever the next instruction 13872 * now happens to be. 13873 * 13874 * This does not return. 13875 */ 13876common_exceptionThrown: 13877 movl rGLUE,%ecx 13878 movl rPC,offGlue_pc(%ecx) 13879 movl rFP,offGlue_fp(%ecx) 13880 movl %ecx,OUT_ARG0(%esp) 13881 call dvmMterp_exceptionThrown 13882 jmp common_resumeAfterGlueCall 13883 13884common_abort: 13885 movl $0xdeadf00d,%eax 13886 call *%eax 13887 13888 13889/* 13890 * Strings 13891 */ 13892 13893 .section .rodata 13894.LstrNullPointerException: 13895 .asciz "Ljava/lang/NullPointerException;" 13896.LstrArithmeticException: 13897 .asciz "Ljava/lang/ArithmeticException;" 13898.LstrDivideByZero: 13899 .asciz "divide by zero" 13900.LstrNegativeArraySizeException: 13901 .asciz "Ljava/lang/NegativeArraySizeException;" 13902.LstrInstantiationError: 13903 .asciz "Ljava/lang/InstantiationError;" 13904.LstrNoSuchMethodError: 13905 .asciz "Ljava/lang/NoSuchMethodError;" 13906.LstrInternalErrorA: 13907 .asciz "Ljava/lang/InternalError;" 13908.LstrFilledNewArrayNotImplA: 13909 .asciz "filled-new-array only implemented for 'int'" 13910 13911