Home | History | Annotate | Download | only in out
      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 /*
     28 386 ABI general notes:
     29 
     30 Caller save set:
     31    eax, edx, ecx, st(0)-st(7)
     32 Callee save set:
     33    ebx, esi, edi, ebp
     34 Return 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 
     39 Parameters passed on stack, pushed right-to-left.  On entry to target, first
     40 parm is at 4(%esp).  Traditional entry code is:
     41 
     42 functEntry:
     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 
     47 Once past the prologue, arguments are referenced at ((argno + 2)*4)(%ebp)
     48 
     49 Stack must be 16-byte aligned to support SSE in native code.
     50 
     51 If we're not doing variable stack allocation (alloca), the frame pointer can be
     52 eliminated and all arg references adjusted to be esp relative.
     53 
     54 Mterp notes:
     55 
     56 Some key interpreter variables will be assigned to registers.  Note that each
     57 will also have an associated spill location (mostly useful for those assigned
     58 to callee save registers).
     59 
     60   nick     reg   purpose
     61   rPC      esi   interpreted program counter, used for fetching instructions
     62   rFP      edi   interpreted frame pointer, used for accessing locals and args
     63   rINSTw   bx    first 16-bit code of current instruction
     64   rINSTbl  bl    opcode portion of instruction word
     65   rINSTbh  bh    high byte of inst word, usually contains src/tgt reg names
     66   rIBASE   edx   base of instruction handler table
     67 
     68 Notes:
     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 and ecx are scratch, rINSTw/ebx sometimes scratch
     72 
     73 */
     74 
     75 #define rSELF    8(%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 #define rIBASE   %edx
     83 
     84 
     85 /* Frame diagram while executing dvmMterpStdRun, high to low addresses */
     86 #define IN_ARG0        (  8)
     87 #define CALLER_RP      (  4)
     88 #define PREV_FP        (  0)
     89 /* Spill offsets relative to %ebp */
     90 #define EDI_SPILL      ( -4)
     91 #define ESI_SPILL      ( -8)
     92 #define EBX_SPILL      (-12)
     93 #define rPC_SPILL      (-16)
     94 #define rFP_SPILL      (-20)
     95 #define rINST_SPILL    (-24)
     96 #define rIBASE_SPILL   (-28)
     97 #define TMP_SPILL1     (-32)
     98 #define TMP_SPILL2     (-36)
     99 #define TMP_SPILL3     (-20)
    100 #define LOCAL0_OFFSET  (-44)
    101 #define LOCAL1_OFFSET  (-48)
    102 #define LOCAL2_OFFSET  (-52)
    103 /* Out Arg offsets, relative to %esp */
    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 #if defined(WITH_JIT)
    110 /* for spill region: increase size by 48 (to keep 16-byte alignment) */
    111 /* 76 + 48 = 124 */
    112 #define JIT_SPILL      (-56)
    113 #define FRAME_SIZE     124
    114 #else
    115 #define FRAME_SIZE     76
    116 #endif
    117 
    118 #define SPILL(reg) movl reg##,reg##_SPILL(%ebp)
    119 #define UNSPILL(reg) movl reg##_SPILL(%ebp),reg
    120 #define SPILL_TMP1(reg) movl reg,TMP_SPILL1(%ebp)
    121 #define UNSPILL_TMP1(reg) movl TMP_SPILL1(%ebp),reg
    122 #define SPILL_TMP2(reg) movl reg,TMP_SPILL2(%ebp)
    123 #define UNSPILL_TMP2(reg) movl TMP_SPILL2(%ebp),reg
    124 #define SPILL_TMP3(reg) movl reg,TMP_SPILL3(%ebp)
    125 #define UNSPILL_TMP3(reg) movl TMP_SPILL3(%ebp),reg
    126 
    127 #if defined(WITH_JIT)
    128 .macro GET_JIT_PROF_TABLE _self _reg
    129     movl    offThread_pJitProfTable(\_self),\_reg
    130 .endm
    131 .macro GET_JIT_THRESHOLD _self _reg
    132     movl    offThread_jitThreshold(\_self),\_reg
    133 .endm
    134 #endif
    135 
    136 /* save/restore the PC and/or FP from the self struct */
    137 .macro SAVE_PC_FP_TO_SELF _reg
    138     movl     rSELF,\_reg
    139     movl     rPC,offThread_pc(\_reg)
    140     movl     rFP,offThread_curFrame(\_reg)
    141 .endm
    142 
    143 .macro LOAD_PC_FP_FROM_SELF
    144     movl    rSELF,rFP
    145     movl    offThread_pc(rFP),rPC
    146     movl    offThread_curFrame(rFP),rFP
    147 .endm
    148 
    149 /* The interpreter assumes a properly aligned stack on entry, and
    150  * will preserve 16-byte alignment.
    151  */
    152 
    153 /*
    154  * "export" the PC to the interpreted stack frame, f/b/o future exception
    155  * objects.  Must be done *before* something throws.
    156  *
    157  * In C this is "SAVEAREA_FROM_FP(fp)->xtra.currentPc = pc", i.e.
    158  * fp - sizeof(StackSaveArea) + offsetof(SaveArea, xtra.currentPc)
    159  *
    160  * It's okay to do this more than once.
    161  */
    162 .macro EXPORT_PC
    163     movl     rPC, (-sizeofStackSaveArea + offStackSaveArea_currentPc)(rFP)
    164 .endm
    165 
    166 .macro GET_PC
    167     movl     (-sizeofStackSaveArea + offStackSaveArea_currentPc)(rFP), rPC
    168 .endm
    169 
    170 /*
    171  * Given a frame pointer, find the stack save area.
    172  *
    173  * In C this is "((StackSaveArea*)(_fp) -1)".
    174  */
    175 .macro SAVEAREA_FROM_FP _reg
    176     leal    -sizeofStackSaveArea(rFP), \_reg
    177 .endm
    178 
    179 /*
    180  * Fetch the next instruction from rPC into rINSTw.  Does not advance rPC.
    181  */
    182 .macro FETCH_INST
    183     movzwl    (rPC),rINST
    184 .endm
    185 
    186 /*
    187  * Fetch the opcode byte and zero-extend it into _reg.  Must be used
    188  * in conjunction with GOTO_NEXT_R
    189  */
    190 .macro FETCH_INST_R _reg
    191     movzbl    (rPC),\_reg
    192 .endm
    193 
    194 /*
    195  * Fetch the opcode byte at _count words offset from rPC and zero-extend
    196  * it into _reg.  Must be used in conjunction with GOTO_NEXT_R
    197  */
    198 .macro FETCH_INST_OPCODE _count _reg
    199     movzbl  \_count*2(rPC),\_reg
    200 .endm
    201 
    202 /*
    203  * Fetch the nth instruction word from rPC into rINSTw.  Does not advance
    204  * rPC, and _count is in words
    205  */
    206 .macro FETCH_INST_WORD _count
    207     movzwl  \_count*2(rPC),rINST
    208 .endm
    209 
    210 /*
    211  * Fetch instruction word indexed (used for branching).
    212  * Index is in instruction word units.
    213  */
    214 .macro FETCH_INST_INDEXED _reg
    215     movzwl  (rPC,\_reg,2),rINST
    216 .endm
    217 
    218 /*
    219  * Advance rPC by instruction count
    220  */
    221 .macro ADVANCE_PC _count
    222     leal  2*\_count(rPC),rPC
    223 .endm
    224 
    225 /*
    226  * Advance rPC by branch offset in register
    227  */
    228 .macro ADVANCE_PC_INDEXED _reg
    229     leal (rPC,\_reg,2),rPC
    230 .endm
    231 
    232 .macro GOTO_NEXT
    233      movzx   rINSTbl,%eax
    234      movzbl  rINSTbh,rINST
    235      jmp     *(rIBASE,%eax,4)
    236 .endm
    237 
    238    /*
    239     * Version of GOTO_NEXT that assumes _reg preloaded with opcode.
    240     * Should be paired with FETCH_INST_R
    241     */
    242 .macro GOTO_NEXT_R _reg
    243      movzbl  1(rPC),rINST
    244      jmp     *(rIBASE,\_reg,4)
    245 .endm
    246 
    247 /*
    248  * Get/set the 32-bit value from a Dalvik register.
    249  */
    250 .macro GET_VREG_R _reg _vreg
    251     movl     (rFP,\_vreg,4),\_reg
    252 .endm
    253 
    254 .macro SET_VREG _reg _vreg
    255     movl     \_reg,(rFP,\_vreg,4)
    256 .endm
    257 
    258 .macro GET_VREG_WORD _reg _vreg _offset
    259     movl     4*(\_offset)(rFP,\_vreg,4),\_reg
    260 .endm
    261 
    262 .macro SET_VREG_WORD _reg _vreg _offset
    263     movl     \_reg,4*(\_offset)(rFP,\_vreg,4)
    264 .endm
    265 
    266 #define sReg0 LOCAL0_OFFSET(%ebp)
    267 #define sReg1 LOCAL1_OFFSET(%ebp)
    268 #define sReg2 LOCAL2_OFFSET(%ebp)
    269 
    270    /*
    271     * x86 JIT Helpers
    272     */
    273 
    274     .macro dumpSwitch _regData _regScratch1 _regScratch2
    275     .endm
    276 
    277    /*
    278     * Hard coded helper values.
    279     */
    280 
    281 .balign 16
    282 
    283 .LdoubNeg:
    284     .quad       0x8000000000000000
    285 
    286 .L64bits:
    287     .quad       0xFFFFFFFFFFFFFFFF
    288 
    289 .LshiftMask2:
    290     .quad       0x0000000000000000
    291 .LshiftMask:
    292     .quad       0x000000000000003F
    293 
    294 .Lvalue64:
    295     .quad       0x0000000000000040
    296 
    297 .LvaluePosInfLong:
    298     .quad       0x7FFFFFFFFFFFFFFF
    299 
    300 .LvalueNegInfLong:
    301     .quad       0x8000000000000000
    302 
    303 .LvalueNanLong:
    304     .quad       0x0000000000000000
    305 
    306 .LintMin:
    307 .long   0x80000000
    308 
    309 .LintMax:
    310 .long   0x7FFFFFFF
    311 
    312 
    313 /*
    314  * This is a #include, not a %include, because we want the C pre-processor
    315  * to expand the macros into assembler assignment statements.
    316  */
    317 #include "../common/asm-constants.h"
    318 
    319 #if defined(WITH_JIT)
    320 #include "../common/jit-config.h"
    321 #endif
    322 
    323 
    324     .global dvmAsmInstructionStartCode
    325     .type   dvmAsmInstructionStartCode, %function
    326 dvmAsmInstructionStartCode = .L_OP_NOP
    327     .text
    328 
    329 /* ------------------------------ */
    330 .L_OP_NOP: /* 0x00 */
    331 /* File: x86/OP_NOP.S */
    332     FETCH_INST_OPCODE 1 %ecx
    333     ADVANCE_PC 1
    334     GOTO_NEXT_R %ecx
    335 
    336 /* ------------------------------ */
    337 .L_OP_MOVE: /* 0x01 */
    338 /* File: x86/OP_MOVE.S */
    339     /* for move, move-object, long-to-int */
    340     /* op vA, vB */
    341     movzbl rINSTbl,%eax          # eax<- BA
    342     andb   $0xf,%al             # eax<- A
    343     shrl   $4,rINST            # rINST<- B
    344     GET_VREG_R rINST rINST
    345     FETCH_INST_OPCODE 1 %ecx
    346     ADVANCE_PC 1
    347     SET_VREG rINST %eax           # fp[A]<-fp[B]
    348     GOTO_NEXT_R %ecx
    349 
    350 /* ------------------------------ */
    351 .L_OP_MOVE_FROM16: /* 0x02 */
    352 /* File: x86/OP_MOVE_FROM16.S */
    353     /* for: move/from16, move-object/from16 */
    354     /* op vAA, vBBBB */
    355     movzx    rINSTbl,%eax              # eax <= AA
    356     movw     2(rPC),rINSTw             # rINSTw <= BBBB
    357     GET_VREG_R rINST rINST             # rINST- fp[BBBB]
    358     FETCH_INST_OPCODE 2 %ecx
    359     ADVANCE_PC 2
    360     SET_VREG rINST %eax                # fp[AA]<- ecx]
    361     GOTO_NEXT_R %ecx
    362 
    363 /* ------------------------------ */
    364 .L_OP_MOVE_16: /* 0x03 */
    365 /* File: x86/OP_MOVE_16.S */
    366     /* for: move/16, move-object/16 */
    367     /* op vAAAA, vBBBB */
    368     movzwl    4(rPC),%ecx              # ecx<- BBBB
    369     movzwl    2(rPC),%eax              # eax<- AAAA
    370     GET_VREG_R  rINST %ecx
    371     FETCH_INST_OPCODE 3 %ecx
    372     ADVANCE_PC 3
    373     SET_VREG  rINST %eax
    374     GOTO_NEXT_R %ecx
    375 
    376 /* ------------------------------ */
    377 .L_OP_MOVE_WIDE: /* 0x04 */
    378 /* File: x86/OP_MOVE_WIDE.S */
    379     /* move-wide vA, vB */
    380     /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
    381     movzbl    rINSTbl,%ecx                # ecx <- BA
    382     sarl      $4,rINST                   # rINST<- B
    383     GET_VREG_WORD %eax rINST 0            # eax<- v[B+0]
    384     GET_VREG_WORD rINST rINST 1           # rINST<- v[B+1]
    385     andb      $0xf,%cl                   # ecx <- A
    386     SET_VREG_WORD rINST %ecx 1            # v[A+1]<- rINST
    387     SET_VREG_WORD %eax %ecx 0             # v[A+0]<- eax
    388     FETCH_INST_OPCODE 1 %ecx
    389     ADVANCE_PC 1
    390     GOTO_NEXT_R %ecx
    391 
    392 /* ------------------------------ */
    393 .L_OP_MOVE_WIDE_FROM16: /* 0x05 */
    394 /* File: x86/OP_MOVE_WIDE_FROM16.S */
    395     /* move-wide/from16 vAA, vBBBB */
    396     /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
    397     movzwl    2(rPC),%ecx              # ecx<- BBBB
    398     movzbl    rINSTbl,%eax             # eax<- AAAA
    399     GET_VREG_WORD rINST %ecx 0         # rINST<- v[BBBB+0]
    400     GET_VREG_WORD %ecx %ecx 1          # ecx<- v[BBBB+1]
    401     SET_VREG_WORD rINST %eax 0         # v[AAAA+0]<- rINST
    402     SET_VREG_WORD %ecx %eax 1          # v[AAAA+1]<- eax
    403     FETCH_INST_OPCODE 2 %ecx
    404     ADVANCE_PC 2
    405     GOTO_NEXT_R %ecx
    406 
    407 /* ------------------------------ */
    408 .L_OP_MOVE_WIDE_16: /* 0x06 */
    409 /* File: x86/OP_MOVE_WIDE_16.S */
    410     /* move-wide/16 vAAAA, vBBBB */
    411     /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
    412     movzwl    4(rPC),%ecx            # ecx<- BBBB
    413     movzwl    2(rPC),%eax            # eax<- AAAA
    414     GET_VREG_WORD rINST %ecx 0       # rINSTw_WORD<- v[BBBB+0]
    415     GET_VREG_WORD %ecx %ecx 1        # ecx<- v[BBBB+1]
    416     SET_VREG_WORD rINST %eax 0       # v[AAAA+0]<- rINST
    417     SET_VREG_WORD %ecx %eax 1        # v[AAAA+1]<- ecx
    418     FETCH_INST_OPCODE 3 %ecx
    419     ADVANCE_PC 3
    420     GOTO_NEXT_R %ecx
    421 
    422 /* ------------------------------ */
    423 .L_OP_MOVE_OBJECT: /* 0x07 */
    424 /* File: x86/OP_MOVE_OBJECT.S */
    425 /* File: x86/OP_MOVE.S */
    426     /* for move, move-object, long-to-int */
    427     /* op vA, vB */
    428     movzbl rINSTbl,%eax          # eax<- BA
    429     andb   $0xf,%al             # eax<- A
    430     shrl   $4,rINST            # rINST<- B
    431     GET_VREG_R rINST rINST
    432     FETCH_INST_OPCODE 1 %ecx
    433     ADVANCE_PC 1
    434     SET_VREG rINST %eax           # fp[A]<-fp[B]
    435     GOTO_NEXT_R %ecx
    436 
    437 
    438 /* ------------------------------ */
    439 .L_OP_MOVE_OBJECT_FROM16: /* 0x08 */
    440 /* File: x86/OP_MOVE_OBJECT_FROM16.S */
    441 /* File: x86/OP_MOVE_FROM16.S */
    442     /* for: move/from16, move-object/from16 */
    443     /* op vAA, vBBBB */
    444     movzx    rINSTbl,%eax              # eax <= AA
    445     movw     2(rPC),rINSTw             # rINSTw <= BBBB
    446     GET_VREG_R rINST rINST             # rINST- fp[BBBB]
    447     FETCH_INST_OPCODE 2 %ecx
    448     ADVANCE_PC 2
    449     SET_VREG rINST %eax                # fp[AA]<- ecx]
    450     GOTO_NEXT_R %ecx
    451 
    452 
    453 /* ------------------------------ */
    454 .L_OP_MOVE_OBJECT_16: /* 0x09 */
    455 /* File: x86/OP_MOVE_OBJECT_16.S */
    456 /* File: x86/OP_MOVE_16.S */
    457     /* for: move/16, move-object/16 */
    458     /* op vAAAA, vBBBB */
    459     movzwl    4(rPC),%ecx              # ecx<- BBBB
    460     movzwl    2(rPC),%eax              # eax<- AAAA
    461     GET_VREG_R  rINST %ecx
    462     FETCH_INST_OPCODE 3 %ecx
    463     ADVANCE_PC 3
    464     SET_VREG  rINST %eax
    465     GOTO_NEXT_R %ecx
    466 
    467 
    468 /* ------------------------------ */
    469 .L_OP_MOVE_RESULT: /* 0x0a */
    470 /* File: x86/OP_MOVE_RESULT.S */
    471     /* for: move-result, move-result-object */
    472     /* op vAA */
    473     movl     rSELF,%eax                    # eax<- rSELF
    474     movl     offThread_retval(%eax),%eax   # eax<- self->retval.l
    475     FETCH_INST_OPCODE 1 %ecx
    476     ADVANCE_PC 1
    477     SET_VREG  %eax rINST                   # fp[AA]<- retval.l
    478     GOTO_NEXT_R %ecx
    479 
    480 /* ------------------------------ */
    481 .L_OP_MOVE_RESULT_WIDE: /* 0x0b */
    482 /* File: x86/OP_MOVE_RESULT_WIDE.S */
    483     /* move-result-wide vAA */
    484     movl    rSELF,%ecx
    485     movl    offThread_retval(%ecx),%eax
    486     movl    4+offThread_retval(%ecx),%ecx
    487     SET_VREG_WORD %eax rINST 0     # v[AA+0] <- eax
    488     SET_VREG_WORD %ecx rINST 1     # v[AA+1] <- ecx
    489     FETCH_INST_OPCODE 1 %ecx
    490     ADVANCE_PC 1
    491     GOTO_NEXT_R %ecx
    492 
    493 /* ------------------------------ */
    494 .L_OP_MOVE_RESULT_OBJECT: /* 0x0c */
    495 /* File: x86/OP_MOVE_RESULT_OBJECT.S */
    496 /* File: x86/OP_MOVE_RESULT.S */
    497     /* for: move-result, move-result-object */
    498     /* op vAA */
    499     movl     rSELF,%eax                    # eax<- rSELF
    500     movl     offThread_retval(%eax),%eax   # eax<- self->retval.l
    501     FETCH_INST_OPCODE 1 %ecx
    502     ADVANCE_PC 1
    503     SET_VREG  %eax rINST                   # fp[AA]<- retval.l
    504     GOTO_NEXT_R %ecx
    505 
    506 
    507 /* ------------------------------ */
    508 .L_OP_MOVE_EXCEPTION: /* 0x0d */
    509 /* File: x86/OP_MOVE_EXCEPTION.S */
    510     /* move-exception vAA */
    511     movl    rSELF,%ecx
    512     movl    offThread_exception(%ecx),%eax # eax<- dvmGetException bypass
    513     SET_VREG %eax rINST                # fp[AA]<- exception object
    514     FETCH_INST_OPCODE 1 %eax
    515     ADVANCE_PC 1
    516     movl    $0,offThread_exception(%ecx) # dvmClearException bypass
    517     GOTO_NEXT_R %eax
    518 
    519 /* ------------------------------ */
    520 .L_OP_RETURN_VOID: /* 0x0e */
    521 /* File: x86/OP_RETURN_VOID.S */
    522     jmp       common_returnFromMethod
    523 
    524 /* ------------------------------ */
    525 .L_OP_RETURN: /* 0x0f */
    526 /* File: x86/OP_RETURN.S */
    527     /*
    528      * Return a 32-bit value.  Copies the return value into the "self"
    529      * structure, then jumps to the return handler.
    530      *
    531      * for: return, return-object
    532      */
    533     /* op vAA */
    534     movl    rSELF,%ecx
    535     GET_VREG_R %eax rINST               # eax<- vAA
    536     movl    %eax,offThread_retval(%ecx)   # retval.i <- AA
    537     jmp     common_returnFromMethod
    538 
    539 /* ------------------------------ */
    540 .L_OP_RETURN_WIDE: /* 0x10 */
    541 /* File: x86/OP_RETURN_WIDE.S */
    542     /*
    543      * Return a 64-bit value.  Copies the return value into the "self"
    544      * structure, then jumps to the return handler.
    545      */
    546     /* return-wide vAA */
    547     movl    rSELF,%ecx
    548     GET_VREG_WORD %eax rINST 0       # eax<- v[AA+0]
    549     GET_VREG_WORD rINST rINST 1      # rINST<- v[AA+1]
    550     movl    %eax,offThread_retval(%ecx)
    551     movl    rINST,4+offThread_retval(%ecx)
    552     jmp     common_returnFromMethod
    553 
    554 /* ------------------------------ */
    555 .L_OP_RETURN_OBJECT: /* 0x11 */
    556 /* File: x86/OP_RETURN_OBJECT.S */
    557 /* File: x86/OP_RETURN.S */
    558     /*
    559      * Return a 32-bit value.  Copies the return value into the "self"
    560      * structure, then jumps to the return handler.
    561      *
    562      * for: return, return-object
    563      */
    564     /* op vAA */
    565     movl    rSELF,%ecx
    566     GET_VREG_R %eax rINST               # eax<- vAA
    567     movl    %eax,offThread_retval(%ecx)   # retval.i <- AA
    568     jmp     common_returnFromMethod
    569 
    570 
    571 /* ------------------------------ */
    572 .L_OP_CONST_4: /* 0x12 */
    573 /* File: x86/OP_CONST_4.S */
    574     /* const/4 vA, #+B */
    575     movsx   rINSTbl,%eax              # eax<-ssssssBx
    576     movl    $0xf,rINST
    577     andl    %eax,rINST                # rINST<- A
    578     FETCH_INST_OPCODE 1 %ecx
    579     ADVANCE_PC 1
    580     sarl    $4,%eax
    581     SET_VREG %eax rINST
    582     GOTO_NEXT_R %ecx
    583 
    584 /* ------------------------------ */
    585 .L_OP_CONST_16: /* 0x13 */
    586 /* File: x86/OP_CONST_16.S */
    587     /* const/16 vAA, #+BBBB */
    588     movswl  2(rPC),%ecx                # ecx<- ssssBBBB
    589     FETCH_INST_OPCODE 2 %eax
    590     ADVANCE_PC 2
    591     SET_VREG %ecx rINST                # vAA<- ssssBBBB
    592     GOTO_NEXT_R %eax
    593 
    594 /* ------------------------------ */
    595 .L_OP_CONST: /* 0x14 */
    596 /* File: x86/OP_CONST.S */
    597     /* const vAA, #+BBBBbbbb */
    598     movl      2(rPC),%eax             # grab all 32 bits at once
    599     movl      rINST,rINST             # rINST<- AA
    600     FETCH_INST_OPCODE 3 %ecx
    601     ADVANCE_PC 3
    602     SET_VREG %eax rINST               # vAA<- eax
    603     GOTO_NEXT_R %ecx
    604 
    605 /* ------------------------------ */
    606 .L_OP_CONST_HIGH16: /* 0x15 */
    607 /* File: x86/OP_CONST_HIGH16.S */
    608     /* const/high16 vAA, #+BBBB0000 */
    609     movzwl     2(rPC),%eax                # eax<- 0000BBBB
    610     FETCH_INST_OPCODE 2 %ecx
    611     ADVANCE_PC 2
    612     sall       $16,%eax                  # eax<- BBBB0000
    613     SET_VREG %eax rINST                   # vAA<- eax
    614     GOTO_NEXT_R %ecx
    615 
    616 /* ------------------------------ */
    617 .L_OP_CONST_WIDE_16: /* 0x16 */
    618 /* File: x86/OP_CONST_WIDE_16.S */
    619     /* const-wide/16 vAA, #+BBBB */
    620     movswl    2(rPC),%eax               # eax<- ssssBBBB
    621     SPILL(rIBASE)                       # preserve rIBASE (cltd trashes it)
    622     cltd                                # rIBASE:eax<- ssssssssssssBBBB
    623     SET_VREG_WORD rIBASE rINST 1        # store msw
    624     FETCH_INST_OPCODE 2 %ecx
    625     UNSPILL(rIBASE)                     # restore rIBASE
    626     SET_VREG_WORD %eax rINST 0          # store lsw
    627     ADVANCE_PC 2
    628     GOTO_NEXT_R %ecx
    629 
    630 /* ------------------------------ */
    631 .L_OP_CONST_WIDE_32: /* 0x17 */
    632 /* File: x86/OP_CONST_WIDE_32.S */
    633     /* const-wide/32 vAA, #+BBBBbbbb */
    634     movl     2(rPC),%eax                # eax<- BBBBbbbb
    635     SPILL(rIBASE)                       # save rIBASE (cltd trashes it)
    636     cltd                                # rIBASE:eax<- ssssssssssssBBBB
    637     SET_VREG_WORD rIBASE rINST,1        # store msw
    638     FETCH_INST_OPCODE 3 %ecx
    639     UNSPILL(rIBASE)                     # restore rIBASE
    640     SET_VREG_WORD %eax rINST 0          # store lsw
    641     ADVANCE_PC 3
    642     GOTO_NEXT_R %ecx
    643 
    644 /* ------------------------------ */
    645 .L_OP_CONST_WIDE: /* 0x18 */
    646 /* File: x86/OP_CONST_WIDE.S */
    647     /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
    648     movl      2(rPC),%eax         # eax<- lsw
    649     movzbl    rINSTbl,%ecx        # ecx<- AA
    650     movl      6(rPC),rINST        # rINST<- msw
    651     leal      (rFP,%ecx,4),%ecx   # dst addr
    652     movl      rINST,4(%ecx)
    653     movl      %eax,(%ecx)
    654     FETCH_INST_OPCODE 5 %ecx
    655     ADVANCE_PC 5
    656     GOTO_NEXT_R %ecx
    657 
    658 /* ------------------------------ */
    659 .L_OP_CONST_WIDE_HIGH16: /* 0x19 */
    660 /* File: x86/OP_CONST_WIDE_HIGH16.S */
    661     /* const-wide/high16 vAA, #+BBBB000000000000 */
    662     movzwl     2(rPC),%eax                # eax<- 0000BBBB
    663     FETCH_INST_OPCODE 2 %ecx
    664     ADVANCE_PC 2
    665     sall       $16,%eax                  # eax<- BBBB0000
    666     SET_VREG_WORD %eax rINST 1            # v[AA+1]<- eax
    667     xorl       %eax,%eax
    668     SET_VREG_WORD %eax rINST 0            # v[AA+0]<- eax
    669     GOTO_NEXT_R %ecx
    670 
    671 /* ------------------------------ */
    672 .L_OP_CONST_STRING: /* 0x1a */
    673 /* File: x86/OP_CONST_STRING.S */
    674 
    675     /* const/string vAA, String@BBBB */
    676     movl      rSELF,%ecx
    677     movzwl    2(rPC),%eax              # eax<- BBBB
    678     movl      offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex
    679     movl      offDvmDex_pResStrings(%ecx),%ecx # ecx<- dvmDex->pResStrings
    680     movl      (%ecx,%eax,4),%eax       # eax<- rResString[BBBB]
    681     FETCH_INST_OPCODE 2 %ecx
    682     testl     %eax,%eax                # resolved yet?
    683     je        .LOP_CONST_STRING_resolve
    684     SET_VREG  %eax rINST               # vAA<- rResString[BBBB]
    685     ADVANCE_PC 2
    686     GOTO_NEXT_R %ecx
    687 
    688 /* This is the less common path, so we'll redo some work
    689    here rather than force spills on the common path */
    690 .LOP_CONST_STRING_resolve:
    691     movl     rSELF,%eax
    692     EXPORT_PC
    693     movl     offThread_method(%eax),%eax # eax<- self->method
    694     movzwl   2(rPC),%ecx               # ecx<- BBBB
    695     movl     offMethod_clazz(%eax),%eax
    696     movl     %ecx,OUT_ARG1(%esp)
    697     movl     %eax,OUT_ARG0(%esp)
    698     SPILL(rIBASE)
    699     call     dvmResolveString          # go resolve
    700     UNSPILL(rIBASE)
    701     testl    %eax,%eax                 # failed?
    702     je       common_exceptionThrown
    703     FETCH_INST_OPCODE 2 %ecx
    704     SET_VREG %eax rINST
    705     ADVANCE_PC 2
    706     GOTO_NEXT_R %ecx
    707 
    708 /* ------------------------------ */
    709 .L_OP_CONST_STRING_JUMBO: /* 0x1b */
    710 /* File: x86/OP_CONST_STRING_JUMBO.S */
    711 
    712     /* const/string vAA, String@BBBBBBBB */
    713     movl      rSELF,%ecx
    714     movl      2(rPC),%eax              # eax<- BBBBBBBB
    715     movl      offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex
    716     movl      offDvmDex_pResStrings(%ecx),%ecx # ecx<- dvmDex->pResStrings
    717     movl      (%ecx,%eax,4),%eax       # eax<- rResString[BBBB]
    718     FETCH_INST_OPCODE 3 %ecx
    719     testl     %eax,%eax                # resolved yet?
    720     je        .LOP_CONST_STRING_JUMBO_resolve
    721     SET_VREG  %eax rINST               # vAA<- rResString[BBBB]
    722     ADVANCE_PC 3
    723     GOTO_NEXT_R %ecx
    724 
    725 /* This is the less common path, so we'll redo some work
    726    here rather than force spills on the common path */
    727 .LOP_CONST_STRING_JUMBO_resolve:
    728     movl     rSELF,%eax
    729     EXPORT_PC
    730     movl     offThread_method(%eax),%eax # eax<- self->method
    731     movl     2(rPC),%ecx               # ecx<- BBBBBBBB
    732     movl     offMethod_clazz(%eax),%eax
    733     movl     %ecx,OUT_ARG1(%esp)
    734     movl     %eax,OUT_ARG0(%esp)
    735     SPILL(rIBASE)
    736     call     dvmResolveString          # go resolve
    737     UNSPILL(rIBASE)
    738     testl    %eax,%eax                 # failed?
    739     je       common_exceptionThrown
    740     FETCH_INST_OPCODE 3 %ecx
    741     SET_VREG %eax rINST
    742     ADVANCE_PC 3
    743     GOTO_NEXT_R %ecx
    744 
    745 /* ------------------------------ */
    746 .L_OP_CONST_CLASS: /* 0x1c */
    747 /* File: x86/OP_CONST_CLASS.S */
    748 
    749     /* const/class vAA, Class@BBBB */
    750     movl      rSELF,%ecx
    751     movzwl    2(rPC),%eax              # eax<- BBBB
    752     movl      offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex
    753     movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- dvmDex->pResClasses
    754     movl      (%ecx,%eax,4),%eax       # eax<- rResClasses[BBBB]
    755     testl     %eax,%eax                # resolved yet?
    756     je        .LOP_CONST_CLASS_resolve
    757     FETCH_INST_OPCODE 2 %ecx
    758     SET_VREG  %eax rINST               # vAA<- rResClasses[BBBB]
    759     ADVANCE_PC 2
    760     GOTO_NEXT_R %ecx
    761 
    762 /* This is the less common path, so we'll redo some work
    763    here rather than force spills on the common path */
    764 .LOP_CONST_CLASS_resolve:
    765     movl     rSELF,%eax
    766     EXPORT_PC
    767     movl     offThread_method(%eax),%eax # eax<- self->method
    768     movl     $1,OUT_ARG2(%esp)        # true
    769     movzwl   2(rPC),%ecx               # ecx<- BBBB
    770     movl     offMethod_clazz(%eax),%eax
    771     movl     %ecx,OUT_ARG1(%esp)
    772     movl     %eax,OUT_ARG0(%esp)
    773     SPILL(rIBASE)
    774     call     dvmResolveClass           # go resolve
    775     UNSPILL(rIBASE)
    776     testl    %eax,%eax                 # failed?
    777     je       common_exceptionThrown
    778     FETCH_INST_OPCODE 2 %ecx
    779     SET_VREG %eax rINST
    780     ADVANCE_PC 2
    781     GOTO_NEXT_R %ecx
    782 
    783 /* ------------------------------ */
    784 .L_OP_MONITOR_ENTER: /* 0x1d */
    785 /* File: x86/OP_MONITOR_ENTER.S */
    786     /*
    787      * Synchronize on an object.
    788      */
    789     /* monitor-enter vAA */
    790     movl    rSELF,%ecx
    791     GET_VREG_R %eax rINST               # eax<- vAA
    792     FETCH_INST_WORD 1
    793     testl   %eax,%eax                   # null object?
    794     EXPORT_PC                           # need for precise GC
    795     je     common_errNullObject
    796     movl    %ecx,OUT_ARG0(%esp)
    797     movl    %eax,OUT_ARG1(%esp)
    798     SPILL(rIBASE)
    799     call    dvmLockObject               # dvmLockObject(self,object)
    800     UNSPILL(rIBASE)
    801     FETCH_INST_OPCODE 1 %ecx
    802     ADVANCE_PC 1
    803     GOTO_NEXT_R %ecx
    804 
    805 /* ------------------------------ */
    806 .L_OP_MONITOR_EXIT: /* 0x1e */
    807 /* File: x86/OP_MONITOR_EXIT.S */
    808     /*
    809      * Unlock an object.
    810      *
    811      * Exceptions that occur when unlocking a monitor need to appear as
    812      * if they happened at the following instruction.  See the Dalvik
    813      * instruction spec.
    814      */
    815     /* monitor-exit vAA */
    816     GET_VREG_R %eax rINST
    817     movl    rSELF,%ecx
    818     EXPORT_PC
    819     testl   %eax,%eax                   # null object?
    820     je      .LOP_MONITOR_EXIT_errNullObject   # go if so
    821     movl    %eax,OUT_ARG1(%esp)
    822     movl    %ecx,OUT_ARG0(%esp)
    823     SPILL(rIBASE)
    824     call    dvmUnlockObject             # unlock(self,obj)
    825     UNSPILL(rIBASE)
    826     FETCH_INST_OPCODE 1 %ecx
    827     testl   %eax,%eax                   # success?
    828     ADVANCE_PC 1
    829     je      common_exceptionThrown      # no, exception pending
    830     GOTO_NEXT_R %ecx
    831 .LOP_MONITOR_EXIT_errNullObject:
    832     ADVANCE_PC 1                        # advance before throw
    833     jmp     common_errNullObject
    834 
    835 /* ------------------------------ */
    836 .L_OP_CHECK_CAST: /* 0x1f */
    837 /* File: x86/OP_CHECK_CAST.S */
    838     /*
    839      * Check to see if a cast from one class to another is allowed.
    840      */
    841     /* check-cast vAA, class@BBBB */
    842     movl      rSELF,%ecx
    843     GET_VREG_R  rINST,rINST             # rINST<- vAA (object)
    844     movzwl    2(rPC),%eax               # eax<- BBBB
    845     movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
    846     testl     rINST,rINST               # is oject null?
    847     movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
    848     je        .LOP_CHECK_CAST_okay          # null obj, cast always succeeds
    849     movl      (%ecx,%eax,4),%eax        # eax<- resolved class
    850     movl      offObject_clazz(rINST),%ecx # ecx<- obj->clazz
    851     testl     %eax,%eax                 # have we resolved this before?
    852     je        .LOP_CHECK_CAST_resolve       # no, go do it now
    853 .LOP_CHECK_CAST_resolved:
    854     cmpl      %eax,%ecx                 # same class (trivial success)?
    855     jne       .LOP_CHECK_CAST_fullcheck     # no, do full check
    856 .LOP_CHECK_CAST_okay:
    857     FETCH_INST_OPCODE 2 %ecx
    858     ADVANCE_PC 2
    859     GOTO_NEXT_R %ecx
    860 
    861     /*
    862      * Trivial test failed, need to perform full check.  This is common.
    863      *  ecx holds obj->clazz
    864      *  eax holds class resolved from BBBB
    865      *  rINST holds object
    866      */
    867 .LOP_CHECK_CAST_fullcheck:
    868     movl    %eax,sReg0                 # we'll need the desired class on failure
    869     movl    %eax,OUT_ARG1(%esp)
    870     movl    %ecx,OUT_ARG0(%esp)
    871     SPILL(rIBASE)
    872     call    dvmInstanceofNonTrivial    # eax<- boolean result
    873     UNSPILL(rIBASE)
    874     testl   %eax,%eax                  # failed?
    875     jne     .LOP_CHECK_CAST_okay           # no, success
    876 
    877     # A cast has failed.  We need to throw a ClassCastException.
    878     EXPORT_PC
    879     movl    offObject_clazz(rINST),%eax
    880     movl    %eax,OUT_ARG0(%esp)                 # arg0<- obj->clazz
    881     movl    sReg0,%ecx
    882     movl    %ecx,OUT_ARG1(%esp)                 # arg1<- desired class
    883     call    dvmThrowClassCastException
    884     jmp     common_exceptionThrown
    885 
    886     /*
    887      * Resolution required.  This is the least-likely path, and we're
    888      * going to have to recreate some data.
    889      *
    890      *  rINST holds object
    891      */
    892 .LOP_CHECK_CAST_resolve:
    893     movl    rSELF,%ecx
    894     EXPORT_PC
    895     movzwl  2(rPC),%eax                # eax<- BBBB
    896     movl    offThread_method(%ecx),%ecx  # ecx<- self->method
    897     movl    %eax,OUT_ARG1(%esp)        # arg1<- BBBB
    898     movl    offMethod_clazz(%ecx),%ecx # ecx<- metho->clazz
    899     movl    $0,OUT_ARG2(%esp)         # arg2<- false
    900     movl    %ecx,OUT_ARG0(%esp)        # arg0<- method->clazz
    901     SPILL(rIBASE)
    902     call    dvmResolveClass            # eax<- resolved ClassObject ptr
    903     UNSPILL(rIBASE)
    904     testl   %eax,%eax                  # got null?
    905     je      common_exceptionThrown     # yes, handle exception
    906     movl    offObject_clazz(rINST),%ecx  # ecx<- obj->clazz
    907     jmp     .LOP_CHECK_CAST_resolved       # pick up where we left off
    908 
    909 /* ------------------------------ */
    910 .L_OP_INSTANCE_OF: /* 0x20 */
    911 /* File: x86/OP_INSTANCE_OF.S */
    912     /*
    913      * Check to see if an object reference is an instance of a class.
    914      *
    915      * Most common situation is a non-null object, being compared against
    916      * an already-resolved class.
    917      */
    918     /* instance-of vA, vB, class@CCCC */
    919     movl    rINST,%eax                  # eax<- BA
    920     sarl    $4,%eax                    # eax<- B
    921     GET_VREG_R %eax %eax                # eax<- vB (obj)
    922     movl    rSELF,%ecx
    923     testl   %eax,%eax                   # object null?
    924     movl    offThread_methodClassDex(%ecx),%ecx  # ecx<- pDvmDex
    925     SPILL(rIBASE)                       # preserve rIBASE
    926     je      .LOP_INSTANCE_OF_store           # null obj, not instance, store it
    927     movzwl  2(rPC),rIBASE               # rIBASE<- CCCC
    928     movl    offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
    929     movl    (%ecx,rIBASE,4),%ecx        # ecx<- resolved class
    930     movl    offObject_clazz(%eax),%eax  # eax<- obj->clazz
    931     testl   %ecx,%ecx                   # have we resolved this before?
    932     je      .LOP_INSTANCE_OF_resolve         # not resolved, do it now
    933 .LOP_INSTANCE_OF_resolved:  # eax<- obj->clazz, ecx<- resolved class
    934     cmpl    %eax,%ecx                   # same class (trivial success)?
    935     je      .LOP_INSTANCE_OF_trivial         # yes, trivial finish
    936     /*
    937      * Trivial test failed, need to perform full check.  This is common.
    938      *  eax holds obj->clazz
    939      *  ecx holds class resolved from BBBB
    940      *  rINST has BA
    941      */
    942     movl    %eax,OUT_ARG0(%esp)
    943     movl    %ecx,OUT_ARG1(%esp)
    944     call    dvmInstanceofNonTrivial     # eax<- boolean result
    945     # fall through to OP_INSTANCE_OF_store
    946 
    947     /*
    948      * eax holds boolean result
    949      * rINST holds BA
    950      */
    951 .LOP_INSTANCE_OF_store:
    952     FETCH_INST_OPCODE 2 %ecx
    953     UNSPILL(rIBASE)
    954     andb    $0xf,rINSTbl               # <- A
    955     ADVANCE_PC 2
    956     SET_VREG %eax rINST                 # vA<- eax
    957     GOTO_NEXT_R %ecx
    958 
    959     /*
    960      * Trivial test succeeded, save and bail.
    961      *  r9 holds A
    962      */
    963 .LOP_INSTANCE_OF_trivial:
    964     FETCH_INST_OPCODE 2 %ecx
    965     UNSPILL(rIBASE)
    966     andb    $0xf,rINSTbl               # <- A
    967     ADVANCE_PC 2
    968     movl    $1,%eax
    969     SET_VREG %eax rINST                 # vA<- true
    970     GOTO_NEXT_R %ecx
    971 
    972     /*
    973      * Resolution required.  This is the least-likely path.
    974      *
    975      *  rIBASE holds BBBB
    976      *  rINST holds BA
    977      */
    978 .LOP_INSTANCE_OF_resolve:
    979     movl    rIBASE,OUT_ARG1(%esp)         # arg1<- BBBB
    980     movl    rSELF,%ecx
    981     movl    offThread_method(%ecx),%ecx
    982     movl    $1,OUT_ARG2(%esp)          # arg2<- true
    983     movl    offMethod_clazz(%ecx),%ecx  # ecx<- method->clazz
    984     EXPORT_PC
    985     movl    %ecx,OUT_ARG0(%esp)         # arg0<- method->clazz
    986     call    dvmResolveClass             # eax<- resolved ClassObject ptr
    987     testl   %eax,%eax                   # success?
    988     je      common_exceptionThrown      # no, handle exception
    989 /* Now, we need to sync up with fast path.  We need eax to
    990  * hold the obj->clazz, and ecx to hold the resolved class
    991  */
    992     movl    %eax,%ecx                   # ecx<- resolved class
    993     movl    rINST,%eax                  # eax<- BA
    994     sarl    $4,%eax                    # eax<- B
    995     GET_VREG_R %eax %eax                # eax<- vB (obj)
    996     movl    offObject_clazz(%eax),%eax  # eax<- obj->clazz
    997     jmp     .LOP_INSTANCE_OF_resolved
    998 
    999 /* ------------------------------ */
   1000 .L_OP_ARRAY_LENGTH: /* 0x21 */
   1001 /* File: x86/OP_ARRAY_LENGTH.S */
   1002     /*
   1003      * Return the length of an array.
   1004      */
   1005    mov      rINST,%eax                # eax<- BA
   1006    sarl     $4,rINST                 # rINST<- B
   1007    GET_VREG_R %ecx rINST              # ecx<- vB (object ref)
   1008    andb     $0xf,%al                 # eax<- A
   1009    testl    %ecx,%ecx                 # is null?
   1010    je       common_errNullObject
   1011    movl     offArrayObject_length(%ecx),rINST
   1012    FETCH_INST_OPCODE 1 %ecx
   1013    ADVANCE_PC 1
   1014    SET_VREG rINST %eax
   1015    GOTO_NEXT_R %ecx
   1016 
   1017 /* ------------------------------ */
   1018 .L_OP_NEW_INSTANCE: /* 0x22 */
   1019 /* File: x86/OP_NEW_INSTANCE.S */
   1020     /*
   1021      * Create a new instance of a class.
   1022      */
   1023     /* new-instance vAA, class@BBBB */
   1024     movl      rSELF,%ecx
   1025     movzwl    2(rPC),%eax               # eax<- BBBB
   1026     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- pDvmDex
   1027     SPILL(rIBASE)
   1028     SPILL_TMP2(%ebx)
   1029     movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
   1030     EXPORT_PC
   1031 #if defined(WITH_JIT)
   1032     lea       (%ecx,%eax,4),%ebx        # ebx <- &resolved class
   1033 #endif
   1034     movl      (%ecx,%eax,4),%ecx        # ecx<- resolved class
   1035     testl     %ecx,%ecx                 # resolved?
   1036     je        .LOP_NEW_INSTANCE_resolve       # no, go do it
   1037 .LOP_NEW_INSTANCE_resolved:  # on entry, ecx<- class
   1038     cmpb      $CLASS_INITIALIZED,offClassObject_status(%ecx)
   1039     jne       .LOP_NEW_INSTANCE_needinit
   1040 .LOP_NEW_INSTANCE_initialized:  # on entry, ecx<- class
   1041     movl      $ALLOC_DONT_TRACK,OUT_ARG1(%esp)
   1042     movl     %ecx,OUT_ARG0(%esp)
   1043     call     dvmAllocObject             # eax<- new object
   1044     testl    %eax,%eax                  # success?
   1045     je       common_exceptionThrown     # no, bail out
   1046 #if defined(WITH_JIT)
   1047         /*
   1048      * The JIT needs the class to be fully resolved before it can
   1049      * include this instruction in a trace.
   1050      */
   1051     movl    rSELF, %ecx
   1052     movl    offThread_subMode(%ecx), %ecx
   1053     andl    $kSubModeJitTraceBuild, %ecx # under construction?
   1054     jne     .LOP_NEW_INSTANCE_jitCheck
   1055 #endif
   1056 .LOP_NEW_INSTANCE_end:
   1057     UNSPILL_TMP2(%ebx)
   1058     SET_VREG %eax rINST
   1059     UNSPILL(rIBASE)
   1060     FETCH_INST_OPCODE 2 %ecx
   1061     ADVANCE_PC 2
   1062     GOTO_NEXT_R %ecx
   1063 
   1064 #if defined(WITH_JIT)
   1065     /*
   1066      * Check to see if we need to stop the trace building early.
   1067      * eax: new object
   1068      */
   1069 .LOP_NEW_INSTANCE_jitCheck:
   1070     cmp     $0, (%ebx)                   # okay?
   1071     jne     .LOP_NEW_INSTANCE_end        # yes, finish
   1072     SPILL_TMP1(%eax)                     # preserve new object
   1073     movl    rSELF, %ecx
   1074     movl    %ecx, OUT_ARG0(%esp)
   1075     movl    rPC, OUT_ARG1(%esp)
   1076     call    dvmJitEndTraceSelect         # (self, pc)
   1077     UNSPILL_TMP1(%eax)
   1078     UNSPILL_TMP2(%ebx)
   1079     SET_VREG %eax rINST                  # vAA <- new object
   1080     UNSPILL(rIBASE)
   1081     FETCH_INST_OPCODE 2 %ecx
   1082     ADVANCE_PC 2
   1083     GOTO_NEXT_R %ecx
   1084 #endif
   1085 
   1086     /*
   1087      * Class initialization required.
   1088      *
   1089      *  ecx holds class object
   1090      */
   1091 .LOP_NEW_INSTANCE_needinit:
   1092     SPILL_TMP1(%ecx)                    # save object
   1093     movl    %ecx,OUT_ARG0(%esp)
   1094     call    dvmInitClass                # initialize class
   1095     UNSPILL_TMP1(%ecx)                  # restore object
   1096     testl   %eax,%eax                   # success?
   1097     jne     .LOP_NEW_INSTANCE_initialized     # success, continue
   1098     jmp     common_exceptionThrown      # go deal with init exception
   1099 
   1100     /*
   1101      * Resolution required.  This is the least-likely path.
   1102      *
   1103      */
   1104 .LOP_NEW_INSTANCE_resolve:
   1105     movl    rSELF,%ecx
   1106     movzwl  2(rPC),%eax
   1107     movl    offThread_method(%ecx),%ecx   # ecx<- self->method
   1108     movl    %eax,OUT_ARG1(%esp)
   1109     movl    offMethod_clazz(%ecx),%ecx  # ecx<- method->clazz
   1110     movl    $0,OUT_ARG2(%esp)
   1111     movl    %ecx,OUT_ARG0(%esp)
   1112     call    dvmResolveClass             # call(clazz,off,flags)
   1113     movl    %eax,%ecx                   # ecx<- resolved ClassObject ptr
   1114     testl   %ecx,%ecx                   # success?
   1115     jne     .LOP_NEW_INSTANCE_resolved        # good to go
   1116     jmp     common_exceptionThrown      # no, handle exception
   1117 
   1118 /* ------------------------------ */
   1119 .L_OP_NEW_ARRAY: /* 0x23 */
   1120 /* File: x86/OP_NEW_ARRAY.S */
   1121     /*
   1122      * Allocate an array of objects, specified with the array class
   1123      * and a count.
   1124      *
   1125      * The verifier guarantees that this is an array class, so we don't
   1126      * check for it here.
   1127      */
   1128     /* new-array vA, vB, class@CCCC */
   1129     movl    rSELF,%ecx
   1130     EXPORT_PC
   1131     movl    offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
   1132     movzwl  2(rPC),%eax                       # eax<- CCCC
   1133     movl    offDvmDex_pResClasses(%ecx),%ecx  # ecx<- pDvmDex->pResClasses
   1134     SPILL(rIBASE)
   1135     movl    (%ecx,%eax,4),%ecx                # ecx<- resolved class
   1136     movzbl  rINSTbl,%eax
   1137     sarl    $4,%eax                          # eax<- B
   1138     GET_VREG_R %eax %eax                      # eax<- vB (array length)
   1139     andb    $0xf,rINSTbl                     # rINST<- A
   1140     testl   %eax,%eax
   1141     js      common_errNegativeArraySize       # bail, passing len in eax
   1142     testl   %ecx,%ecx                         # already resolved?
   1143     jne     .LOP_NEW_ARRAY_finish                # yes, fast path
   1144     /*
   1145      * Resolve class.  (This is an uncommon case.)
   1146      *  ecx holds class (null here)
   1147      *  eax holds array length (vB)
   1148      */
   1149     movl    rSELF,%ecx
   1150     SPILL_TMP1(%eax)                   # save array length
   1151     movl    offThread_method(%ecx),%ecx  # ecx<- self->method
   1152     movzwl  2(rPC),%eax                # eax<- CCCC
   1153     movl    offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
   1154     movl    %eax,OUT_ARG1(%esp)
   1155     movl    $0,OUT_ARG2(%esp)
   1156     movl    %ecx,OUT_ARG0(%esp)
   1157     call    dvmResolveClass            # eax<- call(clazz,ref,flag)
   1158     movl    %eax,%ecx
   1159     UNSPILL_TMP1(%eax)
   1160     testl   %ecx,%ecx                  # successful resolution?
   1161     je      common_exceptionThrown     # no, bail.
   1162 # fall through to OP_NEW_ARRAY_finish
   1163 
   1164     /*
   1165      * Finish allocation
   1166      *
   1167      * ecx holds class
   1168      * eax holds array length (vB)
   1169      */
   1170 .LOP_NEW_ARRAY_finish:
   1171     movl    %ecx,OUT_ARG0(%esp)
   1172     movl    %eax,OUT_ARG1(%esp)
   1173     movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)
   1174     call    dvmAllocArrayByClass    # eax<- call(clazz,length,flags)
   1175     FETCH_INST_OPCODE 2 %ecx
   1176     UNSPILL(rIBASE)
   1177     testl   %eax,%eax               # failed?
   1178     je      common_exceptionThrown  # yup - go handle
   1179     SET_VREG %eax rINST
   1180     ADVANCE_PC 2
   1181     GOTO_NEXT_R %ecx
   1182 
   1183 /* ------------------------------ */
   1184 .L_OP_FILLED_NEW_ARRAY: /* 0x24 */
   1185 /* File: x86/OP_FILLED_NEW_ARRAY.S */
   1186     /*
   1187      * Create a new array with elements filled from registers.
   1188      *
   1189      * for: filled-new-array, filled-new-array/range
   1190      */
   1191     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
   1192     /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
   1193     movl    rSELF,%eax
   1194     movl    offThread_methodClassDex(%eax),%eax # eax<- pDvmDex
   1195     movzwl  2(rPC),%ecx                       # ecx<- BBBB
   1196     movl    offDvmDex_pResClasses(%eax),%eax  # eax<- pDvmDex->pResClasses
   1197     SPILL(rIBASE)                             # preserve rIBASE
   1198     movl    (%eax,%ecx,4),%eax                # eax<- resolved class
   1199     EXPORT_PC
   1200     testl   %eax,%eax                         # already resolved?
   1201     jne     .LOP_FILLED_NEW_ARRAY_continue              # yes, continue
   1202     # less frequent path, so we'll redo some work
   1203     movl    rSELF,%eax
   1204     movl    $0,OUT_ARG2(%esp)                # arg2<- false
   1205     movl    %ecx,OUT_ARG1(%esp)               # arg1<- BBBB
   1206     movl    offThread_method(%eax),%eax         # eax<- self->method
   1207     movl    offMethod_clazz(%eax),%eax        # eax<- method->clazz
   1208     movl    %eax,OUT_ARG0(%esp)               # arg0<- clazz
   1209     call    dvmResolveClass                   # eax<- call(clazz,ref,flag)
   1210     testl   %eax,%eax                         # null?
   1211     je      common_exceptionThrown            # yes, handle it
   1212 
   1213        # note: fall through to .LOP_FILLED_NEW_ARRAY_continue
   1214 
   1215     /*
   1216      * On entry:
   1217      *    eax holds array class [r0]
   1218      *    rINST holds AA or BB [r10]
   1219      *    ecx is scratch
   1220      */
   1221 .LOP_FILLED_NEW_ARRAY_continue:
   1222     movl    offClassObject_descriptor(%eax),%ecx  # ecx<- arrayClass->descriptor
   1223     movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)     # arg2<- flags
   1224     movzbl  1(%ecx),%ecx                          # ecx<- descriptor[1]
   1225     movl    %eax,OUT_ARG0(%esp)                   # arg0<- arrayClass
   1226     movl    rSELF,%eax
   1227     cmpb    $'I',%cl                             # supported?
   1228     je      1f
   1229     cmpb    $'L',%cl
   1230     je      1f
   1231     cmpb    $'[',%cl
   1232     jne      .LOP_FILLED_NEW_ARRAY_notimpl                  # no, not handled yet
   1233 1:
   1234     movl    %ecx,offThread_retval+4(%eax)           # save type
   1235     .if      (!0)
   1236     SPILL_TMP1(rINST)                              # save copy, need "B" later
   1237     sarl    $4,rINST
   1238     .endif
   1239     movl    rINST,OUT_ARG1(%esp)                  # arg1<- A or AA (length)
   1240     call    dvmAllocArrayByClass     # eax<- call(arrayClass, length, flags)
   1241     movl    rSELF,%ecx
   1242     testl   %eax,%eax                             # alloc successful?
   1243     je      common_exceptionThrown                # no, handle exception
   1244     movl    %eax,offThread_retval(%ecx)             # retval.l<- new array
   1245     movzwl  4(rPC),%ecx                           # ecx<- FEDC or CCCC
   1246     leal    offArrayObject_contents(%eax),%eax    # eax<- newArray->contents
   1247 
   1248 /* at this point:
   1249  *     eax is pointer to tgt
   1250  *     rINST is length
   1251  *     ecx is FEDC or CCCC
   1252  *     TMP_SPILL1 is BA
   1253  *  We now need to copy values from registers into the array
   1254  */
   1255 
   1256     .if 0
   1257     # set up src pointer
   1258     SPILL_TMP2(%esi)
   1259     SPILL_TMP3(%edi)
   1260     leal    (rFP,%ecx,4),%esi # set up src ptr
   1261     movl    %eax,%edi         # set up dst ptr
   1262     movl    rINST,%ecx        # load count register
   1263     rep
   1264     movsd
   1265     UNSPILL_TMP2(%esi)
   1266     UNSPILL_TMP3(%edi)
   1267     movl    rSELF,%ecx
   1268     movl    offThread_retval+4(%ecx),%eax      # eax<- type
   1269     .else
   1270     testl  rINST,rINST
   1271     je     4f
   1272     UNSPILL_TMP1(rIBASE)      # restore "BA"
   1273     andl   $0x0f,rIBASE      # rIBASE<- 0000000A
   1274     sall   $16,rIBASE        # rIBASE<- 000A0000
   1275     orl    %ecx,rIBASE        # rIBASE<- 000AFEDC
   1276 3:
   1277     movl   $0xf,%ecx
   1278     andl   rIBASE,%ecx        # ecx<- next reg to load
   1279     GET_VREG_R %ecx %ecx
   1280     shrl   $4,rIBASE
   1281     leal   4(%eax),%eax
   1282     movl   %ecx,-4(%eax)
   1283     sub    $1,rINST
   1284     jne    3b
   1285 4:
   1286     movl   rSELF,%ecx
   1287     movl    offThread_retval+4(%ecx),%eax      # eax<- type
   1288     .endif
   1289 
   1290     cmpb    $'I',%al                        # Int array?
   1291     je      5f                               # skip card mark if so
   1292     movl    offThread_retval(%ecx),%eax        # eax<- object head
   1293     movl    offThread_cardTable(%ecx),%ecx     # card table base
   1294     shrl    $GC_CARD_SHIFT,%eax             # convert to card num
   1295     movb    %cl,(%ecx,%eax)                  # mark card based on object head
   1296 5:
   1297     UNSPILL(rIBASE)                          # restore rIBASE
   1298     FETCH_INST_OPCODE 3 %ecx
   1299     ADVANCE_PC 3
   1300     GOTO_NEXT_R %ecx
   1301 
   1302 
   1303     /*
   1304      * Throw an exception indicating that we have not implemented this
   1305      * mode of filled-new-array.
   1306      */
   1307 .LOP_FILLED_NEW_ARRAY_notimpl:
   1308     movl    $.LstrFilledNewArrayNotImplA,%eax
   1309     movl    %eax,OUT_ARG0(%esp)
   1310     call    dvmThrowInternalError
   1311     jmp     common_exceptionThrown
   1312 
   1313 /* ------------------------------ */
   1314 .L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
   1315 /* File: x86/OP_FILLED_NEW_ARRAY_RANGE.S */
   1316 /* File: x86/OP_FILLED_NEW_ARRAY.S */
   1317     /*
   1318      * Create a new array with elements filled from registers.
   1319      *
   1320      * for: filled-new-array, filled-new-array/range
   1321      */
   1322     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
   1323     /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
   1324     movl    rSELF,%eax
   1325     movl    offThread_methodClassDex(%eax),%eax # eax<- pDvmDex
   1326     movzwl  2(rPC),%ecx                       # ecx<- BBBB
   1327     movl    offDvmDex_pResClasses(%eax),%eax  # eax<- pDvmDex->pResClasses
   1328     SPILL(rIBASE)                             # preserve rIBASE
   1329     movl    (%eax,%ecx,4),%eax                # eax<- resolved class
   1330     EXPORT_PC
   1331     testl   %eax,%eax                         # already resolved?
   1332     jne     .LOP_FILLED_NEW_ARRAY_RANGE_continue              # yes, continue
   1333     # less frequent path, so we'll redo some work
   1334     movl    rSELF,%eax
   1335     movl    $0,OUT_ARG2(%esp)                # arg2<- false
   1336     movl    %ecx,OUT_ARG1(%esp)               # arg1<- BBBB
   1337     movl    offThread_method(%eax),%eax         # eax<- self->method
   1338     movl    offMethod_clazz(%eax),%eax        # eax<- method->clazz
   1339     movl    %eax,OUT_ARG0(%esp)               # arg0<- clazz
   1340     call    dvmResolveClass                   # eax<- call(clazz,ref,flag)
   1341     testl   %eax,%eax                         # null?
   1342     je      common_exceptionThrown            # yes, handle it
   1343 
   1344        # note: fall through to .LOP_FILLED_NEW_ARRAY_RANGE_continue
   1345 
   1346     /*
   1347      * On entry:
   1348      *    eax holds array class [r0]
   1349      *    rINST holds AA or BB [r10]
   1350      *    ecx is scratch
   1351      */
   1352 .LOP_FILLED_NEW_ARRAY_RANGE_continue:
   1353     movl    offClassObject_descriptor(%eax),%ecx  # ecx<- arrayClass->descriptor
   1354     movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)     # arg2<- flags
   1355     movzbl  1(%ecx),%ecx                          # ecx<- descriptor[1]
   1356     movl    %eax,OUT_ARG0(%esp)                   # arg0<- arrayClass
   1357     movl    rSELF,%eax
   1358     cmpb    $'I',%cl                             # supported?
   1359     je      1f
   1360     cmpb    $'L',%cl
   1361     je      1f
   1362     cmpb    $'[',%cl
   1363     jne      .LOP_FILLED_NEW_ARRAY_RANGE_notimpl                  # no, not handled yet
   1364 1:
   1365     movl    %ecx,offThread_retval+4(%eax)           # save type
   1366     .if      (!1)
   1367     SPILL_TMP1(rINST)                              # save copy, need "B" later
   1368     sarl    $4,rINST
   1369     .endif
   1370     movl    rINST,OUT_ARG1(%esp)                  # arg1<- A or AA (length)
   1371     call    dvmAllocArrayByClass     # eax<- call(arrayClass, length, flags)
   1372     movl    rSELF,%ecx
   1373     testl   %eax,%eax                             # alloc successful?
   1374     je      common_exceptionThrown                # no, handle exception
   1375     movl    %eax,offThread_retval(%ecx)             # retval.l<- new array
   1376     movzwl  4(rPC),%ecx                           # ecx<- FEDC or CCCC
   1377     leal    offArrayObject_contents(%eax),%eax    # eax<- newArray->contents
   1378 
   1379 /* at this point:
   1380  *     eax is pointer to tgt
   1381  *     rINST is length
   1382  *     ecx is FEDC or CCCC
   1383  *     TMP_SPILL1 is BA
   1384  *  We now need to copy values from registers into the array
   1385  */
   1386 
   1387     .if 1
   1388     # set up src pointer
   1389     SPILL_TMP2(%esi)
   1390     SPILL_TMP3(%edi)
   1391     leal    (rFP,%ecx,4),%esi # set up src ptr
   1392     movl    %eax,%edi         # set up dst ptr
   1393     movl    rINST,%ecx        # load count register
   1394     rep
   1395     movsd
   1396     UNSPILL_TMP2(%esi)
   1397     UNSPILL_TMP3(%edi)
   1398     movl    rSELF,%ecx
   1399     movl    offThread_retval+4(%ecx),%eax      # eax<- type
   1400     .else
   1401     testl  rINST,rINST
   1402     je     4f
   1403     UNSPILL_TMP1(rIBASE)      # restore "BA"
   1404     andl   $0x0f,rIBASE      # rIBASE<- 0000000A
   1405     sall   $16,rIBASE        # rIBASE<- 000A0000
   1406     orl    %ecx,rIBASE        # rIBASE<- 000AFEDC
   1407 3:
   1408     movl   $0xf,%ecx
   1409     andl   rIBASE,%ecx        # ecx<- next reg to load
   1410     GET_VREG_R %ecx %ecx
   1411     shrl   $4,rIBASE
   1412     leal   4(%eax),%eax
   1413     movl   %ecx,-4(%eax)
   1414     sub    $1,rINST
   1415     jne    3b
   1416 4:
   1417     movl   rSELF,%ecx
   1418     movl    offThread_retval+4(%ecx),%eax      # eax<- type
   1419     .endif
   1420 
   1421     cmpb    $'I',%al                        # Int array?
   1422     je      5f                               # skip card mark if so
   1423     movl    offThread_retval(%ecx),%eax        # eax<- object head
   1424     movl    offThread_cardTable(%ecx),%ecx     # card table base
   1425     shrl    $GC_CARD_SHIFT,%eax             # convert to card num
   1426     movb    %cl,(%ecx,%eax)                  # mark card based on object head
   1427 5:
   1428     UNSPILL(rIBASE)                          # restore rIBASE
   1429     FETCH_INST_OPCODE 3 %ecx
   1430     ADVANCE_PC 3
   1431     GOTO_NEXT_R %ecx
   1432 
   1433 
   1434     /*
   1435      * Throw an exception indicating that we have not implemented this
   1436      * mode of filled-new-array.
   1437      */
   1438 .LOP_FILLED_NEW_ARRAY_RANGE_notimpl:
   1439     movl    $.LstrFilledNewArrayNotImplA,%eax
   1440     movl    %eax,OUT_ARG0(%esp)
   1441     call    dvmThrowInternalError
   1442     jmp     common_exceptionThrown
   1443 
   1444 
   1445 /* ------------------------------ */
   1446 .L_OP_FILL_ARRAY_DATA: /* 0x26 */
   1447 /* File: x86/OP_FILL_ARRAY_DATA.S */
   1448     /* fill-array-data vAA, +BBBBBBBB */
   1449     movl    2(rPC),%ecx                # ecx<- BBBBbbbb
   1450     leal    (rPC,%ecx,2),%ecx          # ecx<- PC + BBBBbbbb*2
   1451     GET_VREG_R %eax rINST
   1452     EXPORT_PC
   1453     movl    %eax,OUT_ARG0(%esp)
   1454     movl    %ecx,OUT_ARG1(%esp)
   1455     SPILL(rIBASE)
   1456     call    dvmInterpHandleFillArrayData
   1457     UNSPILL(rIBASE)
   1458     FETCH_INST_OPCODE 3 %ecx
   1459     testl   %eax,%eax                   # exception thrown?
   1460     je      common_exceptionThrown
   1461     ADVANCE_PC 3
   1462     GOTO_NEXT_R %ecx
   1463 
   1464 /* ------------------------------ */
   1465 .L_OP_THROW: /* 0x27 */
   1466 /* File: x86/OP_THROW.S */
   1467     /*
   1468      * Throw an exception object in the current thread.
   1469      */
   1470     /* throw vAA */
   1471     EXPORT_PC
   1472     GET_VREG_R %eax rINST              # eax<- exception object
   1473     movl     rSELF,%ecx                # ecx<- self
   1474     testl    %eax,%eax                 # null object?
   1475     je       common_errNullObject
   1476     movl     %eax,offThread_exception(%ecx) # thread->exception<- obj
   1477     jmp      common_exceptionThrown
   1478 
   1479 /* ------------------------------ */
   1480 .L_OP_GOTO: /* 0x28 */
   1481 /* File: x86/OP_GOTO.S */
   1482     /*
   1483      * Unconditional branch, 8-bit offset.
   1484      *
   1485      * The branch distance is a signed code-unit offset, which we need to
   1486      * double to get a byte offset.
   1487      */
   1488     /* goto +AA */
   1489     movl    rSELF,%ecx
   1490     movsbl  rINSTbl,%eax          # eax<- ssssssAA
   1491     movl    offThread_curHandlerTable(%ecx),rIBASE
   1492     FETCH_INST_INDEXED %eax
   1493     ADVANCE_PC_INDEXED %eax
   1494 #if defined(WITH_JIT)
   1495     GET_JIT_PROF_TABLE %ecx %eax
   1496     cmp         $0, %eax
   1497     jne         common_updateProfile # set up %ebx & %edx & rPC
   1498 #endif
   1499     GOTO_NEXT
   1500 
   1501 /* ------------------------------ */
   1502 .L_OP_GOTO_16: /* 0x29 */
   1503 /* File: x86/OP_GOTO_16.S */
   1504     /*
   1505      * Unconditional branch, 16-bit offset.
   1506      *
   1507      * The branch distance is a signed code-unit offset
   1508      */
   1509     /* goto/16 +AAAA */
   1510     movl    rSELF,%ecx
   1511     movswl  2(rPC),%eax            # eax<- ssssAAAA
   1512     movl    offThread_curHandlerTable(%ecx),rIBASE
   1513     FETCH_INST_INDEXED %eax
   1514     ADVANCE_PC_INDEXED %eax
   1515 #if defined(WITH_JIT)
   1516     GET_JIT_PROF_TABLE %ecx %eax
   1517     cmp         $0, %eax
   1518     jne         common_updateProfile # set up %ebx & %edx & rPC
   1519 #endif
   1520     GOTO_NEXT
   1521 
   1522 /* ------------------------------ */
   1523 .L_OP_GOTO_32: /* 0x2a */
   1524 /* File: x86/OP_GOTO_32.S */
   1525     /*
   1526      * Unconditional branch, 32-bit offset.
   1527      *
   1528      * The branch distance is a signed code-unit offset.
   1529      */
   1530     /* goto/32 AAAAAAAA */
   1531     movl    rSELF,%ecx
   1532     movl    2(rPC),%eax            # eax<- AAAAAAAA
   1533     movl    offThread_curHandlerTable(%ecx),rIBASE
   1534     FETCH_INST_INDEXED %eax
   1535     ADVANCE_PC_INDEXED %eax
   1536 #if defined(WITH_JIT)
   1537     GET_JIT_PROF_TABLE %ecx %eax
   1538     cmp         $0, %eax
   1539     jne         common_updateProfile # set up %ebx & %edx & rPC
   1540 #endif
   1541     GOTO_NEXT
   1542 
   1543 /* ------------------------------ */
   1544 .L_OP_PACKED_SWITCH: /* 0x2b */
   1545 /* File: x86/OP_PACKED_SWITCH.S */
   1546     /*
   1547      * Handle a packed-switch or sparse-switch instruction.  In both cases
   1548      * we decode it and hand it off to a helper function.
   1549      *
   1550      * We don't really expect backward branches in a switch statement, but
   1551      * they're perfectly legal, so we check for them here.
   1552      *
   1553      * for: packed-switch, sparse-switch
   1554      */
   1555     /* op vAA, +BBBB */
   1556     movl    2(rPC),%ecx           # ecx<- BBBBbbbb
   1557     GET_VREG_R %eax rINST         # eax<- vAA
   1558     leal    (rPC,%ecx,2),%ecx     # ecx<- PC + BBBBbbbb*2
   1559     movl    %eax,OUT_ARG1(%esp)   # ARG1<- vAA
   1560     movl    %ecx,OUT_ARG0(%esp)   # ARG0<- switchData
   1561     call    dvmInterpHandlePackedSwitch
   1562     movl    rSELF,%ecx
   1563     ADVANCE_PC_INDEXED %eax
   1564     movl    offThread_curHandlerTable(%ecx),rIBASE
   1565     FETCH_INST
   1566 #if defined(WITH_JIT)
   1567     GET_JIT_PROF_TABLE %ecx %eax
   1568     cmp         $0, %eax
   1569     jne         common_updateProfile # set up %ebx & %edx & rPC
   1570 #endif
   1571     GOTO_NEXT
   1572 
   1573 /* ------------------------------ */
   1574 .L_OP_SPARSE_SWITCH: /* 0x2c */
   1575 /* File: x86/OP_SPARSE_SWITCH.S */
   1576 /* File: x86/OP_PACKED_SWITCH.S */
   1577     /*
   1578      * Handle a packed-switch or sparse-switch instruction.  In both cases
   1579      * we decode it and hand it off to a helper function.
   1580      *
   1581      * We don't really expect backward branches in a switch statement, but
   1582      * they're perfectly legal, so we check for them here.
   1583      *
   1584      * for: packed-switch, sparse-switch
   1585      */
   1586     /* op vAA, +BBBB */
   1587     movl    2(rPC),%ecx           # ecx<- BBBBbbbb
   1588     GET_VREG_R %eax rINST         # eax<- vAA
   1589     leal    (rPC,%ecx,2),%ecx     # ecx<- PC + BBBBbbbb*2
   1590     movl    %eax,OUT_ARG1(%esp)   # ARG1<- vAA
   1591     movl    %ecx,OUT_ARG0(%esp)   # ARG0<- switchData
   1592     call    dvmInterpHandleSparseSwitch
   1593     movl    rSELF,%ecx
   1594     ADVANCE_PC_INDEXED %eax
   1595     movl    offThread_curHandlerTable(%ecx),rIBASE
   1596     FETCH_INST
   1597 #if defined(WITH_JIT)
   1598     GET_JIT_PROF_TABLE %ecx %eax
   1599     cmp         $0, %eax
   1600     jne         common_updateProfile # set up %ebx & %edx & rPC
   1601 #endif
   1602     GOTO_NEXT
   1603 
   1604 
   1605 /* ------------------------------ */
   1606 .L_OP_CMPL_FLOAT: /* 0x2d */
   1607 /* File: x86/OP_CMPL_FLOAT.S */
   1608 /* File: x86/OP_CMPG_DOUBLE.S */
   1609     /* float/double_cmp[gl] vAA, vBB, vCC */
   1610     movzbl    3(rPC),%eax             # eax<- CC
   1611     movzbl    2(rPC),%ecx             # ecx<- BB
   1612     .if 0
   1613     fldl     (rFP,%eax,4)
   1614     fldl     (rFP,%ecx,4)
   1615     .else
   1616     flds     (rFP,%eax,4)
   1617     flds     (rFP,%ecx,4)
   1618     .endif
   1619     xorl     %ecx,%ecx
   1620     fucompp     # z if equal, p set if NaN, c set if st0 < st1
   1621     fnstsw   %ax
   1622     sahf
   1623     FETCH_INST_OPCODE 2 %eax
   1624     jp       .LOP_CMPL_FLOAT_isNaN
   1625     je       .LOP_CMPL_FLOAT_finish
   1626     sbbl     %ecx,%ecx
   1627     jb       .LOP_CMPL_FLOAT_finish
   1628     incl     %ecx
   1629 .LOP_CMPL_FLOAT_finish:
   1630     SET_VREG %ecx rINST
   1631     ADVANCE_PC 2
   1632     GOTO_NEXT_R %eax
   1633 
   1634 .LOP_CMPL_FLOAT_isNaN:
   1635     movl      $-1,%ecx
   1636     jmp       .LOP_CMPL_FLOAT_finish
   1637 
   1638 
   1639 /* ------------------------------ */
   1640 .L_OP_CMPG_FLOAT: /* 0x2e */
   1641 /* File: x86/OP_CMPG_FLOAT.S */
   1642 /* File: x86/OP_CMPG_DOUBLE.S */
   1643     /* float/double_cmp[gl] vAA, vBB, vCC */
   1644     movzbl    3(rPC),%eax             # eax<- CC
   1645     movzbl    2(rPC),%ecx             # ecx<- BB
   1646     .if 0
   1647     fldl     (rFP,%eax,4)
   1648     fldl     (rFP,%ecx,4)
   1649     .else
   1650     flds     (rFP,%eax,4)
   1651     flds     (rFP,%ecx,4)
   1652     .endif
   1653     xorl     %ecx,%ecx
   1654     fucompp     # z if equal, p set if NaN, c set if st0 < st1
   1655     fnstsw   %ax
   1656     sahf
   1657     FETCH_INST_OPCODE 2 %eax
   1658     jp       .LOP_CMPG_FLOAT_isNaN
   1659     je       .LOP_CMPG_FLOAT_finish
   1660     sbbl     %ecx,%ecx
   1661     jb       .LOP_CMPG_FLOAT_finish
   1662     incl     %ecx
   1663 .LOP_CMPG_FLOAT_finish:
   1664     SET_VREG %ecx rINST
   1665     ADVANCE_PC 2
   1666     GOTO_NEXT_R %eax
   1667 
   1668 .LOP_CMPG_FLOAT_isNaN:
   1669     movl      $1,%ecx
   1670     jmp       .LOP_CMPG_FLOAT_finish
   1671 
   1672 
   1673 /* ------------------------------ */
   1674 .L_OP_CMPL_DOUBLE: /* 0x2f */
   1675 /* File: x86/OP_CMPL_DOUBLE.S */
   1676 /* File: x86/OP_CMPG_DOUBLE.S */
   1677     /* float/double_cmp[gl] vAA, vBB, vCC */
   1678     movzbl    3(rPC),%eax             # eax<- CC
   1679     movzbl    2(rPC),%ecx             # ecx<- BB
   1680     .if 1
   1681     fldl     (rFP,%eax,4)
   1682     fldl     (rFP,%ecx,4)
   1683     .else
   1684     flds     (rFP,%eax,4)
   1685     flds     (rFP,%ecx,4)
   1686     .endif
   1687     xorl     %ecx,%ecx
   1688     fucompp     # z if equal, p set if NaN, c set if st0 < st1
   1689     fnstsw   %ax
   1690     sahf
   1691     FETCH_INST_OPCODE 2 %eax
   1692     jp       .LOP_CMPL_DOUBLE_isNaN
   1693     je       .LOP_CMPL_DOUBLE_finish
   1694     sbbl     %ecx,%ecx
   1695     jb       .LOP_CMPL_DOUBLE_finish
   1696     incl     %ecx
   1697 .LOP_CMPL_DOUBLE_finish:
   1698     SET_VREG %ecx rINST
   1699     ADVANCE_PC 2
   1700     GOTO_NEXT_R %eax
   1701 
   1702 .LOP_CMPL_DOUBLE_isNaN:
   1703     movl      $-1,%ecx
   1704     jmp       .LOP_CMPL_DOUBLE_finish
   1705 
   1706 
   1707 /* ------------------------------ */
   1708 .L_OP_CMPG_DOUBLE: /* 0x30 */
   1709 /* File: x86/OP_CMPG_DOUBLE.S */
   1710     /* float/double_cmp[gl] vAA, vBB, vCC */
   1711     movzbl    3(rPC),%eax             # eax<- CC
   1712     movzbl    2(rPC),%ecx             # ecx<- BB
   1713     .if 1
   1714     fldl     (rFP,%eax,4)
   1715     fldl     (rFP,%ecx,4)
   1716     .else
   1717     flds     (rFP,%eax,4)
   1718     flds     (rFP,%ecx,4)
   1719     .endif
   1720     xorl     %ecx,%ecx
   1721     fucompp     # z if equal, p set if NaN, c set if st0 < st1
   1722     fnstsw   %ax
   1723     sahf
   1724     FETCH_INST_OPCODE 2 %eax
   1725     jp       .LOP_CMPG_DOUBLE_isNaN
   1726     je       .LOP_CMPG_DOUBLE_finish
   1727     sbbl     %ecx,%ecx
   1728     jb       .LOP_CMPG_DOUBLE_finish
   1729     incl     %ecx
   1730 .LOP_CMPG_DOUBLE_finish:
   1731     SET_VREG %ecx rINST
   1732     ADVANCE_PC 2
   1733     GOTO_NEXT_R %eax
   1734 
   1735 .LOP_CMPG_DOUBLE_isNaN:
   1736     movl      $1,%ecx
   1737     jmp       .LOP_CMPG_DOUBLE_finish
   1738 
   1739 /* ------------------------------ */
   1740 .L_OP_CMP_LONG: /* 0x31 */
   1741 /* File: x86/OP_CMP_LONG.S */
   1742     /*
   1743      * Compare two 64-bit values.  Puts 0, 1, or -1 into the destination
   1744      * register based on the results of the comparison.
   1745      */
   1746     // TUNING: rework to avoid rIBASE spill
   1747     /* cmp-long vAA, vBB, vCC */
   1748     movzbl    2(rPC),%ecx              # ecx<- BB
   1749     SPILL(rIBASE)
   1750     movzbl    3(rPC),rIBASE            # rIBASE- CC
   1751     GET_VREG_WORD %eax %ecx,1          # eax<- v[BB+1]
   1752     GET_VREG_WORD %ecx %ecx 0          # ecx<- v[BB+0]
   1753     cmpl      4(rFP,rIBASE,4),%eax
   1754     jl        .LOP_CMP_LONG_smaller
   1755     jg        .LOP_CMP_LONG_bigger
   1756     sub       (rFP,rIBASE,4),%ecx
   1757     ja        .LOP_CMP_LONG_bigger
   1758     jb        .LOP_CMP_LONG_smaller
   1759     SET_VREG %ecx rINST
   1760     FETCH_INST_OPCODE 2 %ecx
   1761     UNSPILL(rIBASE)
   1762     ADVANCE_PC 2
   1763     GOTO_NEXT_R %ecx
   1764 
   1765 .LOP_CMP_LONG_bigger:
   1766     movl      $1,%ecx
   1767     SET_VREG %ecx rINST
   1768     FETCH_INST_OPCODE 2 %ecx
   1769     UNSPILL(rIBASE)
   1770     ADVANCE_PC 2
   1771     GOTO_NEXT_R %ecx
   1772 
   1773 .LOP_CMP_LONG_smaller:
   1774     movl      $-1,%ecx
   1775     SET_VREG %ecx rINST
   1776     FETCH_INST_OPCODE 2 %ecx
   1777     UNSPILL(rIBASE)
   1778     ADVANCE_PC 2
   1779     GOTO_NEXT_R %ecx
   1780 
   1781 /* ------------------------------ */
   1782 .L_OP_IF_EQ: /* 0x32 */
   1783 /* File: x86/OP_IF_EQ.S */
   1784 /* File: x86/bincmp.S */
   1785     /*
   1786      * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
   1787      * fragment that specifies the *reverse* comparison to perform, e.g.
   1788      * for "if-le" you would use "gt".
   1789      *
   1790      * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
   1791      */
   1792     /* if-cmp vA, vB, +CCCC */
   1793     movzx    rINSTbl,%ecx          # ecx <- A+
   1794     andb     $0xf,%cl             # ecx <- A
   1795     GET_VREG_R %eax %ecx           # eax <- vA
   1796     sarl     $4,rINST             # rINST<- B
   1797     movl     rSELF,%ecx
   1798     cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
   1799     movl     $2,%eax              # assume not taken
   1800     jne   1f
   1801     movswl   2(rPC),%eax           # Get signed branch offset
   1802 1:
   1803     movl     offThread_curHandlerTable(%ecx),rIBASE
   1804     FETCH_INST_INDEXED %eax
   1805     ADVANCE_PC_INDEXED %eax
   1806 #if defined(WITH_JIT)
   1807     GET_JIT_PROF_TABLE %ecx %eax
   1808     cmp         $0, %eax
   1809     jne         common_updateProfile # set up %ebx & %edx & rPC
   1810 #endif
   1811     GOTO_NEXT
   1812 
   1813 
   1814 /* ------------------------------ */
   1815 .L_OP_IF_NE: /* 0x33 */
   1816 /* File: x86/OP_IF_NE.S */
   1817 /* File: x86/bincmp.S */
   1818     /*
   1819      * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
   1820      * fragment that specifies the *reverse* comparison to perform, e.g.
   1821      * for "if-le" you would use "gt".
   1822      *
   1823      * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
   1824      */
   1825     /* if-cmp vA, vB, +CCCC */
   1826     movzx    rINSTbl,%ecx          # ecx <- A+
   1827     andb     $0xf,%cl             # ecx <- A
   1828     GET_VREG_R %eax %ecx           # eax <- vA
   1829     sarl     $4,rINST             # rINST<- B
   1830     movl     rSELF,%ecx
   1831     cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
   1832     movl     $2,%eax              # assume not taken
   1833     je   1f
   1834     movswl   2(rPC),%eax           # Get signed branch offset
   1835 1:
   1836     movl     offThread_curHandlerTable(%ecx),rIBASE
   1837     FETCH_INST_INDEXED %eax
   1838     ADVANCE_PC_INDEXED %eax
   1839 #if defined(WITH_JIT)
   1840     GET_JIT_PROF_TABLE %ecx %eax
   1841     cmp         $0, %eax
   1842     jne         common_updateProfile # set up %ebx & %edx & rPC
   1843 #endif
   1844     GOTO_NEXT
   1845 
   1846 
   1847 /* ------------------------------ */
   1848 .L_OP_IF_LT: /* 0x34 */
   1849 /* File: x86/OP_IF_LT.S */
   1850 /* File: x86/bincmp.S */
   1851     /*
   1852      * Generic two-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-eq, if-ne, if-lt, if-ge, if-gt, if-le
   1857      */
   1858     /* if-cmp vA, vB, +CCCC */
   1859     movzx    rINSTbl,%ecx          # ecx <- A+
   1860     andb     $0xf,%cl             # ecx <- A
   1861     GET_VREG_R %eax %ecx           # eax <- vA
   1862     sarl     $4,rINST             # rINST<- B
   1863     movl     rSELF,%ecx
   1864     cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
   1865     movl     $2,%eax              # assume not taken
   1866     jge   1f
   1867     movswl   2(rPC),%eax           # Get signed branch offset
   1868 1:
   1869     movl     offThread_curHandlerTable(%ecx),rIBASE
   1870     FETCH_INST_INDEXED %eax
   1871     ADVANCE_PC_INDEXED %eax
   1872 #if defined(WITH_JIT)
   1873     GET_JIT_PROF_TABLE %ecx %eax
   1874     cmp         $0, %eax
   1875     jne         common_updateProfile # set up %ebx & %edx & rPC
   1876 #endif
   1877     GOTO_NEXT
   1878 
   1879 
   1880 /* ------------------------------ */
   1881 .L_OP_IF_GE: /* 0x35 */
   1882 /* File: x86/OP_IF_GE.S */
   1883 /* File: x86/bincmp.S */
   1884     /*
   1885      * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
   1886      * fragment that specifies the *reverse* comparison to perform, e.g.
   1887      * for "if-le" you would use "gt".
   1888      *
   1889      * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
   1890      */
   1891     /* if-cmp vA, vB, +CCCC */
   1892     movzx    rINSTbl,%ecx          # ecx <- A+
   1893     andb     $0xf,%cl             # ecx <- A
   1894     GET_VREG_R %eax %ecx           # eax <- vA
   1895     sarl     $4,rINST             # rINST<- B
   1896     movl     rSELF,%ecx
   1897     cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
   1898     movl     $2,%eax              # assume not taken
   1899     jl   1f
   1900     movswl   2(rPC),%eax           # Get signed branch offset
   1901 1:
   1902     movl     offThread_curHandlerTable(%ecx),rIBASE
   1903     FETCH_INST_INDEXED %eax
   1904     ADVANCE_PC_INDEXED %eax
   1905 #if defined(WITH_JIT)
   1906     GET_JIT_PROF_TABLE %ecx %eax
   1907     cmp         $0, %eax
   1908     jne         common_updateProfile # set up %ebx & %edx & rPC
   1909 #endif
   1910     GOTO_NEXT
   1911 
   1912 
   1913 /* ------------------------------ */
   1914 .L_OP_IF_GT: /* 0x36 */
   1915 /* File: x86/OP_IF_GT.S */
   1916 /* File: x86/bincmp.S */
   1917     /*
   1918      * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
   1919      * fragment that specifies the *reverse* comparison to perform, e.g.
   1920      * for "if-le" you would use "gt".
   1921      *
   1922      * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
   1923      */
   1924     /* if-cmp vA, vB, +CCCC */
   1925     movzx    rINSTbl,%ecx          # ecx <- A+
   1926     andb     $0xf,%cl             # ecx <- A
   1927     GET_VREG_R %eax %ecx           # eax <- vA
   1928     sarl     $4,rINST             # rINST<- B
   1929     movl     rSELF,%ecx
   1930     cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
   1931     movl     $2,%eax              # assume not taken
   1932     jle   1f
   1933     movswl   2(rPC),%eax           # Get signed branch offset
   1934 1:
   1935     movl     offThread_curHandlerTable(%ecx),rIBASE
   1936     FETCH_INST_INDEXED %eax
   1937     ADVANCE_PC_INDEXED %eax
   1938 #if defined(WITH_JIT)
   1939     GET_JIT_PROF_TABLE %ecx %eax
   1940     cmp         $0, %eax
   1941     jne         common_updateProfile # set up %ebx & %edx & rPC
   1942 #endif
   1943     GOTO_NEXT
   1944 
   1945 
   1946 /* ------------------------------ */
   1947 .L_OP_IF_LE: /* 0x37 */
   1948 /* File: x86/OP_IF_LE.S */
   1949 /* File: x86/bincmp.S */
   1950     /*
   1951      * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
   1952      * fragment that specifies the *reverse* comparison to perform, e.g.
   1953      * for "if-le" you would use "gt".
   1954      *
   1955      * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
   1956      */
   1957     /* if-cmp vA, vB, +CCCC */
   1958     movzx    rINSTbl,%ecx          # ecx <- A+
   1959     andb     $0xf,%cl             # ecx <- A
   1960     GET_VREG_R %eax %ecx           # eax <- vA
   1961     sarl     $4,rINST             # rINST<- B
   1962     movl     rSELF,%ecx
   1963     cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
   1964     movl     $2,%eax              # assume not taken
   1965     jg   1f
   1966     movswl   2(rPC),%eax           # Get signed branch offset
   1967 1:
   1968     movl     offThread_curHandlerTable(%ecx),rIBASE
   1969     FETCH_INST_INDEXED %eax
   1970     ADVANCE_PC_INDEXED %eax
   1971 #if defined(WITH_JIT)
   1972     GET_JIT_PROF_TABLE %ecx %eax
   1973     cmp         $0, %eax
   1974     jne         common_updateProfile # set up %ebx & %edx & rPC
   1975 #endif
   1976     GOTO_NEXT
   1977 
   1978 
   1979 /* ------------------------------ */
   1980 .L_OP_IF_EQZ: /* 0x38 */
   1981 /* File: x86/OP_IF_EQZ.S */
   1982 /* File: x86/zcmp.S */
   1983     /*
   1984      * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
   1985      * fragment that specifies the *reverse* comparison to perform, e.g.
   1986      * for "if-le" you would use "gt".
   1987      *
   1988      * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
   1989      */
   1990     /* if-cmp vAA, +BBBB */
   1991     cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
   1992     movl     rSELF,%ecx
   1993     movl     $2,%eax              # assume branch not taken
   1994     jne   1f
   1995     movswl   2(rPC),%eax           # fetch signed displacement
   1996     movl     offThread_curHandlerTable(%ecx),rIBASE
   1997 1:
   1998     FETCH_INST_INDEXED %eax
   1999     ADVANCE_PC_INDEXED %eax
   2000 #if defined(WITH_JIT)
   2001     GET_JIT_PROF_TABLE %ecx %eax
   2002     cmp         $0, %eax
   2003     jne         common_updateProfile # set up %ebx & %edx & rPC
   2004 #endif
   2005     GOTO_NEXT
   2006 
   2007 
   2008 /* ------------------------------ */
   2009 .L_OP_IF_NEZ: /* 0x39 */
   2010 /* File: x86/OP_IF_NEZ.S */
   2011 /* File: x86/zcmp.S */
   2012     /*
   2013      * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
   2014      * fragment that specifies the *reverse* comparison to perform, e.g.
   2015      * for "if-le" you would use "gt".
   2016      *
   2017      * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
   2018      */
   2019     /* if-cmp vAA, +BBBB */
   2020     cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
   2021     movl     rSELF,%ecx
   2022     movl     $2,%eax              # assume branch not taken
   2023     je   1f
   2024     movswl   2(rPC),%eax           # fetch signed displacement
   2025     movl     offThread_curHandlerTable(%ecx),rIBASE
   2026 1:
   2027     FETCH_INST_INDEXED %eax
   2028     ADVANCE_PC_INDEXED %eax
   2029 #if defined(WITH_JIT)
   2030     GET_JIT_PROF_TABLE %ecx %eax
   2031     cmp         $0, %eax
   2032     jne         common_updateProfile # set up %ebx & %edx & rPC
   2033 #endif
   2034     GOTO_NEXT
   2035 
   2036 
   2037 /* ------------------------------ */
   2038 .L_OP_IF_LTZ: /* 0x3a */
   2039 /* File: x86/OP_IF_LTZ.S */
   2040 /* File: x86/zcmp.S */
   2041     /*
   2042      * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
   2043      * fragment that specifies the *reverse* comparison to perform, e.g.
   2044      * for "if-le" you would use "gt".
   2045      *
   2046      * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
   2047      */
   2048     /* if-cmp vAA, +BBBB */
   2049     cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
   2050     movl     rSELF,%ecx
   2051     movl     $2,%eax              # assume branch not taken
   2052     jge   1f
   2053     movswl   2(rPC),%eax           # fetch signed displacement
   2054     movl     offThread_curHandlerTable(%ecx),rIBASE
   2055 1:
   2056     FETCH_INST_INDEXED %eax
   2057     ADVANCE_PC_INDEXED %eax
   2058 #if defined(WITH_JIT)
   2059     GET_JIT_PROF_TABLE %ecx %eax
   2060     cmp         $0, %eax
   2061     jne         common_updateProfile # set up %ebx & %edx & rPC
   2062 #endif
   2063     GOTO_NEXT
   2064 
   2065 
   2066 /* ------------------------------ */
   2067 .L_OP_IF_GEZ: /* 0x3b */
   2068 /* File: x86/OP_IF_GEZ.S */
   2069 /* File: x86/zcmp.S */
   2070     /*
   2071      * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
   2072      * fragment that specifies the *reverse* comparison to perform, e.g.
   2073      * for "if-le" you would use "gt".
   2074      *
   2075      * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
   2076      */
   2077     /* if-cmp vAA, +BBBB */
   2078     cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
   2079     movl     rSELF,%ecx
   2080     movl     $2,%eax              # assume branch not taken
   2081     jl   1f
   2082     movswl   2(rPC),%eax           # fetch signed displacement
   2083     movl     offThread_curHandlerTable(%ecx),rIBASE
   2084 1:
   2085     FETCH_INST_INDEXED %eax
   2086     ADVANCE_PC_INDEXED %eax
   2087 #if defined(WITH_JIT)
   2088     GET_JIT_PROF_TABLE %ecx %eax
   2089     cmp         $0, %eax
   2090     jne         common_updateProfile # set up %ebx & %edx & rPC
   2091 #endif
   2092     GOTO_NEXT
   2093 
   2094 
   2095 /* ------------------------------ */
   2096 .L_OP_IF_GTZ: /* 0x3c */
   2097 /* File: x86/OP_IF_GTZ.S */
   2098 /* File: x86/zcmp.S */
   2099     /*
   2100      * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
   2101      * fragment that specifies the *reverse* comparison to perform, e.g.
   2102      * for "if-le" you would use "gt".
   2103      *
   2104      * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
   2105      */
   2106     /* if-cmp vAA, +BBBB */
   2107     cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
   2108     movl     rSELF,%ecx
   2109     movl     $2,%eax              # assume branch not taken
   2110     jle   1f
   2111     movswl   2(rPC),%eax           # fetch signed displacement
   2112     movl     offThread_curHandlerTable(%ecx),rIBASE
   2113 1:
   2114     FETCH_INST_INDEXED %eax
   2115     ADVANCE_PC_INDEXED %eax
   2116 #if defined(WITH_JIT)
   2117     GET_JIT_PROF_TABLE %ecx %eax
   2118     cmp         $0, %eax
   2119     jne         common_updateProfile # set up %ebx & %edx & rPC
   2120 #endif
   2121     GOTO_NEXT
   2122 
   2123 
   2124 /* ------------------------------ */
   2125 .L_OP_IF_LEZ: /* 0x3d */
   2126 /* File: x86/OP_IF_LEZ.S */
   2127 /* File: x86/zcmp.S */
   2128     /*
   2129      * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
   2130      * fragment that specifies the *reverse* comparison to perform, e.g.
   2131      * for "if-le" you would use "gt".
   2132      *
   2133      * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
   2134      */
   2135     /* if-cmp vAA, +BBBB */
   2136     cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
   2137     movl     rSELF,%ecx
   2138     movl     $2,%eax              # assume branch not taken
   2139     jg   1f
   2140     movswl   2(rPC),%eax           # fetch signed displacement
   2141     movl     offThread_curHandlerTable(%ecx),rIBASE
   2142 1:
   2143     FETCH_INST_INDEXED %eax
   2144     ADVANCE_PC_INDEXED %eax
   2145 #if defined(WITH_JIT)
   2146     GET_JIT_PROF_TABLE %ecx %eax
   2147     cmp         $0, %eax
   2148     jne         common_updateProfile # set up %ebx & %edx & rPC
   2149 #endif
   2150     GOTO_NEXT
   2151 
   2152 
   2153 /* ------------------------------ */
   2154 .L_OP_UNUSED_3E: /* 0x3e */
   2155 /* File: x86/OP_UNUSED_3E.S */
   2156 /* File: x86/unused.S */
   2157     jmp     common_abort
   2158 
   2159 
   2160 /* ------------------------------ */
   2161 .L_OP_UNUSED_3F: /* 0x3f */
   2162 /* File: x86/OP_UNUSED_3F.S */
   2163 /* File: x86/unused.S */
   2164     jmp     common_abort
   2165 
   2166 
   2167 /* ------------------------------ */
   2168 .L_OP_UNUSED_40: /* 0x40 */
   2169 /* File: x86/OP_UNUSED_40.S */
   2170 /* File: x86/unused.S */
   2171     jmp     common_abort
   2172 
   2173 
   2174 /* ------------------------------ */
   2175 .L_OP_UNUSED_41: /* 0x41 */
   2176 /* File: x86/OP_UNUSED_41.S */
   2177 /* File: x86/unused.S */
   2178     jmp     common_abort
   2179 
   2180 
   2181 /* ------------------------------ */
   2182 .L_OP_UNUSED_42: /* 0x42 */
   2183 /* File: x86/OP_UNUSED_42.S */
   2184 /* File: x86/unused.S */
   2185     jmp     common_abort
   2186 
   2187 
   2188 /* ------------------------------ */
   2189 .L_OP_UNUSED_43: /* 0x43 */
   2190 /* File: x86/OP_UNUSED_43.S */
   2191 /* File: x86/unused.S */
   2192     jmp     common_abort
   2193 
   2194 
   2195 /* ------------------------------ */
   2196 .L_OP_AGET: /* 0x44 */
   2197 /* File: x86/OP_AGET.S */
   2198     /*
   2199      * Array get, 32 bits or less.  vAA <- vBB[vCC].
   2200      *
   2201      * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
   2202      */
   2203     /* op vAA, vBB, vCC */
   2204     movzbl    2(rPC),%eax               # eax<- BB
   2205     movzbl    3(rPC),%ecx               # ecx<- CC
   2206     GET_VREG_R  %eax %eax               # eax<- vBB (array object)
   2207     GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
   2208     testl     %eax,%eax                 # null array object?
   2209     je        common_errNullObject      # bail if so
   2210     cmpl      offArrayObject_length(%eax),%ecx
   2211     jae       common_errArrayIndex      # index >= length, bail.  Expects
   2212                                         #    arrayObj in eax
   2213                                         #    index in ecx
   2214     movl     offArrayObject_contents(%eax,%ecx,4),%eax
   2215 .LOP_AGET_finish:
   2216     FETCH_INST_OPCODE 2 %ecx
   2217     SET_VREG  %eax rINST
   2218     ADVANCE_PC 2
   2219     GOTO_NEXT_R %ecx
   2220 
   2221 /* ------------------------------ */
   2222 .L_OP_AGET_WIDE: /* 0x45 */
   2223 /* File: x86/OP_AGET_WIDE.S */
   2224     /*
   2225      * Array get, 64 bits.  vAA <- vBB[vCC].
   2226      *
   2227      */
   2228     /* op vAA, vBB, vCC */
   2229     movzbl    2(rPC),%eax               # eax<- BB
   2230     movzbl    3(rPC),%ecx               # ecx<- CC
   2231     GET_VREG_R  %eax %eax               # eax<- vBB (array object)
   2232     GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
   2233     testl     %eax,%eax                 # null array object?
   2234     je        common_errNullObject      # bail if so
   2235     cmpl      offArrayObject_length(%eax),%ecx
   2236     jae       common_errArrayIndex      # index >= length, bail.  Expects
   2237                                         #    arrayObj in eax
   2238                                         #    index in ecx
   2239     leal      offArrayObject_contents(%eax,%ecx,8),%eax
   2240     movl      (%eax),%ecx
   2241     movl      4(%eax),%eax
   2242     SET_VREG_WORD %ecx rINST 0
   2243     SET_VREG_WORD %eax rINST 1
   2244     FETCH_INST_OPCODE 2 %ecx
   2245     ADVANCE_PC 2
   2246     GOTO_NEXT_R %ecx
   2247 
   2248 /* ------------------------------ */
   2249 .L_OP_AGET_OBJECT: /* 0x46 */
   2250 /* File: x86/OP_AGET_OBJECT.S */
   2251 /* File: x86/OP_AGET.S */
   2252     /*
   2253      * Array get, 32 bits or less.  vAA <- vBB[vCC].
   2254      *
   2255      * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
   2256      */
   2257     /* op vAA, vBB, vCC */
   2258     movzbl    2(rPC),%eax               # eax<- BB
   2259     movzbl    3(rPC),%ecx               # ecx<- CC
   2260     GET_VREG_R  %eax %eax               # eax<- vBB (array object)
   2261     GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
   2262     testl     %eax,%eax                 # null array object?
   2263     je        common_errNullObject      # bail if so
   2264     cmpl      offArrayObject_length(%eax),%ecx
   2265     jae       common_errArrayIndex      # index >= length, bail.  Expects
   2266                                         #    arrayObj in eax
   2267                                         #    index in ecx
   2268     movl     offArrayObject_contents(%eax,%ecx,4),%eax
   2269 .LOP_AGET_OBJECT_finish:
   2270     FETCH_INST_OPCODE 2 %ecx
   2271     SET_VREG  %eax rINST
   2272     ADVANCE_PC 2
   2273     GOTO_NEXT_R %ecx
   2274 
   2275 
   2276 /* ------------------------------ */
   2277 .L_OP_AGET_BOOLEAN: /* 0x47 */
   2278 /* File: x86/OP_AGET_BOOLEAN.S */
   2279 /* File: x86/OP_AGET.S */
   2280     /*
   2281      * Array get, 32 bits or less.  vAA <- vBB[vCC].
   2282      *
   2283      * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
   2284      */
   2285     /* op vAA, vBB, vCC */
   2286     movzbl    2(rPC),%eax               # eax<- BB
   2287     movzbl    3(rPC),%ecx               # ecx<- CC
   2288     GET_VREG_R  %eax %eax               # eax<- vBB (array object)
   2289     GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
   2290     testl     %eax,%eax                 # null array object?
   2291     je        common_errNullObject      # bail if so
   2292     cmpl      offArrayObject_length(%eax),%ecx
   2293     jae       common_errArrayIndex      # index >= length, bail.  Expects
   2294                                         #    arrayObj in eax
   2295                                         #    index in ecx
   2296     movzbl     offArrayObject_contents(%eax,%ecx,1),%eax
   2297 .LOP_AGET_BOOLEAN_finish:
   2298     FETCH_INST_OPCODE 2 %ecx
   2299     SET_VREG  %eax rINST
   2300     ADVANCE_PC 2
   2301     GOTO_NEXT_R %ecx
   2302 
   2303 
   2304 /* ------------------------------ */
   2305 .L_OP_AGET_BYTE: /* 0x48 */
   2306 /* File: x86/OP_AGET_BYTE.S */
   2307 /* File: x86/OP_AGET.S */
   2308     /*
   2309      * Array get, 32 bits or less.  vAA <- vBB[vCC].
   2310      *
   2311      * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
   2312      */
   2313     /* op vAA, vBB, vCC */
   2314     movzbl    2(rPC),%eax               # eax<- BB
   2315     movzbl    3(rPC),%ecx               # ecx<- CC
   2316     GET_VREG_R  %eax %eax               # eax<- vBB (array object)
   2317     GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
   2318     testl     %eax,%eax                 # null array object?
   2319     je        common_errNullObject      # bail if so
   2320     cmpl      offArrayObject_length(%eax),%ecx
   2321     jae       common_errArrayIndex      # index >= length, bail.  Expects
   2322                                         #    arrayObj in eax
   2323                                         #    index in ecx
   2324     movsbl     offArrayObject_contents(%eax,%ecx,1),%eax
   2325 .LOP_AGET_BYTE_finish:
   2326     FETCH_INST_OPCODE 2 %ecx
   2327     SET_VREG  %eax rINST
   2328     ADVANCE_PC 2
   2329     GOTO_NEXT_R %ecx
   2330 
   2331 
   2332 /* ------------------------------ */
   2333 .L_OP_AGET_CHAR: /* 0x49 */
   2334 /* File: x86/OP_AGET_CHAR.S */
   2335 /* File: x86/OP_AGET.S */
   2336     /*
   2337      * Array get, 32 bits or less.  vAA <- vBB[vCC].
   2338      *
   2339      * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
   2340      */
   2341     /* op vAA, vBB, vCC */
   2342     movzbl    2(rPC),%eax               # eax<- BB
   2343     movzbl    3(rPC),%ecx               # ecx<- CC
   2344     GET_VREG_R  %eax %eax               # eax<- vBB (array object)
   2345     GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
   2346     testl     %eax,%eax                 # null array object?
   2347     je        common_errNullObject      # bail if so
   2348     cmpl      offArrayObject_length(%eax),%ecx
   2349     jae       common_errArrayIndex      # index >= length, bail.  Expects
   2350                                         #    arrayObj in eax
   2351                                         #    index in ecx
   2352     movzwl     offArrayObject_contents(%eax,%ecx,2),%eax
   2353 .LOP_AGET_CHAR_finish:
   2354     FETCH_INST_OPCODE 2 %ecx
   2355     SET_VREG  %eax rINST
   2356     ADVANCE_PC 2
   2357     GOTO_NEXT_R %ecx
   2358 
   2359 
   2360 /* ------------------------------ */
   2361 .L_OP_AGET_SHORT: /* 0x4a */
   2362 /* File: x86/OP_AGET_SHORT.S */
   2363 /* File: x86/OP_AGET.S */
   2364     /*
   2365      * Array get, 32 bits or less.  vAA <- vBB[vCC].
   2366      *
   2367      * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
   2368      */
   2369     /* op vAA, vBB, vCC */
   2370     movzbl    2(rPC),%eax               # eax<- BB
   2371     movzbl    3(rPC),%ecx               # ecx<- CC
   2372     GET_VREG_R  %eax %eax               # eax<- vBB (array object)
   2373     GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
   2374     testl     %eax,%eax                 # null array object?
   2375     je        common_errNullObject      # bail if so
   2376     cmpl      offArrayObject_length(%eax),%ecx
   2377     jae       common_errArrayIndex      # index >= length, bail.  Expects
   2378                                         #    arrayObj in eax
   2379                                         #    index in ecx
   2380     movswl     offArrayObject_contents(%eax,%ecx,2),%eax
   2381 .LOP_AGET_SHORT_finish:
   2382     FETCH_INST_OPCODE 2 %ecx
   2383     SET_VREG  %eax rINST
   2384     ADVANCE_PC 2
   2385     GOTO_NEXT_R %ecx
   2386 
   2387 
   2388 /* ------------------------------ */
   2389 .L_OP_APUT: /* 0x4b */
   2390 /* File: x86/OP_APUT.S */
   2391     /*
   2392      * Array put, 32 bits or less.  vBB[vCC] <- vAA
   2393      *
   2394      * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
   2395      */
   2396     /* op vAA, vBB, vCC */
   2397     movzbl    2(rPC),%eax               # eax<- BB
   2398     movzbl    3(rPC),%ecx               # ecx<- CC
   2399     GET_VREG_R  %eax %eax               # eax<- vBB (array object)
   2400     GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
   2401     testl     %eax,%eax                 # null array object?
   2402     je        common_errNullObject      # bail if so
   2403     cmpl      offArrayObject_length(%eax),%ecx
   2404     jae       common_errArrayIndex      # index >= length, bail.  Expects:
   2405                                         #   arrayObj in eax
   2406                                         #   index in ecx
   2407     leal      offArrayObject_contents(%eax,%ecx,4),%eax
   2408 .LOP_APUT_finish:
   2409     GET_VREG_R  rINST rINST
   2410     FETCH_INST_OPCODE 2 %ecx
   2411     movl     rINST,(%eax)
   2412     ADVANCE_PC 2
   2413     GOTO_NEXT_R %ecx
   2414 
   2415 /* ------------------------------ */
   2416 .L_OP_APUT_WIDE: /* 0x4c */
   2417 /* File: x86/OP_APUT_WIDE.S */
   2418     /*
   2419      * Array put, 64 bits.  vBB[vCC]<-vAA.
   2420      *
   2421      */
   2422     /* op vAA, vBB, vCC */
   2423     movzbl    2(rPC),%eax               # eax<- BB
   2424     movzbl    3(rPC),%ecx               # ecx<- CC
   2425     GET_VREG_R  %eax %eax               # eax<- vBB (array object)
   2426     GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
   2427     testl     %eax,%eax                 # null array object?
   2428     je        common_errNullObject      # bail if so
   2429     cmpl      offArrayObject_length(%eax),%ecx
   2430     jae       common_errArrayIndex      # index >= length, bail.  Expects:
   2431                                         #   arrayObj in eax
   2432                                         #   index in ecx
   2433     leal      offArrayObject_contents(%eax,%ecx,8),%eax
   2434     GET_VREG_WORD %ecx rINST 0
   2435     GET_VREG_WORD rINST rINST 1
   2436     movl      %ecx,(%eax)
   2437     FETCH_INST_OPCODE 2 %ecx
   2438     movl      rINST,4(%eax)
   2439     ADVANCE_PC 2
   2440     GOTO_NEXT_R %ecx
   2441 
   2442 /* ------------------------------ */
   2443 .L_OP_APUT_OBJECT: /* 0x4d */
   2444 /* File: x86/OP_APUT_OBJECT.S */
   2445     /*
   2446      * Array put, 32 bits or less.  vBB[vCC] <- vAA
   2447      *
   2448      * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
   2449      */
   2450     /* op vAA, vBB, vCC */
   2451     movzbl    2(rPC),%eax               # eax<- BB
   2452     movzbl    3(rPC),%ecx               # ecx<- CC
   2453     GET_VREG_R  %eax %eax               # eax<- vBB (array object)
   2454     GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
   2455     GET_VREG_R  rINST rINST             # rINST<- vAA
   2456     testl     %eax,%eax                 # null array object?
   2457     je        common_errNullObject      # bail if so
   2458     cmpl      offArrayObject_length(%eax),%ecx
   2459     jae       common_errArrayIndex      # index >= length, bail.  Expects
   2460                                         #    arrayObj in eax
   2461                                         #    index in ecx
   2462     /* On entry:
   2463      *   eax<- array object
   2464      *   ecx<- index
   2465      *   rINST<- vAA
   2466      */
   2467     leal      offArrayObject_contents(%eax,%ecx,4),%ecx
   2468     testl     rINST,rINST                    # storing null reference?
   2469     je        .LOP_APUT_OBJECT_skip_check
   2470     SPILL_TMP1(%ecx)                         # save target address
   2471     SPILL_TMP2(%eax)                         # save object head
   2472     movl      offObject_clazz(%eax),%eax     # eax<- arrayObj->clazz
   2473     movl      offObject_clazz(rINST),%ecx    # ecx<- obj->clazz
   2474     movl      %eax,OUT_ARG1(%esp)
   2475     movl      %ecx,OUT_ARG0(%esp)
   2476     movl      %ecx,sReg0                     # store the two classes for later
   2477     movl      %eax,sReg1
   2478     SPILL(rIBASE)
   2479     call      dvmCanPutArrayElement          # test object type vs. array type
   2480     UNSPILL(rIBASE)
   2481     UNSPILL_TMP1(%ecx)                       # recover target address
   2482     testl     %eax,%eax
   2483     movl      rSELF,%eax
   2484     jne       .LOP_APUT_OBJECT_types_okay
   2485 
   2486     # The types don't match.  We need to throw an ArrayStoreException.
   2487     EXPORT_PC
   2488     movl      sReg0,%eax                     # restore the two classes...
   2489     movl      %eax,OUT_ARG0(%esp)
   2490     movl      sReg1,%ecx
   2491     movl      %ecx,OUT_ARG1(%esp)
   2492     call      dvmThrowArrayStoreExceptionIncompatibleElement # ...and throw
   2493     jmp       common_exceptionThrown
   2494 
   2495 .LOP_APUT_OBJECT_types_okay:
   2496     movl      offThread_cardTable(%eax),%eax   # get card table base
   2497     movl      rINST,(%ecx)                   # store into array
   2498     UNSPILL_TMP2(rINST)                      # recover object head
   2499     FETCH_INST_OPCODE 2 %ecx
   2500     shrl      $GC_CARD_SHIFT,rINST          # object head to card number
   2501     movb      %al,(%eax,rINST)               # mark card using object head
   2502     ADVANCE_PC 2
   2503     GOTO_NEXT_R %ecx
   2504 
   2505 .LOP_APUT_OBJECT_skip_check:
   2506     movl      rINST,(%ecx)
   2507     FETCH_INST_OPCODE 2 %ecx
   2508     ADVANCE_PC 2
   2509     GOTO_NEXT_R %ecx
   2510 
   2511 /* ------------------------------ */
   2512 .L_OP_APUT_BOOLEAN: /* 0x4e */
   2513 /* File: x86/OP_APUT_BOOLEAN.S */
   2514 /* File: x86/OP_APUT.S */
   2515     /*
   2516      * Array put, 32 bits or less.  vBB[vCC] <- vAA
   2517      *
   2518      * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
   2519      */
   2520     /* op vAA, vBB, vCC */
   2521     movzbl    2(rPC),%eax               # eax<- BB
   2522     movzbl    3(rPC),%ecx               # ecx<- CC
   2523     GET_VREG_R  %eax %eax               # eax<- vBB (array object)
   2524     GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
   2525     testl     %eax,%eax                 # null array object?
   2526     je        common_errNullObject      # bail if so
   2527     cmpl      offArrayObject_length(%eax),%ecx
   2528     jae       common_errArrayIndex      # index >= length, bail.  Expects:
   2529                                         #   arrayObj in eax
   2530                                         #   index in ecx
   2531     leal      offArrayObject_contents(%eax,%ecx,1),%eax
   2532 .LOP_APUT_BOOLEAN_finish:
   2533     GET_VREG_R  rINST rINST
   2534     FETCH_INST_OPCODE 2 %ecx
   2535     movb     rINSTbl,(%eax)
   2536     ADVANCE_PC 2
   2537     GOTO_NEXT_R %ecx
   2538 
   2539 
   2540 /* ------------------------------ */
   2541 .L_OP_APUT_BYTE: /* 0x4f */
   2542 /* File: x86/OP_APUT_BYTE.S */
   2543 /* File: x86/OP_APUT.S */
   2544     /*
   2545      * Array put, 32 bits or less.  vBB[vCC] <- vAA
   2546      *
   2547      * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
   2548      */
   2549     /* op vAA, vBB, vCC */
   2550     movzbl    2(rPC),%eax               # eax<- BB
   2551     movzbl    3(rPC),%ecx               # ecx<- CC
   2552     GET_VREG_R  %eax %eax               # eax<- vBB (array object)
   2553     GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
   2554     testl     %eax,%eax                 # null array object?
   2555     je        common_errNullObject      # bail if so
   2556     cmpl      offArrayObject_length(%eax),%ecx
   2557     jae       common_errArrayIndex      # index >= length, bail.  Expects:
   2558                                         #   arrayObj in eax
   2559                                         #   index in ecx
   2560     leal      offArrayObject_contents(%eax,%ecx,1),%eax
   2561 .LOP_APUT_BYTE_finish:
   2562     GET_VREG_R  rINST rINST
   2563     FETCH_INST_OPCODE 2 %ecx
   2564     movb     rINSTbl,(%eax)
   2565     ADVANCE_PC 2
   2566     GOTO_NEXT_R %ecx
   2567 
   2568 
   2569 /* ------------------------------ */
   2570 .L_OP_APUT_CHAR: /* 0x50 */
   2571 /* File: x86/OP_APUT_CHAR.S */
   2572 /* File: x86/OP_APUT.S */
   2573     /*
   2574      * Array put, 32 bits or less.  vBB[vCC] <- vAA
   2575      *
   2576      * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
   2577      */
   2578     /* op vAA, vBB, vCC */
   2579     movzbl    2(rPC),%eax               # eax<- BB
   2580     movzbl    3(rPC),%ecx               # ecx<- CC
   2581     GET_VREG_R  %eax %eax               # eax<- vBB (array object)
   2582     GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
   2583     testl     %eax,%eax                 # null array object?
   2584     je        common_errNullObject      # bail if so
   2585     cmpl      offArrayObject_length(%eax),%ecx
   2586     jae       common_errArrayIndex      # index >= length, bail.  Expects:
   2587                                         #   arrayObj in eax
   2588                                         #   index in ecx
   2589     leal      offArrayObject_contents(%eax,%ecx,2),%eax
   2590 .LOP_APUT_CHAR_finish:
   2591     GET_VREG_R  rINST rINST
   2592     FETCH_INST_OPCODE 2 %ecx
   2593     movw     rINSTw,(%eax)
   2594     ADVANCE_PC 2
   2595     GOTO_NEXT_R %ecx
   2596 
   2597 
   2598 /* ------------------------------ */
   2599 .L_OP_APUT_SHORT: /* 0x51 */
   2600 /* File: x86/OP_APUT_SHORT.S */
   2601 /* File: x86/OP_APUT.S */
   2602     /*
   2603      * Array put, 32 bits or less.  vBB[vCC] <- vAA
   2604      *
   2605      * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
   2606      */
   2607     /* op vAA, vBB, vCC */
   2608     movzbl    2(rPC),%eax               # eax<- BB
   2609     movzbl    3(rPC),%ecx               # ecx<- CC
   2610     GET_VREG_R  %eax %eax               # eax<- vBB (array object)
   2611     GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
   2612     testl     %eax,%eax                 # null array object?
   2613     je        common_errNullObject      # bail if so
   2614     cmpl      offArrayObject_length(%eax),%ecx
   2615     jae       common_errArrayIndex      # index >= length, bail.  Expects:
   2616                                         #   arrayObj in eax
   2617                                         #   index in ecx
   2618     leal      offArrayObject_contents(%eax,%ecx,2),%eax
   2619 .LOP_APUT_SHORT_finish:
   2620     GET_VREG_R  rINST rINST
   2621     FETCH_INST_OPCODE 2 %ecx
   2622     movw     rINSTw,(%eax)
   2623     ADVANCE_PC 2
   2624     GOTO_NEXT_R %ecx
   2625 
   2626 
   2627 /* ------------------------------ */
   2628 .L_OP_IGET: /* 0x52 */
   2629 /* File: x86/OP_IGET.S */
   2630     /*
   2631      * General 32-bit instance field get.
   2632      *
   2633      * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
   2634      */
   2635     /* op vA, vB, field@CCCC */
   2636     movl    rSELF,%ecx
   2637     SPILL(rIBASE)                               # preserve rIBASE
   2638     movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
   2639     movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
   2640     movzbl  rINSTbl,%ecx                        # ecx<- BA
   2641     sarl    $4,%ecx                            # ecx<- B
   2642     movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
   2643     andb    $0xf,rINSTbl                       # rINST<- A
   2644     GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
   2645     movl    (%eax,rIBASE,4),%eax                # resolved entry
   2646     testl   %eax,%eax                           # is resolved entry null?
   2647     jne     .LOP_IGET_finish                  # no, already resolved
   2648     movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
   2649     movl    rSELF,rIBASE
   2650     EXPORT_PC
   2651     movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
   2652     movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
   2653     SPILL_TMP1(%ecx)                            # save obj pointer across call
   2654     movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
   2655     call    dvmResolveInstField                 #  ... to dvmResolveInstField
   2656     UNSPILL_TMP1(%ecx)
   2657     testl   %eax,%eax                           #  returns InstrField ptr
   2658     jne     .LOP_IGET_finish
   2659     jmp     common_exceptionThrown
   2660 
   2661 .LOP_IGET_finish:
   2662     /*
   2663      * Currently:
   2664      *   eax holds resolved field
   2665      *   ecx holds object
   2666      *   rINST holds A
   2667      */
   2668     movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
   2669     testl   %ecx,%ecx                           # object null?
   2670     je      common_errNullObject                # object was null
   2671     movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
   2672     FETCH_INST_OPCODE 2 %eax
   2673     UNSPILL(rIBASE)
   2674     SET_VREG %ecx rINST
   2675     ADVANCE_PC 2
   2676     GOTO_NEXT_R %eax
   2677 
   2678 /* ------------------------------ */
   2679 .L_OP_IGET_WIDE: /* 0x53 */
   2680 /* File: x86/OP_IGET_WIDE.S */
   2681     /*
   2682      * 64-bit instance field get.
   2683      *
   2684      */
   2685     /* op vA, vB, field@CCCC */
   2686     movl    rSELF,%ecx
   2687     SPILL(rIBASE)                               # preserve rIBASE
   2688     movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
   2689     movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
   2690     movzbl  rINSTbl,%ecx                        # ecx<- BA
   2691     sarl    $4,%ecx                            # ecx<- B
   2692     movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
   2693     andb    $0xf,rINSTbl                       # rINST<- A
   2694     GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
   2695     movl    (%eax,rIBASE,4),%eax                # resolved entry
   2696     testl   %eax,%eax                           # is resolved entry null?
   2697     jne     .LOP_IGET_WIDE_finish                  # no, already resolved
   2698     movl    rIBASE,OUT_ARG1(%esp)               # for dvmResolveInstField
   2699     movl    rSELF,rIBASE
   2700     EXPORT_PC
   2701     movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
   2702     movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
   2703     SPILL_TMP1(%ecx)                            # save objpointer across call
   2704     movl    rPC,OUT_ARG0(%esp)                  # pass in method->clazz
   2705     call    dvmResolveInstField                 #  ... to dvmResolveInstField
   2706     UNSPILL_TMP1(%ecx)
   2707     testl   %eax,%eax                           # returns InstrField ptr
   2708     jne     .LOP_IGET_WIDE_finish
   2709     jmp     common_exceptionThrown
   2710 
   2711 .LOP_IGET_WIDE_finish:
   2712     /*
   2713      * Currently:
   2714      *   eax holds resolved field
   2715      *   ecx holds object
   2716      *   rINST holds A
   2717      */
   2718     movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
   2719     testl   %ecx,%ecx                           # object null?
   2720     je      common_errNullObject                # object was null
   2721     leal    (%ecx,%eax,1),%eax                  # eax<- address of field
   2722     movl    (%eax),%ecx                         # ecx<- lsw
   2723     movl    4(%eax),%eax                        # eax<- msw
   2724     SET_VREG_WORD %ecx rINST 0
   2725     FETCH_INST_OPCODE 2 %ecx
   2726     UNSPILL(rIBASE)                             # restore rIBASE
   2727     SET_VREG_WORD %eax rINST 1
   2728     ADVANCE_PC 2
   2729     GOTO_NEXT_R %ecx
   2730 
   2731 /* ------------------------------ */
   2732 .L_OP_IGET_OBJECT: /* 0x54 */
   2733 /* File: x86/OP_IGET_OBJECT.S */
   2734 /* File: x86/OP_IGET.S */
   2735     /*
   2736      * General 32-bit instance field get.
   2737      *
   2738      * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
   2739      */
   2740     /* op vA, vB, field@CCCC */
   2741     movl    rSELF,%ecx
   2742     SPILL(rIBASE)                               # preserve rIBASE
   2743     movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
   2744     movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
   2745     movzbl  rINSTbl,%ecx                        # ecx<- BA
   2746     sarl    $4,%ecx                            # ecx<- B
   2747     movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
   2748     andb    $0xf,rINSTbl                       # rINST<- A
   2749     GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
   2750     movl    (%eax,rIBASE,4),%eax                # resolved entry
   2751     testl   %eax,%eax                           # is resolved entry null?
   2752     jne     .LOP_IGET_OBJECT_finish                  # no, already resolved
   2753     movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
   2754     movl    rSELF,rIBASE
   2755     EXPORT_PC
   2756     movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
   2757     movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
   2758     SPILL_TMP1(%ecx)                            # save obj pointer across call
   2759     movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
   2760     call    dvmResolveInstField                 #  ... to dvmResolveInstField
   2761     UNSPILL_TMP1(%ecx)
   2762     testl   %eax,%eax                           #  returns InstrField ptr
   2763     jne     .LOP_IGET_OBJECT_finish
   2764     jmp     common_exceptionThrown
   2765 
   2766 .LOP_IGET_OBJECT_finish:
   2767     /*
   2768      * Currently:
   2769      *   eax holds resolved field
   2770      *   ecx holds object
   2771      *   rINST holds A
   2772      */
   2773     movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
   2774     testl   %ecx,%ecx                           # object null?
   2775     je      common_errNullObject                # object was null
   2776     movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
   2777     FETCH_INST_OPCODE 2 %eax
   2778     UNSPILL(rIBASE)
   2779     SET_VREG %ecx rINST
   2780     ADVANCE_PC 2
   2781     GOTO_NEXT_R %eax
   2782 
   2783 
   2784 /* ------------------------------ */
   2785 .L_OP_IGET_BOOLEAN: /* 0x55 */
   2786 /* File: x86/OP_IGET_BOOLEAN.S */
   2787 /* File: x86/OP_IGET.S */
   2788     /*
   2789      * General 32-bit instance field get.
   2790      *
   2791      * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
   2792      */
   2793     /* op vA, vB, field@CCCC */
   2794     movl    rSELF,%ecx
   2795     SPILL(rIBASE)                               # preserve rIBASE
   2796     movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
   2797     movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
   2798     movzbl  rINSTbl,%ecx                        # ecx<- BA
   2799     sarl    $4,%ecx                            # ecx<- B
   2800     movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
   2801     andb    $0xf,rINSTbl                       # rINST<- A
   2802     GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
   2803     movl    (%eax,rIBASE,4),%eax                # resolved entry
   2804     testl   %eax,%eax                           # is resolved entry null?
   2805     jne     .LOP_IGET_BOOLEAN_finish                  # no, already resolved
   2806     movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
   2807     movl    rSELF,rIBASE
   2808     EXPORT_PC
   2809     movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
   2810     movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
   2811     SPILL_TMP1(%ecx)                            # save obj pointer across call
   2812     movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
   2813     call    dvmResolveInstField                 #  ... to dvmResolveInstField
   2814     UNSPILL_TMP1(%ecx)
   2815     testl   %eax,%eax                           #  returns InstrField ptr
   2816     jne     .LOP_IGET_BOOLEAN_finish
   2817     jmp     common_exceptionThrown
   2818 
   2819 .LOP_IGET_BOOLEAN_finish:
   2820     /*
   2821      * Currently:
   2822      *   eax holds resolved field
   2823      *   ecx holds object
   2824      *   rINST holds A
   2825      */
   2826     movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
   2827     testl   %ecx,%ecx                           # object null?
   2828     je      common_errNullObject                # object was null
   2829     movzbl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
   2830     FETCH_INST_OPCODE 2 %eax
   2831     UNSPILL(rIBASE)
   2832     SET_VREG %ecx rINST
   2833     ADVANCE_PC 2
   2834     GOTO_NEXT_R %eax
   2835 
   2836 
   2837 /* ------------------------------ */
   2838 .L_OP_IGET_BYTE: /* 0x56 */
   2839 /* File: x86/OP_IGET_BYTE.S */
   2840 /* File: x86/OP_IGET.S */
   2841     /*
   2842      * General 32-bit instance field get.
   2843      *
   2844      * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
   2845      */
   2846     /* op vA, vB, field@CCCC */
   2847     movl    rSELF,%ecx
   2848     SPILL(rIBASE)                               # preserve rIBASE
   2849     movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
   2850     movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
   2851     movzbl  rINSTbl,%ecx                        # ecx<- BA
   2852     sarl    $4,%ecx                            # ecx<- B
   2853     movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
   2854     andb    $0xf,rINSTbl                       # rINST<- A
   2855     GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
   2856     movl    (%eax,rIBASE,4),%eax                # resolved entry
   2857     testl   %eax,%eax                           # is resolved entry null?
   2858     jne     .LOP_IGET_BYTE_finish                  # no, already resolved
   2859     movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
   2860     movl    rSELF,rIBASE
   2861     EXPORT_PC
   2862     movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
   2863     movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
   2864     SPILL_TMP1(%ecx)                            # save obj pointer across call
   2865     movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
   2866     call    dvmResolveInstField                 #  ... to dvmResolveInstField
   2867     UNSPILL_TMP1(%ecx)
   2868     testl   %eax,%eax                           #  returns InstrField ptr
   2869     jne     .LOP_IGET_BYTE_finish
   2870     jmp     common_exceptionThrown
   2871 
   2872 .LOP_IGET_BYTE_finish:
   2873     /*
   2874      * Currently:
   2875      *   eax holds resolved field
   2876      *   ecx holds object
   2877      *   rINST holds A
   2878      */
   2879     movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
   2880     testl   %ecx,%ecx                           # object null?
   2881     je      common_errNullObject                # object was null
   2882     movsbl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
   2883     FETCH_INST_OPCODE 2 %eax
   2884     UNSPILL(rIBASE)
   2885     SET_VREG %ecx rINST
   2886     ADVANCE_PC 2
   2887     GOTO_NEXT_R %eax
   2888 
   2889 
   2890 /* ------------------------------ */
   2891 .L_OP_IGET_CHAR: /* 0x57 */
   2892 /* File: x86/OP_IGET_CHAR.S */
   2893 /* File: x86/OP_IGET.S */
   2894     /*
   2895      * General 32-bit instance field get.
   2896      *
   2897      * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
   2898      */
   2899     /* op vA, vB, field@CCCC */
   2900     movl    rSELF,%ecx
   2901     SPILL(rIBASE)                               # preserve rIBASE
   2902     movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
   2903     movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
   2904     movzbl  rINSTbl,%ecx                        # ecx<- BA
   2905     sarl    $4,%ecx                            # ecx<- B
   2906     movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
   2907     andb    $0xf,rINSTbl                       # rINST<- A
   2908     GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
   2909     movl    (%eax,rIBASE,4),%eax                # resolved entry
   2910     testl   %eax,%eax                           # is resolved entry null?
   2911     jne     .LOP_IGET_CHAR_finish                  # no, already resolved
   2912     movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
   2913     movl    rSELF,rIBASE
   2914     EXPORT_PC
   2915     movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
   2916     movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
   2917     SPILL_TMP1(%ecx)                            # save obj pointer across call
   2918     movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
   2919     call    dvmResolveInstField                 #  ... to dvmResolveInstField
   2920     UNSPILL_TMP1(%ecx)
   2921     testl   %eax,%eax                           #  returns InstrField ptr
   2922     jne     .LOP_IGET_CHAR_finish
   2923     jmp     common_exceptionThrown
   2924 
   2925 .LOP_IGET_CHAR_finish:
   2926     /*
   2927      * Currently:
   2928      *   eax holds resolved field
   2929      *   ecx holds object
   2930      *   rINST holds A
   2931      */
   2932     movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
   2933     testl   %ecx,%ecx                           # object null?
   2934     je      common_errNullObject                # object was null
   2935     movzwl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
   2936     FETCH_INST_OPCODE 2 %eax
   2937     UNSPILL(rIBASE)
   2938     SET_VREG %ecx rINST
   2939     ADVANCE_PC 2
   2940     GOTO_NEXT_R %eax
   2941 
   2942 
   2943 /* ------------------------------ */
   2944 .L_OP_IGET_SHORT: /* 0x58 */
   2945 /* File: x86/OP_IGET_SHORT.S */
   2946 /* File: x86/OP_IGET.S */
   2947     /*
   2948      * General 32-bit instance field get.
   2949      *
   2950      * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
   2951      */
   2952     /* op vA, vB, field@CCCC */
   2953     movl    rSELF,%ecx
   2954     SPILL(rIBASE)                               # preserve rIBASE
   2955     movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
   2956     movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
   2957     movzbl  rINSTbl,%ecx                        # ecx<- BA
   2958     sarl    $4,%ecx                            # ecx<- B
   2959     movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
   2960     andb    $0xf,rINSTbl                       # rINST<- A
   2961     GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
   2962     movl    (%eax,rIBASE,4),%eax                # resolved entry
   2963     testl   %eax,%eax                           # is resolved entry null?
   2964     jne     .LOP_IGET_SHORT_finish                  # no, already resolved
   2965     movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
   2966     movl    rSELF,rIBASE
   2967     EXPORT_PC
   2968     movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
   2969     movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
   2970     SPILL_TMP1(%ecx)                            # save obj pointer across call
   2971     movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
   2972     call    dvmResolveInstField                 #  ... to dvmResolveInstField
   2973     UNSPILL_TMP1(%ecx)
   2974     testl   %eax,%eax                           #  returns InstrField ptr
   2975     jne     .LOP_IGET_SHORT_finish
   2976     jmp     common_exceptionThrown
   2977 
   2978 .LOP_IGET_SHORT_finish:
   2979     /*
   2980      * Currently:
   2981      *   eax holds resolved field
   2982      *   ecx holds object
   2983      *   rINST holds A
   2984      */
   2985     movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
   2986     testl   %ecx,%ecx                           # object null?
   2987     je      common_errNullObject                # object was null
   2988     movswl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
   2989     FETCH_INST_OPCODE 2 %eax
   2990     UNSPILL(rIBASE)
   2991     SET_VREG %ecx rINST
   2992     ADVANCE_PC 2
   2993     GOTO_NEXT_R %eax
   2994 
   2995 
   2996 /* ------------------------------ */
   2997 .L_OP_IPUT: /* 0x59 */
   2998 /* File: x86/OP_IPUT.S */
   2999 
   3000     /*
   3001      * General 32-bit instance field put.
   3002      *
   3003      * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
   3004      */
   3005     /* op vA, vB, field@CCCC */
   3006     movl    rSELF,%ecx
   3007     SPILL   (rIBASE)
   3008     movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
   3009     movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
   3010     movzbl  rINSTbl,%ecx                        # ecx<- BA
   3011     sarl    $4,%ecx                            # ecx<- B
   3012     movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
   3013     andb    $0xf,rINSTbl                       # rINST<- A
   3014     GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
   3015     movl    (%eax,rIBASE,4),%eax                # resolved entry
   3016     testl   %eax,%eax                           # is resolved entry null?
   3017     jne     .LOP_IPUT_finish                  # no, already resolved
   3018     movl    rIBASE,OUT_ARG1(%esp)
   3019     movl    rSELF,rIBASE
   3020     EXPORT_PC
   3021     movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
   3022     movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
   3023     SPILL_TMP1(%ecx)                            # save obj pointer across call
   3024     movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
   3025     call    dvmResolveInstField                 #  ... to dvmResolveInstField
   3026     UNSPILL_TMP1(%ecx)
   3027     testl   %eax,%eax                           # returns InstrField ptr
   3028     jne     .LOP_IPUT_finish
   3029     jmp     common_exceptionThrown
   3030 
   3031 .LOP_IPUT_finish:
   3032     /*
   3033      * Currently:
   3034      *   eax holds resolved field
   3035      *   ecx holds object
   3036      *   rINST holds A
   3037      */
   3038     GET_VREG_R rINST rINST                       # rINST<- v[A]
   3039     movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
   3040     testl   %ecx,%ecx                            # object null?
   3041     je      common_errNullObject                 # object was null
   3042     movl   rINST,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
   3043     FETCH_INST_OPCODE 2 %ecx
   3044     UNSPILL(rIBASE)
   3045     ADVANCE_PC 2
   3046     GOTO_NEXT_R %ecx
   3047 
   3048 /* ------------------------------ */
   3049 .L_OP_IPUT_WIDE: /* 0x5a */
   3050 /* File: x86/OP_IPUT_WIDE.S */
   3051     /*
   3052      * 64-bit instance field put.
   3053      *
   3054      */
   3055     /* op vA, vB, field@CCCC */
   3056     movl    rSELF,%ecx
   3057     SPILL(rIBASE)
   3058     movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
   3059     movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
   3060     movzbl  rINSTbl,%ecx                        # ecx<- BA
   3061     sarl    $4,%ecx                            # ecx<- B
   3062     movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
   3063     andb    $0xf,rINSTbl                       # rINST<- A
   3064     GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
   3065     movl    (%eax,rIBASE,4),%eax                # resolved entry
   3066     testl   %eax,%eax                           # is resolved entry null?
   3067     jne     .LOP_IPUT_WIDE_finish                  # no, already resolved
   3068     movl    rIBASE,OUT_ARG1(%esp)
   3069     movl    rSELF,rIBASE
   3070     EXPORT_PC
   3071     movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
   3072     movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
   3073     SPILL_TMP1(%ecx)                            # save obj pointer across call
   3074     movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
   3075     call    dvmResolveInstField                 #  ... to dvmResolveInstField
   3076     UNSPILL_TMP1(%ecx)
   3077     testl   %eax,%eax                           #  ... which returns InstrField ptr
   3078     jne     .LOP_IPUT_WIDE_finish
   3079     jmp     common_exceptionThrown
   3080 
   3081 .LOP_IPUT_WIDE_finish:
   3082     /*
   3083      * Currently:
   3084      *   eax holds resolved field
   3085      *   ecx holds object
   3086      *   rIBASE is scratch, but needs to be unspilled
   3087      *   rINST holds A
   3088      */
   3089     movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
   3090     testl   %ecx,%ecx                           # object null?
   3091     je      common_errNullObject                # object was null
   3092     leal    (%ecx,%eax,1),%eax                  # eax<- address of field
   3093     GET_VREG_WORD %ecx rINST 0                  # ecx<- lsw
   3094     GET_VREG_WORD rINST rINST 1                 # rINST<- msw
   3095     movl    rINST,4(%eax)
   3096     movl    %ecx,(%eax)
   3097     FETCH_INST_OPCODE 2 %ecx
   3098     UNSPILL(rIBASE)
   3099     ADVANCE_PC 2
   3100     GOTO_NEXT_R %ecx
   3101 
   3102 /* ------------------------------ */
   3103 .L_OP_IPUT_OBJECT: /* 0x5b */
   3104 /* File: x86/OP_IPUT_OBJECT.S */
   3105     /*
   3106      * Object field put.
   3107      *
   3108      * for: iput-object
   3109      */
   3110     /* op vA, vB, field@CCCC */
   3111     movl    rSELF,%ecx
   3112     SPILL(rIBASE)
   3113     movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
   3114     movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
   3115     movzbl  rINSTbl,%ecx                        # ecx<- BA
   3116     sarl    $4,%ecx                            # ecx<- B
   3117     movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
   3118     andb    $0xf,rINSTbl                       # rINST<- A
   3119     GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
   3120     movl    (%eax,rIBASE,4),%eax                  # resolved entry
   3121     testl   %eax,%eax                           # is resolved entry null?
   3122     jne     .LOP_IPUT_OBJECT_finish                  # no, already resolved
   3123     movl    rIBASE,OUT_ARG1(%esp)
   3124     movl    rSELF,rIBASE
   3125     EXPORT_PC
   3126     movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
   3127     movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
   3128     SPILL_TMP1(%ecx)                            # save obj pointer across call
   3129     movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
   3130     call    dvmResolveInstField                 #  ... to dvmResolveInstField
   3131     UNSPILL_TMP1(%ecx)
   3132     testl   %eax,%eax                           # returns InstrField ptr
   3133     jne     .LOP_IPUT_OBJECT_finish
   3134     jmp     common_exceptionThrown
   3135 
   3136 .LOP_IPUT_OBJECT_finish:
   3137     /*
   3138      * Currently:
   3139      *   eax holds resolved field
   3140      *   ecx holds object
   3141      *   rIBASE is scratch, but needs to be unspilled
   3142      *   rINST holds A
   3143      */
   3144     GET_VREG_R rINST rINST                      # rINST<- v[A]
   3145     movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
   3146     testl   %ecx,%ecx                           # object null?
   3147     je      common_errNullObject                # object was null
   3148     movl    rINST,(%ecx,%eax)      # obj.field <- v[A](8/16/32 bits)
   3149     movl    rSELF,%eax
   3150     testl   rINST,rINST                         # stored a NULL?
   3151     movl    offThread_cardTable(%eax),%eax      # get card table base
   3152     je      1f                                  # skip card mark if null store
   3153     shrl    $GC_CARD_SHIFT,%ecx                # object head to card number
   3154     movb    %al,(%eax,%ecx)                     # mark card using object head
   3155 1:
   3156     UNSPILL(rIBASE)
   3157     FETCH_INST_OPCODE 2 %ecx
   3158     ADVANCE_PC 2
   3159     GOTO_NEXT_R %ecx
   3160 
   3161 /* ------------------------------ */
   3162 .L_OP_IPUT_BOOLEAN: /* 0x5c */
   3163 /* File: x86/OP_IPUT_BOOLEAN.S */
   3164 /* File: x86/OP_IPUT.S */
   3165 
   3166     /*
   3167      * General 32-bit instance field put.
   3168      *
   3169      * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
   3170      */
   3171     /* op vA, vB, field@CCCC */
   3172     movl    rSELF,%ecx
   3173     SPILL   (rIBASE)
   3174     movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
   3175     movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
   3176     movzbl  rINSTbl,%ecx                        # ecx<- BA
   3177     sarl    $4,%ecx                            # ecx<- B
   3178     movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
   3179     andb    $0xf,rINSTbl                       # rINST<- A
   3180     GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
   3181     movl    (%eax,rIBASE,4),%eax                # resolved entry
   3182     testl   %eax,%eax                           # is resolved entry null?
   3183     jne     .LOP_IPUT_BOOLEAN_finish                  # no, already resolved
   3184     movl    rIBASE,OUT_ARG1(%esp)
   3185     movl    rSELF,rIBASE
   3186     EXPORT_PC
   3187     movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
   3188     movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
   3189     SPILL_TMP1(%ecx)                            # save obj pointer across call
   3190     movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
   3191     call    dvmResolveInstField                 #  ... to dvmResolveInstField
   3192     UNSPILL_TMP1(%ecx)
   3193     testl   %eax,%eax                           # returns InstrField ptr
   3194     jne     .LOP_IPUT_BOOLEAN_finish
   3195     jmp     common_exceptionThrown
   3196 
   3197 .LOP_IPUT_BOOLEAN_finish:
   3198     /*
   3199      * Currently:
   3200      *   eax holds resolved field
   3201      *   ecx holds object
   3202      *   rINST holds A
   3203      */
   3204     GET_VREG_R rINST rINST                       # rINST<- v[A]
   3205     movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
   3206     testl   %ecx,%ecx                            # object null?
   3207     je      common_errNullObject                 # object was null
   3208     movb   rINSTbl,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
   3209     FETCH_INST_OPCODE 2 %ecx
   3210     UNSPILL(rIBASE)
   3211     ADVANCE_PC 2
   3212     GOTO_NEXT_R %ecx
   3213 
   3214 
   3215 /* ------------------------------ */
   3216 .L_OP_IPUT_BYTE: /* 0x5d */
   3217 /* File: x86/OP_IPUT_BYTE.S */
   3218 /* File: x86/OP_IPUT.S */
   3219 
   3220     /*
   3221      * General 32-bit instance field put.
   3222      *
   3223      * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
   3224      */
   3225     /* op vA, vB, field@CCCC */
   3226     movl    rSELF,%ecx
   3227     SPILL   (rIBASE)
   3228     movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
   3229     movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
   3230     movzbl  rINSTbl,%ecx                        # ecx<- BA
   3231     sarl    $4,%ecx                            # ecx<- B
   3232     movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
   3233     andb    $0xf,rINSTbl                       # rINST<- A
   3234     GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
   3235     movl    (%eax,rIBASE,4),%eax                # resolved entry
   3236     testl   %eax,%eax                           # is resolved entry null?
   3237     jne     .LOP_IPUT_BYTE_finish                  # no, already resolved
   3238     movl    rIBASE,OUT_ARG1(%esp)
   3239     movl    rSELF,rIBASE
   3240     EXPORT_PC
   3241     movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
   3242     movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
   3243     SPILL_TMP1(%ecx)                            # save obj pointer across call
   3244     movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
   3245     call    dvmResolveInstField                 #  ... to dvmResolveInstField
   3246     UNSPILL_TMP1(%ecx)
   3247     testl   %eax,%eax                           # returns InstrField ptr
   3248     jne     .LOP_IPUT_BYTE_finish
   3249     jmp     common_exceptionThrown
   3250 
   3251 .LOP_IPUT_BYTE_finish:
   3252     /*
   3253      * Currently:
   3254      *   eax holds resolved field
   3255      *   ecx holds object
   3256      *   rINST holds A
   3257      */
   3258     GET_VREG_R rINST rINST                       # rINST<- v[A]
   3259     movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
   3260     testl   %ecx,%ecx                            # object null?
   3261     je      common_errNullObject                 # object was null
   3262     movb   rINSTbl,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
   3263     FETCH_INST_OPCODE 2 %ecx
   3264     UNSPILL(rIBASE)
   3265     ADVANCE_PC 2
   3266     GOTO_NEXT_R %ecx
   3267 
   3268 
   3269 /* ------------------------------ */
   3270 .L_OP_IPUT_CHAR: /* 0x5e */
   3271 /* File: x86/OP_IPUT_CHAR.S */
   3272 /* File: x86/OP_IPUT.S */
   3273 
   3274     /*
   3275      * General 32-bit instance field put.
   3276      *
   3277      * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
   3278      */
   3279     /* op vA, vB, field@CCCC */
   3280     movl    rSELF,%ecx
   3281     SPILL   (rIBASE)
   3282     movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
   3283     movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
   3284     movzbl  rINSTbl,%ecx                        # ecx<- BA
   3285     sarl    $4,%ecx                            # ecx<- B
   3286     movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
   3287     andb    $0xf,rINSTbl                       # rINST<- A
   3288     GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
   3289     movl    (%eax,rIBASE,4),%eax                # resolved entry
   3290     testl   %eax,%eax                           # is resolved entry null?
   3291     jne     .LOP_IPUT_CHAR_finish                  # no, already resolved
   3292     movl    rIBASE,OUT_ARG1(%esp)
   3293     movl    rSELF,rIBASE
   3294     EXPORT_PC
   3295     movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
   3296     movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
   3297     SPILL_TMP1(%ecx)                            # save obj pointer across call
   3298     movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
   3299     call    dvmResolveInstField                 #  ... to dvmResolveInstField
   3300     UNSPILL_TMP1(%ecx)
   3301     testl   %eax,%eax                           # returns InstrField ptr
   3302     jne     .LOP_IPUT_CHAR_finish
   3303     jmp     common_exceptionThrown
   3304 
   3305 .LOP_IPUT_CHAR_finish:
   3306     /*
   3307      * Currently:
   3308      *   eax holds resolved field
   3309      *   ecx holds object
   3310      *   rINST holds A
   3311      */
   3312     GET_VREG_R rINST rINST                       # rINST<- v[A]
   3313     movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
   3314     testl   %ecx,%ecx                            # object null?
   3315     je      common_errNullObject                 # object was null
   3316     movw   rINSTw,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
   3317     FETCH_INST_OPCODE 2 %ecx
   3318     UNSPILL(rIBASE)
   3319     ADVANCE_PC 2
   3320     GOTO_NEXT_R %ecx
   3321 
   3322 
   3323 /* ------------------------------ */
   3324 .L_OP_IPUT_SHORT: /* 0x5f */
   3325 /* File: x86/OP_IPUT_SHORT.S */
   3326 /* File: x86/OP_IPUT.S */
   3327 
   3328     /*
   3329      * General 32-bit instance field put.
   3330      *
   3331      * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
   3332      */
   3333     /* op vA, vB, field@CCCC */
   3334     movl    rSELF,%ecx
   3335     SPILL   (rIBASE)
   3336     movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
   3337     movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
   3338     movzbl  rINSTbl,%ecx                        # ecx<- BA
   3339     sarl    $4,%ecx                            # ecx<- B
   3340     movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
   3341     andb    $0xf,rINSTbl                       # rINST<- A
   3342     GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
   3343     movl    (%eax,rIBASE,4),%eax                # resolved entry
   3344     testl   %eax,%eax                           # is resolved entry null?
   3345     jne     .LOP_IPUT_SHORT_finish                  # no, already resolved
   3346     movl    rIBASE,OUT_ARG1(%esp)
   3347     movl    rSELF,rIBASE
   3348     EXPORT_PC
   3349     movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
   3350     movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
   3351     SPILL_TMP1(%ecx)                            # save obj pointer across call
   3352     movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
   3353     call    dvmResolveInstField                 #  ... to dvmResolveInstField
   3354     UNSPILL_TMP1(%ecx)
   3355     testl   %eax,%eax                           # returns InstrField ptr
   3356     jne     .LOP_IPUT_SHORT_finish
   3357     jmp     common_exceptionThrown
   3358 
   3359 .LOP_IPUT_SHORT_finish:
   3360     /*
   3361      * Currently:
   3362      *   eax holds resolved field
   3363      *   ecx holds object
   3364      *   rINST holds A
   3365      */
   3366     GET_VREG_R rINST rINST                       # rINST<- v[A]
   3367     movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
   3368     testl   %ecx,%ecx                            # object null?
   3369     je      common_errNullObject                 # object was null
   3370     movw   rINSTw,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
   3371     FETCH_INST_OPCODE 2 %ecx
   3372     UNSPILL(rIBASE)
   3373     ADVANCE_PC 2
   3374     GOTO_NEXT_R %ecx
   3375 
   3376 
   3377 /* ------------------------------ */
   3378 .L_OP_SGET: /* 0x60 */
   3379 /* File: x86/OP_SGET.S */
   3380     /*
   3381      * General 32-bit SGET handler.
   3382      *
   3383      * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
   3384      */
   3385     /* op vAA, field@BBBB */
   3386     movl      rSELF,%ecx
   3387     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
   3388     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
   3389     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
   3390 #if defined(WITH_JIT)
   3391     movl      %ecx, TMP_SPILL1(%ebp)
   3392     lea       (%ecx,%eax,4),%ecx
   3393     movl      %ecx, TMP_SPILL2(%ebp)
   3394     movl      TMP_SPILL1(%ebp), %ecx
   3395 #endif
   3396     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
   3397     testl     %eax,%eax                          # resolved entry null?
   3398     je        .LOP_SGET_resolve                # if not, make it so
   3399 .LOP_SGET_finish:     # field ptr in eax
   3400     movl      offStaticField_value(%eax),%eax
   3401     FETCH_INST_OPCODE 2 %ecx
   3402     ADVANCE_PC 2
   3403     SET_VREG %eax rINST
   3404     GOTO_NEXT_R %ecx
   3405 
   3406     /*
   3407      * Go resolve the field
   3408      */
   3409 .LOP_SGET_resolve:
   3410     movl     rSELF,%ecx
   3411     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
   3412     movl     offThread_method(%ecx),%ecx          # ecx<- current method
   3413     EXPORT_PC                                   # could throw, need to export
   3414     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
   3415     movl     %eax,OUT_ARG1(%esp)
   3416     movl     %ecx,OUT_ARG0(%esp)
   3417     SPILL(rIBASE)
   3418     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
   3419     UNSPILL(rIBASE)
   3420     testl    %eax,%eax
   3421     je      common_exceptionThrown             # no, handle exception
   3422 #if defined(WITH_JIT)
   3423     movl      TMP_SPILL2(%ebp), %ecx
   3424     SPILL(rIBASE)
   3425     call     common_verifyField
   3426     UNSPILL(rIBASE)
   3427 #endif
   3428     jmp      .LOP_SGET_finish                 # success, continue
   3429 
   3430 /* ------------------------------ */
   3431 .L_OP_SGET_WIDE: /* 0x61 */
   3432 /* File: x86/OP_SGET_WIDE.S */
   3433     /*
   3434      * 64-bit SGET handler.
   3435      *
   3436      */
   3437     /* sget-wide vAA, field@BBBB */
   3438     movl      rSELF,%ecx
   3439     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
   3440     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
   3441     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
   3442 #if defined(WITH_JIT)
   3443     movl      %ecx, TMP_SPILL1(%ebp)
   3444     lea       (%ecx,%eax,4),%ecx
   3445     movl      %ecx, TMP_SPILL2(%ebp)
   3446     movl      TMP_SPILL1(%ebp), %ecx
   3447 #endif
   3448     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
   3449     testl     %eax,%eax                          # resolved entry null?
   3450     je        .LOP_SGET_WIDE_resolve                # if not, make it so
   3451 .LOP_SGET_WIDE_finish:     # field ptr in eax
   3452     movl      offStaticField_value(%eax),%ecx    # ecx<- lsw
   3453     movl      4+offStaticField_value(%eax),%eax  # eax<- msw
   3454     SET_VREG_WORD %ecx rINST 0
   3455     FETCH_INST_OPCODE 2 %ecx
   3456     SET_VREG_WORD %eax rINST 1
   3457     ADVANCE_PC 2
   3458     GOTO_NEXT_R %ecx
   3459 
   3460     /*
   3461      * Go resolve the field
   3462      */
   3463 .LOP_SGET_WIDE_resolve:
   3464     movl     rSELF,%ecx
   3465     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
   3466     movl     offThread_method(%ecx),%ecx          # ecx<- current method
   3467     EXPORT_PC                                   # could throw, need to export
   3468     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
   3469     movl     %eax,OUT_ARG1(%esp)
   3470     movl     %ecx,OUT_ARG0(%esp)
   3471     SPILL(rIBASE)
   3472     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
   3473     UNSPILL(rIBASE)
   3474     testl    %eax,%eax
   3475     je      common_exceptionThrown             # no, handle exception
   3476 #if defined(WITH_JIT)
   3477     movl      TMP_SPILL2(%ebp), %ecx
   3478     SPILL(rIBASE)
   3479     call     common_verifyField
   3480     UNSPILL(rIBASE)
   3481 #endif
   3482     jmp      .LOP_SGET_WIDE_finish                 # success, continue
   3483 
   3484 /* ------------------------------ */
   3485 .L_OP_SGET_OBJECT: /* 0x62 */
   3486 /* File: x86/OP_SGET_OBJECT.S */
   3487 /* File: x86/OP_SGET.S */
   3488     /*
   3489      * General 32-bit SGET handler.
   3490      *
   3491      * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
   3492      */
   3493     /* op vAA, field@BBBB */
   3494     movl      rSELF,%ecx
   3495     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
   3496     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
   3497     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
   3498 #if defined(WITH_JIT)
   3499     movl      %ecx, TMP_SPILL1(%ebp)
   3500     lea       (%ecx,%eax,4),%ecx
   3501     movl      %ecx, TMP_SPILL2(%ebp)
   3502     movl      TMP_SPILL1(%ebp), %ecx
   3503 #endif
   3504     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
   3505     testl     %eax,%eax                          # resolved entry null?
   3506     je        .LOP_SGET_OBJECT_resolve                # if not, make it so
   3507 .LOP_SGET_OBJECT_finish:     # field ptr in eax
   3508     movl      offStaticField_value(%eax),%eax
   3509     FETCH_INST_OPCODE 2 %ecx
   3510     ADVANCE_PC 2
   3511     SET_VREG %eax rINST
   3512     GOTO_NEXT_R %ecx
   3513 
   3514     /*
   3515      * Go resolve the field
   3516      */
   3517 .LOP_SGET_OBJECT_resolve:
   3518     movl     rSELF,%ecx
   3519     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
   3520     movl     offThread_method(%ecx),%ecx          # ecx<- current method
   3521     EXPORT_PC                                   # could throw, need to export
   3522     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
   3523     movl     %eax,OUT_ARG1(%esp)
   3524     movl     %ecx,OUT_ARG0(%esp)
   3525     SPILL(rIBASE)
   3526     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
   3527     UNSPILL(rIBASE)
   3528     testl    %eax,%eax
   3529     je      common_exceptionThrown             # no, handle exception
   3530 #if defined(WITH_JIT)
   3531     movl      TMP_SPILL2(%ebp), %ecx
   3532     SPILL(rIBASE)
   3533     call     common_verifyField
   3534     UNSPILL(rIBASE)
   3535 #endif
   3536     jmp      .LOP_SGET_OBJECT_finish                 # success, continue
   3537 
   3538 
   3539 /* ------------------------------ */
   3540 .L_OP_SGET_BOOLEAN: /* 0x63 */
   3541 /* File: x86/OP_SGET_BOOLEAN.S */
   3542 /* File: x86/OP_SGET.S */
   3543     /*
   3544      * General 32-bit SGET handler.
   3545      *
   3546      * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
   3547      */
   3548     /* op vAA, field@BBBB */
   3549     movl      rSELF,%ecx
   3550     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
   3551     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
   3552     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
   3553 #if defined(WITH_JIT)
   3554     movl      %ecx, TMP_SPILL1(%ebp)
   3555     lea       (%ecx,%eax,4),%ecx
   3556     movl      %ecx, TMP_SPILL2(%ebp)
   3557     movl      TMP_SPILL1(%ebp), %ecx
   3558 #endif
   3559     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
   3560     testl     %eax,%eax                          # resolved entry null?
   3561     je        .LOP_SGET_BOOLEAN_resolve                # if not, make it so
   3562 .LOP_SGET_BOOLEAN_finish:     # field ptr in eax
   3563     movl      offStaticField_value(%eax),%eax
   3564     FETCH_INST_OPCODE 2 %ecx
   3565     ADVANCE_PC 2
   3566     SET_VREG %eax rINST
   3567     GOTO_NEXT_R %ecx
   3568 
   3569     /*
   3570      * Go resolve the field
   3571      */
   3572 .LOP_SGET_BOOLEAN_resolve:
   3573     movl     rSELF,%ecx
   3574     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
   3575     movl     offThread_method(%ecx),%ecx          # ecx<- current method
   3576     EXPORT_PC                                   # could throw, need to export
   3577     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
   3578     movl     %eax,OUT_ARG1(%esp)
   3579     movl     %ecx,OUT_ARG0(%esp)
   3580     SPILL(rIBASE)
   3581     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
   3582     UNSPILL(rIBASE)
   3583     testl    %eax,%eax
   3584     je      common_exceptionThrown             # no, handle exception
   3585 #if defined(WITH_JIT)
   3586     movl      TMP_SPILL2(%ebp), %ecx
   3587     SPILL(rIBASE)
   3588     call     common_verifyField
   3589     UNSPILL(rIBASE)
   3590 #endif
   3591     jmp      .LOP_SGET_BOOLEAN_finish                 # success, continue
   3592 
   3593 
   3594 /* ------------------------------ */
   3595 .L_OP_SGET_BYTE: /* 0x64 */
   3596 /* File: x86/OP_SGET_BYTE.S */
   3597 /* File: x86/OP_SGET.S */
   3598     /*
   3599      * General 32-bit SGET handler.
   3600      *
   3601      * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
   3602      */
   3603     /* op vAA, field@BBBB */
   3604     movl      rSELF,%ecx
   3605     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
   3606     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
   3607     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
   3608 #if defined(WITH_JIT)
   3609     movl      %ecx, TMP_SPILL1(%ebp)
   3610     lea       (%ecx,%eax,4),%ecx
   3611     movl      %ecx, TMP_SPILL2(%ebp)
   3612     movl      TMP_SPILL1(%ebp), %ecx
   3613 #endif
   3614     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
   3615     testl     %eax,%eax                          # resolved entry null?
   3616     je        .LOP_SGET_BYTE_resolve                # if not, make it so
   3617 .LOP_SGET_BYTE_finish:     # field ptr in eax
   3618     movl      offStaticField_value(%eax),%eax
   3619     FETCH_INST_OPCODE 2 %ecx
   3620     ADVANCE_PC 2
   3621     SET_VREG %eax rINST
   3622     GOTO_NEXT_R %ecx
   3623 
   3624     /*
   3625      * Go resolve the field
   3626      */
   3627 .LOP_SGET_BYTE_resolve:
   3628     movl     rSELF,%ecx
   3629     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
   3630     movl     offThread_method(%ecx),%ecx          # ecx<- current method
   3631     EXPORT_PC                                   # could throw, need to export
   3632     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
   3633     movl     %eax,OUT_ARG1(%esp)
   3634     movl     %ecx,OUT_ARG0(%esp)
   3635     SPILL(rIBASE)
   3636     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
   3637     UNSPILL(rIBASE)
   3638     testl    %eax,%eax
   3639     je      common_exceptionThrown             # no, handle exception
   3640 #if defined(WITH_JIT)
   3641     movl      TMP_SPILL2(%ebp), %ecx
   3642     SPILL(rIBASE)
   3643     call     common_verifyField
   3644     UNSPILL(rIBASE)
   3645 #endif
   3646     jmp      .LOP_SGET_BYTE_finish                 # success, continue
   3647 
   3648 
   3649 /* ------------------------------ */
   3650 .L_OP_SGET_CHAR: /* 0x65 */
   3651 /* File: x86/OP_SGET_CHAR.S */
   3652 /* File: x86/OP_SGET.S */
   3653     /*
   3654      * General 32-bit SGET handler.
   3655      *
   3656      * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
   3657      */
   3658     /* op vAA, field@BBBB */
   3659     movl      rSELF,%ecx
   3660     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
   3661     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
   3662     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
   3663 #if defined(WITH_JIT)
   3664     movl      %ecx, TMP_SPILL1(%ebp)
   3665     lea       (%ecx,%eax,4),%ecx
   3666     movl      %ecx, TMP_SPILL2(%ebp)
   3667     movl      TMP_SPILL1(%ebp), %ecx
   3668 #endif
   3669     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
   3670     testl     %eax,%eax                          # resolved entry null?
   3671     je        .LOP_SGET_CHAR_resolve                # if not, make it so
   3672 .LOP_SGET_CHAR_finish:     # field ptr in eax
   3673     movl      offStaticField_value(%eax),%eax
   3674     FETCH_INST_OPCODE 2 %ecx
   3675     ADVANCE_PC 2
   3676     SET_VREG %eax rINST
   3677     GOTO_NEXT_R %ecx
   3678 
   3679     /*
   3680      * Go resolve the field
   3681      */
   3682 .LOP_SGET_CHAR_resolve:
   3683     movl     rSELF,%ecx
   3684     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
   3685     movl     offThread_method(%ecx),%ecx          # ecx<- current method
   3686     EXPORT_PC                                   # could throw, need to export
   3687     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
   3688     movl     %eax,OUT_ARG1(%esp)
   3689     movl     %ecx,OUT_ARG0(%esp)
   3690     SPILL(rIBASE)
   3691     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
   3692     UNSPILL(rIBASE)
   3693     testl    %eax,%eax
   3694     je      common_exceptionThrown             # no, handle exception
   3695 #if defined(WITH_JIT)
   3696     movl      TMP_SPILL2(%ebp), %ecx
   3697     SPILL(rIBASE)
   3698     call     common_verifyField
   3699     UNSPILL(rIBASE)
   3700 #endif
   3701     jmp      .LOP_SGET_CHAR_finish                 # success, continue
   3702 
   3703 
   3704 /* ------------------------------ */
   3705 .L_OP_SGET_SHORT: /* 0x66 */
   3706 /* File: x86/OP_SGET_SHORT.S */
   3707 /* File: x86/OP_SGET.S */
   3708     /*
   3709      * General 32-bit SGET handler.
   3710      *
   3711      * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
   3712      */
   3713     /* op vAA, field@BBBB */
   3714     movl      rSELF,%ecx
   3715     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
   3716     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
   3717     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
   3718 #if defined(WITH_JIT)
   3719     movl      %ecx, TMP_SPILL1(%ebp)
   3720     lea       (%ecx,%eax,4),%ecx
   3721     movl      %ecx, TMP_SPILL2(%ebp)
   3722     movl      TMP_SPILL1(%ebp), %ecx
   3723 #endif
   3724     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
   3725     testl     %eax,%eax                          # resolved entry null?
   3726     je        .LOP_SGET_SHORT_resolve                # if not, make it so
   3727 .LOP_SGET_SHORT_finish:     # field ptr in eax
   3728     movl      offStaticField_value(%eax),%eax
   3729     FETCH_INST_OPCODE 2 %ecx
   3730     ADVANCE_PC 2
   3731     SET_VREG %eax rINST
   3732     GOTO_NEXT_R %ecx
   3733 
   3734     /*
   3735      * Go resolve the field
   3736      */
   3737 .LOP_SGET_SHORT_resolve:
   3738     movl     rSELF,%ecx
   3739     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
   3740     movl     offThread_method(%ecx),%ecx          # ecx<- current method
   3741     EXPORT_PC                                   # could throw, need to export
   3742     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
   3743     movl     %eax,OUT_ARG1(%esp)
   3744     movl     %ecx,OUT_ARG0(%esp)
   3745     SPILL(rIBASE)
   3746     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
   3747     UNSPILL(rIBASE)
   3748     testl    %eax,%eax
   3749     je      common_exceptionThrown             # no, handle exception
   3750 #if defined(WITH_JIT)
   3751     movl      TMP_SPILL2(%ebp), %ecx
   3752     SPILL(rIBASE)
   3753     call     common_verifyField
   3754     UNSPILL(rIBASE)
   3755 #endif
   3756     jmp      .LOP_SGET_SHORT_finish                 # success, continue
   3757 
   3758 
   3759 /* ------------------------------ */
   3760 .L_OP_SPUT: /* 0x67 */
   3761 /* File: x86/OP_SPUT.S */
   3762     /*
   3763      * General 32-bit SPUT handler.
   3764      *
   3765      * for: sput, sput-boolean, sput-byte, sput-char, sput-short
   3766      */
   3767     /* op vAA, field@BBBB */
   3768     movl      rSELF,%ecx
   3769     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
   3770     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
   3771     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
   3772 #if defined(WITH_JIT)
   3773     movl      %ecx, TMP_SPILL1(%ebp)
   3774     lea       (%ecx,%eax,4),%ecx
   3775     movl      %ecx, TMP_SPILL2(%ebp)
   3776     movl      TMP_SPILL1(%ebp), %ecx
   3777 #endif
   3778     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
   3779     testl     %eax,%eax                          # resolved entry null?
   3780     je        .LOP_SPUT_resolve                # if not, make it so
   3781 .LOP_SPUT_finish:     # field ptr in eax
   3782     GET_VREG_R  rINST rINST
   3783     FETCH_INST_OPCODE 2 %ecx
   3784     ADVANCE_PC 2
   3785     movl      rINST,offStaticField_value(%eax)
   3786     GOTO_NEXT_R %ecx
   3787 
   3788     /*
   3789      * Go resolve the field
   3790      */
   3791 .LOP_SPUT_resolve:
   3792     movl     rSELF,%ecx
   3793     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
   3794     movl     offThread_method(%ecx),%ecx        # ecx<- current method
   3795     EXPORT_PC                                   # could throw, need to export
   3796     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
   3797     movl     %eax,OUT_ARG1(%esp)
   3798     movl     %ecx,OUT_ARG0(%esp)
   3799     SPILL(rIBASE)
   3800     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
   3801     UNSPILL(rIBASE)
   3802     testl    %eax,%eax
   3803     je      common_exceptionThrown             # no, handle exception
   3804 #if defined(WITH_JIT)
   3805     movl      TMP_SPILL2(%ebp), %ecx
   3806     SPILL(rIBASE)
   3807     call     common_verifyField
   3808     UNSPILL(rIBASE)
   3809 #endif
   3810     jmp      .LOP_SPUT_finish                 # success, continue
   3811 /* ------------------------------ */
   3812 .L_OP_SPUT_WIDE: /* 0x68 */
   3813 /* File: x86/OP_SPUT_WIDE.S */
   3814     /*
   3815      * General 32-bit SPUT handler.
   3816      *
   3817      * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
   3818      */
   3819     /* op vAA, field@BBBB */
   3820     movl      rSELF,%ecx
   3821     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
   3822     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
   3823     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
   3824 #if defined(WITH_JIT)
   3825     movl      %ecx, TMP_SPILL1(%ebp)
   3826     lea       (%ecx,%eax,4),%ecx
   3827     movl      %ecx, TMP_SPILL2(%ebp)
   3828     movl      TMP_SPILL1(%ebp), %ecx
   3829 #endif
   3830     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
   3831     testl     %eax,%eax                          # resolved entry null?
   3832     je        .LOP_SPUT_WIDE_resolve                # if not, make it so
   3833 .LOP_SPUT_WIDE_finish:     # field ptr in eax
   3834     GET_VREG_WORD %ecx rINST 0                  # rINST<- lsw
   3835     GET_VREG_WORD rINST rINST 1                 # ecx<- msw
   3836     movl      %ecx,offStaticField_value(%eax)
   3837     FETCH_INST_OPCODE 2 %ecx
   3838     movl      rINST,4+offStaticField_value(%eax)
   3839     ADVANCE_PC 2
   3840     GOTO_NEXT_R %ecx
   3841 
   3842     /*
   3843      * Go resolve the field
   3844      */
   3845 .LOP_SPUT_WIDE_resolve:
   3846     movl     rSELF,%ecx
   3847     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
   3848     movl     offThread_method(%ecx),%ecx          # ecx<- current method
   3849     EXPORT_PC                                   # could throw, need to export
   3850     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
   3851     movl     %eax,OUT_ARG1(%esp)
   3852     movl     %ecx,OUT_ARG0(%esp)
   3853     SPILL(rIBASE)
   3854     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
   3855     UNSPILL(rIBASE)
   3856     testl    %eax,%eax
   3857     je      common_exceptionThrown             # no, handle exception
   3858 #if defined(WITH_JIT)
   3859     movl      TMP_SPILL2(%ebp), %ecx
   3860     SPILL(rIBASE)
   3861     call     common_verifyField
   3862     UNSPILL(rIBASE)
   3863 #endif
   3864     jmp      .LOP_SPUT_WIDE_finish                 # success, continue
   3865 
   3866 /* ------------------------------ */
   3867 .L_OP_SPUT_OBJECT: /* 0x69 */
   3868 /* File: x86/OP_SPUT_OBJECT.S */
   3869     /*
   3870      * SPUT object handler.
   3871      */
   3872     /* op vAA, field@BBBB */
   3873     movl      rSELF,%ecx
   3874     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
   3875     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
   3876     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
   3877 #if defined(WITH_JIT)
   3878     movl      %ecx, TMP_SPILL1(%ebp)
   3879     lea       (%ecx,%eax,4),%ecx
   3880     movl      %ecx, TMP_SPILL2(%ebp)
   3881     movl      TMP_SPILL1(%ebp), %ecx
   3882 #endif
   3883     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField
   3884     testl     %eax,%eax                          # resolved entry null?
   3885     je        .LOP_SPUT_OBJECT_resolve                # if not, make it so
   3886 .LOP_SPUT_OBJECT_finish:                              # field ptr in eax
   3887     movzbl    rINSTbl,%ecx                       # ecx<- AA
   3888     GET_VREG_R  %ecx %ecx
   3889     movl      %ecx,offStaticField_value(%eax)    # do the store
   3890     testl     %ecx,%ecx                          # stored null object ptr?
   3891     je        1f                                 # skip card mark if null
   3892     movl      rSELF,%ecx
   3893     movl      offField_clazz(%eax),%eax          # eax<- method->clazz
   3894     movl      offThread_cardTable(%ecx),%ecx       # get card table base
   3895     shrl      $GC_CARD_SHIFT,%eax               # head to card number
   3896     movb      %cl,(%ecx,%eax)                    # mark card
   3897 1:
   3898     FETCH_INST_OPCODE 2 %ecx
   3899     ADVANCE_PC 2
   3900     GOTO_NEXT_R %ecx
   3901 
   3902 .LOP_SPUT_OBJECT_resolve:
   3903     movl     rSELF,%ecx
   3904     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
   3905     movl     offThread_method(%ecx),%ecx          # ecx<- current method
   3906     EXPORT_PC                                   # could throw, need to export
   3907     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
   3908     movl     %eax,OUT_ARG1(%esp)
   3909     movl     %ecx,OUT_ARG0(%esp)
   3910     SPILL(rIBASE)
   3911     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
   3912     UNSPILL(rIBASE)
   3913     testl    %eax,%eax
   3914     je      common_exceptionThrown             # no, handle exception
   3915 #if defined(WITH_JIT)
   3916     movl      TMP_SPILL2(%ebp), %ecx
   3917     SPILL(rIBASE)
   3918     call     common_verifyField
   3919     UNSPILL(rIBASE)
   3920 #endif
   3921     jmp      .LOP_SPUT_OBJECT_finish                 # success, continue
   3922 
   3923 /* ------------------------------ */
   3924 .L_OP_SPUT_BOOLEAN: /* 0x6a */
   3925 /* File: x86/OP_SPUT_BOOLEAN.S */
   3926 /* File: x86/OP_SPUT.S */
   3927     /*
   3928      * General 32-bit SPUT handler.
   3929      *
   3930      * for: sput, sput-boolean, sput-byte, sput-char, sput-short
   3931      */
   3932     /* op vAA, field@BBBB */
   3933     movl      rSELF,%ecx
   3934     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
   3935     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
   3936     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
   3937 #if defined(WITH_JIT)
   3938     movl      %ecx, TMP_SPILL1(%ebp)
   3939     lea       (%ecx,%eax,4),%ecx
   3940     movl      %ecx, TMP_SPILL2(%ebp)
   3941     movl      TMP_SPILL1(%ebp), %ecx
   3942 #endif
   3943     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
   3944     testl     %eax,%eax                          # resolved entry null?
   3945     je        .LOP_SPUT_BOOLEAN_resolve                # if not, make it so
   3946 .LOP_SPUT_BOOLEAN_finish:     # field ptr in eax
   3947     GET_VREG_R  rINST rINST
   3948     FETCH_INST_OPCODE 2 %ecx
   3949     ADVANCE_PC 2
   3950     movl      rINST,offStaticField_value(%eax)
   3951     GOTO_NEXT_R %ecx
   3952 
   3953     /*
   3954      * Go resolve the field
   3955      */
   3956 .LOP_SPUT_BOOLEAN_resolve:
   3957     movl     rSELF,%ecx
   3958     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
   3959     movl     offThread_method(%ecx),%ecx        # ecx<- current method
   3960     EXPORT_PC                                   # could throw, need to export
   3961     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
   3962     movl     %eax,OUT_ARG1(%esp)
   3963     movl     %ecx,OUT_ARG0(%esp)
   3964     SPILL(rIBASE)
   3965     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
   3966     UNSPILL(rIBASE)
   3967     testl    %eax,%eax
   3968     je      common_exceptionThrown             # no, handle exception
   3969 #if defined(WITH_JIT)
   3970     movl      TMP_SPILL2(%ebp), %ecx
   3971     SPILL(rIBASE)
   3972     call     common_verifyField
   3973     UNSPILL(rIBASE)
   3974 #endif
   3975     jmp      .LOP_SPUT_BOOLEAN_finish                 # success, continue
   3976 
   3977 /* ------------------------------ */
   3978 .L_OP_SPUT_BYTE: /* 0x6b */
   3979 /* File: x86/OP_SPUT_BYTE.S */
   3980 /* File: x86/OP_SPUT.S */
   3981     /*
   3982      * General 32-bit SPUT handler.
   3983      *
   3984      * for: sput, sput-boolean, sput-byte, sput-char, sput-short
   3985      */
   3986     /* op vAA, field@BBBB */
   3987     movl      rSELF,%ecx
   3988     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
   3989     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
   3990     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
   3991 #if defined(WITH_JIT)
   3992     movl      %ecx, TMP_SPILL1(%ebp)
   3993     lea       (%ecx,%eax,4),%ecx
   3994     movl      %ecx, TMP_SPILL2(%ebp)
   3995     movl      TMP_SPILL1(%ebp), %ecx
   3996 #endif
   3997     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
   3998     testl     %eax,%eax                          # resolved entry null?
   3999     je        .LOP_SPUT_BYTE_resolve                # if not, make it so
   4000 .LOP_SPUT_BYTE_finish:     # field ptr in eax
   4001     GET_VREG_R  rINST rINST
   4002     FETCH_INST_OPCODE 2 %ecx
   4003     ADVANCE_PC 2
   4004     movl      rINST,offStaticField_value(%eax)
   4005     GOTO_NEXT_R %ecx
   4006 
   4007     /*
   4008      * Go resolve the field
   4009      */
   4010 .LOP_SPUT_BYTE_resolve:
   4011     movl     rSELF,%ecx
   4012     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
   4013     movl     offThread_method(%ecx),%ecx        # ecx<- current method
   4014     EXPORT_PC                                   # could throw, need to export
   4015     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
   4016     movl     %eax,OUT_ARG1(%esp)
   4017     movl     %ecx,OUT_ARG0(%esp)
   4018     SPILL(rIBASE)
   4019     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
   4020     UNSPILL(rIBASE)
   4021     testl    %eax,%eax
   4022     je      common_exceptionThrown             # no, handle exception
   4023 #if defined(WITH_JIT)
   4024     movl      TMP_SPILL2(%ebp), %ecx
   4025     SPILL(rIBASE)
   4026     call     common_verifyField
   4027     UNSPILL(rIBASE)
   4028 #endif
   4029     jmp      .LOP_SPUT_BYTE_finish                 # success, continue
   4030 
   4031 /* ------------------------------ */
   4032 .L_OP_SPUT_CHAR: /* 0x6c */
   4033 /* File: x86/OP_SPUT_CHAR.S */
   4034 /* File: x86/OP_SPUT.S */
   4035     /*
   4036      * General 32-bit SPUT handler.
   4037      *
   4038      * for: sput, sput-boolean, sput-byte, sput-char, sput-short
   4039      */
   4040     /* op vAA, field@BBBB */
   4041     movl      rSELF,%ecx
   4042     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
   4043     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
   4044     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
   4045 #if defined(WITH_JIT)
   4046     movl      %ecx, TMP_SPILL1(%ebp)
   4047     lea       (%ecx,%eax,4),%ecx
   4048     movl      %ecx, TMP_SPILL2(%ebp)
   4049     movl      TMP_SPILL1(%ebp), %ecx
   4050 #endif
   4051     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
   4052     testl     %eax,%eax                          # resolved entry null?
   4053     je        .LOP_SPUT_CHAR_resolve                # if not, make it so
   4054 .LOP_SPUT_CHAR_finish:     # field ptr in eax
   4055     GET_VREG_R  rINST rINST
   4056     FETCH_INST_OPCODE 2 %ecx
   4057     ADVANCE_PC 2
   4058     movl      rINST,offStaticField_value(%eax)
   4059     GOTO_NEXT_R %ecx
   4060 
   4061     /*
   4062      * Go resolve the field
   4063      */
   4064 .LOP_SPUT_CHAR_resolve:
   4065     movl     rSELF,%ecx
   4066     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
   4067     movl     offThread_method(%ecx),%ecx        # ecx<- current method
   4068     EXPORT_PC                                   # could throw, need to export
   4069     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
   4070     movl     %eax,OUT_ARG1(%esp)
   4071     movl     %ecx,OUT_ARG0(%esp)
   4072     SPILL(rIBASE)
   4073     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
   4074     UNSPILL(rIBASE)
   4075     testl    %eax,%eax
   4076     je      common_exceptionThrown             # no, handle exception
   4077 #if defined(WITH_JIT)
   4078     movl      TMP_SPILL2(%ebp), %ecx
   4079     SPILL(rIBASE)
   4080     call     common_verifyField
   4081     UNSPILL(rIBASE)
   4082 #endif
   4083     jmp      .LOP_SPUT_CHAR_finish                 # success, continue
   4084 
   4085 /* ------------------------------ */
   4086 .L_OP_SPUT_SHORT: /* 0x6d */
   4087 /* File: x86/OP_SPUT_SHORT.S */
   4088 /* File: x86/OP_SPUT.S */
   4089     /*
   4090      * General 32-bit SPUT handler.
   4091      *
   4092      * for: sput, sput-boolean, sput-byte, sput-char, sput-short
   4093      */
   4094     /* op vAA, field@BBBB */
   4095     movl      rSELF,%ecx
   4096     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
   4097     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
   4098     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
   4099 #if defined(WITH_JIT)
   4100     movl      %ecx, TMP_SPILL1(%ebp)
   4101     lea       (%ecx,%eax,4),%ecx
   4102     movl      %ecx, TMP_SPILL2(%ebp)
   4103     movl      TMP_SPILL1(%ebp), %ecx
   4104 #endif
   4105     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
   4106     testl     %eax,%eax                          # resolved entry null?
   4107     je        .LOP_SPUT_SHORT_resolve                # if not, make it so
   4108 .LOP_SPUT_SHORT_finish:     # field ptr in eax
   4109     GET_VREG_R  rINST rINST
   4110     FETCH_INST_OPCODE 2 %ecx
   4111     ADVANCE_PC 2
   4112     movl      rINST,offStaticField_value(%eax)
   4113     GOTO_NEXT_R %ecx
   4114 
   4115     /*
   4116      * Go resolve the field
   4117      */
   4118 .LOP_SPUT_SHORT_resolve:
   4119     movl     rSELF,%ecx
   4120     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
   4121     movl     offThread_method(%ecx),%ecx        # ecx<- current method
   4122     EXPORT_PC                                   # could throw, need to export
   4123     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
   4124     movl     %eax,OUT_ARG1(%esp)
   4125     movl     %ecx,OUT_ARG0(%esp)
   4126     SPILL(rIBASE)
   4127     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
   4128     UNSPILL(rIBASE)
   4129     testl    %eax,%eax
   4130     je      common_exceptionThrown             # no, handle exception
   4131 #if defined(WITH_JIT)
   4132     movl      TMP_SPILL2(%ebp), %ecx
   4133     SPILL(rIBASE)
   4134     call     common_verifyField
   4135     UNSPILL(rIBASE)
   4136 #endif
   4137     jmp      .LOP_SPUT_SHORT_finish                 # success, continue
   4138 
   4139 /* ------------------------------ */
   4140 .L_OP_INVOKE_VIRTUAL: /* 0x6e */
   4141 /* File: x86/OP_INVOKE_VIRTUAL.S */
   4142 
   4143     /*
   4144      * Handle a virtual method call.
   4145      *
   4146      * for: invoke-virtual, invoke-virtual/range
   4147      */
   4148     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
   4149     /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
   4150     movl      rSELF,%eax
   4151     movzwl    2(rPC),%ecx                 # ecx<- BBBB
   4152     movl      offThread_methodClassDex(%eax),%eax  # eax<- pDvmDex
   4153     EXPORT_PC
   4154     movl      offDvmDex_pResMethods(%eax),%eax   # eax<- pDvmDex->pResMethods
   4155     movl      (%eax,%ecx,4),%eax          # eax<- resolved baseMethod
   4156     testl     %eax,%eax                   # already resolved?
   4157     jne       .LOP_INVOKE_VIRTUAL_continue        # yes, continue
   4158     movl      rSELF,%eax
   4159     movl      %ecx,OUT_ARG1(%esp)         # arg1<- ref
   4160     movl      offThread_method(%eax),%eax   # eax<- self->method
   4161     movl      offMethod_clazz(%eax),%eax  # ecx<- method->clazz
   4162     movl      %eax,OUT_ARG0(%esp)         # arg0<- clazz
   4163     movl      $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags
   4164     call      dvmResolveMethod            # eax<- call(clazz, ref, flags)
   4165     testl     %eax,%eax                   # got null?
   4166     jne       .LOP_INVOKE_VIRTUAL_continue        # no, continue
   4167     jmp       common_exceptionThrown      # yes, handle exception
   4168 
   4169     /* At this point:
   4170      *   eax = resolved base method
   4171      *   ecx = scratch
   4172      */
   4173 .LOP_INVOKE_VIRTUAL_continue:
   4174     movzwl    4(rPC),%ecx               # ecx<- GFED or CCCC
   4175     .if       (!0)
   4176     andl      $0xf,%ecx                # ecx<- D (or stays CCCC)
   4177     .endif
   4178     GET_VREG_R  %ecx %ecx               # ecx<- "this"
   4179     movzwl    offMethod_methodIndex(%eax),%eax  # eax<- baseMethod->methodIndex
   4180     testl     %ecx,%ecx                 # null this?
   4181     je        common_errNullObject      # go if so
   4182     movl      offObject_clazz(%ecx),%edx  # edx<- thisPtr->clazz
   4183     movl      offClassObject_vtable(%edx),%edx # edx<- thisPtr->clazz->vtable
   4184     movl      (%edx,%eax,4),%eax        # eax<- vtable[methodIndex]
   4185     jmp       common_invokeMethodNoRange
   4186 
   4187 /* ------------------------------ */
   4188 .L_OP_INVOKE_SUPER: /* 0x6f */
   4189 /* File: x86/OP_INVOKE_SUPER.S */
   4190     /*
   4191      * Handle a "super" method call.
   4192      *
   4193      * for: invoke-super, invoke-super/range
   4194      */
   4195     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
   4196     /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
   4197     movl      rSELF,rINST
   4198     movzwl    2(rPC),%eax               # eax<- BBBB
   4199     movl      offThread_methodClassDex(rINST),%ecx # ecx<- pDvmDex
   4200     EXPORT_PC
   4201     movl      offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods
   4202     movl      (%ecx,%eax,4),%ecx        # ecx<- resolved baseMethod
   4203     movl      offThread_method(rINST),%eax # eax<- method
   4204     movzwl    4(rPC),rINST              # rINST<- GFED or CCCC
   4205     .if       (!0)
   4206     andl      $0xf,rINST               # rINST<- D (or stays CCCC)
   4207     .endif
   4208     GET_VREG_R  %edx rINST             # %edx<- "this" ptr
   4209     testl     %edx,%edx                # null "this"?
   4210     SPILL_TMP1(%edx)
   4211     je        common_errNullObject      # yes, throw
   4212     movl      offMethod_clazz(%eax),%eax # eax<- method->clazz
   4213     testl     %ecx,%ecx                 # already resolved?
   4214     je       .LOP_INVOKE_SUPER_resolve
   4215     /*
   4216      * At this point:
   4217      *  ecx = resolved base method [r0]
   4218      *  eax = method->clazz [r9]
   4219      */
   4220 .LOP_INVOKE_SUPER_continue:
   4221     movl    offClassObject_super(%eax),%eax   # eax<- method->clazz->super
   4222     movzwl  offMethod_methodIndex(%ecx),%edx  # edx<- baseMthod->methodIndex
   4223     cmpl    offClassObject_vtableCount(%eax),%edx # compare(methodIndex,vtableCount)
   4224     jae     .LOP_INVOKE_SUPER_nsm           # method not present in superclass
   4225     movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
   4226     movl    (%eax,%edx,4),%eax        # eax<- vtable[methodIndex]
   4227     UNSPILL_TMP1(%edx)
   4228     movl    %edx, %ecx
   4229     jmp     common_invokeMethodNoRange
   4230 
   4231 
   4232     /* At this point:
   4233      * ecx = null (needs to be resolved base method)
   4234      * eax = method->clazz
   4235     */
   4236 .LOP_INVOKE_SUPER_resolve:
   4237     SPILL_TMP2(%eax)                    # method->clazz
   4238     movl    %eax,OUT_ARG0(%esp)         # arg0<- method->clazz
   4239     movzwl  2(rPC),%ecx                 # ecx<- BBBB
   4240     movl    $METHOD_VIRTUAL,OUT_ARG2(%esp)  # arg2<- resolver method type
   4241     movl    %ecx,OUT_ARG1(%esp)         # arg1<- ref
   4242     call    dvmResolveMethod            # eax<- call(clazz, ref, flags)
   4243     testl   %eax,%eax                   # got null?
   4244     movl    %eax,%ecx                   # ecx<- resolved base method
   4245     UNSPILL_TMP2(%eax)                  # restore method->clazz
   4246     jne     .LOP_INVOKE_SUPER_continue        # good to go - continue
   4247     jmp     common_exceptionThrown      # handle exception
   4248 
   4249     /*
   4250      * Throw a NoSuchMethodError with the method name as the message.
   4251      *  ecx = resolved base method
   4252      */
   4253 .LOP_INVOKE_SUPER_nsm:
   4254     movl    offMethod_name(%ecx),%eax
   4255     jmp     common_errNoSuchMethod
   4256 
   4257 /* ------------------------------ */
   4258 .L_OP_INVOKE_DIRECT: /* 0x70 */
   4259 /* File: x86/OP_INVOKE_DIRECT.S */
   4260     /*
   4261      * Handle a direct method call.
   4262      *
   4263      * (We could defer the "is 'this' pointer null" test to the common
   4264      * method invocation code, and use a flag to indicate that static
   4265      * calls don't count.  If we do this as part of copying the arguments
   4266      * out we could avoiding loading the first arg twice.)
   4267      *
   4268      * for: invoke-direct, invoke-direct/range
   4269      */
   4270     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
   4271     /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
   4272     movl      rSELF,%ecx
   4273     movzwl    2(rPC),%eax              # eax<- BBBB
   4274     movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
   4275     EXPORT_PC
   4276     movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
   4277     movzwl    4(rPC),rIBASE            # rIBASE<- GFED or CCCC
   4278     movl      (%ecx,%eax,4),%eax       # eax<- resolved methodToCall
   4279     .if       (!0)
   4280     andl      $0xf,rIBASE             # rIBASE<- D (or stays CCCC)
   4281     .endif
   4282     testl     %eax,%eax                # already resolved?
   4283     GET_VREG_R  %ecx rIBASE            # ecx<- "this" ptr
   4284     je        .LOP_INVOKE_DIRECT_resolve      # not resolved, do it now
   4285 .LOP_INVOKE_DIRECT_finish:
   4286     testl     %ecx,%ecx                # null "this"?
   4287     jne       common_invokeMethodNoRange  # no, continue on
   4288     jmp       common_errNullObject
   4289 
   4290     /*
   4291      * On entry:
   4292      *   TMP_SPILL  <- "this" register
   4293      * Things a bit ugly on this path, but it's the less
   4294      * frequent one.  We'll have to do some reloading.
   4295      */
   4296 .LOP_INVOKE_DIRECT_resolve:
   4297      SPILL_TMP1(%ecx)
   4298      movl     rSELF,%ecx
   4299      movl     offThread_method(%ecx),%ecx  # ecx<- self->method
   4300      movzwl   2(rPC),%eax      # reference (BBBB or CCCC)
   4301      movl     offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
   4302      movl     $METHOD_DIRECT,OUT_ARG2(%esp)
   4303      movl     %eax,OUT_ARG1(%esp)
   4304      movl     %ecx,OUT_ARG0(%esp)
   4305      call     dvmResolveMethod # eax<- call(clazz, ref, flags)
   4306      UNSPILL_TMP1(%ecx)
   4307      testl    %eax,%eax
   4308      jne      .LOP_INVOKE_DIRECT_finish
   4309      jmp      common_exceptionThrown
   4310 
   4311 /* ------------------------------ */
   4312 .L_OP_INVOKE_STATIC: /* 0x71 */
   4313 /* File: x86/OP_INVOKE_STATIC.S */
   4314     /*
   4315      * Handle a static method call.
   4316      *
   4317      * for: invoke-static, invoke-static/range
   4318      */
   4319     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
   4320     /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
   4321     movl      rSELF,%ecx
   4322     movzwl    2(rPC),%eax               # eax<- BBBB
   4323     movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
   4324     EXPORT_PC
   4325     movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
   4326 #if defined(WITH_JIT)
   4327     movl     %edx, TMP_SPILL1(%ebp)
   4328     lea      (%ecx,%eax,4), %edx
   4329     movl     %edx, TMP_SPILL2(%ebp)
   4330     movl     TMP_SPILL1(%ebp), %edx
   4331 #endif
   4332     movl      (%ecx,%eax,4),%eax        # eax<- resolved methodToCall
   4333     movl      $0, %ecx                 # make "this" null
   4334     testl     %eax,%eax
   4335     jne       common_invokeMethodNoRange
   4336 
   4337     movl      rSELF,%ecx
   4338     movl      offThread_method(%ecx),%ecx # ecx<- self->method
   4339     movzwl    2(rPC),%eax
   4340     movl      offMethod_clazz(%ecx),%ecx# ecx<- method->clazz
   4341     movl      %eax,OUT_ARG1(%esp)       # arg1<- BBBB
   4342     movl      %ecx,OUT_ARG0(%esp)       # arg0<- clazz
   4343     movl      $METHOD_STATIC,%eax
   4344     movl      %eax,OUT_ARG2(%esp)       # arg2<- flags
   4345     SPILL(rIBASE)
   4346     call      dvmResolveMethod          # call(clazz,ref,flags)
   4347     UNSPILL(rIBASE)
   4348     testl     %eax,%eax                 # got null?
   4349 #if defined(WITH_JIT)
   4350     movl      TMP_SPILL1(%ebp), %edx
   4351     movl      rSELF,%ecx
   4352     movzwl    offThread_subMode(%ecx), %ecx
   4353     je        common_exceptionThrown    # null, handle exception
   4354     andl      $kSubModeJitTraceBuild, %ecx # is trace under construction?
   4355     movl      $0, %ecx                 # make "this" null
   4356     je        common_invokeMethodNoRange # no (%eax=method, %ecx="this")
   4357     movl      TMP_SPILL2(%ebp), %edx
   4358     cmpl      $0, (%edx)                  # finished resolving
   4359     movl      TMP_SPILL1(%ebp), %edx
   4360     jne        common_invokeMethodNoRange # yes (%eax=method, %ecx="this")
   4361     movl      rSELF, %edx
   4362     movl      %edx, OUT_ARG0(%esp)
   4363     movl      rPC, OUT_ARG1(%esp)
   4364     movl      %eax, TMP_SPILL2(%ebp)
   4365     movl      %ecx, TMP_SPILL3(%ebp)
   4366     SPILL(rIBASE)
   4367     call      dvmJitEndTraceSelect
   4368     UNSPILL(rIBASE)
   4369     movl      TMP_SPILL1(%ebp), %edx
   4370     movl      TMP_SPILL2(%ebp), %eax
   4371     movl      TMP_SPILL3(%ebp), %ecx
   4372     jmp       common_invokeMethodNoRange
   4373 #else
   4374     movl      $0, %ecx                 # make "this" null
   4375     jne       common_invokeMethodNoRange
   4376     jmp       common_exceptionThrown
   4377 #endif
   4378 
   4379 
   4380 /* ------------------------------ */
   4381 .L_OP_INVOKE_INTERFACE: /* 0x72 */
   4382 /* File: x86/OP_INVOKE_INTERFACE.S */
   4383     /*
   4384      * Handle an interface method call.
   4385      *
   4386      * for: invoke-interface, invoke-interface/range
   4387      */
   4388     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
   4389     /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
   4390     movzwl     4(rPC),%eax              # eax<- FEDC or CCCC
   4391     movl       rSELF,%ecx
   4392     .if        (!0)
   4393     andl       $0xf,%eax               # eax<- C (or stays CCCC)
   4394     .endif
   4395     GET_VREG_R   %eax %eax              # eax<- "this"
   4396     EXPORT_PC
   4397     testl      %eax,%eax                # null this?
   4398     je         common_errNullObject     # yes, fail
   4399     movl       %eax, TMP_SPILL1(%ebp)
   4400     movl       offObject_clazz(%eax),%eax# eax<- thisPtr->clazz
   4401     movl       %eax,OUT_ARG0(%esp)                 # arg0<- class
   4402     movl       offThread_methodClassDex(%ecx),%eax   # eax<- methodClassDex
   4403     movl       offThread_method(%ecx),%ecx           # ecx<- method
   4404     movl       %eax,OUT_ARG3(%esp)                 # arg3<- dex
   4405     movzwl     2(rPC),%eax                         # eax<- BBBB
   4406     movl       %ecx,OUT_ARG2(%esp)                 # arg2<- method
   4407     movl       %eax,OUT_ARG1(%esp)                 # arg1<- BBBB
   4408     call       dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex)
   4409     testl      %eax,%eax
   4410     je         common_exceptionThrown
   4411     movl       TMP_SPILL1(%ebp), %ecx
   4412     jmp        common_invokeMethodNoRange
   4413 
   4414 /* ------------------------------ */
   4415 .L_OP_UNUSED_73: /* 0x73 */
   4416 /* File: x86/OP_UNUSED_73.S */
   4417 /* File: x86/unused.S */
   4418     jmp     common_abort
   4419 
   4420 
   4421 /* ------------------------------ */
   4422 .L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
   4423 /* File: x86/OP_INVOKE_VIRTUAL_RANGE.S */
   4424 /* File: x86/OP_INVOKE_VIRTUAL.S */
   4425 
   4426     /*
   4427      * Handle a virtual method call.
   4428      *
   4429      * for: invoke-virtual, invoke-virtual/range
   4430      */
   4431     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
   4432     /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
   4433     movl      rSELF,%eax
   4434     movzwl    2(rPC),%ecx                 # ecx<- BBBB
   4435     movl      offThread_methodClassDex(%eax),%eax  # eax<- pDvmDex
   4436     EXPORT_PC
   4437     movl      offDvmDex_pResMethods(%eax),%eax   # eax<- pDvmDex->pResMethods
   4438     movl      (%eax,%ecx,4),%eax          # eax<- resolved baseMethod
   4439     testl     %eax,%eax                   # already resolved?
   4440     jne       .LOP_INVOKE_VIRTUAL_RANGE_continue        # yes, continue
   4441     movl      rSELF,%eax
   4442     movl      %ecx,OUT_ARG1(%esp)         # arg1<- ref
   4443     movl      offThread_method(%eax),%eax   # eax<- self->method
   4444     movl      offMethod_clazz(%eax),%eax  # ecx<- method->clazz
   4445     movl      %eax,OUT_ARG0(%esp)         # arg0<- clazz
   4446     movl      $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags
   4447     call      dvmResolveMethod            # eax<- call(clazz, ref, flags)
   4448     testl     %eax,%eax                   # got null?
   4449     jne       .LOP_INVOKE_VIRTUAL_RANGE_continue        # no, continue
   4450     jmp       common_exceptionThrown      # yes, handle exception
   4451 
   4452     /* At this point:
   4453      *   eax = resolved base method
   4454      *   ecx = scratch
   4455      */
   4456 .LOP_INVOKE_VIRTUAL_RANGE_continue:
   4457     movzwl    4(rPC),%ecx               # ecx<- GFED or CCCC
   4458     .if       (!1)
   4459     andl      $0xf,%ecx                # ecx<- D (or stays CCCC)
   4460     .endif
   4461     GET_VREG_R  %ecx %ecx               # ecx<- "this"
   4462     movzwl    offMethod_methodIndex(%eax),%eax  # eax<- baseMethod->methodIndex
   4463     testl     %ecx,%ecx                 # null this?
   4464     je        common_errNullObject      # go if so
   4465     movl      offObject_clazz(%ecx),%edx  # edx<- thisPtr->clazz
   4466     movl      offClassObject_vtable(%edx),%edx # edx<- thisPtr->clazz->vtable
   4467     movl      (%edx,%eax,4),%eax        # eax<- vtable[methodIndex]
   4468     jmp       common_invokeMethodRange
   4469 
   4470 
   4471 /* ------------------------------ */
   4472 .L_OP_INVOKE_SUPER_RANGE: /* 0x75 */
   4473 /* File: x86/OP_INVOKE_SUPER_RANGE.S */
   4474 /* File: x86/OP_INVOKE_SUPER.S */
   4475     /*
   4476      * Handle a "super" method call.
   4477      *
   4478      * for: invoke-super, invoke-super/range
   4479      */
   4480     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
   4481     /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
   4482     movl      rSELF,rINST
   4483     movzwl    2(rPC),%eax               # eax<- BBBB
   4484     movl      offThread_methodClassDex(rINST),%ecx # ecx<- pDvmDex
   4485     EXPORT_PC
   4486     movl      offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods
   4487     movl      (%ecx,%eax,4),%ecx        # ecx<- resolved baseMethod
   4488     movl      offThread_method(rINST),%eax # eax<- method
   4489     movzwl    4(rPC),rINST              # rINST<- GFED or CCCC
   4490     .if       (!1)
   4491     andl      $0xf,rINST               # rINST<- D (or stays CCCC)
   4492     .endif
   4493     GET_VREG_R  %edx rINST             # %edx<- "this" ptr
   4494     testl     %edx,%edx                # null "this"?
   4495     SPILL_TMP1(%edx)
   4496     je        common_errNullObject      # yes, throw
   4497     movl      offMethod_clazz(%eax),%eax # eax<- method->clazz
   4498     testl     %ecx,%ecx                 # already resolved?
   4499     je       .LOP_INVOKE_SUPER_RANGE_resolve
   4500     /*
   4501      * At this point:
   4502      *  ecx = resolved base method [r0]
   4503      *  eax = method->clazz [r9]
   4504      */
   4505 .LOP_INVOKE_SUPER_RANGE_continue:
   4506     movl    offClassObject_super(%eax),%eax   # eax<- method->clazz->super
   4507     movzwl  offMethod_methodIndex(%ecx),%edx  # edx<- baseMthod->methodIndex
   4508     cmpl    offClassObject_vtableCount(%eax),%edx # compare(methodIndex,vtableCount)
   4509     jae     .LOP_INVOKE_SUPER_RANGE_nsm           # method not present in superclass
   4510     movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
   4511     movl    (%eax,%edx,4),%eax        # eax<- vtable[methodIndex]
   4512     UNSPILL_TMP1(%edx)
   4513     movl    %edx, %ecx
   4514     jmp     common_invokeMethodRange
   4515 
   4516 
   4517     /* At this point:
   4518      * ecx = null (needs to be resolved base method)
   4519      * eax = method->clazz
   4520     */
   4521 .LOP_INVOKE_SUPER_RANGE_resolve:
   4522     SPILL_TMP2(%eax)                    # method->clazz
   4523     movl    %eax,OUT_ARG0(%esp)         # arg0<- method->clazz
   4524     movzwl  2(rPC),%ecx                 # ecx<- BBBB
   4525     movl    $METHOD_VIRTUAL,OUT_ARG2(%esp)  # arg2<- resolver method type
   4526     movl    %ecx,OUT_ARG1(%esp)         # arg1<- ref
   4527     call    dvmResolveMethod            # eax<- call(clazz, ref, flags)
   4528     testl   %eax,%eax                   # got null?
   4529     movl    %eax,%ecx                   # ecx<- resolved base method
   4530     UNSPILL_TMP2(%eax)                  # restore method->clazz
   4531     jne     .LOP_INVOKE_SUPER_RANGE_continue        # good to go - continue
   4532     jmp     common_exceptionThrown      # handle exception
   4533 
   4534     /*
   4535      * Throw a NoSuchMethodError with the method name as the message.
   4536      *  ecx = resolved base method
   4537      */
   4538 .LOP_INVOKE_SUPER_RANGE_nsm:
   4539     movl    offMethod_name(%ecx),%eax
   4540     jmp     common_errNoSuchMethod
   4541 
   4542 
   4543 /* ------------------------------ */
   4544 .L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
   4545 /* File: x86/OP_INVOKE_DIRECT_RANGE.S */
   4546 /* File: x86/OP_INVOKE_DIRECT.S */
   4547     /*
   4548      * Handle a direct method call.
   4549      *
   4550      * (We could defer the "is 'this' pointer null" test to the common
   4551      * method invocation code, and use a flag to indicate that static
   4552      * calls don't count.  If we do this as part of copying the arguments
   4553      * out we could avoiding loading the first arg twice.)
   4554      *
   4555      * for: invoke-direct, invoke-direct/range
   4556      */
   4557     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
   4558     /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
   4559     movl      rSELF,%ecx
   4560     movzwl    2(rPC),%eax              # eax<- BBBB
   4561     movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
   4562     EXPORT_PC
   4563     movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
   4564     movzwl    4(rPC),rIBASE            # rIBASE<- GFED or CCCC
   4565     movl      (%ecx,%eax,4),%eax       # eax<- resolved methodToCall
   4566     .if       (!1)
   4567     andl      $0xf,rIBASE             # rIBASE<- D (or stays CCCC)
   4568     .endif
   4569     testl     %eax,%eax                # already resolved?
   4570     GET_VREG_R  %ecx rIBASE            # ecx<- "this" ptr
   4571     je        .LOP_INVOKE_DIRECT_RANGE_resolve      # not resolved, do it now
   4572 .LOP_INVOKE_DIRECT_RANGE_finish:
   4573     testl     %ecx,%ecx                # null "this"?
   4574     jne       common_invokeMethodRange  # no, continue on
   4575     jmp       common_errNullObject
   4576 
   4577     /*
   4578      * On entry:
   4579      *   TMP_SPILL  <- "this" register
   4580      * Things a bit ugly on this path, but it's the less
   4581      * frequent one.  We'll have to do some reloading.
   4582      */
   4583 .LOP_INVOKE_DIRECT_RANGE_resolve:
   4584      SPILL_TMP1(%ecx)
   4585      movl     rSELF,%ecx
   4586      movl     offThread_method(%ecx),%ecx  # ecx<- self->method
   4587      movzwl   2(rPC),%eax      # reference (BBBB or CCCC)
   4588      movl     offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
   4589      movl     $METHOD_DIRECT,OUT_ARG2(%esp)
   4590      movl     %eax,OUT_ARG1(%esp)
   4591      movl     %ecx,OUT_ARG0(%esp)
   4592      call     dvmResolveMethod # eax<- call(clazz, ref, flags)
   4593      UNSPILL_TMP1(%ecx)
   4594      testl    %eax,%eax
   4595      jne      .LOP_INVOKE_DIRECT_RANGE_finish
   4596      jmp      common_exceptionThrown
   4597 
   4598 
   4599 /* ------------------------------ */
   4600 .L_OP_INVOKE_STATIC_RANGE: /* 0x77 */
   4601 /* File: x86/OP_INVOKE_STATIC_RANGE.S */
   4602 /* File: x86/OP_INVOKE_STATIC.S */
   4603     /*
   4604      * Handle a static method call.
   4605      *
   4606      * for: invoke-static, invoke-static/range
   4607      */
   4608     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
   4609     /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
   4610     movl      rSELF,%ecx
   4611     movzwl    2(rPC),%eax               # eax<- BBBB
   4612     movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
   4613     EXPORT_PC
   4614     movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
   4615 #if defined(WITH_JIT)
   4616     movl     %edx, TMP_SPILL1(%ebp)
   4617     lea      (%ecx,%eax,4), %edx
   4618     movl     %edx, TMP_SPILL2(%ebp)
   4619     movl     TMP_SPILL1(%ebp), %edx
   4620 #endif
   4621     movl      (%ecx,%eax,4),%eax        # eax<- resolved methodToCall
   4622     movl      $0, %ecx                 # make "this" null
   4623     testl     %eax,%eax
   4624     jne       common_invokeMethodRange
   4625 
   4626     movl      rSELF,%ecx
   4627     movl      offThread_method(%ecx),%ecx # ecx<- self->method
   4628     movzwl    2(rPC),%eax
   4629     movl      offMethod_clazz(%ecx),%ecx# ecx<- method->clazz
   4630     movl      %eax,OUT_ARG1(%esp)       # arg1<- BBBB
   4631     movl      %ecx,OUT_ARG0(%esp)       # arg0<- clazz
   4632     movl      $METHOD_STATIC,%eax
   4633     movl      %eax,OUT_ARG2(%esp)       # arg2<- flags
   4634     SPILL(rIBASE)
   4635     call      dvmResolveMethod          # call(clazz,ref,flags)
   4636     UNSPILL(rIBASE)
   4637     testl     %eax,%eax                 # got null?
   4638 #if defined(WITH_JIT)
   4639     movl      TMP_SPILL1(%ebp), %edx
   4640     movl      rSELF,%ecx
   4641     movzwl    offThread_subMode(%ecx), %ecx
   4642     je        common_exceptionThrown    # null, handle exception
   4643     andl      $kSubModeJitTraceBuild, %ecx # is trace under construction?
   4644     movl      $0, %ecx                 # make "this" null
   4645     je        common_invokeMethodRange # no (%eax=method, %ecx="this")
   4646     movl      TMP_SPILL2(%ebp), %edx
   4647     cmpl      $0, (%edx)                  # finished resolving
   4648     movl      TMP_SPILL1(%ebp), %edx
   4649     jne        common_invokeMethodRange # yes (%eax=method, %ecx="this")
   4650     movl      rSELF, %edx
   4651     movl      %edx, OUT_ARG0(%esp)
   4652     movl      rPC, OUT_ARG1(%esp)
   4653     movl      %eax, TMP_SPILL2(%ebp)
   4654     movl      %ecx, TMP_SPILL3(%ebp)
   4655     SPILL(rIBASE)
   4656     call      dvmJitEndTraceSelect
   4657     UNSPILL(rIBASE)
   4658     movl      TMP_SPILL1(%ebp), %edx
   4659     movl      TMP_SPILL2(%ebp), %eax
   4660     movl      TMP_SPILL3(%ebp), %ecx
   4661     jmp       common_invokeMethodRange
   4662 #else
   4663     movl      $0, %ecx                 # make "this" null
   4664     jne       common_invokeMethodRange
   4665     jmp       common_exceptionThrown
   4666 #endif
   4667 
   4668 
   4669 
   4670 /* ------------------------------ */
   4671 .L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
   4672 /* File: x86/OP_INVOKE_INTERFACE_RANGE.S */
   4673 /* File: x86/OP_INVOKE_INTERFACE.S */
   4674     /*
   4675      * Handle an interface method call.
   4676      *
   4677      * for: invoke-interface, invoke-interface/range
   4678      */
   4679     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
   4680     /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
   4681     movzwl     4(rPC),%eax              # eax<- FEDC or CCCC
   4682     movl       rSELF,%ecx
   4683     .if        (!1)
   4684     andl       $0xf,%eax               # eax<- C (or stays CCCC)
   4685     .endif
   4686     GET_VREG_R   %eax %eax              # eax<- "this"
   4687     EXPORT_PC
   4688     testl      %eax,%eax                # null this?
   4689     je         common_errNullObject     # yes, fail
   4690     movl       %eax, TMP_SPILL1(%ebp)
   4691     movl       offObject_clazz(%eax),%eax# eax<- thisPtr->clazz
   4692     movl       %eax,OUT_ARG0(%esp)                 # arg0<- class
   4693     movl       offThread_methodClassDex(%ecx),%eax   # eax<- methodClassDex
   4694     movl       offThread_method(%ecx),%ecx           # ecx<- method
   4695     movl       %eax,OUT_ARG3(%esp)                 # arg3<- dex
   4696     movzwl     2(rPC),%eax                         # eax<- BBBB
   4697     movl       %ecx,OUT_ARG2(%esp)                 # arg2<- method
   4698     movl       %eax,OUT_ARG1(%esp)                 # arg1<- BBBB
   4699     call       dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex)
   4700     testl      %eax,%eax
   4701     je         common_exceptionThrown
   4702     movl       TMP_SPILL1(%ebp), %ecx
   4703     jmp        common_invokeMethodRange
   4704 
   4705 
   4706 /* ------------------------------ */
   4707 .L_OP_UNUSED_79: /* 0x79 */
   4708 /* File: x86/OP_UNUSED_79.S */
   4709 /* File: x86/unused.S */
   4710     jmp     common_abort
   4711 
   4712 
   4713 /* ------------------------------ */
   4714 .L_OP_UNUSED_7A: /* 0x7a */
   4715 /* File: x86/OP_UNUSED_7A.S */
   4716 /* File: x86/unused.S */
   4717     jmp     common_abort
   4718 
   4719 
   4720 /* ------------------------------ */
   4721 .L_OP_NEG_INT: /* 0x7b */
   4722 /* File: x86/OP_NEG_INT.S */
   4723 /* File: x86/unop.S */
   4724     /*
   4725      * Generic 32-bit unary operation.  Provide an "instr" line that
   4726      * specifies an instruction that performs "result = op eax".
   4727      */
   4728     /* unop vA, vB */
   4729     movzbl   rINSTbl,%ecx           # ecx<- A+
   4730     sarl     $4,rINST             # rINST<- B
   4731     GET_VREG_R %eax rINST           # eax<- vB
   4732     andb     $0xf,%cl              # ecx<- A
   4733 
   4734 
   4735     negl %eax
   4736     SET_VREG %eax %ecx
   4737     FETCH_INST_OPCODE 1 %ecx
   4738     ADVANCE_PC 1
   4739     GOTO_NEXT_R %ecx
   4740 
   4741 
   4742 /* ------------------------------ */
   4743 .L_OP_NOT_INT: /* 0x7c */
   4744 /* File: x86/OP_NOT_INT.S */
   4745 /* File: x86/unop.S */
   4746     /*
   4747      * Generic 32-bit unary operation.  Provide an "instr" line that
   4748      * specifies an instruction that performs "result = op eax".
   4749      */
   4750     /* unop vA, vB */
   4751     movzbl   rINSTbl,%ecx           # ecx<- A+
   4752     sarl     $4,rINST             # rINST<- B
   4753     GET_VREG_R %eax rINST           # eax<- vB
   4754     andb     $0xf,%cl              # ecx<- A
   4755 
   4756 
   4757     notl %eax
   4758     SET_VREG %eax %ecx
   4759     FETCH_INST_OPCODE 1 %ecx
   4760     ADVANCE_PC 1
   4761     GOTO_NEXT_R %ecx
   4762 
   4763 
   4764 /* ------------------------------ */
   4765 .L_OP_NEG_LONG: /* 0x7d */
   4766 /* File: x86/OP_NEG_LONG.S */
   4767     /* unop vA, vB */
   4768     movzbl    rINSTbl,%ecx        # ecx<- BA
   4769     sarl      $4,%ecx            # ecx<- B
   4770     andb      $0xf,rINSTbl       # rINST<- A
   4771     GET_VREG_WORD %eax %ecx 0     # eax<- v[B+0]
   4772     GET_VREG_WORD %ecx %ecx 1     # ecx<- v[B+1]
   4773     negl      %eax
   4774     adcl      $0,%ecx
   4775     negl      %ecx
   4776     SET_VREG_WORD %eax rINST 0    # v[A+0]<- eax
   4777     FETCH_INST_OPCODE 1 %eax
   4778     SET_VREG_WORD %ecx rINST 1    # v[A+1]<- ecx
   4779     ADVANCE_PC 1
   4780     GOTO_NEXT_R %eax
   4781 
   4782 /* ------------------------------ */
   4783 .L_OP_NOT_LONG: /* 0x7e */
   4784 /* File: x86/OP_NOT_LONG.S */
   4785     /* unop vA, vB */
   4786     movzbl    rINSTbl,%ecx       # ecx<- BA
   4787     sarl      $4,%ecx           # ecx<- B
   4788     andb      $0xf,rINSTbl      # rINST<- A
   4789     GET_VREG_WORD %eax %ecx 0    # eax<- v[B+0]
   4790     GET_VREG_WORD %ecx %ecx 1    # ecx<- v[B+1]
   4791     notl      %eax
   4792     notl      %ecx
   4793     SET_VREG_WORD %eax rINST 0   # v[A+0]<- eax
   4794     FETCH_INST_OPCODE 1 %eax
   4795     SET_VREG_WORD %ecx rINST 1   # v[A+1]<- ecx
   4796     ADVANCE_PC 1
   4797     GOTO_NEXT_R %eax
   4798 
   4799 /* ------------------------------ */
   4800 .L_OP_NEG_FLOAT: /* 0x7f */
   4801 /* File: x86/OP_NEG_FLOAT.S */
   4802 /* File: x86/fpcvt.S */
   4803     /*
   4804      * Generic 32-bit FP conversion operation.
   4805      */
   4806     /* unop vA, vB */
   4807     movzbl   rINSTbl,%ecx       # ecx<- A+
   4808     sarl     $4,rINST         # rINST<- B
   4809     flds    (rFP,rINST,4)      # %st0<- vB
   4810     andb     $0xf,%cl          # ecx<- A
   4811     fchs
   4812     fstps  (rFP,%ecx,4)        # vA<- %st0
   4813     FETCH_INST_OPCODE 1 %ecx
   4814     ADVANCE_PC 1
   4815     GOTO_NEXT_R %ecx
   4816 
   4817 
   4818 /* ------------------------------ */
   4819 .L_OP_NEG_DOUBLE: /* 0x80 */
   4820 /* File: x86/OP_NEG_DOUBLE.S */
   4821 /* File: x86/fpcvt.S */
   4822     /*
   4823      * Generic 32-bit FP conversion operation.
   4824      */
   4825     /* unop vA, vB */
   4826     movzbl   rINSTbl,%ecx       # ecx<- A+
   4827     sarl     $4,rINST         # rINST<- B
   4828     fldl    (rFP,rINST,4)      # %st0<- vB
   4829     andb     $0xf,%cl          # ecx<- A
   4830     fchs
   4831     fstpl  (rFP,%ecx,4)        # vA<- %st0
   4832     FETCH_INST_OPCODE 1 %ecx
   4833     ADVANCE_PC 1
   4834     GOTO_NEXT_R %ecx
   4835 
   4836 
   4837 /* ------------------------------ */
   4838 .L_OP_INT_TO_LONG: /* 0x81 */
   4839 /* File: x86/OP_INT_TO_LONG.S */
   4840     /* int to long vA, vB */
   4841     movzbl  rINSTbl,%eax                # eax<- +A
   4842     sarl    $4,%eax                    # eax<- B
   4843     GET_VREG_R %eax %eax                # eax<- vB
   4844     andb    $0xf,rINSTbl               # rINST<- A
   4845     SPILL(rIBASE)                       # cltd trashes rIBASE/edx
   4846     cltd                                # rINST:eax<- sssssssBBBBBBBB
   4847     SET_VREG_WORD rIBASE rINST 1        # v[A+1]<- rIBASE/rPC
   4848     FETCH_INST_OPCODE 1 %ecx
   4849     UNSPILL(rIBASE)
   4850     SET_VREG_WORD %eax rINST 0          # v[A+0]<- %eax
   4851     ADVANCE_PC 1
   4852     GOTO_NEXT_R %ecx
   4853 
   4854 /* ------------------------------ */
   4855 .L_OP_INT_TO_FLOAT: /* 0x82 */
   4856 /* File: x86/OP_INT_TO_FLOAT.S */
   4857 /* File: x86/fpcvt.S */
   4858     /*
   4859      * Generic 32-bit FP conversion operation.
   4860      */
   4861     /* unop vA, vB */
   4862     movzbl   rINSTbl,%ecx       # ecx<- A+
   4863     sarl     $4,rINST         # rINST<- B
   4864     fildl    (rFP,rINST,4)      # %st0<- vB
   4865     andb     $0xf,%cl          # ecx<- A
   4866 
   4867     fstps  (rFP,%ecx,4)        # vA<- %st0
   4868     FETCH_INST_OPCODE 1 %ecx
   4869     ADVANCE_PC 1
   4870     GOTO_NEXT_R %ecx
   4871 
   4872 
   4873 /* ------------------------------ */
   4874 .L_OP_INT_TO_DOUBLE: /* 0x83 */
   4875 /* File: x86/OP_INT_TO_DOUBLE.S */
   4876 /* File: x86/fpcvt.S */
   4877     /*
   4878      * Generic 32-bit FP conversion operation.
   4879      */
   4880     /* unop vA, vB */
   4881     movzbl   rINSTbl,%ecx       # ecx<- A+
   4882     sarl     $4,rINST         # rINST<- B
   4883     fildl    (rFP,rINST,4)      # %st0<- vB
   4884     andb     $0xf,%cl          # ecx<- A
   4885 
   4886     fstpl  (rFP,%ecx,4)        # vA<- %st0
   4887     FETCH_INST_OPCODE 1 %ecx
   4888     ADVANCE_PC 1
   4889     GOTO_NEXT_R %ecx
   4890 
   4891 
   4892 /* ------------------------------ */
   4893 .L_OP_LONG_TO_INT: /* 0x84 */
   4894 /* File: x86/OP_LONG_TO_INT.S */
   4895 /* we ignore the high word, making this equivalent to a 32-bit reg move */
   4896 /* File: x86/OP_MOVE.S */
   4897     /* for move, move-object, long-to-int */
   4898     /* op vA, vB */
   4899     movzbl rINSTbl,%eax          # eax<- BA
   4900     andb   $0xf,%al             # eax<- A
   4901     shrl   $4,rINST            # rINST<- B
   4902     GET_VREG_R rINST rINST
   4903     FETCH_INST_OPCODE 1 %ecx
   4904     ADVANCE_PC 1
   4905     SET_VREG rINST %eax           # fp[A]<-fp[B]
   4906     GOTO_NEXT_R %ecx
   4907 
   4908 
   4909 /* ------------------------------ */
   4910 .L_OP_LONG_TO_FLOAT: /* 0x85 */
   4911 /* File: x86/OP_LONG_TO_FLOAT.S */
   4912 /* File: x86/fpcvt.S */
   4913     /*
   4914      * Generic 32-bit FP conversion operation.
   4915      */
   4916     /* unop vA, vB */
   4917     movzbl   rINSTbl,%ecx       # ecx<- A+
   4918     sarl     $4,rINST         # rINST<- B
   4919     fildll    (rFP,rINST,4)      # %st0<- vB
   4920     andb     $0xf,%cl          # ecx<- A
   4921 
   4922     fstps  (rFP,%ecx,4)        # vA<- %st0
   4923     FETCH_INST_OPCODE 1 %ecx
   4924     ADVANCE_PC 1
   4925     GOTO_NEXT_R %ecx
   4926 
   4927 
   4928 /* ------------------------------ */
   4929 .L_OP_LONG_TO_DOUBLE: /* 0x86 */
   4930 /* File: x86/OP_LONG_TO_DOUBLE.S */
   4931 /* File: x86/fpcvt.S */
   4932     /*
   4933      * Generic 32-bit FP conversion operation.
   4934      */
   4935     /* unop vA, vB */
   4936     movzbl   rINSTbl,%ecx       # ecx<- A+
   4937     sarl     $4,rINST         # rINST<- B
   4938     fildll    (rFP,rINST,4)      # %st0<- vB
   4939     andb     $0xf,%cl          # ecx<- A
   4940 
   4941     fstpl  (rFP,%ecx,4)        # vA<- %st0
   4942     FETCH_INST_OPCODE 1 %ecx
   4943     ADVANCE_PC 1
   4944     GOTO_NEXT_R %ecx
   4945 
   4946 
   4947 /* ------------------------------ */
   4948 .L_OP_FLOAT_TO_INT: /* 0x87 */
   4949 /* File: x86/OP_FLOAT_TO_INT.S */
   4950 /* File: x86/cvtfp_int.S */
   4951 /* On fp to int conversions, Java requires that
   4952  * if the result > maxint, it should be clamped to maxint.  If it is less
   4953  * than minint, it should be clamped to minint.  If it is a nan, the result
   4954  * should be zero.  Further, the rounding mode is to truncate.  This model
   4955  * differs from what is delivered normally via the x86 fpu, so we have
   4956  * to play some games.
   4957  */
   4958     /* float/double to int/long vA, vB */
   4959     movzbl    rINSTbl,%ecx       # ecx<- A+
   4960     sarl      $4,rINST         # rINST<- B
   4961     .if 0
   4962     fldl     (rFP,rINST,4)       # %st0<- vB
   4963     .else
   4964     flds     (rFP,rINST,4)       # %st0<- vB
   4965     .endif
   4966     ftst
   4967     fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
   4968     movzwl   LOCAL0_OFFSET(%ebp),%eax
   4969     movb     $0xc,%ah
   4970     movw     %ax,LOCAL0_OFFSET+2(%ebp)
   4971     fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
   4972     andb     $0xf,%cl                # ecx<- A
   4973     .if 0
   4974     fistpll  (rFP,%ecx,4)             # convert and store
   4975     .else
   4976     fistpl   (rFP,%ecx,4)             # convert and store
   4977     .endif
   4978     fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
   4979     .if 0
   4980     movl     $0x80000000,%eax
   4981     xorl     4(rFP,%ecx,4),%eax
   4982     orl      (rFP,%ecx,4),%eax
   4983     .else
   4984     cmpl     $0x80000000,(rFP,%ecx,4)
   4985     .endif
   4986     je       .LOP_FLOAT_TO_INT_special_case # fix up result
   4987 
   4988 .LOP_FLOAT_TO_INT_finish:
   4989     FETCH_INST_OPCODE 1 %ecx
   4990     ADVANCE_PC 1
   4991     GOTO_NEXT_R %ecx
   4992 
   4993 .LOP_FLOAT_TO_INT_special_case:
   4994     fnstsw   %ax
   4995     sahf
   4996     jp       .LOP_FLOAT_TO_INT_isNaN
   4997     adcl     $-1,(rFP,%ecx,4)
   4998     .if 0
   4999     adcl     $-1,4(rFP,%ecx,4)
   5000     .endif
   5001    jmp       .LOP_FLOAT_TO_INT_finish
   5002 .LOP_FLOAT_TO_INT_isNaN:
   5003     movl      $0,(rFP,%ecx,4)
   5004     .if 0
   5005     movl      $0,4(rFP,%ecx,4)
   5006     .endif
   5007     jmp       .LOP_FLOAT_TO_INT_finish
   5008 
   5009 
   5010 /* ------------------------------ */
   5011 .L_OP_FLOAT_TO_LONG: /* 0x88 */
   5012 /* File: x86/OP_FLOAT_TO_LONG.S */
   5013 /* File: x86/cvtfp_int.S */
   5014 /* On fp to int conversions, Java requires that
   5015  * if the result > maxint, it should be clamped to maxint.  If it is less
   5016  * than minint, it should be clamped to minint.  If it is a nan, the result
   5017  * should be zero.  Further, the rounding mode is to truncate.  This model
   5018  * differs from what is delivered normally via the x86 fpu, so we have
   5019  * to play some games.
   5020  */
   5021     /* float/double to int/long vA, vB */
   5022     movzbl    rINSTbl,%ecx       # ecx<- A+
   5023     sarl      $4,rINST         # rINST<- B
   5024     .if 0
   5025     fldl     (rFP,rINST,4)       # %st0<- vB
   5026     .else
   5027     flds     (rFP,rINST,4)       # %st0<- vB
   5028     .endif
   5029     ftst
   5030     fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
   5031     movzwl   LOCAL0_OFFSET(%ebp),%eax
   5032     movb     $0xc,%ah
   5033     movw     %ax,LOCAL0_OFFSET+2(%ebp)
   5034     fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
   5035     andb     $0xf,%cl                # ecx<- A
   5036     .if 1
   5037     fistpll  (rFP,%ecx,4)             # convert and store
   5038     .else
   5039     fistpl   (rFP,%ecx,4)             # convert and store
   5040     .endif
   5041     fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
   5042     .if 1
   5043     movl     $0x80000000,%eax
   5044     xorl     4(rFP,%ecx,4),%eax
   5045     orl      (rFP,%ecx,4),%eax
   5046     .else
   5047     cmpl     $0x80000000,(rFP,%ecx,4)
   5048     .endif
   5049     je       .LOP_FLOAT_TO_LONG_special_case # fix up result
   5050 
   5051 .LOP_FLOAT_TO_LONG_finish:
   5052     FETCH_INST_OPCODE 1 %ecx
   5053     ADVANCE_PC 1
   5054     GOTO_NEXT_R %ecx
   5055 
   5056 .LOP_FLOAT_TO_LONG_special_case:
   5057     fnstsw   %ax
   5058     sahf
   5059     jp       .LOP_FLOAT_TO_LONG_isNaN
   5060     adcl     $-1,(rFP,%ecx,4)
   5061     .if 1
   5062     adcl     $-1,4(rFP,%ecx,4)
   5063     .endif
   5064    jmp       .LOP_FLOAT_TO_LONG_finish
   5065 .LOP_FLOAT_TO_LONG_isNaN:
   5066     movl      $0,(rFP,%ecx,4)
   5067     .if 1
   5068     movl      $0,4(rFP,%ecx,4)
   5069     .endif
   5070     jmp       .LOP_FLOAT_TO_LONG_finish
   5071 
   5072 
   5073 /* ------------------------------ */
   5074 .L_OP_FLOAT_TO_DOUBLE: /* 0x89 */
   5075 /* File: x86/OP_FLOAT_TO_DOUBLE.S */
   5076 /* File: x86/fpcvt.S */
   5077     /*
   5078      * Generic 32-bit FP conversion operation.
   5079      */
   5080     /* unop vA, vB */
   5081     movzbl   rINSTbl,%ecx       # ecx<- A+
   5082     sarl     $4,rINST         # rINST<- B
   5083     flds    (rFP,rINST,4)      # %st0<- vB
   5084     andb     $0xf,%cl          # ecx<- A
   5085 
   5086     fstpl  (rFP,%ecx,4)        # vA<- %st0
   5087     FETCH_INST_OPCODE 1 %ecx
   5088     ADVANCE_PC 1
   5089     GOTO_NEXT_R %ecx
   5090 
   5091 
   5092 /* ------------------------------ */
   5093 .L_OP_DOUBLE_TO_INT: /* 0x8a */
   5094 /* File: x86/OP_DOUBLE_TO_INT.S */
   5095 /* File: x86/cvtfp_int.S */
   5096 /* On fp to int conversions, Java requires that
   5097  * if the result > maxint, it should be clamped to maxint.  If it is less
   5098  * than minint, it should be clamped to minint.  If it is a nan, the result
   5099  * should be zero.  Further, the rounding mode is to truncate.  This model
   5100  * differs from what is delivered normally via the x86 fpu, so we have
   5101  * to play some games.
   5102  */
   5103     /* float/double to int/long vA, vB */
   5104     movzbl    rINSTbl,%ecx       # ecx<- A+
   5105     sarl      $4,rINST         # rINST<- B
   5106     .if 1
   5107     fldl     (rFP,rINST,4)       # %st0<- vB
   5108     .else
   5109     flds     (rFP,rINST,4)       # %st0<- vB
   5110     .endif
   5111     ftst
   5112     fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
   5113     movzwl   LOCAL0_OFFSET(%ebp),%eax
   5114     movb     $0xc,%ah
   5115     movw     %ax,LOCAL0_OFFSET+2(%ebp)
   5116     fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
   5117     andb     $0xf,%cl                # ecx<- A
   5118     .if 0
   5119     fistpll  (rFP,%ecx,4)             # convert and store
   5120     .else
   5121     fistpl   (rFP,%ecx,4)             # convert and store
   5122     .endif
   5123     fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
   5124     .if 0
   5125     movl     $0x80000000,%eax
   5126     xorl     4(rFP,%ecx,4),%eax
   5127     orl      (rFP,%ecx,4),%eax
   5128     .else
   5129     cmpl     $0x80000000,(rFP,%ecx,4)
   5130     .endif
   5131     je       .LOP_DOUBLE_TO_INT_special_case # fix up result
   5132 
   5133 .LOP_DOUBLE_TO_INT_finish:
   5134     FETCH_INST_OPCODE 1 %ecx
   5135     ADVANCE_PC 1
   5136     GOTO_NEXT_R %ecx
   5137 
   5138 .LOP_DOUBLE_TO_INT_special_case:
   5139     fnstsw   %ax
   5140     sahf
   5141     jp       .LOP_DOUBLE_TO_INT_isNaN
   5142     adcl     $-1,(rFP,%ecx,4)
   5143     .if 0
   5144     adcl     $-1,4(rFP,%ecx,4)
   5145     .endif
   5146    jmp       .LOP_DOUBLE_TO_INT_finish
   5147 .LOP_DOUBLE_TO_INT_isNaN:
   5148     movl      $0,(rFP,%ecx,4)
   5149     .if 0
   5150     movl      $0,4(rFP,%ecx,4)
   5151     .endif
   5152     jmp       .LOP_DOUBLE_TO_INT_finish
   5153 
   5154 
   5155 /* ------------------------------ */
   5156 .L_OP_DOUBLE_TO_LONG: /* 0x8b */
   5157 /* File: x86/OP_DOUBLE_TO_LONG.S */
   5158 /* File: x86/cvtfp_int.S */
   5159 /* On fp to int conversions, Java requires that
   5160  * if the result > maxint, it should be clamped to maxint.  If it is less
   5161  * than minint, it should be clamped to minint.  If it is a nan, the result
   5162  * should be zero.  Further, the rounding mode is to truncate.  This model
   5163  * differs from what is delivered normally via the x86 fpu, so we have
   5164  * to play some games.
   5165  */
   5166     /* float/double to int/long vA, vB */
   5167     movzbl    rINSTbl,%ecx       # ecx<- A+
   5168     sarl      $4,rINST         # rINST<- B
   5169     .if 1
   5170     fldl     (rFP,rINST,4)       # %st0<- vB
   5171     .else
   5172     flds     (rFP,rINST,4)       # %st0<- vB
   5173     .endif
   5174     ftst
   5175     fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
   5176     movzwl   LOCAL0_OFFSET(%ebp),%eax
   5177     movb     $0xc,%ah
   5178     movw     %ax,LOCAL0_OFFSET+2(%ebp)
   5179     fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
   5180     andb     $0xf,%cl                # ecx<- A
   5181     .if 1
   5182     fistpll  (rFP,%ecx,4)             # convert and store
   5183     .else
   5184     fistpl   (rFP,%ecx,4)             # convert and store
   5185     .endif
   5186     fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
   5187     .if 1
   5188     movl     $0x80000000,%eax
   5189     xorl     4(rFP,%ecx,4),%eax
   5190     orl      (rFP,%ecx,4),%eax
   5191     .else
   5192     cmpl     $0x80000000,(rFP,%ecx,4)
   5193     .endif
   5194     je       .LOP_DOUBLE_TO_LONG_special_case # fix up result
   5195 
   5196 .LOP_DOUBLE_TO_LONG_finish:
   5197     FETCH_INST_OPCODE 1 %ecx
   5198     ADVANCE_PC 1
   5199     GOTO_NEXT_R %ecx
   5200 
   5201 .LOP_DOUBLE_TO_LONG_special_case:
   5202     fnstsw   %ax
   5203     sahf
   5204     jp       .LOP_DOUBLE_TO_LONG_isNaN
   5205     adcl     $-1,(rFP,%ecx,4)
   5206     .if 1
   5207     adcl     $-1,4(rFP,%ecx,4)
   5208     .endif
   5209    jmp       .LOP_DOUBLE_TO_LONG_finish
   5210 .LOP_DOUBLE_TO_LONG_isNaN:
   5211     movl      $0,(rFP,%ecx,4)
   5212     .if 1
   5213     movl      $0,4(rFP,%ecx,4)
   5214     .endif
   5215     jmp       .LOP_DOUBLE_TO_LONG_finish
   5216 
   5217 
   5218 /* ------------------------------ */
   5219 .L_OP_DOUBLE_TO_FLOAT: /* 0x8c */
   5220 /* File: x86/OP_DOUBLE_TO_FLOAT.S */
   5221 /* File: x86/fpcvt.S */
   5222     /*
   5223      * Generic 32-bit FP conversion operation.
   5224      */
   5225     /* unop vA, vB */
   5226     movzbl   rINSTbl,%ecx       # ecx<- A+
   5227     sarl     $4,rINST         # rINST<- B
   5228     fldl    (rFP,rINST,4)      # %st0<- vB
   5229     andb     $0xf,%cl          # ecx<- A
   5230 
   5231     fstps  (rFP,%ecx,4)        # vA<- %st0
   5232     FETCH_INST_OPCODE 1 %ecx
   5233     ADVANCE_PC 1
   5234     GOTO_NEXT_R %ecx
   5235 
   5236 
   5237 /* ------------------------------ */
   5238 .L_OP_INT_TO_BYTE: /* 0x8d */
   5239 /* File: x86/OP_INT_TO_BYTE.S */
   5240 /* File: x86/unop.S */
   5241     /*
   5242      * Generic 32-bit unary operation.  Provide an "instr" line that
   5243      * specifies an instruction that performs "result = op eax".
   5244      */
   5245     /* unop vA, vB */
   5246     movzbl   rINSTbl,%ecx           # ecx<- A+
   5247     sarl     $4,rINST             # rINST<- B
   5248     GET_VREG_R %eax rINST           # eax<- vB
   5249     andb     $0xf,%cl              # ecx<- A
   5250 
   5251 
   5252     movsbl %al,%eax
   5253     SET_VREG %eax %ecx
   5254     FETCH_INST_OPCODE 1 %ecx
   5255     ADVANCE_PC 1
   5256     GOTO_NEXT_R %ecx
   5257 
   5258 
   5259 /* ------------------------------ */
   5260 .L_OP_INT_TO_CHAR: /* 0x8e */
   5261 /* File: x86/OP_INT_TO_CHAR.S */
   5262 /* File: x86/unop.S */
   5263     /*
   5264      * Generic 32-bit unary operation.  Provide an "instr" line that
   5265      * specifies an instruction that performs "result = op eax".
   5266      */
   5267     /* unop vA, vB */
   5268     movzbl   rINSTbl,%ecx           # ecx<- A+
   5269     sarl     $4,rINST             # rINST<- B
   5270     GET_VREG_R %eax rINST           # eax<- vB
   5271     andb     $0xf,%cl              # ecx<- A
   5272 
   5273 
   5274     movzwl %ax,%eax
   5275     SET_VREG %eax %ecx
   5276     FETCH_INST_OPCODE 1 %ecx
   5277     ADVANCE_PC 1
   5278     GOTO_NEXT_R %ecx
   5279 
   5280 
   5281 /* ------------------------------ */
   5282 .L_OP_INT_TO_SHORT: /* 0x8f */
   5283 /* File: x86/OP_INT_TO_SHORT.S */
   5284 /* File: x86/unop.S */
   5285     /*
   5286      * Generic 32-bit unary operation.  Provide an "instr" line that
   5287      * specifies an instruction that performs "result = op eax".
   5288      */
   5289     /* unop vA, vB */
   5290     movzbl   rINSTbl,%ecx           # ecx<- A+
   5291     sarl     $4,rINST             # rINST<- B
   5292     GET_VREG_R %eax rINST           # eax<- vB
   5293     andb     $0xf,%cl              # ecx<- A
   5294 
   5295 
   5296     movswl %ax,%eax
   5297     SET_VREG %eax %ecx
   5298     FETCH_INST_OPCODE 1 %ecx
   5299     ADVANCE_PC 1
   5300     GOTO_NEXT_R %ecx
   5301 
   5302 
   5303 /* ------------------------------ */
   5304 .L_OP_ADD_INT: /* 0x90 */
   5305 /* File: x86/OP_ADD_INT.S */
   5306 /* File: x86/binop.S */
   5307     /*
   5308      * Generic 32-bit binary operation.  Provide an "instr" line that
   5309      * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
   5310      * This could be an x86 instruction or a function call.  (If the result
   5311      * comes back in a register other than eax, you can override "result".)
   5312      *
   5313      * For: add-int, sub-int, and-int, or-int,
   5314      *      xor-int, shl-int, shr-int, ushr-int
   5315      */
   5316     /* binop vAA, vBB, vCC */
   5317     movzbl   2(rPC),%eax   # eax<- BB
   5318     movzbl   3(rPC),%ecx   # ecx<- CC
   5319     GET_VREG_R %eax %eax   # eax<- vBB
   5320     addl (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
   5321     SET_VREG %eax rINST
   5322     FETCH_INST_OPCODE 2 %ecx
   5323     ADVANCE_PC 2
   5324     GOTO_NEXT_R %ecx
   5325 
   5326 
   5327 /* ------------------------------ */
   5328 .L_OP_SUB_INT: /* 0x91 */
   5329 /* File: x86/OP_SUB_INT.S */
   5330 /* File: x86/binop.S */
   5331     /*
   5332      * Generic 32-bit binary operation.  Provide an "instr" line that
   5333      * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
   5334      * This could be an x86 instruction or a function call.  (If the result
   5335      * comes back in a register other than eax, you can override "result".)
   5336      *
   5337      * For: add-int, sub-int, and-int, or-int,
   5338      *      xor-int, shl-int, shr-int, ushr-int
   5339      */
   5340     /* binop vAA, vBB, vCC */
   5341     movzbl   2(rPC),%eax   # eax<- BB
   5342     movzbl   3(rPC),%ecx   # ecx<- CC
   5343     GET_VREG_R %eax %eax   # eax<- vBB
   5344     subl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
   5345     SET_VREG %eax rINST
   5346     FETCH_INST_OPCODE 2 %ecx
   5347     ADVANCE_PC 2
   5348     GOTO_NEXT_R %ecx
   5349 
   5350 
   5351 /* ------------------------------ */
   5352 .L_OP_MUL_INT: /* 0x92 */
   5353 /* File: x86/OP_MUL_INT.S */
   5354     /*
   5355      * 32-bit binary multiplication.
   5356      */
   5357     /* mul vAA, vBB, vCC */
   5358     movzbl   2(rPC),%eax            # eax<- BB
   5359     movzbl   3(rPC),%ecx            # ecx<- CC
   5360     GET_VREG_R %eax %eax            # eax<- vBB
   5361     SPILL(rIBASE)
   5362     imull    (rFP,%ecx,4),%eax      # trashes rIBASE/edx
   5363     UNSPILL(rIBASE)
   5364     FETCH_INST_OPCODE 2 %ecx
   5365     ADVANCE_PC 2
   5366     SET_VREG %eax rINST
   5367     GOTO_NEXT_R %ecx
   5368 
   5369 /* ------------------------------ */
   5370 .L_OP_DIV_INT: /* 0x93 */
   5371 /* File: x86/OP_DIV_INT.S */
   5372 /* File: x86/bindiv.S */
   5373 
   5374     /*
   5375      * 32-bit binary div/rem operation.  Handles special case of op0=minint and
   5376      * op1=-1.
   5377      */
   5378     /* binop vAA, vBB, vCC */
   5379     movzbl   2(rPC),%eax            # eax<- BB
   5380     movzbl   3(rPC),%ecx            # ecx<- CC
   5381     GET_VREG_R %eax %eax            # eax<- vBB
   5382     GET_VREG_R %ecx %ecx            # eax<- vBB
   5383     SPILL(rIBASE)
   5384     cmpl     $0,%ecx
   5385     je       common_errDivideByZero
   5386     cmpl     $-1,%ecx
   5387     jne      .LOP_DIV_INT_continue_div
   5388     cmpl     $0x80000000,%eax
   5389     jne      .LOP_DIV_INT_continue_div
   5390     movl     $0x80000000,%eax
   5391     SET_VREG %eax rINST
   5392     UNSPILL(rIBASE)
   5393     FETCH_INST_OPCODE 2 %ecx
   5394     ADVANCE_PC 2
   5395     GOTO_NEXT_R %ecx
   5396 
   5397 .LOP_DIV_INT_continue_div:
   5398     cltd
   5399     idivl   %ecx
   5400     SET_VREG %eax rINST
   5401     UNSPILL(rIBASE)
   5402     FETCH_INST_OPCODE 2 %ecx
   5403     ADVANCE_PC 2
   5404     GOTO_NEXT_R %ecx
   5405 
   5406 
   5407 /* ------------------------------ */
   5408 .L_OP_REM_INT: /* 0x94 */
   5409 /* File: x86/OP_REM_INT.S */
   5410 /* File: x86/bindiv.S */
   5411 
   5412     /*
   5413      * 32-bit binary div/rem operation.  Handles special case of op0=minint and
   5414      * op1=-1.
   5415      */
   5416     /* binop vAA, vBB, vCC */
   5417     movzbl   2(rPC),%eax            # eax<- BB
   5418     movzbl   3(rPC),%ecx            # ecx<- CC
   5419     GET_VREG_R %eax %eax            # eax<- vBB
   5420     GET_VREG_R %ecx %ecx            # eax<- vBB
   5421     SPILL(rIBASE)
   5422     cmpl     $0,%ecx
   5423     je       common_errDivideByZero
   5424     cmpl     $-1,%ecx
   5425     jne      .LOP_REM_INT_continue_div
   5426     cmpl     $0x80000000,%eax
   5427     jne      .LOP_REM_INT_continue_div
   5428     movl     $0,rIBASE
   5429     SET_VREG rIBASE rINST
   5430     UNSPILL(rIBASE)
   5431     FETCH_INST_OPCODE 2 %ecx
   5432     ADVANCE_PC 2
   5433     GOTO_NEXT_R %ecx
   5434 
   5435 .LOP_REM_INT_continue_div:
   5436     cltd
   5437     idivl   %ecx
   5438     SET_VREG rIBASE rINST
   5439     UNSPILL(rIBASE)
   5440     FETCH_INST_OPCODE 2 %ecx
   5441     ADVANCE_PC 2
   5442     GOTO_NEXT_R %ecx
   5443 
   5444 
   5445 /* ------------------------------ */
   5446 .L_OP_AND_INT: /* 0x95 */
   5447 /* File: x86/OP_AND_INT.S */
   5448 /* File: x86/binop.S */
   5449     /*
   5450      * Generic 32-bit binary operation.  Provide an "instr" line that
   5451      * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
   5452      * This could be an x86 instruction or a function call.  (If the result
   5453      * comes back in a register other than eax, you can override "result".)
   5454      *
   5455      * For: add-int, sub-int, and-int, or-int,
   5456      *      xor-int, shl-int, shr-int, ushr-int
   5457      */
   5458     /* binop vAA, vBB, vCC */
   5459     movzbl   2(rPC),%eax   # eax<- BB
   5460     movzbl   3(rPC),%ecx   # ecx<- CC
   5461     GET_VREG_R %eax %eax   # eax<- vBB
   5462     andl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
   5463     SET_VREG %eax rINST
   5464     FETCH_INST_OPCODE 2 %ecx
   5465     ADVANCE_PC 2
   5466     GOTO_NEXT_R %ecx
   5467 
   5468 
   5469 /* ------------------------------ */
   5470 .L_OP_OR_INT: /* 0x96 */
   5471 /* File: x86/OP_OR_INT.S */
   5472 /* File: x86/binop.S */
   5473     /*
   5474      * Generic 32-bit binary operation.  Provide an "instr" line that
   5475      * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
   5476      * This could be an x86 instruction or a function call.  (If the result
   5477      * comes back in a register other than eax, you can override "result".)
   5478      *
   5479      * For: add-int, sub-int, and-int, or-int,
   5480      *      xor-int, shl-int, shr-int, ushr-int
   5481      */
   5482     /* binop vAA, vBB, vCC */
   5483     movzbl   2(rPC),%eax   # eax<- BB
   5484     movzbl   3(rPC),%ecx   # ecx<- CC
   5485     GET_VREG_R %eax %eax   # eax<- vBB
   5486     orl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
   5487     SET_VREG %eax rINST
   5488     FETCH_INST_OPCODE 2 %ecx
   5489     ADVANCE_PC 2
   5490     GOTO_NEXT_R %ecx
   5491 
   5492 
   5493 /* ------------------------------ */
   5494 .L_OP_XOR_INT: /* 0x97 */
   5495 /* File: x86/OP_XOR_INT.S */
   5496 /* File: x86/binop.S */
   5497     /*
   5498      * Generic 32-bit binary operation.  Provide an "instr" line that
   5499      * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
   5500      * This could be an x86 instruction or a function call.  (If the result
   5501      * comes back in a register other than eax, you can override "result".)
   5502      *
   5503      * For: add-int, sub-int, and-int, or-int,
   5504      *      xor-int, shl-int, shr-int, ushr-int
   5505      */
   5506     /* binop vAA, vBB, vCC */
   5507     movzbl   2(rPC),%eax   # eax<- BB
   5508     movzbl   3(rPC),%ecx   # ecx<- CC
   5509     GET_VREG_R %eax %eax   # eax<- vBB
   5510     xorl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
   5511     SET_VREG %eax rINST
   5512     FETCH_INST_OPCODE 2 %ecx
   5513     ADVANCE_PC 2
   5514     GOTO_NEXT_R %ecx
   5515 
   5516 
   5517 /* ------------------------------ */
   5518 .L_OP_SHL_INT: /* 0x98 */
   5519 /* File: x86/OP_SHL_INT.S */
   5520 /* File: x86/binop1.S */
   5521     /*
   5522      * Generic 32-bit binary operation in which both operands loaded to
   5523      * registers (op0 in eax, op1 in ecx).
   5524      */
   5525     /* binop vAA, vBB, vCC */
   5526     movzbl   2(rPC),%eax            # eax<- BB
   5527     movzbl   3(rPC),%ecx            # ecx<- CC
   5528     GET_VREG_R %eax %eax            # eax<- vBB
   5529     GET_VREG_R %ecx %ecx            # eax<- vBB
   5530     sall    %cl,%eax                          # ex: addl    %ecx,%eax
   5531     SET_VREG %eax rINST
   5532     FETCH_INST_OPCODE 2 %ecx
   5533     ADVANCE_PC 2
   5534     GOTO_NEXT_R %ecx
   5535 
   5536 
   5537 /* ------------------------------ */
   5538 .L_OP_SHR_INT: /* 0x99 */
   5539 /* File: x86/OP_SHR_INT.S */
   5540 /* File: x86/binop1.S */
   5541     /*
   5542      * Generic 32-bit binary operation in which both operands loaded to
   5543      * registers (op0 in eax, op1 in ecx).
   5544      */
   5545     /* binop vAA, vBB, vCC */
   5546     movzbl   2(rPC),%eax            # eax<- BB
   5547     movzbl   3(rPC),%ecx            # ecx<- CC
   5548     GET_VREG_R %eax %eax            # eax<- vBB
   5549     GET_VREG_R %ecx %ecx            # eax<- vBB
   5550     sarl    %cl,%eax                          # ex: addl    %ecx,%eax
   5551     SET_VREG %eax rINST
   5552     FETCH_INST_OPCODE 2 %ecx
   5553     ADVANCE_PC 2
   5554     GOTO_NEXT_R %ecx
   5555 
   5556 
   5557 /* ------------------------------ */
   5558 .L_OP_USHR_INT: /* 0x9a */
   5559 /* File: x86/OP_USHR_INT.S */
   5560 /* File: x86/binop1.S */
   5561     /*
   5562      * Generic 32-bit binary operation in which both operands loaded to
   5563      * registers (op0 in eax, op1 in ecx).
   5564      */
   5565     /* binop vAA, vBB, vCC */
   5566     movzbl   2(rPC),%eax            # eax<- BB
   5567     movzbl   3(rPC),%ecx            # ecx<- CC
   5568     GET_VREG_R %eax %eax            # eax<- vBB
   5569     GET_VREG_R %ecx %ecx            # eax<- vBB
   5570     shrl    %cl,%eax                          # ex: addl    %ecx,%eax
   5571     SET_VREG %eax rINST
   5572     FETCH_INST_OPCODE 2 %ecx
   5573     ADVANCE_PC 2
   5574     GOTO_NEXT_R %ecx
   5575 
   5576 
   5577 /* ------------------------------ */
   5578 .L_OP_ADD_LONG: /* 0x9b */
   5579 /* File: x86/OP_ADD_LONG.S */
   5580 /* File: x86/binopWide.S */
   5581     /*
   5582      * Generic 64-bit binary operation.
   5583      */
   5584     /* binop vAA, vBB, vCC */
   5585 
   5586     movzbl    2(rPC),%eax               # eax<- BB
   5587     movzbl    3(rPC),%ecx               # ecx<- CC
   5588     SPILL(rIBASE)                       # save rIBASE
   5589     GET_VREG_WORD rIBASE %eax 0         # rIBASE<- v[BB+0]
   5590     GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
   5591     addl (rFP,%ecx,4),rIBASE         # ex: addl   (rFP,%ecx,4),rIBASE
   5592     adcl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
   5593     SET_VREG_WORD rIBASE rINST 0        # v[AA+0] <- rIBASE
   5594     FETCH_INST_OPCODE 2 %ecx
   5595     UNSPILL(rIBASE)                     # restore rIBASE
   5596     SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
   5597     ADVANCE_PC 2
   5598     GOTO_NEXT_R %ecx
   5599 
   5600 
   5601 /* ------------------------------ */
   5602 .L_OP_SUB_LONG: /* 0x9c */
   5603 /* File: x86/OP_SUB_LONG.S */
   5604 /* File: x86/binopWide.S */
   5605     /*
   5606      * Generic 64-bit binary operation.
   5607      */
   5608     /* binop vAA, vBB, vCC */
   5609 
   5610     movzbl    2(rPC),%eax               # eax<- BB
   5611     movzbl    3(rPC),%ecx               # ecx<- CC
   5612     SPILL(rIBASE)                       # save rIBASE
   5613     GET_VREG_WORD rIBASE %eax 0         # rIBASE<- v[BB+0]
   5614     GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
   5615     subl (rFP,%ecx,4),rIBASE         # ex: addl   (rFP,%ecx,4),rIBASE
   5616     sbbl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
   5617     SET_VREG_WORD rIBASE rINST 0        # v[AA+0] <- rIBASE
   5618     FETCH_INST_OPCODE 2 %ecx
   5619     UNSPILL(rIBASE)                     # restore rIBASE
   5620     SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
   5621     ADVANCE_PC 2
   5622     GOTO_NEXT_R %ecx
   5623 
   5624 
   5625 /* ------------------------------ */
   5626 .L_OP_MUL_LONG: /* 0x9d */
   5627 /* File: x86/OP_MUL_LONG.S */
   5628     /*
   5629      * Signed 64-bit integer multiply.
   5630      *
   5631      * We could definately use more free registers for
   5632      * this code.   We spill rINSTw (ebx),
   5633      * giving us eax, ebc, ecx and edx as computational
   5634      * temps.  On top of that, we'll spill edi (rFP)
   5635      * for use as the vB pointer and esi (rPC) for use
   5636      * as the vC pointer.  Yuck.
   5637      */
   5638     /* mul-long vAA, vBB, vCC */
   5639     movzbl    2(rPC),%eax              # eax<- B
   5640     movzbl    3(rPC),%ecx              # ecx<- C
   5641     SPILL_TMP2(%esi)                   # save Dalvik PC
   5642     SPILL(rFP)
   5643     SPILL(rINST)
   5644     SPILL(rIBASE)
   5645     leal      (rFP,%eax,4),%esi        # esi<- &v[B]
   5646     leal      (rFP,%ecx,4),rFP         # rFP<- &v[C]
   5647     movl      4(%esi),%ecx             # ecx<- Bmsw
   5648     imull     (rFP),%ecx               # ecx<- (Bmsw*Clsw)
   5649     movl      4(rFP),%eax              # eax<- Cmsw
   5650     imull     (%esi),%eax              # eax<- (Cmsw*Blsw)
   5651     addl      %eax,%ecx                # ecx<- (Bmsw*Clsw)+(Cmsw*Blsw)
   5652     movl      (rFP),%eax               # eax<- Clsw
   5653     mull      (%esi)                   # eax<- (Clsw*Alsw)
   5654     UNSPILL(rINST)
   5655     UNSPILL(rFP)
   5656     leal      (%ecx,rIBASE),rIBASE # full result now in rIBASE:%eax
   5657     UNSPILL_TMP2(%esi)             # Restore Dalvik PC
   5658     FETCH_INST_OPCODE 2 %ecx       # Fetch next instruction
   5659     movl      rIBASE,4(rFP,rINST,4)# v[B+1]<- rIBASE
   5660     UNSPILL(rIBASE)
   5661     movl      %eax,(rFP,rINST,4)   # v[B]<- %eax
   5662     ADVANCE_PC 2
   5663     GOTO_NEXT_R %ecx
   5664 
   5665 /* ------------------------------ */
   5666 .L_OP_DIV_LONG: /* 0x9e */
   5667 /* File: x86/OP_DIV_LONG.S */
   5668     /* div vAA, vBB, vCC */
   5669     movzbl    3(rPC),%eax              # eax<- CC
   5670     movzbl    2(rPC),%ecx              # ecx<- BB
   5671     SPILL(rIBASE)                      # save rIBASE/%edx
   5672     GET_VREG_WORD rIBASE %eax 0
   5673     GET_VREG_WORD %eax %eax 1
   5674     movl     rIBASE,OUT_ARG2(%esp)
   5675     testl    %eax,%eax
   5676     je       .LOP_DIV_LONG_check_zero
   5677     cmpl     $-1,%eax
   5678     je       .LOP_DIV_LONG_check_neg1
   5679 .LOP_DIV_LONG_notSpecial:
   5680     GET_VREG_WORD rIBASE %ecx 0
   5681     GET_VREG_WORD %ecx %ecx 1
   5682 .LOP_DIV_LONG_notSpecial1:
   5683     movl     %eax,OUT_ARG3(%esp)
   5684     movl     rIBASE,OUT_ARG0(%esp)
   5685     movl     %ecx,OUT_ARG1(%esp)
   5686     call     __divdi3
   5687 .LOP_DIV_LONG_finish:
   5688     SET_VREG_WORD rIBASE rINST 1
   5689     UNSPILL(rIBASE)                 # restore rIBASE/%edx
   5690     SET_VREG_WORD %eax rINST 0
   5691     FETCH_INST_OPCODE 2 %ecx
   5692     ADVANCE_PC 2
   5693     GOTO_NEXT_R %ecx
   5694 
   5695 .LOP_DIV_LONG_check_zero:
   5696     testl   rIBASE,rIBASE
   5697     jne     .LOP_DIV_LONG_notSpecial
   5698     jmp     common_errDivideByZero
   5699 .LOP_DIV_LONG_check_neg1:
   5700     testl   rIBASE,%eax
   5701     jne     .LOP_DIV_LONG_notSpecial
   5702     GET_VREG_WORD rIBASE %ecx 0
   5703     GET_VREG_WORD %ecx %ecx 1
   5704     testl    rIBASE,rIBASE
   5705     jne      .LOP_DIV_LONG_notSpecial1
   5706     cmpl     $0x80000000,%ecx
   5707     jne      .LOP_DIV_LONG_notSpecial1
   5708     /* minint / -1, return minint on div, 0 on rem */
   5709     xorl     %eax,%eax
   5710     movl     $0x80000000,rIBASE
   5711     jmp      .LOP_DIV_LONG_finish
   5712 
   5713 /* ------------------------------ */
   5714 .L_OP_REM_LONG: /* 0x9f */
   5715 /* File: x86/OP_REM_LONG.S */
   5716 /* File: x86/OP_DIV_LONG.S */
   5717     /* div vAA, vBB, vCC */
   5718     movzbl    3(rPC),%eax              # eax<- CC
   5719     movzbl    2(rPC),%ecx              # ecx<- BB
   5720     SPILL(rIBASE)                      # save rIBASE/%edx
   5721     GET_VREG_WORD rIBASE %eax 0
   5722     GET_VREG_WORD %eax %eax 1
   5723     movl     rIBASE,OUT_ARG2(%esp)
   5724     testl    %eax,%eax
   5725     je       .LOP_REM_LONG_check_zero
   5726     cmpl     $-1,%eax
   5727     je       .LOP_REM_LONG_check_neg1
   5728 .LOP_REM_LONG_notSpecial:
   5729     GET_VREG_WORD rIBASE %ecx 0
   5730     GET_VREG_WORD %ecx %ecx 1
   5731 .LOP_REM_LONG_notSpecial1:
   5732     movl     %eax,OUT_ARG3(%esp)
   5733     movl     rIBASE,OUT_ARG0(%esp)
   5734     movl     %ecx,OUT_ARG1(%esp)
   5735     call     __moddi3
   5736 .LOP_REM_LONG_finish:
   5737     SET_VREG_WORD rIBASE rINST 1
   5738     UNSPILL(rIBASE)                 # restore rIBASE/%edx
   5739     SET_VREG_WORD %eax rINST 0
   5740     FETCH_INST_OPCODE 2 %ecx
   5741     ADVANCE_PC 2
   5742     GOTO_NEXT_R %ecx
   5743 
   5744 .LOP_REM_LONG_check_zero:
   5745     testl   rIBASE,rIBASE
   5746     jne     .LOP_REM_LONG_notSpecial
   5747     jmp     common_errDivideByZero
   5748 .LOP_REM_LONG_check_neg1:
   5749     testl   rIBASE,%eax
   5750     jne     .LOP_REM_LONG_notSpecial
   5751     GET_VREG_WORD rIBASE %ecx 0
   5752     GET_VREG_WORD %ecx %ecx 1
   5753     testl    rIBASE,rIBASE
   5754     jne      .LOP_REM_LONG_notSpecial1
   5755     cmpl     $0x80000000,%ecx
   5756     jne      .LOP_REM_LONG_notSpecial1
   5757     /* minint / -1, return minint on div, 0 on rem */
   5758     xorl     %eax,%eax
   5759     movl     $0,rIBASE
   5760     jmp      .LOP_REM_LONG_finish
   5761 
   5762 
   5763 /* ------------------------------ */
   5764 .L_OP_AND_LONG: /* 0xa0 */
   5765 /* File: x86/OP_AND_LONG.S */
   5766 /* File: x86/binopWide.S */
   5767     /*
   5768      * Generic 64-bit binary operation.
   5769      */
   5770     /* binop vAA, vBB, vCC */
   5771 
   5772     movzbl    2(rPC),%eax               # eax<- BB
   5773     movzbl    3(rPC),%ecx               # ecx<- CC
   5774     SPILL(rIBASE)                       # save rIBASE
   5775     GET_VREG_WORD rIBASE %eax 0         # rIBASE<- v[BB+0]
   5776     GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
   5777     andl (rFP,%ecx,4),rIBASE         # ex: addl   (rFP,%ecx,4),rIBASE
   5778     andl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
   5779     SET_VREG_WORD rIBASE rINST 0        # v[AA+0] <- rIBASE
   5780     FETCH_INST_OPCODE 2 %ecx
   5781     UNSPILL(rIBASE)                     # restore rIBASE
   5782     SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
   5783     ADVANCE_PC 2
   5784     GOTO_NEXT_R %ecx
   5785 
   5786 
   5787 /* ------------------------------ */
   5788 .L_OP_OR_LONG: /* 0xa1 */
   5789 /* File: x86/OP_OR_LONG.S */
   5790 /* File: x86/binopWide.S */
   5791     /*
   5792      * Generic 64-bit binary operation.
   5793      */
   5794     /* binop vAA, vBB, vCC */
   5795 
   5796     movzbl    2(rPC),%eax               # eax<- BB
   5797     movzbl    3(rPC),%ecx               # ecx<- CC
   5798     SPILL(rIBASE)                       # save rIBASE
   5799     GET_VREG_WORD rIBASE %eax 0         # rIBASE<- v[BB+0]
   5800     GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
   5801     orl (rFP,%ecx,4),rIBASE         # ex: addl   (rFP,%ecx,4),rIBASE
   5802     orl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
   5803     SET_VREG_WORD rIBASE rINST 0        # v[AA+0] <- rIBASE
   5804     FETCH_INST_OPCODE 2 %ecx
   5805     UNSPILL(rIBASE)                     # restore rIBASE
   5806     SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
   5807     ADVANCE_PC 2
   5808     GOTO_NEXT_R %ecx
   5809 
   5810 
   5811 /* ------------------------------ */
   5812 .L_OP_XOR_LONG: /* 0xa2 */
   5813 /* File: x86/OP_XOR_LONG.S */
   5814 /* File: x86/binopWide.S */
   5815     /*
   5816      * Generic 64-bit binary operation.
   5817      */
   5818     /* binop vAA, vBB, vCC */
   5819 
   5820     movzbl    2(rPC),%eax               # eax<- BB
   5821     movzbl    3(rPC),%ecx               # ecx<- CC
   5822     SPILL(rIBASE)                       # save rIBASE
   5823     GET_VREG_WORD rIBASE %eax 0         # rIBASE<- v[BB+0]
   5824     GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
   5825     xorl (rFP,%ecx,4),rIBASE         # ex: addl   (rFP,%ecx,4),rIBASE
   5826     xorl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
   5827     SET_VREG_WORD rIBASE rINST 0        # v[AA+0] <- rIBASE
   5828     FETCH_INST_OPCODE 2 %ecx
   5829     UNSPILL(rIBASE)                     # restore rIBASE
   5830     SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
   5831     ADVANCE_PC 2
   5832     GOTO_NEXT_R %ecx
   5833 
   5834 
   5835 /* ------------------------------ */
   5836 .L_OP_SHL_LONG: /* 0xa3 */
   5837 /* File: x86/OP_SHL_LONG.S */
   5838     /*
   5839      * Long integer shift.  This is different from the generic 32/64-bit
   5840      * binary operations because vAA/vBB are 64-bit but vCC (the shift
   5841      * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
   5842      * 6 bits of the shift distance.  x86 shifts automatically mask off
   5843      * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
   5844      * case specially.
   5845      */
   5846     /* shl-long vAA, vBB, vCC */
   5847     /* ecx gets shift count */
   5848     /* Need to spill rINST */
   5849     /* rINSTw gets AA */
   5850     movzbl    2(rPC),%eax               # eax<- BB
   5851     movzbl    3(rPC),%ecx               # ecx<- CC
   5852     SPILL(rIBASE)
   5853     GET_VREG_WORD rIBASE %eax 1         # ecx<- v[BB+1]
   5854     GET_VREG_R   %ecx %ecx              # ecx<- vCC
   5855     GET_VREG_WORD %eax %eax 0           # eax<- v[BB+0]
   5856     shldl     %eax,rIBASE
   5857     sall      %cl,%eax
   5858     testb     $32,%cl
   5859     je        2f
   5860     movl      %eax,rIBASE
   5861     xorl      %eax,%eax
   5862 2:
   5863     SET_VREG_WORD rIBASE rINST 1        # v[AA+1]<- rIBASE
   5864     FETCH_INST_OPCODE 2 %ecx
   5865     UNSPILL(rIBASE)
   5866     SET_VREG_WORD %eax rINST 0          # v[AA+0]<- %eax
   5867     ADVANCE_PC 2
   5868     GOTO_NEXT_R %ecx
   5869 
   5870 /* ------------------------------ */
   5871 .L_OP_SHR_LONG: /* 0xa4 */
   5872 /* File: x86/OP_SHR_LONG.S */
   5873     /*
   5874      * Long integer shift.  This is different from the generic 32/64-bit
   5875      * binary operations because vAA/vBB are 64-bit but vCC (the shift
   5876      * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
   5877      * 6 bits of the shift distance.  x86 shifts automatically mask off
   5878      * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
   5879      * case specially.
   5880      */
   5881     /* shr-long vAA, vBB, vCC */
   5882     /* ecx gets shift count */
   5883     /* Need to spill rIBASE */
   5884     /* rINSTw gets AA */
   5885     movzbl    2(rPC),%eax               # eax<- BB
   5886     movzbl    3(rPC),%ecx               # ecx<- CC
   5887     SPILL(rIBASE)
   5888     GET_VREG_WORD rIBASE %eax 1         # rIBASE<- v[BB+1]
   5889     GET_VREG_R   %ecx %ecx              # ecx<- vCC
   5890     GET_VREG_WORD %eax %eax 0           # eax<- v[BB+0]
   5891     shrdl     rIBASE,%eax
   5892     sarl      %cl,rIBASE
   5893     testb     $32,%cl
   5894     je        2f
   5895     movl      rIBASE,%eax
   5896     sarl      $31,rIBASE
   5897 2:
   5898     SET_VREG_WORD rIBASE rINST 1        # v[AA+1]<- rIBASE
   5899     FETCH_INST_OPCODE 2 %ecx
   5900     UNSPILL(rIBASE)
   5901     SET_VREG_WORD %eax rINST 0          # v[AA+0]<- eax
   5902     ADVANCE_PC 2
   5903     GOTO_NEXT_R %ecx
   5904 
   5905 /* ------------------------------ */
   5906 .L_OP_USHR_LONG: /* 0xa5 */
   5907 /* File: x86/OP_USHR_LONG.S */
   5908     /*
   5909      * Long integer shift.  This is different from the generic 32/64-bit
   5910      * binary operations because vAA/vBB are 64-bit but vCC (the shift
   5911      * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
   5912      * 6 bits of the shift distance.  x86 shifts automatically mask off
   5913      * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
   5914      * case specially.
   5915      */
   5916     /* shr-long vAA, vBB, vCC */
   5917     /* ecx gets shift count */
   5918     /* Need to spill rIBASE */
   5919     /* rINSTw gets AA */
   5920     movzbl    2(rPC),%eax               # eax<- BB
   5921     movzbl    3(rPC),%ecx               # ecx<- CC
   5922     SPILL(rIBASE)
   5923     GET_VREG_WORD rIBASE %eax 1         # rIBASE<- v[BB+1]
   5924     GET_VREG_R  %ecx %ecx               # ecx<- vCC
   5925     GET_VREG_WORD %eax %eax 0           # eax<- v[BB+0]
   5926     shrdl     rIBASE,%eax
   5927     shrl      %cl,rIBASE
   5928     testb     $32,%cl
   5929     je        2f
   5930     movl      rIBASE,%eax
   5931     xorl      rIBASE,rIBASE
   5932 2:
   5933     SET_VREG_WORD rIBASE rINST 1          # v[AA+1]<- rIBASE
   5934     FETCH_INST_OPCODE 2 %ecx
   5935     UNSPILL(rIBASE)
   5936     SET_VREG_WORD %eax rINST 0         # v[BB+0]<- eax
   5937     ADVANCE_PC 2
   5938     GOTO_NEXT_R %ecx
   5939 
   5940 /* ------------------------------ */
   5941 .L_OP_ADD_FLOAT: /* 0xa6 */
   5942 /* File: x86/OP_ADD_FLOAT.S */
   5943 /* File: x86/binflop.S */
   5944     /*
   5945      * Generic 32-bit binary float operation.
   5946      *
   5947      * For: add-fp, sub-fp, mul-fp, div-fp
   5948      */
   5949     /* binop vAA, vBB, vCC */
   5950     movzbl   2(rPC),%eax          # eax<- CC
   5951     movzbl   3(rPC),%ecx          # ecx<- BB
   5952     flds    (rFP,%eax,4)         # vCC to fp stack
   5953     fadds   (rFP,%ecx,4)         # ex: faddp
   5954     FETCH_INST_OPCODE 2 %ecx
   5955     ADVANCE_PC 2
   5956     fstps   (rFP,rINST,4)         # %st to vAA
   5957     GOTO_NEXT_R %ecx
   5958 
   5959 
   5960 /* ------------------------------ */
   5961 .L_OP_SUB_FLOAT: /* 0xa7 */
   5962 /* File: x86/OP_SUB_FLOAT.S */
   5963 /* File: x86/binflop.S */
   5964     /*
   5965      * Generic 32-bit binary float operation.
   5966      *
   5967      * For: add-fp, sub-fp, mul-fp, div-fp
   5968      */
   5969     /* binop vAA, vBB, vCC */
   5970     movzbl   2(rPC),%eax          # eax<- CC
   5971     movzbl   3(rPC),%ecx          # ecx<- BB
   5972     flds    (rFP,%eax,4)         # vCC to fp stack
   5973     fsubs   (rFP,%ecx,4)         # ex: faddp
   5974     FETCH_INST_OPCODE 2 %ecx
   5975     ADVANCE_PC 2
   5976     fstps   (rFP,rINST,4)         # %st to vAA
   5977     GOTO_NEXT_R %ecx
   5978 
   5979 
   5980 /* ------------------------------ */
   5981 .L_OP_MUL_FLOAT: /* 0xa8 */
   5982 /* File: x86/OP_MUL_FLOAT.S */
   5983 /* File: x86/binflop.S */
   5984     /*
   5985      * Generic 32-bit binary float operation.
   5986      *
   5987      * For: add-fp, sub-fp, mul-fp, div-fp
   5988      */
   5989     /* binop vAA, vBB, vCC */
   5990     movzbl   2(rPC),%eax          # eax<- CC
   5991     movzbl   3(rPC),%ecx          # ecx<- BB
   5992     flds    (rFP,%eax,4)         # vCC to fp stack
   5993     fmuls   (rFP,%ecx,4)         # ex: faddp
   5994     FETCH_INST_OPCODE 2 %ecx
   5995     ADVANCE_PC 2
   5996     fstps   (rFP,rINST,4)         # %st to vAA
   5997     GOTO_NEXT_R %ecx
   5998 
   5999 
   6000 /* ------------------------------ */
   6001 .L_OP_DIV_FLOAT: /* 0xa9 */
   6002 /* File: x86/OP_DIV_FLOAT.S */
   6003 /* File: x86/binflop.S */
   6004     /*
   6005      * Generic 32-bit binary float operation.
   6006      *
   6007      * For: add-fp, sub-fp, mul-fp, div-fp
   6008      */
   6009     /* binop vAA, vBB, vCC */
   6010     movzbl   2(rPC),%eax          # eax<- CC
   6011     movzbl   3(rPC),%ecx          # ecx<- BB
   6012     flds    (rFP,%eax,4)         # vCC to fp stack
   6013     fdivs   (rFP,%ecx,4)         # ex: faddp
   6014     FETCH_INST_OPCODE 2 %ecx
   6015     ADVANCE_PC 2
   6016     fstps   (rFP,rINST,4)         # %st to vAA
   6017     GOTO_NEXT_R %ecx
   6018 
   6019 
   6020 /* ------------------------------ */
   6021 .L_OP_REM_FLOAT: /* 0xaa */
   6022 /* File: x86/OP_REM_FLOAT.S */
   6023     /* rem_float vAA, vBB, vCC */
   6024     movzbl   3(rPC),%ecx            # ecx<- BB
   6025     movzbl   2(rPC),%eax            # eax<- CC
   6026     flds     (rFP,%ecx,4)           # vCC to fp stack
   6027     flds     (rFP,%eax,4)           # vCC to fp stack
   6028     movzbl   rINSTbl,%ecx           # ecx<- AA
   6029 1:
   6030     fprem
   6031     fstsw     %ax
   6032     sahf
   6033     jp        1b
   6034     fstp      %st(1)
   6035     FETCH_INST_OPCODE 2 %eax
   6036     ADVANCE_PC 2
   6037     fstps    (rFP,%ecx,4)           # %st to vAA
   6038     GOTO_NEXT_R %eax
   6039 
   6040 /* ------------------------------ */
   6041 .L_OP_ADD_DOUBLE: /* 0xab */
   6042 /* File: x86/OP_ADD_DOUBLE.S */
   6043    /*
   6044     * File: OP_ADD_DOUBLE.S
   6045     */
   6046 
   6047     movzbl   2(rPC),%eax                # eax<- BB
   6048     movzbl   3(rPC),%ecx                # ecx<- CC
   6049     movq     (rFP, %eax, 4), %xmm0      # %xmm0<- vBB
   6050     movq     (rFP, %ecx, 4), %xmm1      # %xmm1<- vCC
   6051     FETCH_INST_OPCODE 2 %ecx
   6052     addsd    %xmm1, %xmm0
   6053     ADVANCE_PC 2
   6054     movq     %xmm0, (rFP, rINST, 4)     # vAA<- vBB * vCC
   6055     GOTO_NEXT_R %ecx
   6056 
   6057 
   6058 /* ------------------------------ */
   6059 .L_OP_SUB_DOUBLE: /* 0xac */
   6060 /* File: x86/OP_SUB_DOUBLE.S */
   6061    /*
   6062     * File: OP_SUB_DOUBLE.S
   6063     */
   6064 
   6065     movzbl   2(rPC),%eax                # eax<- BB
   6066     movzbl   3(rPC),%ecx                # ecx<- CC
   6067     # TODO: movsd?
   6068     movq        (rFP, %eax, 4), %xmm0   # %xmm0<- vBB
   6069     movq        (rFP, %ecx, 4), %xmm1   # %xmm1<- vCC
   6070     FETCH_INST_OPCODE 2 %ecx
   6071     subsd       %xmm1, %xmm0
   6072     ADVANCE_PC 2
   6073     movq        %xmm0, (rFP, rINST, 4)  # vAA<- vBB - vCC
   6074     GOTO_NEXT_R %ecx
   6075 
   6076 /* ------------------------------ */
   6077 .L_OP_MUL_DOUBLE: /* 0xad */
   6078 /* File: x86/OP_MUL_DOUBLE.S */
   6079    /*
   6080     * File: OP_MUL_DOUBLE.S
   6081     */
   6082 
   6083     movzbl   2(rPC),%eax                # eax<- BB
   6084     movzbl   3(rPC),%ecx                # ecx<- CC
   6085     # TODO: movsd?
   6086     movq        (rFP, %eax, 4), %xmm0   # %xmm0<- vBB
   6087     movq        (rFP, %ecx, 4), %xmm1   # %xmm1<- vCC
   6088     FETCH_INST_OPCODE 2 %ecx
   6089     mulsd       %xmm1, %xmm0
   6090     ADVANCE_PC 2
   6091     movq        %xmm0, (rFP, rINST, 4)  # vAA<- vBB * vCC
   6092     GOTO_NEXT_R %ecx
   6093 
   6094 /* ------------------------------ */
   6095 .L_OP_DIV_DOUBLE: /* 0xae */
   6096 /* File: x86/OP_DIV_DOUBLE.S */
   6097 /* File: x86/binflop.S */
   6098     /*
   6099      * Generic 32-bit binary float operation.
   6100      *
   6101      * For: add-fp, sub-fp, mul-fp, div-fp
   6102      */
   6103     /* binop vAA, vBB, vCC */
   6104     movzbl   2(rPC),%eax          # eax<- CC
   6105     movzbl   3(rPC),%ecx          # ecx<- BB
   6106     fldl    (rFP,%eax,4)         # vCC to fp stack
   6107     fdivl   (rFP,%ecx,4)         # ex: faddp
   6108     FETCH_INST_OPCODE 2 %ecx
   6109     ADVANCE_PC 2
   6110     fstpl   (rFP,rINST,4)         # %st to vAA
   6111     GOTO_NEXT_R %ecx
   6112 
   6113 
   6114 /* ------------------------------ */
   6115 .L_OP_REM_DOUBLE: /* 0xaf */
   6116 /* File: x86/OP_REM_DOUBLE.S */
   6117     /* rem_float vAA, vBB, vCC */
   6118     movzbl   3(rPC),%ecx            # ecx<- BB
   6119     movzbl   2(rPC),%eax            # eax<- CC
   6120     fldl     (rFP,%ecx,4)           # vCC to fp stack
   6121     fldl     (rFP,%eax,4)           # vCC to fp stack
   6122     FETCH_INST_OPCODE 2 %ecx
   6123 1:
   6124     fprem
   6125     fstsw     %ax
   6126     sahf
   6127     jp        1b
   6128     fstp      %st(1)
   6129     ADVANCE_PC 2
   6130     fstpl    (rFP,rINST,4)           # %st to vAA
   6131     GOTO_NEXT_R %ecx
   6132 
   6133 /* ------------------------------ */
   6134 .L_OP_ADD_INT_2ADDR: /* 0xb0 */
   6135 /* File: x86/OP_ADD_INT_2ADDR.S */
   6136 /* File: x86/binop2addr.S */
   6137     /*
   6138      * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
   6139      * that specifies an instruction that performs "result = r0 op r1".
   6140      * This could be an instruction or a function call.
   6141      *
   6142      * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
   6143      *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
   6144      *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
   6145      *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
   6146      */
   6147     /* binop/2addr vA, vB */
   6148     movzx   rINSTbl,%ecx               # ecx<- A+
   6149     sarl    $4,rINST                  # rINST<- B
   6150     GET_VREG_R %eax rINST              # eax<- vB
   6151     andb    $0xf,%cl                  # ecx<- A
   6152     addl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
   6153     FETCH_INST_OPCODE 1 %ecx
   6154     ADVANCE_PC 1
   6155     GOTO_NEXT_R %ecx
   6156 
   6157 
   6158 /* ------------------------------ */
   6159 .L_OP_SUB_INT_2ADDR: /* 0xb1 */
   6160 /* File: x86/OP_SUB_INT_2ADDR.S */
   6161 /* File: x86/binop2addr.S */
   6162     /*
   6163      * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
   6164      * that specifies an instruction that performs "result = r0 op r1".
   6165      * This could be an instruction or a function call.
   6166      *
   6167      * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
   6168      *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
   6169      *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
   6170      *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
   6171      */
   6172     /* binop/2addr vA, vB */
   6173     movzx   rINSTbl,%ecx               # ecx<- A+
   6174     sarl    $4,rINST                  # rINST<- B
   6175     GET_VREG_R %eax rINST              # eax<- vB
   6176     andb    $0xf,%cl                  # ecx<- A
   6177     subl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
   6178     FETCH_INST_OPCODE 1 %ecx
   6179     ADVANCE_PC 1
   6180     GOTO_NEXT_R %ecx
   6181 
   6182 
   6183 /* ------------------------------ */
   6184 .L_OP_MUL_INT_2ADDR: /* 0xb2 */
   6185 /* File: x86/OP_MUL_INT_2ADDR.S */
   6186     /* mul vA, vB */
   6187     movzx   rINSTbl,%ecx              # ecx<- A+
   6188     sarl    $4,rINST                 # rINST<- B
   6189     GET_VREG_R %eax rINST             # eax<- vB
   6190     andb    $0xf,%cl                 # ecx<- A
   6191     SPILL(rIBASE)
   6192     imull   (rFP,%ecx,4),%eax         # trashes rIBASE/edx
   6193     UNSPILL(rIBASE)
   6194     SET_VREG %eax %ecx
   6195     FETCH_INST_OPCODE 1 %ecx
   6196     ADVANCE_PC 1
   6197     GOTO_NEXT_R %ecx
   6198 
   6199 /* ------------------------------ */
   6200 .L_OP_DIV_INT_2ADDR: /* 0xb3 */
   6201 /* File: x86/OP_DIV_INT_2ADDR.S */
   6202 /* File: x86/bindiv2addr.S */
   6203     /*
   6204      * 32-bit binary div/rem operation.  Handles special case of op0=minint and
   6205      * op1=-1.
   6206      */
   6207     /* div/rem/2addr vA, vB */
   6208     movzx    rINSTbl,%ecx          # eax<- BA
   6209     SPILL(rIBASE)
   6210     sarl     $4,%ecx              # ecx<- B
   6211     GET_VREG_R %ecx %ecx           # eax<- vBB
   6212     andb     $0xf,rINSTbl         # rINST<- A
   6213     GET_VREG_R %eax rINST          # eax<- vBB
   6214     cmpl     $0,%ecx
   6215     je       common_errDivideByZero
   6216     cmpl     $-1,%ecx
   6217     jne      .LOP_DIV_INT_2ADDR_continue_div2addr
   6218     cmpl     $0x80000000,%eax
   6219     jne      .LOP_DIV_INT_2ADDR_continue_div2addr
   6220     movl     $0x80000000,%eax
   6221     SET_VREG %eax rINST
   6222     UNSPILL(rIBASE)
   6223     FETCH_INST_OPCODE 1 %ecx
   6224     ADVANCE_PC 1
   6225     GOTO_NEXT_R %ecx
   6226 
   6227 .LOP_DIV_INT_2ADDR_continue_div2addr:
   6228     cltd
   6229     idivl   %ecx
   6230     SET_VREG %eax rINST
   6231     UNSPILL(rIBASE)
   6232     FETCH_INST_OPCODE 1 %ecx
   6233     ADVANCE_PC 1
   6234     GOTO_NEXT_R %ecx
   6235 
   6236 
   6237 /* ------------------------------ */
   6238 .L_OP_REM_INT_2ADDR: /* 0xb4 */
   6239 /* File: x86/OP_REM_INT_2ADDR.S */
   6240 /* File: x86/bindiv2addr.S */
   6241     /*
   6242      * 32-bit binary div/rem operation.  Handles special case of op0=minint and
   6243      * op1=-1.
   6244      */
   6245     /* div/rem/2addr vA, vB */
   6246     movzx    rINSTbl,%ecx          # eax<- BA
   6247     SPILL(rIBASE)
   6248     sarl     $4,%ecx              # ecx<- B
   6249     GET_VREG_R %ecx %ecx           # eax<- vBB
   6250     andb     $0xf,rINSTbl         # rINST<- A
   6251     GET_VREG_R %eax rINST          # eax<- vBB
   6252     cmpl     $0,%ecx
   6253     je       common_errDivideByZero
   6254     cmpl     $-1,%ecx
   6255     jne      .LOP_REM_INT_2ADDR_continue_div2addr
   6256     cmpl     $0x80000000,%eax
   6257     jne      .LOP_REM_INT_2ADDR_continue_div2addr
   6258     movl     $0,rIBASE
   6259     SET_VREG rIBASE rINST
   6260     UNSPILL(rIBASE)
   6261     FETCH_INST_OPCODE 1 %ecx
   6262     ADVANCE_PC 1
   6263     GOTO_NEXT_R %ecx
   6264 
   6265 .LOP_REM_INT_2ADDR_continue_div2addr:
   6266     cltd
   6267     idivl   %ecx
   6268     SET_VREG rIBASE rINST
   6269     UNSPILL(rIBASE)
   6270     FETCH_INST_OPCODE 1 %ecx
   6271     ADVANCE_PC 1
   6272     GOTO_NEXT_R %ecx
   6273 
   6274 
   6275 /* ------------------------------ */
   6276 .L_OP_AND_INT_2ADDR: /* 0xb5 */
   6277 /* File: x86/OP_AND_INT_2ADDR.S */
   6278 /* File: x86/binop2addr.S */
   6279     /*
   6280      * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
   6281      * that specifies an instruction that performs "result = r0 op r1".
   6282      * This could be an instruction or a function call.
   6283      *
   6284      * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
   6285      *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
   6286      *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
   6287      *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
   6288      */
   6289     /* binop/2addr vA, vB */
   6290     movzx   rINSTbl,%ecx               # ecx<- A+
   6291     sarl    $4,rINST                  # rINST<- B
   6292     GET_VREG_R %eax rINST              # eax<- vB
   6293     andb    $0xf,%cl                  # ecx<- A
   6294     andl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
   6295     FETCH_INST_OPCODE 1 %ecx
   6296     ADVANCE_PC 1
   6297     GOTO_NEXT_R %ecx
   6298 
   6299 
   6300 /* ------------------------------ */
   6301 .L_OP_OR_INT_2ADDR: /* 0xb6 */
   6302 /* File: x86/OP_OR_INT_2ADDR.S */
   6303 /* File: x86/binop2addr.S */
   6304     /*
   6305      * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
   6306      * that specifies an instruction that performs "result = r0 op r1".
   6307      * This could be an instruction or a function call.
   6308      *
   6309      * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
   6310      *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
   6311      *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
   6312      *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
   6313      */
   6314     /* binop/2addr vA, vB */
   6315     movzx   rINSTbl,%ecx               # ecx<- A+
   6316     sarl    $4,rINST                  # rINST<- B
   6317     GET_VREG_R %eax rINST              # eax<- vB
   6318     andb    $0xf,%cl                  # ecx<- A
   6319     orl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
   6320     FETCH_INST_OPCODE 1 %ecx
   6321     ADVANCE_PC 1
   6322     GOTO_NEXT_R %ecx
   6323 
   6324 
   6325 /* ------------------------------ */
   6326 .L_OP_XOR_INT_2ADDR: /* 0xb7 */
   6327 /* File: x86/OP_XOR_INT_2ADDR.S */
   6328 /* File: x86/binop2addr.S */
   6329     /*
   6330      * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
   6331      * that specifies an instruction that performs "result = r0 op r1".
   6332      * This could be an instruction or a function call.
   6333      *
   6334      * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
   6335      *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
   6336      *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
   6337      *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
   6338      */
   6339     /* binop/2addr vA, vB */
   6340     movzx   rINSTbl,%ecx               # ecx<- A+
   6341     sarl    $4,rINST                  # rINST<- B
   6342     GET_VREG_R %eax rINST              # eax<- vB
   6343     andb    $0xf,%cl                  # ecx<- A
   6344     xorl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
   6345     FETCH_INST_OPCODE 1 %ecx
   6346     ADVANCE_PC 1
   6347     GOTO_NEXT_R %ecx
   6348 
   6349 
   6350 /* ------------------------------ */
   6351 .L_OP_SHL_INT_2ADDR: /* 0xb8 */
   6352 /* File: x86/OP_SHL_INT_2ADDR.S */
   6353 /* File: x86/shop2addr.S */
   6354     /*
   6355      * Generic 32-bit "shift/2addr" operation.
   6356      */
   6357     /* shift/2addr vA, vB */
   6358     movzx    rINSTbl,%ecx           # eax<- BA
   6359     sarl     $4,%ecx               # ecx<- B
   6360     GET_VREG_R %ecx %ecx            # eax<- vBB
   6361     andb     $0xf,rINSTbl          # rINST<- A
   6362     GET_VREG_R %eax rINST           # eax<- vAA
   6363     sall    %cl,%eax                          # ex: sarl %cl,%eax
   6364     FETCH_INST_OPCODE 1 %ecx
   6365     SET_VREG %eax rINST
   6366     ADVANCE_PC 1
   6367     GOTO_NEXT_R %ecx
   6368 
   6369 
   6370 /* ------------------------------ */
   6371 .L_OP_SHR_INT_2ADDR: /* 0xb9 */
   6372 /* File: x86/OP_SHR_INT_2ADDR.S */
   6373 /* File: x86/shop2addr.S */
   6374     /*
   6375      * Generic 32-bit "shift/2addr" operation.
   6376      */
   6377     /* shift/2addr vA, vB */
   6378     movzx    rINSTbl,%ecx           # eax<- BA
   6379     sarl     $4,%ecx               # ecx<- B
   6380     GET_VREG_R %ecx %ecx            # eax<- vBB
   6381     andb     $0xf,rINSTbl          # rINST<- A
   6382     GET_VREG_R %eax rINST           # eax<- vAA
   6383     sarl    %cl,%eax                          # ex: sarl %cl,%eax
   6384     FETCH_INST_OPCODE 1 %ecx
   6385     SET_VREG %eax rINST
   6386     ADVANCE_PC 1
   6387     GOTO_NEXT_R %ecx
   6388 
   6389 
   6390 /* ------------------------------ */
   6391 .L_OP_USHR_INT_2ADDR: /* 0xba */
   6392 /* File: x86/OP_USHR_INT_2ADDR.S */
   6393 /* File: x86/shop2addr.S */
   6394     /*
   6395      * Generic 32-bit "shift/2addr" operation.
   6396      */
   6397     /* shift/2addr vA, vB */
   6398     movzx    rINSTbl,%ecx           # eax<- BA
   6399     sarl     $4,%ecx               # ecx<- B
   6400     GET_VREG_R %ecx %ecx            # eax<- vBB
   6401     andb     $0xf,rINSTbl          # rINST<- A
   6402     GET_VREG_R %eax rINST           # eax<- vAA
   6403     shrl    %cl,%eax                          # ex: sarl %cl,%eax
   6404     FETCH_INST_OPCODE 1 %ecx
   6405     SET_VREG %eax rINST
   6406     ADVANCE_PC 1
   6407     GOTO_NEXT_R %ecx
   6408 
   6409 
   6410 /* ------------------------------ */
   6411 .L_OP_ADD_LONG_2ADDR: /* 0xbb */
   6412 /* File: x86/OP_ADD_LONG_2ADDR.S */
   6413 /* File: x86/binopWide2addr.S */
   6414     /*
   6415      * Generic 64-bit binary operation.
   6416      */
   6417     /* binop/2addr vA, vB */
   6418     movzbl    rINSTbl,%ecx              # ecx<- BA
   6419     sarl      $4,%ecx                  # ecx<- B
   6420     GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
   6421     GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
   6422     andb      $0xF,rINSTbl             # rINST<- A
   6423     addl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
   6424     adcl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
   6425     FETCH_INST_OPCODE 1 %ecx
   6426     ADVANCE_PC 1
   6427     GOTO_NEXT_R %ecx
   6428 
   6429 
   6430 /* ------------------------------ */
   6431 .L_OP_SUB_LONG_2ADDR: /* 0xbc */
   6432 /* File: x86/OP_SUB_LONG_2ADDR.S */
   6433 /* File: x86/binopWide2addr.S */
   6434     /*
   6435      * Generic 64-bit binary operation.
   6436      */
   6437     /* binop/2addr vA, vB */
   6438     movzbl    rINSTbl,%ecx              # ecx<- BA
   6439     sarl      $4,%ecx                  # ecx<- B
   6440     GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
   6441     GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
   6442     andb      $0xF,rINSTbl             # rINST<- A
   6443     subl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
   6444     sbbl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
   6445     FETCH_INST_OPCODE 1 %ecx
   6446     ADVANCE_PC 1
   6447     GOTO_NEXT_R %ecx
   6448 
   6449 
   6450 /* ------------------------------ */
   6451 .L_OP_MUL_LONG_2ADDR: /* 0xbd */
   6452 /* File: x86/OP_MUL_LONG_2ADDR.S */
   6453     /*
   6454      * Signed 64-bit integer multiply, 2-addr version
   6455      *
   6456      * We could definately use more free registers for
   6457      * this code.  We must spill %edx (rIBASE) because it
   6458      * is used by imul.  We'll also spill rINST (ebx),
   6459      * giving us eax, ebc, ecx and rIBASE as computational
   6460      * temps.  On top of that, we'll spill %esi (edi)
   6461      * for use as the vA pointer and rFP (esi) for use
   6462      * as the vB pointer.  Yuck.
   6463      */
   6464     /* mul-long/2addr vA, vB */
   6465     movzbl    rINSTbl,%eax             # eax<- BA
   6466     andb      $0xf,%al                # eax<- A
   6467     sarl      $4,rINST                # rINST<- B
   6468     SPILL_TMP2(%esi)
   6469     SPILL(rFP)
   6470     SPILL(rIBASE)
   6471     leal      (rFP,%eax,4),%esi        # %esi<- &v[A]
   6472     leal      (rFP,rINST,4),rFP        # rFP<- &v[B]
   6473     movl      4(%esi),%ecx             # ecx<- Amsw
   6474     imull     (rFP),%ecx               # ecx<- (Amsw*Blsw)
   6475     movl      4(rFP),%eax              # eax<- Bmsw
   6476     imull     (%esi),%eax              # eax<- (Bmsw*Alsw)
   6477     addl      %eax,%ecx                # ecx<- (Amsw*Blsw)+(Bmsw*Alsw)
   6478     movl      (rFP),%eax               # eax<- Blsw
   6479     mull      (%esi)                   # eax<- (Blsw*Alsw)
   6480     leal      (%ecx,rIBASE),rIBASE     # full result now in %edx:%eax
   6481     movl      rIBASE,4(%esi)           # v[A+1]<- rIBASE
   6482     movl      %eax,(%esi)              # v[A]<- %eax
   6483     UNSPILL_TMP2(%esi)
   6484     FETCH_INST_OPCODE 1 %ecx
   6485     UNSPILL(rIBASE)
   6486     UNSPILL(rFP)
   6487     ADVANCE_PC 1
   6488     GOTO_NEXT_R %ecx
   6489 
   6490 /* ------------------------------ */
   6491 .L_OP_DIV_LONG_2ADDR: /* 0xbe */
   6492 /* File: x86/OP_DIV_LONG_2ADDR.S */
   6493     /* div/2addr vA, vB */
   6494     movzbl    rINSTbl,%eax
   6495     shrl      $4,%eax                  # eax<- B
   6496     andb      $0xf,rINSTbl             # rINST<- A
   6497     SPILL(rIBASE)                       # save rIBASE/%edx
   6498     GET_VREG_WORD rIBASE %eax 0
   6499     GET_VREG_WORD %eax %eax 1
   6500     movl     rIBASE,OUT_ARG2(%esp)
   6501     testl    %eax,%eax
   6502     je       .LOP_DIV_LONG_2ADDR_check_zero
   6503     cmpl     $-1,%eax
   6504     je       .LOP_DIV_LONG_2ADDR_check_neg1
   6505 .LOP_DIV_LONG_2ADDR_notSpecial:
   6506     GET_VREG_WORD rIBASE rINST 0
   6507     GET_VREG_WORD %ecx rINST 1
   6508 .LOP_DIV_LONG_2ADDR_notSpecial1:
   6509     movl     %eax,OUT_ARG3(%esp)
   6510     movl     rIBASE,OUT_ARG0(%esp)
   6511     movl     %ecx,OUT_ARG1(%esp)
   6512     call     __divdi3
   6513 .LOP_DIV_LONG_2ADDR_finish:
   6514     SET_VREG_WORD rIBASE rINST 1
   6515     UNSPILL(rIBASE)                    # restore rIBASE/%edx
   6516     SET_VREG_WORD %eax rINST 0
   6517     FETCH_INST_OPCODE 1 %ecx
   6518     ADVANCE_PC 1
   6519     GOTO_NEXT_R %ecx
   6520 
   6521 .LOP_DIV_LONG_2ADDR_check_zero:
   6522     testl   rIBASE,rIBASE
   6523     jne     .LOP_DIV_LONG_2ADDR_notSpecial
   6524     jmp     common_errDivideByZero
   6525 .LOP_DIV_LONG_2ADDR_check_neg1:
   6526     testl   rIBASE,%eax
   6527     jne     .LOP_DIV_LONG_2ADDR_notSpecial
   6528     GET_VREG_WORD rIBASE rINST 0
   6529     GET_VREG_WORD %ecx rINST 1
   6530     testl    rIBASE,rIBASE
   6531     jne      .LOP_DIV_LONG_2ADDR_notSpecial1
   6532     cmpl     $0x80000000,%ecx
   6533     jne      .LOP_DIV_LONG_2ADDR_notSpecial1
   6534     /* minint / -1, return minint on div, 0 on rem */
   6535     xorl     %eax,%eax
   6536     movl     $0x80000000,rIBASE
   6537     jmp      .LOP_DIV_LONG_2ADDR_finish
   6538 
   6539 /* ------------------------------ */
   6540 .L_OP_REM_LONG_2ADDR: /* 0xbf */
   6541 /* File: x86/OP_REM_LONG_2ADDR.S */
   6542 /* File: x86/OP_DIV_LONG_2ADDR.S */
   6543     /* div/2addr vA, vB */
   6544     movzbl    rINSTbl,%eax
   6545     shrl      $4,%eax                  # eax<- B
   6546     andb      $0xf,rINSTbl             # rINST<- A
   6547     SPILL(rIBASE)                       # save rIBASE/%edx
   6548     GET_VREG_WORD rIBASE %eax 0
   6549     GET_VREG_WORD %eax %eax 1
   6550     movl     rIBASE,OUT_ARG2(%esp)
   6551     testl    %eax,%eax
   6552     je       .LOP_REM_LONG_2ADDR_check_zero
   6553     cmpl     $-1,%eax
   6554     je       .LOP_REM_LONG_2ADDR_check_neg1
   6555 .LOP_REM_LONG_2ADDR_notSpecial:
   6556     GET_VREG_WORD rIBASE rINST 0
   6557     GET_VREG_WORD %ecx rINST 1
   6558 .LOP_REM_LONG_2ADDR_notSpecial1:
   6559     movl     %eax,OUT_ARG3(%esp)
   6560     movl     rIBASE,OUT_ARG0(%esp)
   6561     movl     %ecx,OUT_ARG1(%esp)
   6562     call     __moddi3
   6563 .LOP_REM_LONG_2ADDR_finish:
   6564     SET_VREG_WORD rIBASE rINST 1
   6565     UNSPILL(rIBASE)                    # restore rIBASE/%edx
   6566     SET_VREG_WORD %eax rINST 0
   6567     FETCH_INST_OPCODE 1 %ecx
   6568     ADVANCE_PC 1
   6569     GOTO_NEXT_R %ecx
   6570 
   6571 .LOP_REM_LONG_2ADDR_check_zero:
   6572     testl   rIBASE,rIBASE
   6573     jne     .LOP_REM_LONG_2ADDR_notSpecial
   6574     jmp     common_errDivideByZero
   6575 .LOP_REM_LONG_2ADDR_check_neg1:
   6576     testl   rIBASE,%eax
   6577     jne     .LOP_REM_LONG_2ADDR_notSpecial
   6578     GET_VREG_WORD rIBASE rINST 0
   6579     GET_VREG_WORD %ecx rINST 1
   6580     testl    rIBASE,rIBASE
   6581     jne      .LOP_REM_LONG_2ADDR_notSpecial1
   6582     cmpl     $0x80000000,%ecx
   6583     jne      .LOP_REM_LONG_2ADDR_notSpecial1
   6584     /* minint / -1, return minint on div, 0 on rem */
   6585     xorl     %eax,%eax
   6586     movl     $0,rIBASE
   6587     jmp      .LOP_REM_LONG_2ADDR_finish
   6588 
   6589 
   6590 /* ------------------------------ */
   6591 .L_OP_AND_LONG_2ADDR: /* 0xc0 */
   6592 /* File: x86/OP_AND_LONG_2ADDR.S */
   6593 /* File: x86/binopWide2addr.S */
   6594     /*
   6595      * Generic 64-bit binary operation.
   6596      */
   6597     /* binop/2addr vA, vB */
   6598     movzbl    rINSTbl,%ecx              # ecx<- BA
   6599     sarl      $4,%ecx                  # ecx<- B
   6600     GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
   6601     GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
   6602     andb      $0xF,rINSTbl             # rINST<- A
   6603     andl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
   6604     andl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
   6605     FETCH_INST_OPCODE 1 %ecx
   6606     ADVANCE_PC 1
   6607     GOTO_NEXT_R %ecx
   6608 
   6609 
   6610 /* ------------------------------ */
   6611 .L_OP_OR_LONG_2ADDR: /* 0xc1 */
   6612 /* File: x86/OP_OR_LONG_2ADDR.S */
   6613 /* File: x86/binopWide2addr.S */
   6614     /*
   6615      * Generic 64-bit binary operation.
   6616      */
   6617     /* binop/2addr vA, vB */
   6618     movzbl    rINSTbl,%ecx              # ecx<- BA
   6619     sarl      $4,%ecx                  # ecx<- B
   6620     GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
   6621     GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
   6622     andb      $0xF,rINSTbl             # rINST<- A
   6623     orl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
   6624     orl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
   6625     FETCH_INST_OPCODE 1 %ecx
   6626     ADVANCE_PC 1
   6627     GOTO_NEXT_R %ecx
   6628 
   6629 
   6630 /* ------------------------------ */
   6631 .L_OP_XOR_LONG_2ADDR: /* 0xc2 */
   6632 /* File: x86/OP_XOR_LONG_2ADDR.S */
   6633 /* File: x86/binopWide2addr.S */
   6634     /*
   6635      * Generic 64-bit binary operation.
   6636      */
   6637     /* binop/2addr vA, vB */
   6638     movzbl    rINSTbl,%ecx              # ecx<- BA
   6639     sarl      $4,%ecx                  # ecx<- B
   6640     GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
   6641     GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
   6642     andb      $0xF,rINSTbl             # rINST<- A
   6643     xorl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
   6644     xorl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
   6645     FETCH_INST_OPCODE 1 %ecx
   6646     ADVANCE_PC 1
   6647     GOTO_NEXT_R %ecx
   6648 
   6649 
   6650 /* ------------------------------ */
   6651 .L_OP_SHL_LONG_2ADDR: /* 0xc3 */
   6652 /* File: x86/OP_SHL_LONG_2ADDR.S */
   6653     /*
   6654      * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
   6655      * 32-bit shift distance.
   6656      */
   6657     /* shl-long/2addr vA, vB */
   6658     /* ecx gets shift count */
   6659     /* Need to spill rIBASE */
   6660     /* rINSTw gets AA */
   6661     movzbl    rINSTbl,%ecx             # ecx<- BA
   6662     andb      $0xf,rINSTbl            # rINST<- A
   6663     GET_VREG_WORD %eax rINST 0         # eax<- v[AA+0]
   6664     sarl      $4,%ecx                 # ecx<- B
   6665     SPILL(rIBASE)
   6666     GET_VREG_WORD rIBASE rINST 1       # rIBASE<- v[AA+1]
   6667     GET_VREG_R  %ecx %ecx              # ecx<- vBB
   6668     shldl     %eax,rIBASE
   6669     sall      %cl,%eax
   6670     testb     $32,%cl
   6671     je        2f
   6672     movl      %eax,rIBASE
   6673     xorl      %eax,%eax
   6674 2:
   6675     SET_VREG_WORD rIBASE rINST 1       # v[AA+1]<- rIBASE
   6676     UNSPILL(rIBASE)
   6677     FETCH_INST_OPCODE 1 %ecx
   6678     SET_VREG_WORD %eax rINST 0         # v[AA+0]<- eax
   6679     ADVANCE_PC 1
   6680     GOTO_NEXT_R %ecx
   6681 
   6682 /* ------------------------------ */
   6683 .L_OP_SHR_LONG_2ADDR: /* 0xc4 */
   6684 /* File: x86/OP_SHR_LONG_2ADDR.S */
   6685     /*
   6686      * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
   6687      * 32-bit shift distance.
   6688      */
   6689     /* shl-long/2addr vA, vB */
   6690     /* ecx gets shift count */
   6691     /* Need to spill rIBASE */
   6692     /* rINSTw gets AA */
   6693     movzbl    rINSTbl,%ecx         # ecx<- BA
   6694     andb      $0xf,rINSTbl        # rINST<- A
   6695     GET_VREG_WORD %eax rINST 0     # eax<- v[AA+0]
   6696     sarl      $4,%ecx             # ecx<- B
   6697     SPILL(rIBASE)
   6698     GET_VREG_WORD rIBASE rINST 1   # rIBASE<- v[AA+1]
   6699     GET_VREG_R %ecx %ecx           # ecx<- vBB
   6700     shrdl     rIBASE,%eax
   6701     sarl      %cl,rIBASE
   6702     testb     $32,%cl
   6703     je        2f
   6704     movl      rIBASE,%eax
   6705     sarl      $31,rIBASE
   6706 2:
   6707     SET_VREG_WORD rIBASE rINST 1   # v[AA+1]<- rIBASE
   6708     UNSPILL(rIBASE)
   6709     FETCH_INST_OPCODE 1 %ecx
   6710     SET_VREG_WORD %eax rINST 0    # v[AA+0]<- eax
   6711     ADVANCE_PC 1
   6712     GOTO_NEXT_R %ecx
   6713 
   6714 /* ------------------------------ */
   6715 .L_OP_USHR_LONG_2ADDR: /* 0xc5 */
   6716 /* File: x86/OP_USHR_LONG_2ADDR.S */
   6717     /*
   6718      * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
   6719      * 32-bit shift distance.
   6720      */
   6721     /* shl-long/2addr vA, vB */
   6722     /* ecx gets shift count */
   6723     /* Need to spill rIBASE */
   6724     /* rINSTw gets AA */
   6725     movzbl    rINSTbl,%ecx             # ecx<- BA
   6726     andb      $0xf,rINSTbl            # rINST<- A
   6727     GET_VREG_WORD %eax rINST 0         # eax<- v[AA+0]
   6728     sarl      $4,%ecx                 # ecx<- B
   6729     SPILL(rIBASE)
   6730     GET_VREG_WORD rIBASE rINST 1       # rIBASE<- v[AA+1]
   6731     GET_VREG_R %ecx %ecx               # ecx<- vBB
   6732     shrdl     rIBASE,%eax
   6733     shrl      %cl,rIBASE
   6734     testb     $32,%cl
   6735     je        2f
   6736     movl      rIBASE,%eax
   6737     xorl      rIBASE,rIBASE
   6738 2:
   6739     SET_VREG_WORD rIBASE rINST 1       # v[AA+1]<- rIBASE
   6740     FETCH_INST_OPCODE 1 %ecx
   6741     UNSPILL(rIBASE)
   6742     SET_VREG_WORD %eax rINST 0         # v[AA+0]<- eax
   6743     ADVANCE_PC 1
   6744     GOTO_NEXT_R %ecx
   6745 
   6746 /* ------------------------------ */
   6747 .L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
   6748 /* File: x86/OP_ADD_FLOAT_2ADDR.S */
   6749 /* File: x86/binflop2addr.S */
   6750     /*
   6751      * Generic 32-bit binary float operation.
   6752      *
   6753      * For: add-fp, sub-fp, mul-fp, div-fp
   6754      */
   6755 
   6756     /* binop/2addr vA, vB */
   6757     movzx   rINSTbl,%ecx           # ecx<- A+
   6758     andb    $0xf,%cl              # ecx<- A
   6759     flds    (rFP,%ecx,4)          # vAA to fp stack
   6760     sarl    $4,rINST             # rINST<- B
   6761     fadds   (rFP,rINST,4)         # ex: faddp
   6762     FETCH_INST_OPCODE 1 %eax
   6763     ADVANCE_PC 1
   6764     fstps    (rFP,%ecx,4)         # %st to vA
   6765     GOTO_NEXT_R %eax
   6766 
   6767 
   6768 /* ------------------------------ */
   6769 .L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
   6770 /* File: x86/OP_SUB_FLOAT_2ADDR.S */
   6771 /* File: x86/binflop2addr.S */
   6772     /*
   6773      * Generic 32-bit binary float operation.
   6774      *
   6775      * For: add-fp, sub-fp, mul-fp, div-fp
   6776      */
   6777 
   6778     /* binop/2addr vA, vB */
   6779     movzx   rINSTbl,%ecx           # ecx<- A+
   6780     andb    $0xf,%cl              # ecx<- A
   6781     flds    (rFP,%ecx,4)          # vAA to fp stack
   6782     sarl    $4,rINST             # rINST<- B
   6783     fsubs   (rFP,rINST,4)         # ex: faddp
   6784     FETCH_INST_OPCODE 1 %eax
   6785     ADVANCE_PC 1
   6786     fstps    (rFP,%ecx,4)         # %st to vA
   6787     GOTO_NEXT_R %eax
   6788 
   6789 
   6790 /* ------------------------------ */
   6791 .L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
   6792 /* File: x86/OP_MUL_FLOAT_2ADDR.S */
   6793 /* File: x86/binflop2addr.S */
   6794     /*
   6795      * Generic 32-bit binary float operation.
   6796      *
   6797      * For: add-fp, sub-fp, mul-fp, div-fp
   6798      */
   6799 
   6800     /* binop/2addr vA, vB */
   6801     movzx   rINSTbl,%ecx           # ecx<- A+
   6802     andb    $0xf,%cl              # ecx<- A
   6803     flds    (rFP,%ecx,4)          # vAA to fp stack
   6804     sarl    $4,rINST             # rINST<- B
   6805     fmuls   (rFP,rINST,4)         # ex: faddp
   6806     FETCH_INST_OPCODE 1 %eax
   6807     ADVANCE_PC 1
   6808     fstps    (rFP,%ecx,4)         # %st to vA
   6809     GOTO_NEXT_R %eax
   6810 
   6811 
   6812 /* ------------------------------ */
   6813 .L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
   6814 /* File: x86/OP_DIV_FLOAT_2ADDR.S */
   6815 /* File: x86/binflop2addr.S */
   6816     /*
   6817      * Generic 32-bit binary float operation.
   6818      *
   6819      * For: add-fp, sub-fp, mul-fp, div-fp
   6820      */
   6821 
   6822     /* binop/2addr vA, vB */
   6823     movzx   rINSTbl,%ecx           # ecx<- A+
   6824     andb    $0xf,%cl              # ecx<- A
   6825     flds    (rFP,%ecx,4)          # vAA to fp stack
   6826     sarl    $4,rINST             # rINST<- B
   6827     fdivs   (rFP,rINST,4)         # ex: faddp
   6828     FETCH_INST_OPCODE 1 %eax
   6829     ADVANCE_PC 1
   6830     fstps    (rFP,%ecx,4)         # %st to vA
   6831     GOTO_NEXT_R %eax
   6832 
   6833 
   6834 /* ------------------------------ */
   6835 .L_OP_REM_FLOAT_2ADDR: /* 0xca */
   6836 /* File: x86/OP_REM_FLOAT_2ADDR.S */
   6837     /* rem_float/2addr vA, vB */
   6838     movzx   rINSTbl,%ecx                # ecx<- A+
   6839     sarl    $4,rINST                  # rINST<- B
   6840     flds     (rFP,rINST,4)              # vBB to fp stack
   6841     andb    $0xf,%cl                   # ecx<- A
   6842     flds     (rFP,%ecx,4)               # vAA to fp stack
   6843 1:
   6844     fprem
   6845     fstsw     %ax
   6846     sahf
   6847     jp        1b
   6848     fstp      %st(1)
   6849     FETCH_INST_OPCODE 1 %eax
   6850     ADVANCE_PC 1
   6851     fstps    (rFP,%ecx,4)               # %st to vA
   6852     GOTO_NEXT_R %eax
   6853 
   6854 /* ------------------------------ */
   6855 .L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
   6856 /* File: x86/OP_ADD_DOUBLE_2ADDR.S */
   6857    /*
   6858     * File: OP_ADD_DOUBLE_2ADDR.S
   6859     */
   6860 
   6861     movzx       rINSTbl,%ecx            # ecx<- A+
   6862     andb        $0xf,%cl               # ecx<- A
   6863     sarl        $4,rINST               # rINST<- B
   6864     movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
   6865     movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vA
   6866     FETCH_INST_OPCODE 1 %eax
   6867     addsd       %xmm1, %xmm0            # %xmm0<- vA op vB
   6868     ADVANCE_PC 1
   6869     movq        %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
   6870     GOTO_NEXT_R %eax
   6871 
   6872 /* ------------------------------ */
   6873 .L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
   6874 /* File: x86/OP_SUB_DOUBLE_2ADDR.S */
   6875    /*
   6876     * File: OP_SUB_DOUBLE_2ADDR.S
   6877     */
   6878 
   6879     movzx       rINSTbl,%ecx            # ecx<- A+
   6880     andb        $0xf,%cl               # ecx<- A
   6881     sarl        $4,rINST               # rINST<- B
   6882     # TODO: movsd?
   6883     movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
   6884     movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vA
   6885     FETCH_INST_OPCODE 1 %eax
   6886     subsd       %xmm1, %xmm0            # %xmm0<- vA op vB
   6887     ADVANCE_PC 1
   6888     movq        %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
   6889     GOTO_NEXT_R %eax
   6890 
   6891 /* ------------------------------ */
   6892 .L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
   6893 /* File: x86/OP_MUL_DOUBLE_2ADDR.S */
   6894    /*
   6895     * File: OP_MUL_DOUBLE_2ADDR.S
   6896     */
   6897 
   6898     movzx       rINSTbl,%ecx            # ecx<- A+
   6899     andb        $0xf,%cl               # ecx<- A
   6900     sarl        $4,rINST               # rINST<- B
   6901     # TODO: movsd?
   6902     movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
   6903     movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vA
   6904     FETCH_INST_OPCODE 1 %eax
   6905     mulsd       %xmm1, %xmm0            # %xmm0<- vA op vB
   6906     ADVANCE_PC 1
   6907     movq        %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
   6908     GOTO_NEXT_R %eax
   6909 
   6910 /* ------------------------------ */
   6911 .L_OP_DIV_DOUBLE_2ADDR: /* 0xce */
   6912 /* File: x86/OP_DIV_DOUBLE_2ADDR.S */
   6913 /* File: x86/binflop2addr.S */
   6914     /*
   6915      * Generic 32-bit binary float operation.
   6916      *
   6917      * For: add-fp, sub-fp, mul-fp, div-fp
   6918      */
   6919 
   6920     /* binop/2addr vA, vB */
   6921     movzx   rINSTbl,%ecx           # ecx<- A+
   6922     andb    $0xf,%cl              # ecx<- A
   6923     fldl    (rFP,%ecx,4)          # vAA to fp stack
   6924     sarl    $4,rINST             # rINST<- B
   6925     fdivl   (rFP,rINST,4)         # ex: faddp
   6926     FETCH_INST_OPCODE 1 %eax
   6927     ADVANCE_PC 1
   6928     fstpl    (rFP,%ecx,4)         # %st to vA
   6929     GOTO_NEXT_R %eax
   6930 
   6931 
   6932 /* ------------------------------ */
   6933 .L_OP_REM_DOUBLE_2ADDR: /* 0xcf */
   6934 /* File: x86/OP_REM_DOUBLE_2ADDR.S */
   6935     /* rem_float/2addr vA, vB */
   6936     movzx   rINSTbl,%ecx                # ecx<- A+
   6937     sarl    $4,rINST                  # rINST<- B
   6938     fldl     (rFP,rINST,4)              # vBB to fp stack
   6939     andb    $0xf,%cl                   # ecx<- A
   6940     fldl     (rFP,%ecx,4)               # vAA to fp stack
   6941 1:
   6942     fprem
   6943     fstsw     %ax
   6944     sahf
   6945     jp        1b
   6946     fstp      %st(1)
   6947     FETCH_INST_OPCODE 1 %eax
   6948     ADVANCE_PC 1
   6949     fstpl    (rFP,%ecx,4)               # %st to vA
   6950     GOTO_NEXT_R %eax
   6951 
   6952 /* ------------------------------ */
   6953 .L_OP_ADD_INT_LIT16: /* 0xd0 */
   6954 /* File: x86/OP_ADD_INT_LIT16.S */
   6955 /* File: x86/binopLit16.S */
   6956     /*
   6957      * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
   6958      * that specifies an instruction that performs "result = eax op ecx".
   6959      * This could be an x86 instruction or a function call.  (If the result
   6960      * comes back in a register other than eax, you can override "result".)
   6961      *
   6962      * For: add-int/lit16, rsub-int,
   6963      *      and-int/lit16, or-int/lit16, xor-int/lit16
   6964      */
   6965     /* binop/lit16 vA, vB, #+CCCC */
   6966     movzbl   rINSTbl,%eax               # eax<- 000000BA
   6967     sarl     $4,%eax                   # eax<- B
   6968     GET_VREG_R %eax %eax                # eax<- vB
   6969     movswl   2(rPC),%ecx                # ecx<- ssssCCCC
   6970     andb     $0xf,rINSTbl              # rINST<- A
   6971     addl %ecx,%eax                              # for example: addl %ecx, %eax
   6972     SET_VREG %eax rINST
   6973     FETCH_INST_OPCODE 2 %ecx
   6974     ADVANCE_PC 2
   6975     GOTO_NEXT_R %ecx
   6976 
   6977 
   6978 /* ------------------------------ */
   6979 .L_OP_RSUB_INT: /* 0xd1 */
   6980 /* File: x86/OP_RSUB_INT.S */
   6981 /* File: x86/binopLit16.S */
   6982     /*
   6983      * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
   6984      * that specifies an instruction that performs "result = eax op ecx".
   6985      * This could be an x86 instruction or a function call.  (If the result
   6986      * comes back in a register other than eax, you can override "result".)
   6987      *
   6988      * For: add-int/lit16, rsub-int,
   6989      *      and-int/lit16, or-int/lit16, xor-int/lit16
   6990      */
   6991     /* binop/lit16 vA, vB, #+CCCC */
   6992     movzbl   rINSTbl,%eax               # eax<- 000000BA
   6993     sarl     $4,%eax                   # eax<- B
   6994     GET_VREG_R %eax %eax                # eax<- vB
   6995     movswl   2(rPC),%ecx                # ecx<- ssssCCCC
   6996     andb     $0xf,rINSTbl              # rINST<- A
   6997     subl %eax,%ecx                              # for example: addl %ecx, %eax
   6998     SET_VREG %ecx rINST
   6999     FETCH_INST_OPCODE 2 %ecx
   7000     ADVANCE_PC 2
   7001     GOTO_NEXT_R %ecx
   7002 
   7003 
   7004 /* ------------------------------ */
   7005 .L_OP_MUL_INT_LIT16: /* 0xd2 */
   7006 /* File: x86/OP_MUL_INT_LIT16.S */
   7007     /* mul/lit16 vA, vB, #+CCCC */
   7008     /* Need A in rINST, ssssCCCC in ecx, vB in eax */
   7009     movzbl   rINSTbl,%eax               # eax<- 000000BA
   7010     sarl     $4,%eax                   # eax<- B
   7011     GET_VREG_R %eax %eax                # eax<- vB
   7012     movswl   2(rPC),%ecx                # ecx<- ssssCCCC
   7013     andb     $0xf,rINSTbl              # rINST<- A
   7014     SPILL(rIBASE)
   7015     imull     %ecx,%eax                 # trashes rIBASE/edx
   7016     UNSPILL(rIBASE)
   7017     FETCH_INST_OPCODE 2 %ecx
   7018     ADVANCE_PC 2
   7019     SET_VREG %eax rINST
   7020     GOTO_NEXT_R %ecx
   7021 
   7022 /* ------------------------------ */
   7023 .L_OP_DIV_INT_LIT16: /* 0xd3 */
   7024 /* File: x86/OP_DIV_INT_LIT16.S */
   7025 /* File: x86/bindivLit16.S */
   7026     /*
   7027      * 32-bit binary div/rem operation.  Handles special case of op0=minint and
   7028      * op1=-1.
   7029      */
   7030     /* div/rem/lit16 vA, vB, #+CCCC */
   7031     /* Need A in rINST, ssssCCCC in ecx, vB in eax */
   7032     movzbl   rINSTbl,%eax         # eax<- 000000BA
   7033     SPILL(rIBASE)
   7034     sarl     $4,%eax             # eax<- B
   7035     GET_VREG_R %eax %eax          # eax<- vB
   7036     movswl   2(rPC),%ecx          # ecx<- ssssCCCC
   7037     andb     $0xf,rINSTbl        # rINST<- A
   7038     cmpl     $0,%ecx
   7039     je       common_errDivideByZero
   7040     cmpl     $-1,%ecx
   7041     jne      .LOP_DIV_INT_LIT16_continue_div
   7042     cmpl     $0x80000000,%eax
   7043     jne      .LOP_DIV_INT_LIT16_continue_div
   7044     movl     $0x80000000,%eax
   7045     SET_VREG %eax rINST
   7046     UNSPILL(rIBASE)
   7047     FETCH_INST_OPCODE 2 %ecx
   7048     ADVANCE_PC 2
   7049     GOTO_NEXT_R %ecx
   7050 
   7051 .LOP_DIV_INT_LIT16_continue_div:
   7052     cltd
   7053     idivl   %ecx
   7054     SET_VREG %eax rINST
   7055     UNSPILL(rIBASE)
   7056     FETCH_INST_OPCODE 2 %ecx
   7057     ADVANCE_PC 2
   7058     GOTO_NEXT_R %ecx
   7059 
   7060 
   7061 /* ------------------------------ */
   7062 .L_OP_REM_INT_LIT16: /* 0xd4 */
   7063 /* File: x86/OP_REM_INT_LIT16.S */
   7064 /* File: x86/bindivLit16.S */
   7065     /*
   7066      * 32-bit binary div/rem operation.  Handles special case of op0=minint and
   7067      * op1=-1.
   7068      */
   7069     /* div/rem/lit16 vA, vB, #+CCCC */
   7070     /* Need A in rINST, ssssCCCC in ecx, vB in eax */
   7071     movzbl   rINSTbl,%eax         # eax<- 000000BA
   7072     SPILL(rIBASE)
   7073     sarl     $4,%eax             # eax<- B
   7074     GET_VREG_R %eax %eax          # eax<- vB
   7075     movswl   2(rPC),%ecx          # ecx<- ssssCCCC
   7076     andb     $0xf,rINSTbl        # rINST<- A
   7077     cmpl     $0,%ecx
   7078     je       common_errDivideByZero
   7079     cmpl     $-1,%ecx
   7080     jne      .LOP_REM_INT_LIT16_continue_div
   7081     cmpl     $0x80000000,%eax
   7082     jne      .LOP_REM_INT_LIT16_continue_div
   7083     movl     $0,rIBASE
   7084     SET_VREG rIBASE rINST
   7085     UNSPILL(rIBASE)
   7086     FETCH_INST_OPCODE 2 %ecx
   7087     ADVANCE_PC 2
   7088     GOTO_NEXT_R %ecx
   7089 
   7090 .LOP_REM_INT_LIT16_continue_div:
   7091     cltd
   7092     idivl   %ecx
   7093     SET_VREG rIBASE rINST
   7094     UNSPILL(rIBASE)
   7095     FETCH_INST_OPCODE 2 %ecx
   7096     ADVANCE_PC 2
   7097     GOTO_NEXT_R %ecx
   7098 
   7099 
   7100 /* ------------------------------ */
   7101 .L_OP_AND_INT_LIT16: /* 0xd5 */
   7102 /* File: x86/OP_AND_INT_LIT16.S */
   7103 /* File: x86/binopLit16.S */
   7104     /*
   7105      * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
   7106      * that specifies an instruction that performs "result = eax op ecx".
   7107      * This could be an x86 instruction or a function call.  (If the result
   7108      * comes back in a register other than eax, you can override "result".)
   7109      *
   7110      * For: add-int/lit16, rsub-int,
   7111      *      and-int/lit16, or-int/lit16, xor-int/lit16
   7112      */
   7113     /* binop/lit16 vA, vB, #+CCCC */
   7114     movzbl   rINSTbl,%eax               # eax<- 000000BA
   7115     sarl     $4,%eax                   # eax<- B
   7116     GET_VREG_R %eax %eax                # eax<- vB
   7117     movswl   2(rPC),%ecx                # ecx<- ssssCCCC
   7118     andb     $0xf,rINSTbl              # rINST<- A
   7119     andl %ecx,%eax                              # for example: addl %ecx, %eax
   7120     SET_VREG %eax rINST
   7121     FETCH_INST_OPCODE 2 %ecx
   7122     ADVANCE_PC 2
   7123     GOTO_NEXT_R %ecx
   7124 
   7125 
   7126 /* ------------------------------ */
   7127 .L_OP_OR_INT_LIT16: /* 0xd6 */
   7128 /* File: x86/OP_OR_INT_LIT16.S */
   7129 /* File: x86/binopLit16.S */
   7130     /*
   7131      * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
   7132      * that specifies an instruction that performs "result = eax op ecx".
   7133      * This could be an x86 instruction or a function call.  (If the result
   7134      * comes back in a register other than eax, you can override "result".)
   7135      *
   7136      * For: add-int/lit16, rsub-int,
   7137      *      and-int/lit16, or-int/lit16, xor-int/lit16
   7138      */
   7139     /* binop/lit16 vA, vB, #+CCCC */
   7140     movzbl   rINSTbl,%eax               # eax<- 000000BA
   7141     sarl     $4,%eax                   # eax<- B
   7142     GET_VREG_R %eax %eax                # eax<- vB
   7143     movswl   2(rPC),%ecx                # ecx<- ssssCCCC
   7144     andb     $0xf,rINSTbl              # rINST<- A
   7145     orl     %ecx,%eax                              # for example: addl %ecx, %eax
   7146     SET_VREG %eax rINST
   7147     FETCH_INST_OPCODE 2 %ecx
   7148     ADVANCE_PC 2
   7149     GOTO_NEXT_R %ecx
   7150 
   7151 
   7152 /* ------------------------------ */
   7153 .L_OP_XOR_INT_LIT16: /* 0xd7 */
   7154 /* File: x86/OP_XOR_INT_LIT16.S */
   7155 /* File: x86/binopLit16.S */
   7156     /*
   7157      * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
   7158      * that specifies an instruction that performs "result = eax op ecx".
   7159      * This could be an x86 instruction or a function call.  (If the result
   7160      * comes back in a register other than eax, you can override "result".)
   7161      *
   7162      * For: add-int/lit16, rsub-int,
   7163      *      and-int/lit16, or-int/lit16, xor-int/lit16
   7164      */
   7165     /* binop/lit16 vA, vB, #+CCCC */
   7166     movzbl   rINSTbl,%eax               # eax<- 000000BA
   7167     sarl     $4,%eax                   # eax<- B
   7168     GET_VREG_R %eax %eax                # eax<- vB
   7169     movswl   2(rPC),%ecx                # ecx<- ssssCCCC
   7170     andb     $0xf,rINSTbl              # rINST<- A
   7171     xor    %ecx,%eax                              # for example: addl %ecx, %eax
   7172     SET_VREG %eax rINST
   7173     FETCH_INST_OPCODE 2 %ecx
   7174     ADVANCE_PC 2
   7175     GOTO_NEXT_R %ecx
   7176 
   7177 
   7178 /* ------------------------------ */
   7179 .L_OP_ADD_INT_LIT8: /* 0xd8 */
   7180 /* File: x86/OP_ADD_INT_LIT8.S */
   7181 /* File: x86/binopLit8.S */
   7182     /*
   7183      * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
   7184      * that specifies an instruction that performs "result = eax op ecx".
   7185      * This could be an x86 instruction or a function call.  (If the result
   7186      * comes back in a register other than r0, you can override "result".)
   7187      *
   7188      * For: add-int/lit8, rsub-int/lit8
   7189      *      and-int/lit8, or-int/lit8, xor-int/lit8,
   7190      *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
   7191      */
   7192     /* binop/lit8 vAA, vBB, #+CC */
   7193     movzbl    2(rPC),%eax              # eax<- BB
   7194     movsbl    3(rPC),%ecx              # ecx<- ssssssCC
   7195     GET_VREG_R   %eax %eax             # eax<- rBB
   7196     addl %ecx,%eax                             # ex: addl %ecx,%eax
   7197     SET_VREG   %eax rINST
   7198     FETCH_INST_OPCODE 2 %ecx
   7199     ADVANCE_PC 2
   7200     GOTO_NEXT_R %ecx
   7201 
   7202 
   7203 /* ------------------------------ */
   7204 .L_OP_RSUB_INT_LIT8: /* 0xd9 */
   7205 /* File: x86/OP_RSUB_INT_LIT8.S */
   7206 /* File: x86/binopLit8.S */
   7207     /*
   7208      * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
   7209      * that specifies an instruction that performs "result = eax op ecx".
   7210      * This could be an x86 instruction or a function call.  (If the result
   7211      * comes back in a register other than r0, you can override "result".)
   7212      *
   7213      * For: add-int/lit8, rsub-int/lit8
   7214      *      and-int/lit8, or-int/lit8, xor-int/lit8,
   7215      *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
   7216      */
   7217     /* binop/lit8 vAA, vBB, #+CC */
   7218     movzbl    2(rPC),%eax              # eax<- BB
   7219     movsbl    3(rPC),%ecx              # ecx<- ssssssCC
   7220     GET_VREG_R   %eax %eax             # eax<- rBB
   7221     subl  %eax,%ecx                             # ex: addl %ecx,%eax
   7222     SET_VREG   %ecx rINST
   7223     FETCH_INST_OPCODE 2 %ecx
   7224     ADVANCE_PC 2
   7225     GOTO_NEXT_R %ecx
   7226 
   7227 
   7228 /* ------------------------------ */
   7229 .L_OP_MUL_INT_LIT8: /* 0xda */
   7230 /* File: x86/OP_MUL_INT_LIT8.S */
   7231     /* mul/lit8 vAA, vBB, #+CC */
   7232     movzbl    2(rPC),%eax              # eax<- BB
   7233     movsbl    3(rPC),%ecx              # ecx<- ssssssCC
   7234     GET_VREG_R   %eax %eax             # eax<- rBB
   7235     SPILL(rIBASE)
   7236     imull     %ecx,%eax                # trashes rIBASE/edx
   7237     UNSPILL(rIBASE)
   7238     FETCH_INST_OPCODE 2 %ecx
   7239     ADVANCE_PC 2
   7240     SET_VREG  %eax rINST
   7241     GOTO_NEXT_R %ecx
   7242 
   7243 /* ------------------------------ */
   7244 .L_OP_DIV_INT_LIT8: /* 0xdb */
   7245 /* File: x86/OP_DIV_INT_LIT8.S */
   7246 /* File: x86/bindivLit8.S */
   7247     /*
   7248      * 32-bit div/rem "lit8" binary operation.  Handles special case of
   7249      * op0=minint & op1=-1
   7250      */
   7251     /* div/rem/lit8 vAA, vBB, #+CC */
   7252     movzbl    2(rPC),%eax        # eax<- BB
   7253     movsbl    3(rPC),%ecx        # ecx<- ssssssCC
   7254     SPILL(rIBASE)
   7255     GET_VREG_R  %eax %eax        # eax<- rBB
   7256     cmpl     $0,%ecx
   7257     je       common_errDivideByZero
   7258     cmpl     $0x80000000,%eax
   7259     jne      .LOP_DIV_INT_LIT8_continue_div
   7260     cmpl     $-1,%ecx
   7261     jne      .LOP_DIV_INT_LIT8_continue_div
   7262     movl     $0x80000000,%eax
   7263     SET_VREG %eax rINST
   7264     UNSPILL(rIBASE)
   7265     FETCH_INST_OPCODE 2 %ecx
   7266     ADVANCE_PC 2
   7267     GOTO_NEXT_R %ecx
   7268 
   7269 .LOP_DIV_INT_LIT8_continue_div:
   7270     cltd
   7271     idivl   %ecx
   7272     SET_VREG %eax rINST
   7273     UNSPILL(rIBASE)
   7274     FETCH_INST_OPCODE 2 %ecx
   7275     ADVANCE_PC 2
   7276     GOTO_NEXT_R %ecx
   7277 
   7278 
   7279 /* ------------------------------ */
   7280 .L_OP_REM_INT_LIT8: /* 0xdc */
   7281 /* File: x86/OP_REM_INT_LIT8.S */
   7282 /* File: x86/bindivLit8.S */
   7283     /*
   7284      * 32-bit div/rem "lit8" binary operation.  Handles special case of
   7285      * op0=minint & op1=-1
   7286      */
   7287     /* div/rem/lit8 vAA, vBB, #+CC */
   7288     movzbl    2(rPC),%eax        # eax<- BB
   7289     movsbl    3(rPC),%ecx        # ecx<- ssssssCC
   7290     SPILL(rIBASE)
   7291     GET_VREG_R  %eax %eax        # eax<- rBB
   7292     cmpl     $0,%ecx
   7293     je       common_errDivideByZero
   7294     cmpl     $0x80000000,%eax
   7295     jne      .LOP_REM_INT_LIT8_continue_div
   7296     cmpl     $-1,%ecx
   7297     jne      .LOP_REM_INT_LIT8_continue_div
   7298     movl     $0,rIBASE
   7299     SET_VREG rIBASE rINST
   7300     UNSPILL(rIBASE)
   7301     FETCH_INST_OPCODE 2 %ecx
   7302     ADVANCE_PC 2
   7303     GOTO_NEXT_R %ecx
   7304 
   7305 .LOP_REM_INT_LIT8_continue_div:
   7306     cltd
   7307     idivl   %ecx
   7308     SET_VREG rIBASE rINST
   7309     UNSPILL(rIBASE)
   7310     FETCH_INST_OPCODE 2 %ecx
   7311     ADVANCE_PC 2
   7312     GOTO_NEXT_R %ecx
   7313 
   7314 
   7315 /* ------------------------------ */
   7316 .L_OP_AND_INT_LIT8: /* 0xdd */
   7317 /* File: x86/OP_AND_INT_LIT8.S */
   7318 /* File: x86/binopLit8.S */
   7319     /*
   7320      * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
   7321      * that specifies an instruction that performs "result = eax op ecx".
   7322      * This could be an x86 instruction or a function call.  (If the result
   7323      * comes back in a register other than r0, you can override "result".)
   7324      *
   7325      * For: add-int/lit8, rsub-int/lit8
   7326      *      and-int/lit8, or-int/lit8, xor-int/lit8,
   7327      *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
   7328      */
   7329     /* binop/lit8 vAA, vBB, #+CC */
   7330     movzbl    2(rPC),%eax              # eax<- BB
   7331     movsbl    3(rPC),%ecx              # ecx<- ssssssCC
   7332     GET_VREG_R   %eax %eax             # eax<- rBB
   7333     andl %ecx,%eax                             # ex: addl %ecx,%eax
   7334     SET_VREG   %eax rINST
   7335     FETCH_INST_OPCODE 2 %ecx
   7336     ADVANCE_PC 2
   7337     GOTO_NEXT_R %ecx
   7338 
   7339 
   7340 /* ------------------------------ */
   7341 .L_OP_OR_INT_LIT8: /* 0xde */
   7342 /* File: x86/OP_OR_INT_LIT8.S */
   7343 /* File: x86/binopLit8.S */
   7344     /*
   7345      * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
   7346      * that specifies an instruction that performs "result = eax op ecx".
   7347      * This could be an x86 instruction or a function call.  (If the result
   7348      * comes back in a register other than r0, you can override "result".)
   7349      *
   7350      * For: add-int/lit8, rsub-int/lit8
   7351      *      and-int/lit8, or-int/lit8, xor-int/lit8,
   7352      *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
   7353      */
   7354     /* binop/lit8 vAA, vBB, #+CC */
   7355     movzbl    2(rPC),%eax              # eax<- BB
   7356     movsbl    3(rPC),%ecx              # ecx<- ssssssCC
   7357     GET_VREG_R   %eax %eax             # eax<- rBB
   7358     orl     %ecx,%eax                             # ex: addl %ecx,%eax
   7359     SET_VREG   %eax rINST
   7360     FETCH_INST_OPCODE 2 %ecx
   7361     ADVANCE_PC 2
   7362     GOTO_NEXT_R %ecx
   7363 
   7364 
   7365 /* ------------------------------ */
   7366 .L_OP_XOR_INT_LIT8: /* 0xdf */
   7367 /* File: x86/OP_XOR_INT_LIT8.S */
   7368 /* File: x86/binopLit8.S */
   7369     /*
   7370      * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
   7371      * that specifies an instruction that performs "result = eax op ecx".
   7372      * This could be an x86 instruction or a function call.  (If the result
   7373      * comes back in a register other than r0, you can override "result".)
   7374      *
   7375      * For: add-int/lit8, rsub-int/lit8
   7376      *      and-int/lit8, or-int/lit8, xor-int/lit8,
   7377      *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
   7378      */
   7379     /* binop/lit8 vAA, vBB, #+CC */
   7380     movzbl    2(rPC),%eax              # eax<- BB
   7381     movsbl    3(rPC),%ecx              # ecx<- ssssssCC
   7382     GET_VREG_R   %eax %eax             # eax<- rBB
   7383     xor    %ecx,%eax                             # ex: addl %ecx,%eax
   7384     SET_VREG   %eax rINST
   7385     FETCH_INST_OPCODE 2 %ecx
   7386     ADVANCE_PC 2
   7387     GOTO_NEXT_R %ecx
   7388 
   7389 
   7390 /* ------------------------------ */
   7391 .L_OP_SHL_INT_LIT8: /* 0xe0 */
   7392 /* File: x86/OP_SHL_INT_LIT8.S */
   7393 /* File: x86/binopLit8.S */
   7394     /*
   7395      * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
   7396      * that specifies an instruction that performs "result = eax op ecx".
   7397      * This could be an x86 instruction or a function call.  (If the result
   7398      * comes back in a register other than r0, you can override "result".)
   7399      *
   7400      * For: add-int/lit8, rsub-int/lit8
   7401      *      and-int/lit8, or-int/lit8, xor-int/lit8,
   7402      *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
   7403      */
   7404     /* binop/lit8 vAA, vBB, #+CC */
   7405     movzbl    2(rPC),%eax              # eax<- BB
   7406     movsbl    3(rPC),%ecx              # ecx<- ssssssCC
   7407     GET_VREG_R   %eax %eax             # eax<- rBB
   7408     sall  %cl,%eax                             # ex: addl %ecx,%eax
   7409     SET_VREG   %eax rINST
   7410     FETCH_INST_OPCODE 2 %ecx
   7411     ADVANCE_PC 2
   7412     GOTO_NEXT_R %ecx
   7413 
   7414 
   7415 /* ------------------------------ */
   7416 .L_OP_SHR_INT_LIT8: /* 0xe1 */
   7417 /* File: x86/OP_SHR_INT_LIT8.S */
   7418 /* File: x86/binopLit8.S */
   7419     /*
   7420      * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
   7421      * that specifies an instruction that performs "result = eax op ecx".
   7422      * This could be an x86 instruction or a function call.  (If the result
   7423      * comes back in a register other than r0, you can override "result".)
   7424      *
   7425      * For: add-int/lit8, rsub-int/lit8
   7426      *      and-int/lit8, or-int/lit8, xor-int/lit8,
   7427      *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
   7428      */
   7429     /* binop/lit8 vAA, vBB, #+CC */
   7430     movzbl    2(rPC),%eax              # eax<- BB
   7431     movsbl    3(rPC),%ecx              # ecx<- ssssssCC
   7432     GET_VREG_R   %eax %eax             # eax<- rBB
   7433     sarl    %cl,%eax                             # ex: addl %ecx,%eax
   7434     SET_VREG   %eax rINST
   7435     FETCH_INST_OPCODE 2 %ecx
   7436     ADVANCE_PC 2
   7437     GOTO_NEXT_R %ecx
   7438 
   7439 
   7440 /* ------------------------------ */
   7441 .L_OP_USHR_INT_LIT8: /* 0xe2 */
   7442 /* File: x86/OP_USHR_INT_LIT8.S */
   7443 /* File: x86/binopLit8.S */
   7444     /*
   7445      * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
   7446      * that specifies an instruction that performs "result = eax op ecx".
   7447      * This could be an x86 instruction or a function call.  (If the result
   7448      * comes back in a register other than r0, you can override "result".)
   7449      *
   7450      * For: add-int/lit8, rsub-int/lit8
   7451      *      and-int/lit8, or-int/lit8, xor-int/lit8,
   7452      *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
   7453      */
   7454     /* binop/lit8 vAA, vBB, #+CC */
   7455     movzbl    2(rPC),%eax              # eax<- BB
   7456     movsbl    3(rPC),%ecx              # ecx<- ssssssCC
   7457     GET_VREG_R   %eax %eax             # eax<- rBB
   7458     shrl     %cl,%eax                             # ex: addl %ecx,%eax
   7459     SET_VREG   %eax rINST
   7460     FETCH_INST_OPCODE 2 %ecx
   7461     ADVANCE_PC 2
   7462     GOTO_NEXT_R %ecx
   7463 
   7464 
   7465 /* ------------------------------ */
   7466 .L_OP_IGET_VOLATILE: /* 0xe3 */
   7467 /* File: x86/OP_IGET_VOLATILE.S */
   7468 /* File: x86/OP_IGET.S */
   7469     /*
   7470      * General 32-bit instance field get.
   7471      *
   7472      * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
   7473      */
   7474     /* op vA, vB, field@CCCC */
   7475     movl    rSELF,%ecx
   7476     SPILL(rIBASE)                               # preserve rIBASE
   7477     movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
   7478     movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
   7479     movzbl  rINSTbl,%ecx                        # ecx<- BA
   7480     sarl    $4,%ecx                            # ecx<- B
   7481     movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
   7482     andb    $0xf,rINSTbl                       # rINST<- A
   7483     GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
   7484     movl    (%eax,rIBASE,4),%eax                # resolved entry
   7485     testl   %eax,%eax                           # is resolved entry null?
   7486     jne     .LOP_IGET_VOLATILE_finish                  # no, already resolved
   7487     movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
   7488     movl    rSELF,rIBASE
   7489     EXPORT_PC
   7490     movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
   7491     movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
   7492     SPILL_TMP1(%ecx)                            # save obj pointer across call
   7493     movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
   7494     call    dvmResolveInstField                 #  ... to dvmResolveInstField
   7495     UNSPILL_TMP1(%ecx)
   7496     testl   %eax,%eax                           #  returns InstrField ptr
   7497     jne     .LOP_IGET_VOLATILE_finish
   7498     jmp     common_exceptionThrown
   7499 
   7500 .LOP_IGET_VOLATILE_finish:
   7501     /*
   7502      * Currently:
   7503      *   eax holds resolved field
   7504      *   ecx holds object
   7505      *   rINST holds A
   7506      */
   7507     movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
   7508     testl   %ecx,%ecx                           # object null?
   7509     je      common_errNullObject                # object was null
   7510     movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
   7511     FETCH_INST_OPCODE 2 %eax
   7512     UNSPILL(rIBASE)
   7513     SET_VREG %ecx rINST
   7514     ADVANCE_PC 2
   7515     GOTO_NEXT_R %eax
   7516 
   7517 
   7518 /* ------------------------------ */
   7519 .L_OP_IPUT_VOLATILE: /* 0xe4 */
   7520 /* File: x86/OP_IPUT_VOLATILE.S */
   7521 /* File: x86/OP_IPUT.S */
   7522 
   7523     /*
   7524      * General 32-bit instance field put.
   7525      *
   7526      * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
   7527      */
   7528     /* op vA, vB, field@CCCC */
   7529     movl    rSELF,%ecx
   7530     SPILL   (rIBASE)
   7531     movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
   7532     movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
   7533     movzbl  rINSTbl,%ecx                        # ecx<- BA
   7534     sarl    $4,%ecx                            # ecx<- B
   7535     movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
   7536     andb    $0xf,rINSTbl                       # rINST<- A
   7537     GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
   7538     movl    (%eax,rIBASE,4),%eax                # resolved entry
   7539     testl   %eax,%eax                           # is resolved entry null?
   7540     jne     .LOP_IPUT_VOLATILE_finish                  # no, already resolved
   7541     movl    rIBASE,OUT_ARG1(%esp)
   7542     movl    rSELF,rIBASE
   7543     EXPORT_PC
   7544     movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
   7545     movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
   7546     SPILL_TMP1(%ecx)                            # save obj pointer across call
   7547     movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
   7548     call    dvmResolveInstField                 #  ... to dvmResolveInstField
   7549     UNSPILL_TMP1(%ecx)
   7550     testl   %eax,%eax                           # returns InstrField ptr
   7551     jne     .LOP_IPUT_VOLATILE_finish
   7552     jmp     common_exceptionThrown
   7553 
   7554 .LOP_IPUT_VOLATILE_finish:
   7555     /*
   7556      * Currently:
   7557      *   eax holds resolved field
   7558      *   ecx holds object
   7559      *   rINST holds A
   7560      */
   7561     GET_VREG_R rINST rINST                       # rINST<- v[A]
   7562     movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
   7563     testl   %ecx,%ecx                            # object null?
   7564     je      common_errNullObject                 # object was null
   7565     movl   rINST,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
   7566     FETCH_INST_OPCODE 2 %ecx
   7567     UNSPILL(rIBASE)
   7568     ADVANCE_PC 2
   7569     GOTO_NEXT_R %ecx
   7570 
   7571 
   7572 /* ------------------------------ */
   7573 .L_OP_SGET_VOLATILE: /* 0xe5 */
   7574 /* File: x86/OP_SGET_VOLATILE.S */
   7575 /* File: x86/OP_SGET.S */
   7576     /*
   7577      * General 32-bit SGET handler.
   7578      *
   7579      * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
   7580      */
   7581     /* op vAA, field@BBBB */
   7582     movl      rSELF,%ecx
   7583     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
   7584     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
   7585     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
   7586 #if defined(WITH_JIT)
   7587     movl      %ecx, TMP_SPILL1(%ebp)
   7588     lea       (%ecx,%eax,4),%ecx
   7589     movl      %ecx, TMP_SPILL2(%ebp)
   7590     movl      TMP_SPILL1(%ebp), %ecx
   7591 #endif
   7592     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
   7593     testl     %eax,%eax                          # resolved entry null?
   7594     je        .LOP_SGET_VOLATILE_resolve                # if not, make it so
   7595 .LOP_SGET_VOLATILE_finish:     # field ptr in eax
   7596     movl      offStaticField_value(%eax),%eax
   7597     FETCH_INST_OPCODE 2 %ecx
   7598     ADVANCE_PC 2
   7599     SET_VREG %eax rINST
   7600     GOTO_NEXT_R %ecx
   7601 
   7602     /*
   7603      * Go resolve the field
   7604      */
   7605 .LOP_SGET_VOLATILE_resolve:
   7606     movl     rSELF,%ecx
   7607     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
   7608     movl     offThread_method(%ecx),%ecx          # ecx<- current method
   7609     EXPORT_PC                                   # could throw, need to export
   7610     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
   7611     movl     %eax,OUT_ARG1(%esp)
   7612     movl     %ecx,OUT_ARG0(%esp)
   7613     SPILL(rIBASE)
   7614     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
   7615     UNSPILL(rIBASE)
   7616     testl    %eax,%eax
   7617     je      common_exceptionThrown             # no, handle exception
   7618 #if defined(WITH_JIT)
   7619     movl      TMP_SPILL2(%ebp), %ecx
   7620     SPILL(rIBASE)
   7621     call     common_verifyField
   7622     UNSPILL(rIBASE)
   7623 #endif
   7624     jmp      .LOP_SGET_VOLATILE_finish                 # success, continue
   7625 
   7626 
   7627 /* ------------------------------ */
   7628 .L_OP_SPUT_VOLATILE: /* 0xe6 */
   7629 /* File: x86/OP_SPUT_VOLATILE.S */
   7630 /* File: x86/OP_SPUT.S */
   7631     /*
   7632      * General 32-bit SPUT handler.
   7633      *
   7634      * for: sput, sput-boolean, sput-byte, sput-char, sput-short
   7635      */
   7636     /* op vAA, field@BBBB */
   7637     movl      rSELF,%ecx
   7638     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
   7639     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
   7640     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
   7641 #if defined(WITH_JIT)
   7642     movl      %ecx, TMP_SPILL1(%ebp)
   7643     lea       (%ecx,%eax,4),%ecx
   7644     movl      %ecx, TMP_SPILL2(%ebp)
   7645     movl      TMP_SPILL1(%ebp), %ecx
   7646 #endif
   7647     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
   7648     testl     %eax,%eax                          # resolved entry null?
   7649     je        .LOP_SPUT_VOLATILE_resolve                # if not, make it so
   7650 .LOP_SPUT_VOLATILE_finish:     # field ptr in eax
   7651     GET_VREG_R  rINST rINST
   7652     FETCH_INST_OPCODE 2 %ecx
   7653     ADVANCE_PC 2
   7654     movl      rINST,offStaticField_value(%eax)
   7655     GOTO_NEXT_R %ecx
   7656 
   7657     /*
   7658      * Go resolve the field
   7659      */
   7660 .LOP_SPUT_VOLATILE_resolve:
   7661     movl     rSELF,%ecx
   7662     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
   7663     movl     offThread_method(%ecx),%ecx        # ecx<- current method
   7664     EXPORT_PC                                   # could throw, need to export
   7665     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
   7666     movl     %eax,OUT_ARG1(%esp)
   7667     movl     %ecx,OUT_ARG0(%esp)
   7668     SPILL(rIBASE)
   7669     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
   7670     UNSPILL(rIBASE)
   7671     testl    %eax,%eax
   7672     je      common_exceptionThrown             # no, handle exception
   7673 #if defined(WITH_JIT)
   7674     movl      TMP_SPILL2(%ebp), %ecx
   7675     SPILL(rIBASE)
   7676     call     common_verifyField
   7677     UNSPILL(rIBASE)
   7678 #endif
   7679     jmp      .LOP_SPUT_VOLATILE_finish                 # success, continue
   7680 
   7681 /* ------------------------------ */
   7682 .L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
   7683 /* File: x86/OP_IGET_OBJECT_VOLATILE.S */
   7684 /* File: x86/OP_IGET.S */
   7685     /*
   7686      * General 32-bit instance field get.
   7687      *
   7688      * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
   7689      */
   7690     /* op vA, vB, field@CCCC */
   7691     movl    rSELF,%ecx
   7692     SPILL(rIBASE)                               # preserve rIBASE
   7693     movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
   7694     movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
   7695     movzbl  rINSTbl,%ecx                        # ecx<- BA
   7696     sarl    $4,%ecx                            # ecx<- B
   7697     movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
   7698     andb    $0xf,rINSTbl                       # rINST<- A
   7699     GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
   7700     movl    (%eax,rIBASE,4),%eax                # resolved entry
   7701     testl   %eax,%eax                           # is resolved entry null?
   7702     jne     .LOP_IGET_OBJECT_VOLATILE_finish                  # no, already resolved
   7703     movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
   7704     movl    rSELF,rIBASE
   7705     EXPORT_PC
   7706     movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
   7707     movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
   7708     SPILL_TMP1(%ecx)                            # save obj pointer across call
   7709     movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
   7710     call    dvmResolveInstField                 #  ... to dvmResolveInstField
   7711     UNSPILL_TMP1(%ecx)
   7712     testl   %eax,%eax                           #  returns InstrField ptr
   7713     jne     .LOP_IGET_OBJECT_VOLATILE_finish
   7714     jmp     common_exceptionThrown
   7715 
   7716 .LOP_IGET_OBJECT_VOLATILE_finish:
   7717     /*
   7718      * Currently:
   7719      *   eax holds resolved field
   7720      *   ecx holds object
   7721      *   rINST holds A
   7722      */
   7723     movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
   7724     testl   %ecx,%ecx                           # object null?
   7725     je      common_errNullObject                # object was null
   7726     movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
   7727     FETCH_INST_OPCODE 2 %eax
   7728     UNSPILL(rIBASE)
   7729     SET_VREG %ecx rINST
   7730     ADVANCE_PC 2
   7731     GOTO_NEXT_R %eax
   7732 
   7733 
   7734 /* ------------------------------ */
   7735 .L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
   7736     /* (stub) */
   7737     SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
   7738     movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
   7739     call      dvmMterp_OP_IGET_WIDE_VOLATILE     # do the real work
   7740     movl      rSELF,%ecx
   7741     LOAD_PC_FP_FROM_SELF             # retrieve updated values
   7742     movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
   7743     FETCH_INST
   7744     GOTO_NEXT
   7745 /* ------------------------------ */
   7746 .L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
   7747     /* (stub) */
   7748     SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
   7749     movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
   7750     call      dvmMterp_OP_IPUT_WIDE_VOLATILE     # do the real work
   7751     movl      rSELF,%ecx
   7752     LOAD_PC_FP_FROM_SELF             # retrieve updated values
   7753     movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
   7754     FETCH_INST
   7755     GOTO_NEXT
   7756 /* ------------------------------ */
   7757 .L_OP_SGET_WIDE_VOLATILE: /* 0xea */
   7758     /* (stub) */
   7759     SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
   7760     movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
   7761     call      dvmMterp_OP_SGET_WIDE_VOLATILE     # do the real work
   7762     movl      rSELF,%ecx
   7763     LOAD_PC_FP_FROM_SELF             # retrieve updated values
   7764     movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
   7765     FETCH_INST
   7766     GOTO_NEXT
   7767 /* ------------------------------ */
   7768 .L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
   7769     /* (stub) */
   7770     SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
   7771     movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
   7772     call      dvmMterp_OP_SPUT_WIDE_VOLATILE     # do the real work
   7773     movl      rSELF,%ecx
   7774     LOAD_PC_FP_FROM_SELF             # retrieve updated values
   7775     movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
   7776     FETCH_INST
   7777     GOTO_NEXT
   7778 /* ------------------------------ */
   7779 .L_OP_BREAKPOINT: /* 0xec */
   7780 /* File: x86/OP_BREAKPOINT.S */
   7781     /*
   7782      * Breakpoint handler.
   7783      *
   7784      * Restart this instruction with the original opcode.  By
   7785      * the time we get here, the breakpoint will have already been
   7786      * handled.  We also assume that all other special "checkBefore"
   7787      * actions have been handled, so we'll transition directly
   7788      * to the real handler
   7789      */
   7790     SPILL(rIBASE)
   7791     movl    rPC,OUT_ARG0(%esp)
   7792     call    dvmGetOriginalOpcode
   7793     UNSPILL(rIBASE)
   7794     movl    rSELF,%ecx
   7795     movzbl  1(rPC),rINST
   7796     movl    offThread_mainHandlerTable(%ecx),%ecx
   7797     jmp     *(%ecx,%eax,4)
   7798 
   7799 
   7800 /* ------------------------------ */
   7801 .L_OP_THROW_VERIFICATION_ERROR: /* 0xed */
   7802 /* File: x86/OP_THROW_VERIFICATION_ERROR.S */
   7803     /*
   7804      * Handle a throw-verification-error instruction.  This throws an
   7805      * exception for an error discovered during verification.  The
   7806      * exception is indicated by AA, with some detail provided by BBBB.
   7807      */
   7808     /* op AA, ref@BBBB */
   7809     movl     rSELF,%ecx
   7810     movzwl   2(rPC),%eax                     # eax<- BBBB
   7811     movl     offThread_method(%ecx),%ecx       # ecx<- self->method
   7812     EXPORT_PC
   7813     movl     %eax,OUT_ARG2(%esp)             # arg2<- BBBB
   7814     movl     rINST,OUT_ARG1(%esp)            # arg1<- AA
   7815     movl     %ecx,OUT_ARG0(%esp)             # arg0<- method
   7816     call     dvmThrowVerificationError       # call(method, kind, ref)
   7817     jmp      common_exceptionThrown          # handle exception
   7818 
   7819 /* ------------------------------ */
   7820 .L_OP_EXECUTE_INLINE: /* 0xee */
   7821 /* File: x86/OP_EXECUTE_INLINE.S */
   7822     /*
   7823      * Execute a "native inline" instruction.
   7824      *
   7825      * We will be calling through a function table:
   7826      *
   7827      * (*gDvmInlineOpsTable[opIndex].func)(arg0, arg1, arg2, arg3, pResult)
   7828      *
   7829      * Ignores argument count - always loads 4.
   7830      *
   7831      */
   7832     /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */
   7833     movl      rSELF,%ecx
   7834     EXPORT_PC
   7835     movzwl    2(rPC),%eax               # eax<- BBBB
   7836     SPILL(rIBASE)                       # preserve rIBASE
   7837     movl      offThread_subMode(%ecx), %edx # edx<- submode flags
   7838     andl      $kSubModeDebugProfile, %edx # debug or profile mode active?
   7839     jnz       .LOP_EXECUTE_INLINE_debugprofile   # yes, take slow path
   7840 .LOP_EXECUTE_INLINE_resume:
   7841     leal      offThread_retval(%ecx),%ecx # ecx<- &self->retval
   7842     movl      %ecx,OUT_ARG4(%esp)
   7843     call      .LOP_EXECUTE_INLINE_continue      # make call; will return after
   7844     UNSPILL(rIBASE)                     # restore rIBASE
   7845     testl     %eax,%eax                 # successful?
   7846     jz        common_exceptionThrown    # no, handle exception
   7847     FETCH_INST_OPCODE 3 %ecx
   7848     ADVANCE_PC 3
   7849     GOTO_NEXT_R %ecx
   7850 
   7851 .LOP_EXECUTE_INLINE_continue:
   7852     /*
   7853      * Extract args, call function.
   7854      *  ecx = #of args (0-4)
   7855      *  eax = call index
   7856      *  @esp = return addr
   7857      *  esp is -4 from normal
   7858      *
   7859      *  Go ahead and load all 4 args, even if not used.
   7860      */
   7861     movzwl    4(rPC),rIBASE
   7862 
   7863     movl      $0xf,%ecx
   7864     andl      rIBASE,%ecx
   7865     GET_VREG_R  %ecx %ecx
   7866     sarl      $4,rIBASE
   7867     movl      %ecx,4+OUT_ARG0(%esp)
   7868 
   7869     movl      $0xf,%ecx
   7870     andl      rIBASE,%ecx
   7871     GET_VREG_R  %ecx %ecx
   7872     sarl      $4,rIBASE
   7873     movl      %ecx,4+OUT_ARG1(%esp)
   7874 
   7875     movl      $0xf,%ecx
   7876     andl      rIBASE,%ecx
   7877     GET_VREG_R  %ecx %ecx
   7878     sarl      $4,rIBASE
   7879     movl      %ecx,4+OUT_ARG2(%esp)
   7880 
   7881     movl      $0xf,%ecx
   7882     andl      rIBASE,%ecx
   7883     GET_VREG_R  %ecx %ecx
   7884     sarl      $4,rIBASE
   7885     movl      %ecx,4+OUT_ARG3(%esp)
   7886 
   7887     sall      $4,%eax      # index *= sizeof(table entry)
   7888     jmp       *gDvmInlineOpsTable(%eax)
   7889     # will return to caller of .LOP_EXECUTE_INLINE_continue
   7890 
   7891     /*
   7892      * We're debugging or profiling.
   7893      * eax: opIndex
   7894      */
   7895 .LOP_EXECUTE_INLINE_debugprofile:
   7896     movl      %eax,OUT_ARG0(%esp)       # arg0<- BBBB
   7897     SPILL_TMP1(%eax)                    # save opIndex
   7898     call      dvmResolveInlineNative    # dvmResolveInlineNative(opIndex)
   7899     movl      rSELF,%ecx                # restore self
   7900     testl     %eax,%eax                 # method resolved?
   7901     movl      %eax,%edx                 # save possibly resolved method in edx
   7902     UNSPILL_TMP1(%eax)                  # in case not resolved, restore opIndex
   7903     jz        .LOP_EXECUTE_INLINE_resume        # not resolved, just move on
   7904     SPILL_TMP2(%edx)                    # save method
   7905     movl      %edx,OUT_ARG0(%esp)       # arg0<- method
   7906     movl      %ecx,OUT_ARG1(%esp)       # arg1<- self
   7907     call      dvmFastMethodTraceEnter   # dvmFastMethodTraceEnter(method,self)
   7908     movl      rSELF,%ecx                # restore self
   7909     UNSPILL_TMP1(%eax)                  # restore opIndex
   7910     leal      offThread_retval(%ecx),%ecx # ecx<- &self->retval
   7911     movl      %ecx,OUT_ARG4(%esp)       # needed for pResult of inline operation handler
   7912     call      .LOP_EXECUTE_INLINE_continue      # make call; will return after
   7913     SPILL_TMP1(%eax)                    # save result of inline
   7914     UNSPILL_TMP2(%eax)                  # restore method
   7915     movl      rSELF,%ecx                # restore self
   7916     movl      %eax,OUT_ARG0(%esp)       # arg0<- method
   7917     movl      %ecx,OUT_ARG1(%esp)       # arg1<- self
   7918     call      dvmFastNativeMethodTraceExit # dvmFastNativeMethodTraceExit(method,self)
   7919     UNSPILL(rIBASE)                     # restore rIBASE
   7920     UNSPILL_TMP1(%eax)                  # restore result of inline
   7921     testl     %eax,%eax                 # successful?
   7922     jz        common_exceptionThrown    # no, handle exception
   7923     FETCH_INST_OPCODE 3 %ecx
   7924     ADVANCE_PC 3
   7925     GOTO_NEXT_R %ecx
   7926 
   7927 /* ------------------------------ */
   7928 .L_OP_EXECUTE_INLINE_RANGE: /* 0xef */
   7929     /* (stub) */
   7930     SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
   7931     movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
   7932     call      dvmMterp_OP_EXECUTE_INLINE_RANGE     # do the real work
   7933     movl      rSELF,%ecx
   7934     LOAD_PC_FP_FROM_SELF             # retrieve updated values
   7935     movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
   7936     FETCH_INST
   7937     GOTO_NEXT
   7938 /* ------------------------------ */
   7939 .L_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */
   7940     /* (stub) */
   7941     SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
   7942     movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
   7943     call      dvmMterp_OP_INVOKE_OBJECT_INIT_RANGE     # do the real work
   7944     movl      rSELF,%ecx
   7945     LOAD_PC_FP_FROM_SELF             # retrieve updated values
   7946     movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
   7947     FETCH_INST
   7948     GOTO_NEXT
   7949 /* ------------------------------ */
   7950 .L_OP_RETURN_VOID_BARRIER: /* 0xf1 */
   7951     /* (stub) */
   7952     SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
   7953     movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
   7954     call      dvmMterp_OP_RETURN_VOID_BARRIER     # do the real work
   7955     movl      rSELF,%ecx
   7956     LOAD_PC_FP_FROM_SELF             # retrieve updated values
   7957     movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
   7958     FETCH_INST
   7959     GOTO_NEXT
   7960 /* ------------------------------ */
   7961 .L_OP_IGET_QUICK: /* 0xf2 */
   7962 /* File: x86/OP_IGET_QUICK.S */
   7963     /* For: iget-quick, iget-object-quick */
   7964     /* op vA, vB, offset@CCCC */
   7965     movzbl    rINSTbl,%ecx              # ecx<- BA
   7966     sarl      $4,%ecx                  # ecx<- B
   7967     GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
   7968     movzwl    2(rPC),%eax               # eax<- field byte offset
   7969     cmpl      $0,%ecx                  # is object null?
   7970     je        common_errNullObject
   7971     movl      (%ecx,%eax,1),%eax
   7972     FETCH_INST_OPCODE 2 %ecx
   7973     ADVANCE_PC 2
   7974     andb      $0xf,rINSTbl             # rINST<- A
   7975     SET_VREG  %eax rINST                # fp[A]<- result
   7976     GOTO_NEXT_R %ecx
   7977 
   7978 /* ------------------------------ */
   7979 .L_OP_IGET_WIDE_QUICK: /* 0xf3 */
   7980 /* File: x86/OP_IGET_WIDE_QUICK.S */
   7981     /* For: iget-wide-quick */
   7982     /* op vA, vB, offset@CCCC */
   7983     movzbl    rINSTbl,%ecx              # ecx<- BA
   7984     sarl      $4,%ecx                  # ecx<- B
   7985     GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
   7986     movzwl    2(rPC),%eax               # eax<- field byte offset
   7987     cmpl      $0,%ecx                  # is object null?
   7988     je        common_errNullObject
   7989     leal      (%ecx,%eax,1),%eax        # eax<- address of 64-bit source
   7990     movl      (%eax),%ecx               # ecx<- lsw
   7991     movl      4(%eax),%eax              # eax<- msw
   7992     andb      $0xf,rINSTbl             # rINST<- A
   7993     SET_VREG_WORD %ecx rINST 0          # v[A+0]<- lsw
   7994     FETCH_INST_OPCODE 2 %ecx
   7995     SET_VREG_WORD %eax rINST 1          # v[A+1]<- msw
   7996     ADVANCE_PC 2
   7997     GOTO_NEXT_R %ecx
   7998 
   7999 /* ------------------------------ */
   8000 .L_OP_IGET_OBJECT_QUICK: /* 0xf4 */
   8001 /* File: x86/OP_IGET_OBJECT_QUICK.S */
   8002 /* File: x86/OP_IGET_QUICK.S */
   8003     /* For: iget-quick, iget-object-quick */
   8004     /* op vA, vB, offset@CCCC */
   8005     movzbl    rINSTbl,%ecx              # ecx<- BA
   8006     sarl      $4,%ecx                  # ecx<- B
   8007     GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
   8008     movzwl    2(rPC),%eax               # eax<- field byte offset
   8009     cmpl      $0,%ecx                  # is object null?
   8010     je        common_errNullObject
   8011     movl      (%ecx,%eax,1),%eax
   8012     FETCH_INST_OPCODE 2 %ecx
   8013     ADVANCE_PC 2
   8014     andb      $0xf,rINSTbl             # rINST<- A
   8015     SET_VREG  %eax rINST                # fp[A]<- result
   8016     GOTO_NEXT_R %ecx
   8017 
   8018 
   8019 /* ------------------------------ */
   8020 .L_OP_IPUT_QUICK: /* 0xf5 */
   8021 /* File: x86/OP_IPUT_QUICK.S */
   8022     /* For: iput-quick */
   8023     /* op vA, vB, offset@CCCC */
   8024     movzbl    rINSTbl,%ecx              # ecx<- BA
   8025     sarl      $4,%ecx                  # ecx<- B
   8026     GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
   8027     andb      $0xf,rINSTbl             # rINST<- A
   8028     GET_VREG_R  rINST,rINST             # rINST<- v[A]
   8029     movzwl    2(rPC),%eax               # eax<- field byte offset
   8030     testl     %ecx,%ecx                 # is object null?
   8031     je        common_errNullObject
   8032     movl      rINST,(%ecx,%eax,1)
   8033     FETCH_INST_OPCODE 2 %ecx
   8034     ADVANCE_PC 2
   8035     GOTO_NEXT_R %ecx
   8036 
   8037 /* ------------------------------ */
   8038 .L_OP_IPUT_WIDE_QUICK: /* 0xf6 */
   8039 /* File: x86/OP_IPUT_WIDE_QUICK.S */
   8040     /* For: iput-wide-quick */
   8041     /* op vA, vB, offset@CCCC */
   8042     movzbl    rINSTbl,%ecx              # ecx<- BA
   8043     sarl      $4,%ecx                  # ecx<- B
   8044     GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
   8045     movzwl    2(rPC),%eax               # eax<- field byte offset
   8046     testl      %ecx,%ecx                # is object null?
   8047     je        common_errNullObject
   8048     leal      (%ecx,%eax,1),%ecx        # ecx<- Address of 64-bit target
   8049     andb      $0xf,rINSTbl             # rINST<- A
   8050     GET_VREG_WORD %eax rINST 0          # eax<- lsw
   8051     GET_VREG_WORD rINST rINST 1         # rINST<- msw
   8052     movl      %eax,(%ecx)
   8053     movl      rINST,4(%ecx)
   8054     FETCH_INST_OPCODE 2 %ecx
   8055     ADVANCE_PC 2
   8056     GOTO_NEXT_R %ecx
   8057 
   8058 /* ------------------------------ */
   8059 .L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
   8060 /* File: x86/OP_IPUT_OBJECT_QUICK.S */
   8061     /* For: iput-object-quick */
   8062     /* op vA, vB, offset@CCCC */
   8063     movzbl    rINSTbl,%ecx              # ecx<- BA
   8064     sarl      $4,%ecx                  # ecx<- B
   8065     GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
   8066     andb      $0xf,rINSTbl             # rINST<- A
   8067     GET_VREG_R  rINST rINST             # rINST<- v[A]
   8068     movzwl    2(rPC),%eax               # eax<- field byte offset
   8069     testl     %ecx,%ecx                 # is object null?
   8070     je        common_errNullObject
   8071     movl      rINST,(%ecx,%eax,1)
   8072     movl      rSELF,%eax
   8073     testl     rINST,rINST               # did we store null?
   8074     movl      offThread_cardTable(%eax),%eax  # get card table base
   8075     je        1f                            # skip card mark if null store
   8076     shrl      $GC_CARD_SHIFT,%ecx          # object head to card number
   8077     movb      %al,(%eax,%ecx)               # mark card based on object head
   8078 1:
   8079     FETCH_INST_OPCODE 2 %ecx
   8080     ADVANCE_PC 2
   8081     GOTO_NEXT_R %ecx
   8082 
   8083 /* ------------------------------ */
   8084 .L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
   8085 /* File: x86/OP_INVOKE_VIRTUAL_QUICK.S */
   8086     /*
   8087      * Handle an optimized virtual method call.
   8088      *
   8089      * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
   8090      */
   8091     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
   8092     /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
   8093     movzwl    4(rPC),%ecx               # eax<- FEDC or CCCC
   8094     movzwl    2(rPC),%edx               # ecx<- BBBB
   8095     .if     (!0)
   8096     andl      $0xf,%ecx                # eax<- C (or stays CCCC)
   8097     .endif
   8098     GET_VREG_R  %ecx %ecx               # ecx<- vC ("this" ptr)
   8099     testl     %ecx,%ecx                 # null?
   8100     je        common_errNullObject      # yep, throw exception
   8101     movl      offObject_clazz(%ecx),%eax # eax<- thisPtr->clazz
   8102     movl      offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable
   8103     EXPORT_PC                           # might throw later - get ready
   8104     movl      (%eax,%edx,4),%eax        # eax<- vtable[BBBB]
   8105     jmp       common_invokeMethodNoRange
   8106 
   8107 /* ------------------------------ */
   8108 .L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
   8109 /* File: x86/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */
   8110 /* File: x86/OP_INVOKE_VIRTUAL_QUICK.S */
   8111     /*
   8112      * Handle an optimized virtual method call.
   8113      *
   8114      * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
   8115      */
   8116     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
   8117     /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
   8118     movzwl    4(rPC),%ecx               # eax<- FEDC or CCCC
   8119     movzwl    2(rPC),%edx               # ecx<- BBBB
   8120     .if     (!1)
   8121     andl      $0xf,%ecx                # eax<- C (or stays CCCC)
   8122     .endif
   8123     GET_VREG_R  %ecx %ecx               # ecx<- vC ("this" ptr)
   8124     testl     %ecx,%ecx                 # null?
   8125     je        common_errNullObject      # yep, throw exception
   8126     movl      offObject_clazz(%ecx),%eax # eax<- thisPtr->clazz
   8127     movl      offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable
   8128     EXPORT_PC                           # might throw later - get ready
   8129     movl      (%eax,%edx,4),%eax        # eax<- vtable[BBBB]
   8130     jmp       common_invokeMethodRange
   8131 
   8132 
   8133 /* ------------------------------ */
   8134 .L_OP_INVOKE_SUPER_QUICK: /* 0xfa */
   8135 /* File: x86/OP_INVOKE_SUPER_QUICK.S */
   8136     /*
   8137      * Handle an optimized "super" method call.
   8138      *
   8139      * for: [opt] invoke-super-quick, invoke-super-quick/range
   8140      */
   8141     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
   8142     /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
   8143     movl      rSELF,%ecx
   8144     movzwl    4(rPC),%eax               # eax<- GFED or CCCC
   8145     movl      offThread_method(%ecx),%ecx # ecx<- current method
   8146     .if       (!0)
   8147     andl      $0xf,%eax                # eax<- D (or stays CCCC)
   8148     .endif
   8149     movl      offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
   8150     GET_VREG_R  %eax %eax               # eax<- "this"
   8151     movl      offClassObject_super(%ecx),%ecx # ecx<- method->clazz->super
   8152     testl     %eax,%eax                 # null "this"?
   8153     je        common_errNullObject      # "this" is null, throw exception
   8154     movl       %eax, TMP_SPILL1(%ebp)
   8155     movzwl    2(rPC),%eax               # eax<- BBBB
   8156     movl      offClassObject_vtable(%ecx),%ecx # ecx<- vtable
   8157     EXPORT_PC
   8158     movl      (%ecx,%eax,4),%eax        # eax<- super->vtable[BBBB]
   8159     movl      TMP_SPILL1(%ebp), %ecx
   8160     jmp       common_invokeMethodNoRange
   8161 
   8162 /* ------------------------------ */
   8163 .L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
   8164 /* File: x86/OP_INVOKE_SUPER_QUICK_RANGE.S */
   8165 /* File: x86/OP_INVOKE_SUPER_QUICK.S */
   8166     /*
   8167      * Handle an optimized "super" method call.
   8168      *
   8169      * for: [opt] invoke-super-quick, invoke-super-quick/range
   8170      */
   8171     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
   8172     /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
   8173     movl      rSELF,%ecx
   8174     movzwl    4(rPC),%eax               # eax<- GFED or CCCC
   8175     movl      offThread_method(%ecx),%ecx # ecx<- current method
   8176     .if       (!1)
   8177     andl      $0xf,%eax                # eax<- D (or stays CCCC)
   8178     .endif
   8179     movl      offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
   8180     GET_VREG_R  %eax %eax               # eax<- "this"
   8181     movl      offClassObject_super(%ecx),%ecx # ecx<- method->clazz->super
   8182     testl     %eax,%eax                 # null "this"?
   8183     je        common_errNullObject      # "this" is null, throw exception
   8184     movl       %eax, TMP_SPILL1(%ebp)
   8185     movzwl    2(rPC),%eax               # eax<- BBBB
   8186     movl      offClassObject_vtable(%ecx),%ecx # ecx<- vtable
   8187     EXPORT_PC
   8188     movl      (%ecx,%eax,4),%eax        # eax<- super->vtable[BBBB]
   8189     movl      TMP_SPILL1(%ebp), %ecx
   8190     jmp       common_invokeMethodRange
   8191 
   8192 
   8193 /* ------------------------------ */
   8194 .L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
   8195 /* File: x86/OP_IPUT_OBJECT_VOLATILE.S */
   8196 /* File: x86/OP_IPUT_OBJECT.S */
   8197     /*
   8198      * Object field put.
   8199      *
   8200      * for: iput-object
   8201      */
   8202     /* op vA, vB, field@CCCC */
   8203     movl    rSELF,%ecx
   8204     SPILL(rIBASE)
   8205     movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
   8206     movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
   8207     movzbl  rINSTbl,%ecx                        # ecx<- BA
   8208     sarl    $4,%ecx                            # ecx<- B
   8209     movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
   8210     andb    $0xf,rINSTbl                       # rINST<- A
   8211     GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
   8212     movl    (%eax,rIBASE,4),%eax                  # resolved entry
   8213     testl   %eax,%eax                           # is resolved entry null?
   8214     jne     .LOP_IPUT_OBJECT_VOLATILE_finish                  # no, already resolved
   8215     movl    rIBASE,OUT_ARG1(%esp)
   8216     movl    rSELF,rIBASE
   8217     EXPORT_PC
   8218     movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
   8219     movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
   8220     SPILL_TMP1(%ecx)                            # save obj pointer across call
   8221     movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
   8222     call    dvmResolveInstField                 #  ... to dvmResolveInstField
   8223     UNSPILL_TMP1(%ecx)
   8224     testl   %eax,%eax                           # returns InstrField ptr
   8225     jne     .LOP_IPUT_OBJECT_VOLATILE_finish
   8226     jmp     common_exceptionThrown
   8227 
   8228 .LOP_IPUT_OBJECT_VOLATILE_finish:
   8229     /*
   8230      * Currently:
   8231      *   eax holds resolved field
   8232      *   ecx holds object
   8233      *   rIBASE is scratch, but needs to be unspilled
   8234      *   rINST holds A
   8235      */
   8236     GET_VREG_R rINST rINST                      # rINST<- v[A]
   8237     movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
   8238     testl   %ecx,%ecx                           # object null?
   8239     je      common_errNullObject                # object was null
   8240     movl    rINST,(%ecx,%eax)      # obj.field <- v[A](8/16/32 bits)
   8241     movl    rSELF,%eax
   8242     testl   rINST,rINST                         # stored a NULL?
   8243     movl    offThread_cardTable(%eax),%eax      # get card table base
   8244     je      1f                                  # skip card mark if null store
   8245     shrl    $GC_CARD_SHIFT,%ecx                # object head to card number
   8246     movb    %al,(%eax,%ecx)                     # mark card using object head
   8247 1:
   8248     UNSPILL(rIBASE)
   8249     FETCH_INST_OPCODE 2 %ecx
   8250     ADVANCE_PC 2
   8251     GOTO_NEXT_R %ecx
   8252 
   8253 
   8254 /* ------------------------------ */
   8255 .L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
   8256 /* File: x86/OP_SGET_OBJECT_VOLATILE.S */
   8257 /* File: x86/OP_SGET.S */
   8258     /*
   8259      * General 32-bit SGET handler.
   8260      *
   8261      * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
   8262      */
   8263     /* op vAA, field@BBBB */
   8264     movl      rSELF,%ecx
   8265     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
   8266     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
   8267     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
   8268 #if defined(WITH_JIT)
   8269     movl      %ecx, TMP_SPILL1(%ebp)
   8270     lea       (%ecx,%eax,4),%ecx
   8271     movl      %ecx, TMP_SPILL2(%ebp)
   8272     movl      TMP_SPILL1(%ebp), %ecx
   8273 #endif
   8274     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
   8275     testl     %eax,%eax                          # resolved entry null?
   8276     je        .LOP_SGET_OBJECT_VOLATILE_resolve                # if not, make it so
   8277 .LOP_SGET_OBJECT_VOLATILE_finish:     # field ptr in eax
   8278     movl      offStaticField_value(%eax),%eax
   8279     FETCH_INST_OPCODE 2 %ecx
   8280     ADVANCE_PC 2
   8281     SET_VREG %eax rINST
   8282     GOTO_NEXT_R %ecx
   8283 
   8284     /*
   8285      * Go resolve the field
   8286      */
   8287 .LOP_SGET_OBJECT_VOLATILE_resolve:
   8288     movl     rSELF,%ecx
   8289     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
   8290     movl     offThread_method(%ecx),%ecx          # ecx<- current method
   8291     EXPORT_PC                                   # could throw, need to export
   8292     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
   8293     movl     %eax,OUT_ARG1(%esp)
   8294     movl     %ecx,OUT_ARG0(%esp)
   8295     SPILL(rIBASE)
   8296     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
   8297     UNSPILL(rIBASE)
   8298     testl    %eax,%eax
   8299     je      common_exceptionThrown             # no, handle exception
   8300 #if defined(WITH_JIT)
   8301     movl      TMP_SPILL2(%ebp), %ecx
   8302     SPILL(rIBASE)
   8303     call     common_verifyField
   8304     UNSPILL(rIBASE)
   8305 #endif
   8306     jmp      .LOP_SGET_OBJECT_VOLATILE_finish                 # success, continue
   8307 
   8308 
   8309 /* ------------------------------ */
   8310 .L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
   8311 /* File: x86/OP_SPUT_OBJECT_VOLATILE.S */
   8312 /* File: x86/OP_SPUT_OBJECT.S */
   8313     /*
   8314      * SPUT object handler.
   8315      */
   8316     /* op vAA, field@BBBB */
   8317     movl      rSELF,%ecx
   8318     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
   8319     movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
   8320     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
   8321 #if defined(WITH_JIT)
   8322     movl      %ecx, TMP_SPILL1(%ebp)
   8323     lea       (%ecx,%eax,4),%ecx
   8324     movl      %ecx, TMP_SPILL2(%ebp)
   8325     movl      TMP_SPILL1(%ebp), %ecx
   8326 #endif
   8327     movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField
   8328     testl     %eax,%eax                          # resolved entry null?
   8329     je        .LOP_SPUT_OBJECT_VOLATILE_resolve                # if not, make it so
   8330 .LOP_SPUT_OBJECT_VOLATILE_finish:                              # field ptr in eax
   8331     movzbl    rINSTbl,%ecx                       # ecx<- AA
   8332     GET_VREG_R  %ecx %ecx
   8333     movl      %ecx,offStaticField_value(%eax)    # do the store
   8334     testl     %ecx,%ecx                          # stored null object ptr?
   8335     je        1f                                 # skip card mark if null
   8336     movl      rSELF,%ecx
   8337     movl      offField_clazz(%eax),%eax          # eax<- method->clazz
   8338     movl      offThread_cardTable(%ecx),%ecx       # get card table base
   8339     shrl      $GC_CARD_SHIFT,%eax               # head to card number
   8340     movb      %cl,(%ecx,%eax)                    # mark card
   8341 1:
   8342     FETCH_INST_OPCODE 2 %ecx
   8343     ADVANCE_PC 2
   8344     GOTO_NEXT_R %ecx
   8345 
   8346 .LOP_SPUT_OBJECT_VOLATILE_resolve:
   8347     movl     rSELF,%ecx
   8348     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
   8349     movl     offThread_method(%ecx),%ecx          # ecx<- current method
   8350     EXPORT_PC                                   # could throw, need to export
   8351     movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
   8352     movl     %eax,OUT_ARG1(%esp)
   8353     movl     %ecx,OUT_ARG0(%esp)
   8354     SPILL(rIBASE)
   8355     call     dvmResolveStaticField              # eax<- resolved StaticField ptr
   8356     UNSPILL(rIBASE)
   8357     testl    %eax,%eax
   8358     je      common_exceptionThrown             # no, handle exception
   8359 #if defined(WITH_JIT)
   8360     movl      TMP_SPILL2(%ebp), %ecx
   8361     SPILL(rIBASE)
   8362     call     common_verifyField
   8363     UNSPILL(rIBASE)
   8364 #endif
   8365     jmp      .LOP_SPUT_OBJECT_VOLATILE_finish                 # success, continue
   8366 
   8367 
   8368 /* ------------------------------ */
   8369 .L_OP_UNUSED_FF: /* 0xff */
   8370 /* File: x86/OP_UNUSED_FF.S */
   8371 /* File: x86/unused.S */
   8372     jmp     common_abort
   8373 
   8374 
   8375     .size   dvmAsmInstructionStartCode, .-dvmAsmInstructionStartCode
   8376     .global dvmAsmInstructionEndCode
   8377 dvmAsmInstructionEndCode:
   8378 
   8379     .global dvmAsmAltInstructionStartCode
   8380     .type   dvmAsmAltInstructionStartCode, %function
   8381     .text
   8382 
   8383 dvmAsmAltInstructionStartCode = .L_ALT_OP_NOP
   8384 /* ------------------------------ */
   8385 .L_ALT_OP_NOP: /* 0x00 */
   8386 /* File: x86/alt_stub.S */
   8387 /*
   8388  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8389  * any interesting requests and then jump to the real instruction
   8390  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8391  * because rIBASE is caller save and we need to reload it.
   8392  *
   8393  * Note that unlike in the Arm implementation, we should never arrive
   8394  * here with a zero breakFlag because we always refresh rIBASE on
   8395  * return.
   8396  */
   8397     EXPORT_PC
   8398     movl   rSELF, %eax
   8399     movl   rPC, OUT_ARG0(%esp)
   8400     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8401     movl   rFP, OUT_ARG1(%esp)
   8402     je     1f                                # reload rIBASE & resume if not
   8403     movl   %eax, OUT_ARG2(%esp)
   8404     call   dvmCheckBefore                    # (dPC, dFP, self)
   8405     movl   rSELF, %eax
   8406 1:
   8407     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8408     jmp    *dvmAsmInstructionStart+(0*4)
   8409 
   8410 /* ------------------------------ */
   8411 .L_ALT_OP_MOVE: /* 0x01 */
   8412 /* File: x86/alt_stub.S */
   8413 /*
   8414  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8415  * any interesting requests and then jump to the real instruction
   8416  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8417  * because rIBASE is caller save and we need to reload it.
   8418  *
   8419  * Note that unlike in the Arm implementation, we should never arrive
   8420  * here with a zero breakFlag because we always refresh rIBASE on
   8421  * return.
   8422  */
   8423     EXPORT_PC
   8424     movl   rSELF, %eax
   8425     movl   rPC, OUT_ARG0(%esp)
   8426     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8427     movl   rFP, OUT_ARG1(%esp)
   8428     je     1f                                # reload rIBASE & resume if not
   8429     movl   %eax, OUT_ARG2(%esp)
   8430     call   dvmCheckBefore                    # (dPC, dFP, self)
   8431     movl   rSELF, %eax
   8432 1:
   8433     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8434     jmp    *dvmAsmInstructionStart+(1*4)
   8435 
   8436 /* ------------------------------ */
   8437 .L_ALT_OP_MOVE_FROM16: /* 0x02 */
   8438 /* File: x86/alt_stub.S */
   8439 /*
   8440  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8441  * any interesting requests and then jump to the real instruction
   8442  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8443  * because rIBASE is caller save and we need to reload it.
   8444  *
   8445  * Note that unlike in the Arm implementation, we should never arrive
   8446  * here with a zero breakFlag because we always refresh rIBASE on
   8447  * return.
   8448  */
   8449     EXPORT_PC
   8450     movl   rSELF, %eax
   8451     movl   rPC, OUT_ARG0(%esp)
   8452     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8453     movl   rFP, OUT_ARG1(%esp)
   8454     je     1f                                # reload rIBASE & resume if not
   8455     movl   %eax, OUT_ARG2(%esp)
   8456     call   dvmCheckBefore                    # (dPC, dFP, self)
   8457     movl   rSELF, %eax
   8458 1:
   8459     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8460     jmp    *dvmAsmInstructionStart+(2*4)
   8461 
   8462 /* ------------------------------ */
   8463 .L_ALT_OP_MOVE_16: /* 0x03 */
   8464 /* File: x86/alt_stub.S */
   8465 /*
   8466  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8467  * any interesting requests and then jump to the real instruction
   8468  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8469  * because rIBASE is caller save and we need to reload it.
   8470  *
   8471  * Note that unlike in the Arm implementation, we should never arrive
   8472  * here with a zero breakFlag because we always refresh rIBASE on
   8473  * return.
   8474  */
   8475     EXPORT_PC
   8476     movl   rSELF, %eax
   8477     movl   rPC, OUT_ARG0(%esp)
   8478     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8479     movl   rFP, OUT_ARG1(%esp)
   8480     je     1f                                # reload rIBASE & resume if not
   8481     movl   %eax, OUT_ARG2(%esp)
   8482     call   dvmCheckBefore                    # (dPC, dFP, self)
   8483     movl   rSELF, %eax
   8484 1:
   8485     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8486     jmp    *dvmAsmInstructionStart+(3*4)
   8487 
   8488 /* ------------------------------ */
   8489 .L_ALT_OP_MOVE_WIDE: /* 0x04 */
   8490 /* File: x86/alt_stub.S */
   8491 /*
   8492  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8493  * any interesting requests and then jump to the real instruction
   8494  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8495  * because rIBASE is caller save and we need to reload it.
   8496  *
   8497  * Note that unlike in the Arm implementation, we should never arrive
   8498  * here with a zero breakFlag because we always refresh rIBASE on
   8499  * return.
   8500  */
   8501     EXPORT_PC
   8502     movl   rSELF, %eax
   8503     movl   rPC, OUT_ARG0(%esp)
   8504     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8505     movl   rFP, OUT_ARG1(%esp)
   8506     je     1f                                # reload rIBASE & resume if not
   8507     movl   %eax, OUT_ARG2(%esp)
   8508     call   dvmCheckBefore                    # (dPC, dFP, self)
   8509     movl   rSELF, %eax
   8510 1:
   8511     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8512     jmp    *dvmAsmInstructionStart+(4*4)
   8513 
   8514 /* ------------------------------ */
   8515 .L_ALT_OP_MOVE_WIDE_FROM16: /* 0x05 */
   8516 /* File: x86/alt_stub.S */
   8517 /*
   8518  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8519  * any interesting requests and then jump to the real instruction
   8520  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8521  * because rIBASE is caller save and we need to reload it.
   8522  *
   8523  * Note that unlike in the Arm implementation, we should never arrive
   8524  * here with a zero breakFlag because we always refresh rIBASE on
   8525  * return.
   8526  */
   8527     EXPORT_PC
   8528     movl   rSELF, %eax
   8529     movl   rPC, OUT_ARG0(%esp)
   8530     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8531     movl   rFP, OUT_ARG1(%esp)
   8532     je     1f                                # reload rIBASE & resume if not
   8533     movl   %eax, OUT_ARG2(%esp)
   8534     call   dvmCheckBefore                    # (dPC, dFP, self)
   8535     movl   rSELF, %eax
   8536 1:
   8537     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8538     jmp    *dvmAsmInstructionStart+(5*4)
   8539 
   8540 /* ------------------------------ */
   8541 .L_ALT_OP_MOVE_WIDE_16: /* 0x06 */
   8542 /* File: x86/alt_stub.S */
   8543 /*
   8544  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8545  * any interesting requests and then jump to the real instruction
   8546  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8547  * because rIBASE is caller save and we need to reload it.
   8548  *
   8549  * Note that unlike in the Arm implementation, we should never arrive
   8550  * here with a zero breakFlag because we always refresh rIBASE on
   8551  * return.
   8552  */
   8553     EXPORT_PC
   8554     movl   rSELF, %eax
   8555     movl   rPC, OUT_ARG0(%esp)
   8556     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8557     movl   rFP, OUT_ARG1(%esp)
   8558     je     1f                                # reload rIBASE & resume if not
   8559     movl   %eax, OUT_ARG2(%esp)
   8560     call   dvmCheckBefore                    # (dPC, dFP, self)
   8561     movl   rSELF, %eax
   8562 1:
   8563     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8564     jmp    *dvmAsmInstructionStart+(6*4)
   8565 
   8566 /* ------------------------------ */
   8567 .L_ALT_OP_MOVE_OBJECT: /* 0x07 */
   8568 /* File: x86/alt_stub.S */
   8569 /*
   8570  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8571  * any interesting requests and then jump to the real instruction
   8572  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8573  * because rIBASE is caller save and we need to reload it.
   8574  *
   8575  * Note that unlike in the Arm implementation, we should never arrive
   8576  * here with a zero breakFlag because we always refresh rIBASE on
   8577  * return.
   8578  */
   8579     EXPORT_PC
   8580     movl   rSELF, %eax
   8581     movl   rPC, OUT_ARG0(%esp)
   8582     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8583     movl   rFP, OUT_ARG1(%esp)
   8584     je     1f                                # reload rIBASE & resume if not
   8585     movl   %eax, OUT_ARG2(%esp)
   8586     call   dvmCheckBefore                    # (dPC, dFP, self)
   8587     movl   rSELF, %eax
   8588 1:
   8589     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8590     jmp    *dvmAsmInstructionStart+(7*4)
   8591 
   8592 /* ------------------------------ */
   8593 .L_ALT_OP_MOVE_OBJECT_FROM16: /* 0x08 */
   8594 /* File: x86/alt_stub.S */
   8595 /*
   8596  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8597  * any interesting requests and then jump to the real instruction
   8598  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8599  * because rIBASE is caller save and we need to reload it.
   8600  *
   8601  * Note that unlike in the Arm implementation, we should never arrive
   8602  * here with a zero breakFlag because we always refresh rIBASE on
   8603  * return.
   8604  */
   8605     EXPORT_PC
   8606     movl   rSELF, %eax
   8607     movl   rPC, OUT_ARG0(%esp)
   8608     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8609     movl   rFP, OUT_ARG1(%esp)
   8610     je     1f                                # reload rIBASE & resume if not
   8611     movl   %eax, OUT_ARG2(%esp)
   8612     call   dvmCheckBefore                    # (dPC, dFP, self)
   8613     movl   rSELF, %eax
   8614 1:
   8615     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8616     jmp    *dvmAsmInstructionStart+(8*4)
   8617 
   8618 /* ------------------------------ */
   8619 .L_ALT_OP_MOVE_OBJECT_16: /* 0x09 */
   8620 /* File: x86/alt_stub.S */
   8621 /*
   8622  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8623  * any interesting requests and then jump to the real instruction
   8624  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8625  * because rIBASE is caller save and we need to reload it.
   8626  *
   8627  * Note that unlike in the Arm implementation, we should never arrive
   8628  * here with a zero breakFlag because we always refresh rIBASE on
   8629  * return.
   8630  */
   8631     EXPORT_PC
   8632     movl   rSELF, %eax
   8633     movl   rPC, OUT_ARG0(%esp)
   8634     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8635     movl   rFP, OUT_ARG1(%esp)
   8636     je     1f                                # reload rIBASE & resume if not
   8637     movl   %eax, OUT_ARG2(%esp)
   8638     call   dvmCheckBefore                    # (dPC, dFP, self)
   8639     movl   rSELF, %eax
   8640 1:
   8641     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8642     jmp    *dvmAsmInstructionStart+(9*4)
   8643 
   8644 /* ------------------------------ */
   8645 .L_ALT_OP_MOVE_RESULT: /* 0x0a */
   8646 /* File: x86/alt_stub.S */
   8647 /*
   8648  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8649  * any interesting requests and then jump to the real instruction
   8650  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8651  * because rIBASE is caller save and we need to reload it.
   8652  *
   8653  * Note that unlike in the Arm implementation, we should never arrive
   8654  * here with a zero breakFlag because we always refresh rIBASE on
   8655  * return.
   8656  */
   8657     EXPORT_PC
   8658     movl   rSELF, %eax
   8659     movl   rPC, OUT_ARG0(%esp)
   8660     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8661     movl   rFP, OUT_ARG1(%esp)
   8662     je     1f                                # reload rIBASE & resume if not
   8663     movl   %eax, OUT_ARG2(%esp)
   8664     call   dvmCheckBefore                    # (dPC, dFP, self)
   8665     movl   rSELF, %eax
   8666 1:
   8667     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8668     jmp    *dvmAsmInstructionStart+(10*4)
   8669 
   8670 /* ------------------------------ */
   8671 .L_ALT_OP_MOVE_RESULT_WIDE: /* 0x0b */
   8672 /* File: x86/alt_stub.S */
   8673 /*
   8674  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8675  * any interesting requests and then jump to the real instruction
   8676  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8677  * because rIBASE is caller save and we need to reload it.
   8678  *
   8679  * Note that unlike in the Arm implementation, we should never arrive
   8680  * here with a zero breakFlag because we always refresh rIBASE on
   8681  * return.
   8682  */
   8683     EXPORT_PC
   8684     movl   rSELF, %eax
   8685     movl   rPC, OUT_ARG0(%esp)
   8686     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8687     movl   rFP, OUT_ARG1(%esp)
   8688     je     1f                                # reload rIBASE & resume if not
   8689     movl   %eax, OUT_ARG2(%esp)
   8690     call   dvmCheckBefore                    # (dPC, dFP, self)
   8691     movl   rSELF, %eax
   8692 1:
   8693     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8694     jmp    *dvmAsmInstructionStart+(11*4)
   8695 
   8696 /* ------------------------------ */
   8697 .L_ALT_OP_MOVE_RESULT_OBJECT: /* 0x0c */
   8698 /* File: x86/alt_stub.S */
   8699 /*
   8700  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8701  * any interesting requests and then jump to the real instruction
   8702  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8703  * because rIBASE is caller save and we need to reload it.
   8704  *
   8705  * Note that unlike in the Arm implementation, we should never arrive
   8706  * here with a zero breakFlag because we always refresh rIBASE on
   8707  * return.
   8708  */
   8709     EXPORT_PC
   8710     movl   rSELF, %eax
   8711     movl   rPC, OUT_ARG0(%esp)
   8712     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8713     movl   rFP, OUT_ARG1(%esp)
   8714     je     1f                                # reload rIBASE & resume if not
   8715     movl   %eax, OUT_ARG2(%esp)
   8716     call   dvmCheckBefore                    # (dPC, dFP, self)
   8717     movl   rSELF, %eax
   8718 1:
   8719     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8720     jmp    *dvmAsmInstructionStart+(12*4)
   8721 
   8722 /* ------------------------------ */
   8723 .L_ALT_OP_MOVE_EXCEPTION: /* 0x0d */
   8724 /* File: x86/alt_stub.S */
   8725 /*
   8726  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8727  * any interesting requests and then jump to the real instruction
   8728  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8729  * because rIBASE is caller save and we need to reload it.
   8730  *
   8731  * Note that unlike in the Arm implementation, we should never arrive
   8732  * here with a zero breakFlag because we always refresh rIBASE on
   8733  * return.
   8734  */
   8735     EXPORT_PC
   8736     movl   rSELF, %eax
   8737     movl   rPC, OUT_ARG0(%esp)
   8738     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8739     movl   rFP, OUT_ARG1(%esp)
   8740     je     1f                                # reload rIBASE & resume if not
   8741     movl   %eax, OUT_ARG2(%esp)
   8742     call   dvmCheckBefore                    # (dPC, dFP, self)
   8743     movl   rSELF, %eax
   8744 1:
   8745     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8746     jmp    *dvmAsmInstructionStart+(13*4)
   8747 
   8748 /* ------------------------------ */
   8749 .L_ALT_OP_RETURN_VOID: /* 0x0e */
   8750 /* File: x86/alt_stub.S */
   8751 /*
   8752  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8753  * any interesting requests and then jump to the real instruction
   8754  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8755  * because rIBASE is caller save and we need to reload it.
   8756  *
   8757  * Note that unlike in the Arm implementation, we should never arrive
   8758  * here with a zero breakFlag because we always refresh rIBASE on
   8759  * return.
   8760  */
   8761     EXPORT_PC
   8762     movl   rSELF, %eax
   8763     movl   rPC, OUT_ARG0(%esp)
   8764     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8765     movl   rFP, OUT_ARG1(%esp)
   8766     je     1f                                # reload rIBASE & resume if not
   8767     movl   %eax, OUT_ARG2(%esp)
   8768     call   dvmCheckBefore                    # (dPC, dFP, self)
   8769     movl   rSELF, %eax
   8770 1:
   8771     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8772     jmp    *dvmAsmInstructionStart+(14*4)
   8773 
   8774 /* ------------------------------ */
   8775 .L_ALT_OP_RETURN: /* 0x0f */
   8776 /* File: x86/alt_stub.S */
   8777 /*
   8778  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8779  * any interesting requests and then jump to the real instruction
   8780  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8781  * because rIBASE is caller save and we need to reload it.
   8782  *
   8783  * Note that unlike in the Arm implementation, we should never arrive
   8784  * here with a zero breakFlag because we always refresh rIBASE on
   8785  * return.
   8786  */
   8787     EXPORT_PC
   8788     movl   rSELF, %eax
   8789     movl   rPC, OUT_ARG0(%esp)
   8790     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8791     movl   rFP, OUT_ARG1(%esp)
   8792     je     1f                                # reload rIBASE & resume if not
   8793     movl   %eax, OUT_ARG2(%esp)
   8794     call   dvmCheckBefore                    # (dPC, dFP, self)
   8795     movl   rSELF, %eax
   8796 1:
   8797     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8798     jmp    *dvmAsmInstructionStart+(15*4)
   8799 
   8800 /* ------------------------------ */
   8801 .L_ALT_OP_RETURN_WIDE: /* 0x10 */
   8802 /* File: x86/alt_stub.S */
   8803 /*
   8804  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8805  * any interesting requests and then jump to the real instruction
   8806  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8807  * because rIBASE is caller save and we need to reload it.
   8808  *
   8809  * Note that unlike in the Arm implementation, we should never arrive
   8810  * here with a zero breakFlag because we always refresh rIBASE on
   8811  * return.
   8812  */
   8813     EXPORT_PC
   8814     movl   rSELF, %eax
   8815     movl   rPC, OUT_ARG0(%esp)
   8816     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8817     movl   rFP, OUT_ARG1(%esp)
   8818     je     1f                                # reload rIBASE & resume if not
   8819     movl   %eax, OUT_ARG2(%esp)
   8820     call   dvmCheckBefore                    # (dPC, dFP, self)
   8821     movl   rSELF, %eax
   8822 1:
   8823     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8824     jmp    *dvmAsmInstructionStart+(16*4)
   8825 
   8826 /* ------------------------------ */
   8827 .L_ALT_OP_RETURN_OBJECT: /* 0x11 */
   8828 /* File: x86/alt_stub.S */
   8829 /*
   8830  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8831  * any interesting requests and then jump to the real instruction
   8832  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8833  * because rIBASE is caller save and we need to reload it.
   8834  *
   8835  * Note that unlike in the Arm implementation, we should never arrive
   8836  * here with a zero breakFlag because we always refresh rIBASE on
   8837  * return.
   8838  */
   8839     EXPORT_PC
   8840     movl   rSELF, %eax
   8841     movl   rPC, OUT_ARG0(%esp)
   8842     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8843     movl   rFP, OUT_ARG1(%esp)
   8844     je     1f                                # reload rIBASE & resume if not
   8845     movl   %eax, OUT_ARG2(%esp)
   8846     call   dvmCheckBefore                    # (dPC, dFP, self)
   8847     movl   rSELF, %eax
   8848 1:
   8849     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8850     jmp    *dvmAsmInstructionStart+(17*4)
   8851 
   8852 /* ------------------------------ */
   8853 .L_ALT_OP_CONST_4: /* 0x12 */
   8854 /* File: x86/alt_stub.S */
   8855 /*
   8856  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8857  * any interesting requests and then jump to the real instruction
   8858  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8859  * because rIBASE is caller save and we need to reload it.
   8860  *
   8861  * Note that unlike in the Arm implementation, we should never arrive
   8862  * here with a zero breakFlag because we always refresh rIBASE on
   8863  * return.
   8864  */
   8865     EXPORT_PC
   8866     movl   rSELF, %eax
   8867     movl   rPC, OUT_ARG0(%esp)
   8868     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8869     movl   rFP, OUT_ARG1(%esp)
   8870     je     1f                                # reload rIBASE & resume if not
   8871     movl   %eax, OUT_ARG2(%esp)
   8872     call   dvmCheckBefore                    # (dPC, dFP, self)
   8873     movl   rSELF, %eax
   8874 1:
   8875     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8876     jmp    *dvmAsmInstructionStart+(18*4)
   8877 
   8878 /* ------------------------------ */
   8879 .L_ALT_OP_CONST_16: /* 0x13 */
   8880 /* File: x86/alt_stub.S */
   8881 /*
   8882  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8883  * any interesting requests and then jump to the real instruction
   8884  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8885  * because rIBASE is caller save and we need to reload it.
   8886  *
   8887  * Note that unlike in the Arm implementation, we should never arrive
   8888  * here with a zero breakFlag because we always refresh rIBASE on
   8889  * return.
   8890  */
   8891     EXPORT_PC
   8892     movl   rSELF, %eax
   8893     movl   rPC, OUT_ARG0(%esp)
   8894     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8895     movl   rFP, OUT_ARG1(%esp)
   8896     je     1f                                # reload rIBASE & resume if not
   8897     movl   %eax, OUT_ARG2(%esp)
   8898     call   dvmCheckBefore                    # (dPC, dFP, self)
   8899     movl   rSELF, %eax
   8900 1:
   8901     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8902     jmp    *dvmAsmInstructionStart+(19*4)
   8903 
   8904 /* ------------------------------ */
   8905 .L_ALT_OP_CONST: /* 0x14 */
   8906 /* File: x86/alt_stub.S */
   8907 /*
   8908  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8909  * any interesting requests and then jump to the real instruction
   8910  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8911  * because rIBASE is caller save and we need to reload it.
   8912  *
   8913  * Note that unlike in the Arm implementation, we should never arrive
   8914  * here with a zero breakFlag because we always refresh rIBASE on
   8915  * return.
   8916  */
   8917     EXPORT_PC
   8918     movl   rSELF, %eax
   8919     movl   rPC, OUT_ARG0(%esp)
   8920     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8921     movl   rFP, OUT_ARG1(%esp)
   8922     je     1f                                # reload rIBASE & resume if not
   8923     movl   %eax, OUT_ARG2(%esp)
   8924     call   dvmCheckBefore                    # (dPC, dFP, self)
   8925     movl   rSELF, %eax
   8926 1:
   8927     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8928     jmp    *dvmAsmInstructionStart+(20*4)
   8929 
   8930 /* ------------------------------ */
   8931 .L_ALT_OP_CONST_HIGH16: /* 0x15 */
   8932 /* File: x86/alt_stub.S */
   8933 /*
   8934  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8935  * any interesting requests and then jump to the real instruction
   8936  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8937  * because rIBASE is caller save and we need to reload it.
   8938  *
   8939  * Note that unlike in the Arm implementation, we should never arrive
   8940  * here with a zero breakFlag because we always refresh rIBASE on
   8941  * return.
   8942  */
   8943     EXPORT_PC
   8944     movl   rSELF, %eax
   8945     movl   rPC, OUT_ARG0(%esp)
   8946     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8947     movl   rFP, OUT_ARG1(%esp)
   8948     je     1f                                # reload rIBASE & resume if not
   8949     movl   %eax, OUT_ARG2(%esp)
   8950     call   dvmCheckBefore                    # (dPC, dFP, self)
   8951     movl   rSELF, %eax
   8952 1:
   8953     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8954     jmp    *dvmAsmInstructionStart+(21*4)
   8955 
   8956 /* ------------------------------ */
   8957 .L_ALT_OP_CONST_WIDE_16: /* 0x16 */
   8958 /* File: x86/alt_stub.S */
   8959 /*
   8960  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8961  * any interesting requests and then jump to the real instruction
   8962  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8963  * because rIBASE is caller save and we need to reload it.
   8964  *
   8965  * Note that unlike in the Arm implementation, we should never arrive
   8966  * here with a zero breakFlag because we always refresh rIBASE on
   8967  * return.
   8968  */
   8969     EXPORT_PC
   8970     movl   rSELF, %eax
   8971     movl   rPC, OUT_ARG0(%esp)
   8972     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8973     movl   rFP, OUT_ARG1(%esp)
   8974     je     1f                                # reload rIBASE & resume if not
   8975     movl   %eax, OUT_ARG2(%esp)
   8976     call   dvmCheckBefore                    # (dPC, dFP, self)
   8977     movl   rSELF, %eax
   8978 1:
   8979     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   8980     jmp    *dvmAsmInstructionStart+(22*4)
   8981 
   8982 /* ------------------------------ */
   8983 .L_ALT_OP_CONST_WIDE_32: /* 0x17 */
   8984 /* File: x86/alt_stub.S */
   8985 /*
   8986  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   8987  * any interesting requests and then jump to the real instruction
   8988  * handler.  Unlike the Arm handler, we can't do this as a tail call
   8989  * because rIBASE is caller save and we need to reload it.
   8990  *
   8991  * Note that unlike in the Arm implementation, we should never arrive
   8992  * here with a zero breakFlag because we always refresh rIBASE on
   8993  * return.
   8994  */
   8995     EXPORT_PC
   8996     movl   rSELF, %eax
   8997     movl   rPC, OUT_ARG0(%esp)
   8998     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   8999     movl   rFP, OUT_ARG1(%esp)
   9000     je     1f                                # reload rIBASE & resume if not
   9001     movl   %eax, OUT_ARG2(%esp)
   9002     call   dvmCheckBefore                    # (dPC, dFP, self)
   9003     movl   rSELF, %eax
   9004 1:
   9005     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9006     jmp    *dvmAsmInstructionStart+(23*4)
   9007 
   9008 /* ------------------------------ */
   9009 .L_ALT_OP_CONST_WIDE: /* 0x18 */
   9010 /* File: x86/alt_stub.S */
   9011 /*
   9012  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9013  * any interesting requests and then jump to the real instruction
   9014  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9015  * because rIBASE is caller save and we need to reload it.
   9016  *
   9017  * Note that unlike in the Arm implementation, we should never arrive
   9018  * here with a zero breakFlag because we always refresh rIBASE on
   9019  * return.
   9020  */
   9021     EXPORT_PC
   9022     movl   rSELF, %eax
   9023     movl   rPC, OUT_ARG0(%esp)
   9024     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9025     movl   rFP, OUT_ARG1(%esp)
   9026     je     1f                                # reload rIBASE & resume if not
   9027     movl   %eax, OUT_ARG2(%esp)
   9028     call   dvmCheckBefore                    # (dPC, dFP, self)
   9029     movl   rSELF, %eax
   9030 1:
   9031     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9032     jmp    *dvmAsmInstructionStart+(24*4)
   9033 
   9034 /* ------------------------------ */
   9035 .L_ALT_OP_CONST_WIDE_HIGH16: /* 0x19 */
   9036 /* File: x86/alt_stub.S */
   9037 /*
   9038  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9039  * any interesting requests and then jump to the real instruction
   9040  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9041  * because rIBASE is caller save and we need to reload it.
   9042  *
   9043  * Note that unlike in the Arm implementation, we should never arrive
   9044  * here with a zero breakFlag because we always refresh rIBASE on
   9045  * return.
   9046  */
   9047     EXPORT_PC
   9048     movl   rSELF, %eax
   9049     movl   rPC, OUT_ARG0(%esp)
   9050     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9051     movl   rFP, OUT_ARG1(%esp)
   9052     je     1f                                # reload rIBASE & resume if not
   9053     movl   %eax, OUT_ARG2(%esp)
   9054     call   dvmCheckBefore                    # (dPC, dFP, self)
   9055     movl   rSELF, %eax
   9056 1:
   9057     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9058     jmp    *dvmAsmInstructionStart+(25*4)
   9059 
   9060 /* ------------------------------ */
   9061 .L_ALT_OP_CONST_STRING: /* 0x1a */
   9062 /* File: x86/alt_stub.S */
   9063 /*
   9064  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9065  * any interesting requests and then jump to the real instruction
   9066  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9067  * because rIBASE is caller save and we need to reload it.
   9068  *
   9069  * Note that unlike in the Arm implementation, we should never arrive
   9070  * here with a zero breakFlag because we always refresh rIBASE on
   9071  * return.
   9072  */
   9073     EXPORT_PC
   9074     movl   rSELF, %eax
   9075     movl   rPC, OUT_ARG0(%esp)
   9076     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9077     movl   rFP, OUT_ARG1(%esp)
   9078     je     1f                                # reload rIBASE & resume if not
   9079     movl   %eax, OUT_ARG2(%esp)
   9080     call   dvmCheckBefore                    # (dPC, dFP, self)
   9081     movl   rSELF, %eax
   9082 1:
   9083     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9084     jmp    *dvmAsmInstructionStart+(26*4)
   9085 
   9086 /* ------------------------------ */
   9087 .L_ALT_OP_CONST_STRING_JUMBO: /* 0x1b */
   9088 /* File: x86/alt_stub.S */
   9089 /*
   9090  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9091  * any interesting requests and then jump to the real instruction
   9092  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9093  * because rIBASE is caller save and we need to reload it.
   9094  *
   9095  * Note that unlike in the Arm implementation, we should never arrive
   9096  * here with a zero breakFlag because we always refresh rIBASE on
   9097  * return.
   9098  */
   9099     EXPORT_PC
   9100     movl   rSELF, %eax
   9101     movl   rPC, OUT_ARG0(%esp)
   9102     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9103     movl   rFP, OUT_ARG1(%esp)
   9104     je     1f                                # reload rIBASE & resume if not
   9105     movl   %eax, OUT_ARG2(%esp)
   9106     call   dvmCheckBefore                    # (dPC, dFP, self)
   9107     movl   rSELF, %eax
   9108 1:
   9109     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9110     jmp    *dvmAsmInstructionStart+(27*4)
   9111 
   9112 /* ------------------------------ */
   9113 .L_ALT_OP_CONST_CLASS: /* 0x1c */
   9114 /* File: x86/alt_stub.S */
   9115 /*
   9116  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9117  * any interesting requests and then jump to the real instruction
   9118  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9119  * because rIBASE is caller save and we need to reload it.
   9120  *
   9121  * Note that unlike in the Arm implementation, we should never arrive
   9122  * here with a zero breakFlag because we always refresh rIBASE on
   9123  * return.
   9124  */
   9125     EXPORT_PC
   9126     movl   rSELF, %eax
   9127     movl   rPC, OUT_ARG0(%esp)
   9128     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9129     movl   rFP, OUT_ARG1(%esp)
   9130     je     1f                                # reload rIBASE & resume if not
   9131     movl   %eax, OUT_ARG2(%esp)
   9132     call   dvmCheckBefore                    # (dPC, dFP, self)
   9133     movl   rSELF, %eax
   9134 1:
   9135     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9136     jmp    *dvmAsmInstructionStart+(28*4)
   9137 
   9138 /* ------------------------------ */
   9139 .L_ALT_OP_MONITOR_ENTER: /* 0x1d */
   9140 /* File: x86/alt_stub.S */
   9141 /*
   9142  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9143  * any interesting requests and then jump to the real instruction
   9144  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9145  * because rIBASE is caller save and we need to reload it.
   9146  *
   9147  * Note that unlike in the Arm implementation, we should never arrive
   9148  * here with a zero breakFlag because we always refresh rIBASE on
   9149  * return.
   9150  */
   9151     EXPORT_PC
   9152     movl   rSELF, %eax
   9153     movl   rPC, OUT_ARG0(%esp)
   9154     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9155     movl   rFP, OUT_ARG1(%esp)
   9156     je     1f                                # reload rIBASE & resume if not
   9157     movl   %eax, OUT_ARG2(%esp)
   9158     call   dvmCheckBefore                    # (dPC, dFP, self)
   9159     movl   rSELF, %eax
   9160 1:
   9161     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9162     jmp    *dvmAsmInstructionStart+(29*4)
   9163 
   9164 /* ------------------------------ */
   9165 .L_ALT_OP_MONITOR_EXIT: /* 0x1e */
   9166 /* File: x86/alt_stub.S */
   9167 /*
   9168  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9169  * any interesting requests and then jump to the real instruction
   9170  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9171  * because rIBASE is caller save and we need to reload it.
   9172  *
   9173  * Note that unlike in the Arm implementation, we should never arrive
   9174  * here with a zero breakFlag because we always refresh rIBASE on
   9175  * return.
   9176  */
   9177     EXPORT_PC
   9178     movl   rSELF, %eax
   9179     movl   rPC, OUT_ARG0(%esp)
   9180     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9181     movl   rFP, OUT_ARG1(%esp)
   9182     je     1f                                # reload rIBASE & resume if not
   9183     movl   %eax, OUT_ARG2(%esp)
   9184     call   dvmCheckBefore                    # (dPC, dFP, self)
   9185     movl   rSELF, %eax
   9186 1:
   9187     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9188     jmp    *dvmAsmInstructionStart+(30*4)
   9189 
   9190 /* ------------------------------ */
   9191 .L_ALT_OP_CHECK_CAST: /* 0x1f */
   9192 /* File: x86/alt_stub.S */
   9193 /*
   9194  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9195  * any interesting requests and then jump to the real instruction
   9196  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9197  * because rIBASE is caller save and we need to reload it.
   9198  *
   9199  * Note that unlike in the Arm implementation, we should never arrive
   9200  * here with a zero breakFlag because we always refresh rIBASE on
   9201  * return.
   9202  */
   9203     EXPORT_PC
   9204     movl   rSELF, %eax
   9205     movl   rPC, OUT_ARG0(%esp)
   9206     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9207     movl   rFP, OUT_ARG1(%esp)
   9208     je     1f                                # reload rIBASE & resume if not
   9209     movl   %eax, OUT_ARG2(%esp)
   9210     call   dvmCheckBefore                    # (dPC, dFP, self)
   9211     movl   rSELF, %eax
   9212 1:
   9213     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9214     jmp    *dvmAsmInstructionStart+(31*4)
   9215 
   9216 /* ------------------------------ */
   9217 .L_ALT_OP_INSTANCE_OF: /* 0x20 */
   9218 /* File: x86/alt_stub.S */
   9219 /*
   9220  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9221  * any interesting requests and then jump to the real instruction
   9222  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9223  * because rIBASE is caller save and we need to reload it.
   9224  *
   9225  * Note that unlike in the Arm implementation, we should never arrive
   9226  * here with a zero breakFlag because we always refresh rIBASE on
   9227  * return.
   9228  */
   9229     EXPORT_PC
   9230     movl   rSELF, %eax
   9231     movl   rPC, OUT_ARG0(%esp)
   9232     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9233     movl   rFP, OUT_ARG1(%esp)
   9234     je     1f                                # reload rIBASE & resume if not
   9235     movl   %eax, OUT_ARG2(%esp)
   9236     call   dvmCheckBefore                    # (dPC, dFP, self)
   9237     movl   rSELF, %eax
   9238 1:
   9239     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9240     jmp    *dvmAsmInstructionStart+(32*4)
   9241 
   9242 /* ------------------------------ */
   9243 .L_ALT_OP_ARRAY_LENGTH: /* 0x21 */
   9244 /* File: x86/alt_stub.S */
   9245 /*
   9246  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9247  * any interesting requests and then jump to the real instruction
   9248  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9249  * because rIBASE is caller save and we need to reload it.
   9250  *
   9251  * Note that unlike in the Arm implementation, we should never arrive
   9252  * here with a zero breakFlag because we always refresh rIBASE on
   9253  * return.
   9254  */
   9255     EXPORT_PC
   9256     movl   rSELF, %eax
   9257     movl   rPC, OUT_ARG0(%esp)
   9258     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9259     movl   rFP, OUT_ARG1(%esp)
   9260     je     1f                                # reload rIBASE & resume if not
   9261     movl   %eax, OUT_ARG2(%esp)
   9262     call   dvmCheckBefore                    # (dPC, dFP, self)
   9263     movl   rSELF, %eax
   9264 1:
   9265     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9266     jmp    *dvmAsmInstructionStart+(33*4)
   9267 
   9268 /* ------------------------------ */
   9269 .L_ALT_OP_NEW_INSTANCE: /* 0x22 */
   9270 /* File: x86/alt_stub.S */
   9271 /*
   9272  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9273  * any interesting requests and then jump to the real instruction
   9274  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9275  * because rIBASE is caller save and we need to reload it.
   9276  *
   9277  * Note that unlike in the Arm implementation, we should never arrive
   9278  * here with a zero breakFlag because we always refresh rIBASE on
   9279  * return.
   9280  */
   9281     EXPORT_PC
   9282     movl   rSELF, %eax
   9283     movl   rPC, OUT_ARG0(%esp)
   9284     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9285     movl   rFP, OUT_ARG1(%esp)
   9286     je     1f                                # reload rIBASE & resume if not
   9287     movl   %eax, OUT_ARG2(%esp)
   9288     call   dvmCheckBefore                    # (dPC, dFP, self)
   9289     movl   rSELF, %eax
   9290 1:
   9291     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9292     jmp    *dvmAsmInstructionStart+(34*4)
   9293 
   9294 /* ------------------------------ */
   9295 .L_ALT_OP_NEW_ARRAY: /* 0x23 */
   9296 /* File: x86/alt_stub.S */
   9297 /*
   9298  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9299  * any interesting requests and then jump to the real instruction
   9300  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9301  * because rIBASE is caller save and we need to reload it.
   9302  *
   9303  * Note that unlike in the Arm implementation, we should never arrive
   9304  * here with a zero breakFlag because we always refresh rIBASE on
   9305  * return.
   9306  */
   9307     EXPORT_PC
   9308     movl   rSELF, %eax
   9309     movl   rPC, OUT_ARG0(%esp)
   9310     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9311     movl   rFP, OUT_ARG1(%esp)
   9312     je     1f                                # reload rIBASE & resume if not
   9313     movl   %eax, OUT_ARG2(%esp)
   9314     call   dvmCheckBefore                    # (dPC, dFP, self)
   9315     movl   rSELF, %eax
   9316 1:
   9317     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9318     jmp    *dvmAsmInstructionStart+(35*4)
   9319 
   9320 /* ------------------------------ */
   9321 .L_ALT_OP_FILLED_NEW_ARRAY: /* 0x24 */
   9322 /* File: x86/alt_stub.S */
   9323 /*
   9324  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9325  * any interesting requests and then jump to the real instruction
   9326  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9327  * because rIBASE is caller save and we need to reload it.
   9328  *
   9329  * Note that unlike in the Arm implementation, we should never arrive
   9330  * here with a zero breakFlag because we always refresh rIBASE on
   9331  * return.
   9332  */
   9333     EXPORT_PC
   9334     movl   rSELF, %eax
   9335     movl   rPC, OUT_ARG0(%esp)
   9336     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9337     movl   rFP, OUT_ARG1(%esp)
   9338     je     1f                                # reload rIBASE & resume if not
   9339     movl   %eax, OUT_ARG2(%esp)
   9340     call   dvmCheckBefore                    # (dPC, dFP, self)
   9341     movl   rSELF, %eax
   9342 1:
   9343     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9344     jmp    *dvmAsmInstructionStart+(36*4)
   9345 
   9346 /* ------------------------------ */
   9347 .L_ALT_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
   9348 /* File: x86/alt_stub.S */
   9349 /*
   9350  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9351  * any interesting requests and then jump to the real instruction
   9352  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9353  * because rIBASE is caller save and we need to reload it.
   9354  *
   9355  * Note that unlike in the Arm implementation, we should never arrive
   9356  * here with a zero breakFlag because we always refresh rIBASE on
   9357  * return.
   9358  */
   9359     EXPORT_PC
   9360     movl   rSELF, %eax
   9361     movl   rPC, OUT_ARG0(%esp)
   9362     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9363     movl   rFP, OUT_ARG1(%esp)
   9364     je     1f                                # reload rIBASE & resume if not
   9365     movl   %eax, OUT_ARG2(%esp)
   9366     call   dvmCheckBefore                    # (dPC, dFP, self)
   9367     movl   rSELF, %eax
   9368 1:
   9369     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9370     jmp    *dvmAsmInstructionStart+(37*4)
   9371 
   9372 /* ------------------------------ */
   9373 .L_ALT_OP_FILL_ARRAY_DATA: /* 0x26 */
   9374 /* File: x86/alt_stub.S */
   9375 /*
   9376  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9377  * any interesting requests and then jump to the real instruction
   9378  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9379  * because rIBASE is caller save and we need to reload it.
   9380  *
   9381  * Note that unlike in the Arm implementation, we should never arrive
   9382  * here with a zero breakFlag because we always refresh rIBASE on
   9383  * return.
   9384  */
   9385     EXPORT_PC
   9386     movl   rSELF, %eax
   9387     movl   rPC, OUT_ARG0(%esp)
   9388     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9389     movl   rFP, OUT_ARG1(%esp)
   9390     je     1f                                # reload rIBASE & resume if not
   9391     movl   %eax, OUT_ARG2(%esp)
   9392     call   dvmCheckBefore                    # (dPC, dFP, self)
   9393     movl   rSELF, %eax
   9394 1:
   9395     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9396     jmp    *dvmAsmInstructionStart+(38*4)
   9397 
   9398 /* ------------------------------ */
   9399 .L_ALT_OP_THROW: /* 0x27 */
   9400 /* File: x86/alt_stub.S */
   9401 /*
   9402  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9403  * any interesting requests and then jump to the real instruction
   9404  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9405  * because rIBASE is caller save and we need to reload it.
   9406  *
   9407  * Note that unlike in the Arm implementation, we should never arrive
   9408  * here with a zero breakFlag because we always refresh rIBASE on
   9409  * return.
   9410  */
   9411     EXPORT_PC
   9412     movl   rSELF, %eax
   9413     movl   rPC, OUT_ARG0(%esp)
   9414     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9415     movl   rFP, OUT_ARG1(%esp)
   9416     je     1f                                # reload rIBASE & resume if not
   9417     movl   %eax, OUT_ARG2(%esp)
   9418     call   dvmCheckBefore                    # (dPC, dFP, self)
   9419     movl   rSELF, %eax
   9420 1:
   9421     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9422     jmp    *dvmAsmInstructionStart+(39*4)
   9423 
   9424 /* ------------------------------ */
   9425 .L_ALT_OP_GOTO: /* 0x28 */
   9426 /* File: x86/alt_stub.S */
   9427 /*
   9428  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9429  * any interesting requests and then jump to the real instruction
   9430  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9431  * because rIBASE is caller save and we need to reload it.
   9432  *
   9433  * Note that unlike in the Arm implementation, we should never arrive
   9434  * here with a zero breakFlag because we always refresh rIBASE on
   9435  * return.
   9436  */
   9437     EXPORT_PC
   9438     movl   rSELF, %eax
   9439     movl   rPC, OUT_ARG0(%esp)
   9440     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9441     movl   rFP, OUT_ARG1(%esp)
   9442     je     1f                                # reload rIBASE & resume if not
   9443     movl   %eax, OUT_ARG2(%esp)
   9444     call   dvmCheckBefore                    # (dPC, dFP, self)
   9445     movl   rSELF, %eax
   9446 1:
   9447     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9448     jmp    *dvmAsmInstructionStart+(40*4)
   9449 
   9450 /* ------------------------------ */
   9451 .L_ALT_OP_GOTO_16: /* 0x29 */
   9452 /* File: x86/alt_stub.S */
   9453 /*
   9454  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9455  * any interesting requests and then jump to the real instruction
   9456  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9457  * because rIBASE is caller save and we need to reload it.
   9458  *
   9459  * Note that unlike in the Arm implementation, we should never arrive
   9460  * here with a zero breakFlag because we always refresh rIBASE on
   9461  * return.
   9462  */
   9463     EXPORT_PC
   9464     movl   rSELF, %eax
   9465     movl   rPC, OUT_ARG0(%esp)
   9466     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9467     movl   rFP, OUT_ARG1(%esp)
   9468     je     1f                                # reload rIBASE & resume if not
   9469     movl   %eax, OUT_ARG2(%esp)
   9470     call   dvmCheckBefore                    # (dPC, dFP, self)
   9471     movl   rSELF, %eax
   9472 1:
   9473     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9474     jmp    *dvmAsmInstructionStart+(41*4)
   9475 
   9476 /* ------------------------------ */
   9477 .L_ALT_OP_GOTO_32: /* 0x2a */
   9478 /* File: x86/alt_stub.S */
   9479 /*
   9480  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9481  * any interesting requests and then jump to the real instruction
   9482  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9483  * because rIBASE is caller save and we need to reload it.
   9484  *
   9485  * Note that unlike in the Arm implementation, we should never arrive
   9486  * here with a zero breakFlag because we always refresh rIBASE on
   9487  * return.
   9488  */
   9489     EXPORT_PC
   9490     movl   rSELF, %eax
   9491     movl   rPC, OUT_ARG0(%esp)
   9492     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9493     movl   rFP, OUT_ARG1(%esp)
   9494     je     1f                                # reload rIBASE & resume if not
   9495     movl   %eax, OUT_ARG2(%esp)
   9496     call   dvmCheckBefore                    # (dPC, dFP, self)
   9497     movl   rSELF, %eax
   9498 1:
   9499     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9500     jmp    *dvmAsmInstructionStart+(42*4)
   9501 
   9502 /* ------------------------------ */
   9503 .L_ALT_OP_PACKED_SWITCH: /* 0x2b */
   9504 /* File: x86/alt_stub.S */
   9505 /*
   9506  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9507  * any interesting requests and then jump to the real instruction
   9508  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9509  * because rIBASE is caller save and we need to reload it.
   9510  *
   9511  * Note that unlike in the Arm implementation, we should never arrive
   9512  * here with a zero breakFlag because we always refresh rIBASE on
   9513  * return.
   9514  */
   9515     EXPORT_PC
   9516     movl   rSELF, %eax
   9517     movl   rPC, OUT_ARG0(%esp)
   9518     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9519     movl   rFP, OUT_ARG1(%esp)
   9520     je     1f                                # reload rIBASE & resume if not
   9521     movl   %eax, OUT_ARG2(%esp)
   9522     call   dvmCheckBefore                    # (dPC, dFP, self)
   9523     movl   rSELF, %eax
   9524 1:
   9525     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9526     jmp    *dvmAsmInstructionStart+(43*4)
   9527 
   9528 /* ------------------------------ */
   9529 .L_ALT_OP_SPARSE_SWITCH: /* 0x2c */
   9530 /* File: x86/alt_stub.S */
   9531 /*
   9532  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9533  * any interesting requests and then jump to the real instruction
   9534  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9535  * because rIBASE is caller save and we need to reload it.
   9536  *
   9537  * Note that unlike in the Arm implementation, we should never arrive
   9538  * here with a zero breakFlag because we always refresh rIBASE on
   9539  * return.
   9540  */
   9541     EXPORT_PC
   9542     movl   rSELF, %eax
   9543     movl   rPC, OUT_ARG0(%esp)
   9544     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9545     movl   rFP, OUT_ARG1(%esp)
   9546     je     1f                                # reload rIBASE & resume if not
   9547     movl   %eax, OUT_ARG2(%esp)
   9548     call   dvmCheckBefore                    # (dPC, dFP, self)
   9549     movl   rSELF, %eax
   9550 1:
   9551     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9552     jmp    *dvmAsmInstructionStart+(44*4)
   9553 
   9554 /* ------------------------------ */
   9555 .L_ALT_OP_CMPL_FLOAT: /* 0x2d */
   9556 /* File: x86/alt_stub.S */
   9557 /*
   9558  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9559  * any interesting requests and then jump to the real instruction
   9560  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9561  * because rIBASE is caller save and we need to reload it.
   9562  *
   9563  * Note that unlike in the Arm implementation, we should never arrive
   9564  * here with a zero breakFlag because we always refresh rIBASE on
   9565  * return.
   9566  */
   9567     EXPORT_PC
   9568     movl   rSELF, %eax
   9569     movl   rPC, OUT_ARG0(%esp)
   9570     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9571     movl   rFP, OUT_ARG1(%esp)
   9572     je     1f                                # reload rIBASE & resume if not
   9573     movl   %eax, OUT_ARG2(%esp)
   9574     call   dvmCheckBefore                    # (dPC, dFP, self)
   9575     movl   rSELF, %eax
   9576 1:
   9577     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9578     jmp    *dvmAsmInstructionStart+(45*4)
   9579 
   9580 /* ------------------------------ */
   9581 .L_ALT_OP_CMPG_FLOAT: /* 0x2e */
   9582 /* File: x86/alt_stub.S */
   9583 /*
   9584  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9585  * any interesting requests and then jump to the real instruction
   9586  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9587  * because rIBASE is caller save and we need to reload it.
   9588  *
   9589  * Note that unlike in the Arm implementation, we should never arrive
   9590  * here with a zero breakFlag because we always refresh rIBASE on
   9591  * return.
   9592  */
   9593     EXPORT_PC
   9594     movl   rSELF, %eax
   9595     movl   rPC, OUT_ARG0(%esp)
   9596     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9597     movl   rFP, OUT_ARG1(%esp)
   9598     je     1f                                # reload rIBASE & resume if not
   9599     movl   %eax, OUT_ARG2(%esp)
   9600     call   dvmCheckBefore                    # (dPC, dFP, self)
   9601     movl   rSELF, %eax
   9602 1:
   9603     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9604     jmp    *dvmAsmInstructionStart+(46*4)
   9605 
   9606 /* ------------------------------ */
   9607 .L_ALT_OP_CMPL_DOUBLE: /* 0x2f */
   9608 /* File: x86/alt_stub.S */
   9609 /*
   9610  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9611  * any interesting requests and then jump to the real instruction
   9612  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9613  * because rIBASE is caller save and we need to reload it.
   9614  *
   9615  * Note that unlike in the Arm implementation, we should never arrive
   9616  * here with a zero breakFlag because we always refresh rIBASE on
   9617  * return.
   9618  */
   9619     EXPORT_PC
   9620     movl   rSELF, %eax
   9621     movl   rPC, OUT_ARG0(%esp)
   9622     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9623     movl   rFP, OUT_ARG1(%esp)
   9624     je     1f                                # reload rIBASE & resume if not
   9625     movl   %eax, OUT_ARG2(%esp)
   9626     call   dvmCheckBefore                    # (dPC, dFP, self)
   9627     movl   rSELF, %eax
   9628 1:
   9629     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9630     jmp    *dvmAsmInstructionStart+(47*4)
   9631 
   9632 /* ------------------------------ */
   9633 .L_ALT_OP_CMPG_DOUBLE: /* 0x30 */
   9634 /* File: x86/alt_stub.S */
   9635 /*
   9636  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9637  * any interesting requests and then jump to the real instruction
   9638  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9639  * because rIBASE is caller save and we need to reload it.
   9640  *
   9641  * Note that unlike in the Arm implementation, we should never arrive
   9642  * here with a zero breakFlag because we always refresh rIBASE on
   9643  * return.
   9644  */
   9645     EXPORT_PC
   9646     movl   rSELF, %eax
   9647     movl   rPC, OUT_ARG0(%esp)
   9648     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9649     movl   rFP, OUT_ARG1(%esp)
   9650     je     1f                                # reload rIBASE & resume if not
   9651     movl   %eax, OUT_ARG2(%esp)
   9652     call   dvmCheckBefore                    # (dPC, dFP, self)
   9653     movl   rSELF, %eax
   9654 1:
   9655     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9656     jmp    *dvmAsmInstructionStart+(48*4)
   9657 
   9658 /* ------------------------------ */
   9659 .L_ALT_OP_CMP_LONG: /* 0x31 */
   9660 /* File: x86/alt_stub.S */
   9661 /*
   9662  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9663  * any interesting requests and then jump to the real instruction
   9664  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9665  * because rIBASE is caller save and we need to reload it.
   9666  *
   9667  * Note that unlike in the Arm implementation, we should never arrive
   9668  * here with a zero breakFlag because we always refresh rIBASE on
   9669  * return.
   9670  */
   9671     EXPORT_PC
   9672     movl   rSELF, %eax
   9673     movl   rPC, OUT_ARG0(%esp)
   9674     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9675     movl   rFP, OUT_ARG1(%esp)
   9676     je     1f                                # reload rIBASE & resume if not
   9677     movl   %eax, OUT_ARG2(%esp)
   9678     call   dvmCheckBefore                    # (dPC, dFP, self)
   9679     movl   rSELF, %eax
   9680 1:
   9681     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9682     jmp    *dvmAsmInstructionStart+(49*4)
   9683 
   9684 /* ------------------------------ */
   9685 .L_ALT_OP_IF_EQ: /* 0x32 */
   9686 /* File: x86/alt_stub.S */
   9687 /*
   9688  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9689  * any interesting requests and then jump to the real instruction
   9690  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9691  * because rIBASE is caller save and we need to reload it.
   9692  *
   9693  * Note that unlike in the Arm implementation, we should never arrive
   9694  * here with a zero breakFlag because we always refresh rIBASE on
   9695  * return.
   9696  */
   9697     EXPORT_PC
   9698     movl   rSELF, %eax
   9699     movl   rPC, OUT_ARG0(%esp)
   9700     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9701     movl   rFP, OUT_ARG1(%esp)
   9702     je     1f                                # reload rIBASE & resume if not
   9703     movl   %eax, OUT_ARG2(%esp)
   9704     call   dvmCheckBefore                    # (dPC, dFP, self)
   9705     movl   rSELF, %eax
   9706 1:
   9707     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9708     jmp    *dvmAsmInstructionStart+(50*4)
   9709 
   9710 /* ------------------------------ */
   9711 .L_ALT_OP_IF_NE: /* 0x33 */
   9712 /* File: x86/alt_stub.S */
   9713 /*
   9714  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9715  * any interesting requests and then jump to the real instruction
   9716  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9717  * because rIBASE is caller save and we need to reload it.
   9718  *
   9719  * Note that unlike in the Arm implementation, we should never arrive
   9720  * here with a zero breakFlag because we always refresh rIBASE on
   9721  * return.
   9722  */
   9723     EXPORT_PC
   9724     movl   rSELF, %eax
   9725     movl   rPC, OUT_ARG0(%esp)
   9726     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9727     movl   rFP, OUT_ARG1(%esp)
   9728     je     1f                                # reload rIBASE & resume if not
   9729     movl   %eax, OUT_ARG2(%esp)
   9730     call   dvmCheckBefore                    # (dPC, dFP, self)
   9731     movl   rSELF, %eax
   9732 1:
   9733     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9734     jmp    *dvmAsmInstructionStart+(51*4)
   9735 
   9736 /* ------------------------------ */
   9737 .L_ALT_OP_IF_LT: /* 0x34 */
   9738 /* File: x86/alt_stub.S */
   9739 /*
   9740  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9741  * any interesting requests and then jump to the real instruction
   9742  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9743  * because rIBASE is caller save and we need to reload it.
   9744  *
   9745  * Note that unlike in the Arm implementation, we should never arrive
   9746  * here with a zero breakFlag because we always refresh rIBASE on
   9747  * return.
   9748  */
   9749     EXPORT_PC
   9750     movl   rSELF, %eax
   9751     movl   rPC, OUT_ARG0(%esp)
   9752     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9753     movl   rFP, OUT_ARG1(%esp)
   9754     je     1f                                # reload rIBASE & resume if not
   9755     movl   %eax, OUT_ARG2(%esp)
   9756     call   dvmCheckBefore                    # (dPC, dFP, self)
   9757     movl   rSELF, %eax
   9758 1:
   9759     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9760     jmp    *dvmAsmInstructionStart+(52*4)
   9761 
   9762 /* ------------------------------ */
   9763 .L_ALT_OP_IF_GE: /* 0x35 */
   9764 /* File: x86/alt_stub.S */
   9765 /*
   9766  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9767  * any interesting requests and then jump to the real instruction
   9768  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9769  * because rIBASE is caller save and we need to reload it.
   9770  *
   9771  * Note that unlike in the Arm implementation, we should never arrive
   9772  * here with a zero breakFlag because we always refresh rIBASE on
   9773  * return.
   9774  */
   9775     EXPORT_PC
   9776     movl   rSELF, %eax
   9777     movl   rPC, OUT_ARG0(%esp)
   9778     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9779     movl   rFP, OUT_ARG1(%esp)
   9780     je     1f                                # reload rIBASE & resume if not
   9781     movl   %eax, OUT_ARG2(%esp)
   9782     call   dvmCheckBefore                    # (dPC, dFP, self)
   9783     movl   rSELF, %eax
   9784 1:
   9785     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9786     jmp    *dvmAsmInstructionStart+(53*4)
   9787 
   9788 /* ------------------------------ */
   9789 .L_ALT_OP_IF_GT: /* 0x36 */
   9790 /* File: x86/alt_stub.S */
   9791 /*
   9792  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9793  * any interesting requests and then jump to the real instruction
   9794  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9795  * because rIBASE is caller save and we need to reload it.
   9796  *
   9797  * Note that unlike in the Arm implementation, we should never arrive
   9798  * here with a zero breakFlag because we always refresh rIBASE on
   9799  * return.
   9800  */
   9801     EXPORT_PC
   9802     movl   rSELF, %eax
   9803     movl   rPC, OUT_ARG0(%esp)
   9804     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9805     movl   rFP, OUT_ARG1(%esp)
   9806     je     1f                                # reload rIBASE & resume if not
   9807     movl   %eax, OUT_ARG2(%esp)
   9808     call   dvmCheckBefore                    # (dPC, dFP, self)
   9809     movl   rSELF, %eax
   9810 1:
   9811     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9812     jmp    *dvmAsmInstructionStart+(54*4)
   9813 
   9814 /* ------------------------------ */
   9815 .L_ALT_OP_IF_LE: /* 0x37 */
   9816 /* File: x86/alt_stub.S */
   9817 /*
   9818  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9819  * any interesting requests and then jump to the real instruction
   9820  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9821  * because rIBASE is caller save and we need to reload it.
   9822  *
   9823  * Note that unlike in the Arm implementation, we should never arrive
   9824  * here with a zero breakFlag because we always refresh rIBASE on
   9825  * return.
   9826  */
   9827     EXPORT_PC
   9828     movl   rSELF, %eax
   9829     movl   rPC, OUT_ARG0(%esp)
   9830     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9831     movl   rFP, OUT_ARG1(%esp)
   9832     je     1f                                # reload rIBASE & resume if not
   9833     movl   %eax, OUT_ARG2(%esp)
   9834     call   dvmCheckBefore                    # (dPC, dFP, self)
   9835     movl   rSELF, %eax
   9836 1:
   9837     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9838     jmp    *dvmAsmInstructionStart+(55*4)
   9839 
   9840 /* ------------------------------ */
   9841 .L_ALT_OP_IF_EQZ: /* 0x38 */
   9842 /* File: x86/alt_stub.S */
   9843 /*
   9844  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9845  * any interesting requests and then jump to the real instruction
   9846  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9847  * because rIBASE is caller save and we need to reload it.
   9848  *
   9849  * Note that unlike in the Arm implementation, we should never arrive
   9850  * here with a zero breakFlag because we always refresh rIBASE on
   9851  * return.
   9852  */
   9853     EXPORT_PC
   9854     movl   rSELF, %eax
   9855     movl   rPC, OUT_ARG0(%esp)
   9856     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9857     movl   rFP, OUT_ARG1(%esp)
   9858     je     1f                                # reload rIBASE & resume if not
   9859     movl   %eax, OUT_ARG2(%esp)
   9860     call   dvmCheckBefore                    # (dPC, dFP, self)
   9861     movl   rSELF, %eax
   9862 1:
   9863     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9864     jmp    *dvmAsmInstructionStart+(56*4)
   9865 
   9866 /* ------------------------------ */
   9867 .L_ALT_OP_IF_NEZ: /* 0x39 */
   9868 /* File: x86/alt_stub.S */
   9869 /*
   9870  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9871  * any interesting requests and then jump to the real instruction
   9872  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9873  * because rIBASE is caller save and we need to reload it.
   9874  *
   9875  * Note that unlike in the Arm implementation, we should never arrive
   9876  * here with a zero breakFlag because we always refresh rIBASE on
   9877  * return.
   9878  */
   9879     EXPORT_PC
   9880     movl   rSELF, %eax
   9881     movl   rPC, OUT_ARG0(%esp)
   9882     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9883     movl   rFP, OUT_ARG1(%esp)
   9884     je     1f                                # reload rIBASE & resume if not
   9885     movl   %eax, OUT_ARG2(%esp)
   9886     call   dvmCheckBefore                    # (dPC, dFP, self)
   9887     movl   rSELF, %eax
   9888 1:
   9889     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9890     jmp    *dvmAsmInstructionStart+(57*4)
   9891 
   9892 /* ------------------------------ */
   9893 .L_ALT_OP_IF_LTZ: /* 0x3a */
   9894 /* File: x86/alt_stub.S */
   9895 /*
   9896  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9897  * any interesting requests and then jump to the real instruction
   9898  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9899  * because rIBASE is caller save and we need to reload it.
   9900  *
   9901  * Note that unlike in the Arm implementation, we should never arrive
   9902  * here with a zero breakFlag because we always refresh rIBASE on
   9903  * return.
   9904  */
   9905     EXPORT_PC
   9906     movl   rSELF, %eax
   9907     movl   rPC, OUT_ARG0(%esp)
   9908     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9909     movl   rFP, OUT_ARG1(%esp)
   9910     je     1f                                # reload rIBASE & resume if not
   9911     movl   %eax, OUT_ARG2(%esp)
   9912     call   dvmCheckBefore                    # (dPC, dFP, self)
   9913     movl   rSELF, %eax
   9914 1:
   9915     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9916     jmp    *dvmAsmInstructionStart+(58*4)
   9917 
   9918 /* ------------------------------ */
   9919 .L_ALT_OP_IF_GEZ: /* 0x3b */
   9920 /* File: x86/alt_stub.S */
   9921 /*
   9922  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9923  * any interesting requests and then jump to the real instruction
   9924  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9925  * because rIBASE is caller save and we need to reload it.
   9926  *
   9927  * Note that unlike in the Arm implementation, we should never arrive
   9928  * here with a zero breakFlag because we always refresh rIBASE on
   9929  * return.
   9930  */
   9931     EXPORT_PC
   9932     movl   rSELF, %eax
   9933     movl   rPC, OUT_ARG0(%esp)
   9934     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9935     movl   rFP, OUT_ARG1(%esp)
   9936     je     1f                                # reload rIBASE & resume if not
   9937     movl   %eax, OUT_ARG2(%esp)
   9938     call   dvmCheckBefore                    # (dPC, dFP, self)
   9939     movl   rSELF, %eax
   9940 1:
   9941     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9942     jmp    *dvmAsmInstructionStart+(59*4)
   9943 
   9944 /* ------------------------------ */
   9945 .L_ALT_OP_IF_GTZ: /* 0x3c */
   9946 /* File: x86/alt_stub.S */
   9947 /*
   9948  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9949  * any interesting requests and then jump to the real instruction
   9950  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9951  * because rIBASE is caller save and we need to reload it.
   9952  *
   9953  * Note that unlike in the Arm implementation, we should never arrive
   9954  * here with a zero breakFlag because we always refresh rIBASE on
   9955  * return.
   9956  */
   9957     EXPORT_PC
   9958     movl   rSELF, %eax
   9959     movl   rPC, OUT_ARG0(%esp)
   9960     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9961     movl   rFP, OUT_ARG1(%esp)
   9962     je     1f                                # reload rIBASE & resume if not
   9963     movl   %eax, OUT_ARG2(%esp)
   9964     call   dvmCheckBefore                    # (dPC, dFP, self)
   9965     movl   rSELF, %eax
   9966 1:
   9967     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9968     jmp    *dvmAsmInstructionStart+(60*4)
   9969 
   9970 /* ------------------------------ */
   9971 .L_ALT_OP_IF_LEZ: /* 0x3d */
   9972 /* File: x86/alt_stub.S */
   9973 /*
   9974  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   9975  * any interesting requests and then jump to the real instruction
   9976  * handler.  Unlike the Arm handler, we can't do this as a tail call
   9977  * because rIBASE is caller save and we need to reload it.
   9978  *
   9979  * Note that unlike in the Arm implementation, we should never arrive
   9980  * here with a zero breakFlag because we always refresh rIBASE on
   9981  * return.
   9982  */
   9983     EXPORT_PC
   9984     movl   rSELF, %eax
   9985     movl   rPC, OUT_ARG0(%esp)
   9986     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   9987     movl   rFP, OUT_ARG1(%esp)
   9988     je     1f                                # reload rIBASE & resume if not
   9989     movl   %eax, OUT_ARG2(%esp)
   9990     call   dvmCheckBefore                    # (dPC, dFP, self)
   9991     movl   rSELF, %eax
   9992 1:
   9993     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   9994     jmp    *dvmAsmInstructionStart+(61*4)
   9995 
   9996 /* ------------------------------ */
   9997 .L_ALT_OP_UNUSED_3E: /* 0x3e */
   9998 /* File: x86/alt_stub.S */
   9999 /*
   10000  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10001  * any interesting requests and then jump to the real instruction
   10002  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10003  * because rIBASE is caller save and we need to reload it.
   10004  *
   10005  * Note that unlike in the Arm implementation, we should never arrive
   10006  * here with a zero breakFlag because we always refresh rIBASE on
   10007  * return.
   10008  */
   10009     EXPORT_PC
   10010     movl   rSELF, %eax
   10011     movl   rPC, OUT_ARG0(%esp)
   10012     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10013     movl   rFP, OUT_ARG1(%esp)
   10014     je     1f                                # reload rIBASE & resume if not
   10015     movl   %eax, OUT_ARG2(%esp)
   10016     call   dvmCheckBefore                    # (dPC, dFP, self)
   10017     movl   rSELF, %eax
   10018 1:
   10019     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10020     jmp    *dvmAsmInstructionStart+(62*4)
   10021 
   10022 /* ------------------------------ */
   10023 .L_ALT_OP_UNUSED_3F: /* 0x3f */
   10024 /* File: x86/alt_stub.S */
   10025 /*
   10026  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10027  * any interesting requests and then jump to the real instruction
   10028  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10029  * because rIBASE is caller save and we need to reload it.
   10030  *
   10031  * Note that unlike in the Arm implementation, we should never arrive
   10032  * here with a zero breakFlag because we always refresh rIBASE on
   10033  * return.
   10034  */
   10035     EXPORT_PC
   10036     movl   rSELF, %eax
   10037     movl   rPC, OUT_ARG0(%esp)
   10038     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10039     movl   rFP, OUT_ARG1(%esp)
   10040     je     1f                                # reload rIBASE & resume if not
   10041     movl   %eax, OUT_ARG2(%esp)
   10042     call   dvmCheckBefore                    # (dPC, dFP, self)
   10043     movl   rSELF, %eax
   10044 1:
   10045     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10046     jmp    *dvmAsmInstructionStart+(63*4)
   10047 
   10048 /* ------------------------------ */
   10049 .L_ALT_OP_UNUSED_40: /* 0x40 */
   10050 /* File: x86/alt_stub.S */
   10051 /*
   10052  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10053  * any interesting requests and then jump to the real instruction
   10054  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10055  * because rIBASE is caller save and we need to reload it.
   10056  *
   10057  * Note that unlike in the Arm implementation, we should never arrive
   10058  * here with a zero breakFlag because we always refresh rIBASE on
   10059  * return.
   10060  */
   10061     EXPORT_PC
   10062     movl   rSELF, %eax
   10063     movl   rPC, OUT_ARG0(%esp)
   10064     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10065     movl   rFP, OUT_ARG1(%esp)
   10066     je     1f                                # reload rIBASE & resume if not
   10067     movl   %eax, OUT_ARG2(%esp)
   10068     call   dvmCheckBefore                    # (dPC, dFP, self)
   10069     movl   rSELF, %eax
   10070 1:
   10071     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10072     jmp    *dvmAsmInstructionStart+(64*4)
   10073 
   10074 /* ------------------------------ */
   10075 .L_ALT_OP_UNUSED_41: /* 0x41 */
   10076 /* File: x86/alt_stub.S */
   10077 /*
   10078  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10079  * any interesting requests and then jump to the real instruction
   10080  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10081  * because rIBASE is caller save and we need to reload it.
   10082  *
   10083  * Note that unlike in the Arm implementation, we should never arrive
   10084  * here with a zero breakFlag because we always refresh rIBASE on
   10085  * return.
   10086  */
   10087     EXPORT_PC
   10088     movl   rSELF, %eax
   10089     movl   rPC, OUT_ARG0(%esp)
   10090     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10091     movl   rFP, OUT_ARG1(%esp)
   10092     je     1f                                # reload rIBASE & resume if not
   10093     movl   %eax, OUT_ARG2(%esp)
   10094     call   dvmCheckBefore                    # (dPC, dFP, self)
   10095     movl   rSELF, %eax
   10096 1:
   10097     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10098     jmp    *dvmAsmInstructionStart+(65*4)
   10099 
   10100 /* ------------------------------ */
   10101 .L_ALT_OP_UNUSED_42: /* 0x42 */
   10102 /* File: x86/alt_stub.S */
   10103 /*
   10104  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10105  * any interesting requests and then jump to the real instruction
   10106  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10107  * because rIBASE is caller save and we need to reload it.
   10108  *
   10109  * Note that unlike in the Arm implementation, we should never arrive
   10110  * here with a zero breakFlag because we always refresh rIBASE on
   10111  * return.
   10112  */
   10113     EXPORT_PC
   10114     movl   rSELF, %eax
   10115     movl   rPC, OUT_ARG0(%esp)
   10116     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10117     movl   rFP, OUT_ARG1(%esp)
   10118     je     1f                                # reload rIBASE & resume if not
   10119     movl   %eax, OUT_ARG2(%esp)
   10120     call   dvmCheckBefore                    # (dPC, dFP, self)
   10121     movl   rSELF, %eax
   10122 1:
   10123     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10124     jmp    *dvmAsmInstructionStart+(66*4)
   10125 
   10126 /* ------------------------------ */
   10127 .L_ALT_OP_UNUSED_43: /* 0x43 */
   10128 /* File: x86/alt_stub.S */
   10129 /*
   10130  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10131  * any interesting requests and then jump to the real instruction
   10132  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10133  * because rIBASE is caller save and we need to reload it.
   10134  *
   10135  * Note that unlike in the Arm implementation, we should never arrive
   10136  * here with a zero breakFlag because we always refresh rIBASE on
   10137  * return.
   10138  */
   10139     EXPORT_PC
   10140     movl   rSELF, %eax
   10141     movl   rPC, OUT_ARG0(%esp)
   10142     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10143     movl   rFP, OUT_ARG1(%esp)
   10144     je     1f                                # reload rIBASE & resume if not
   10145     movl   %eax, OUT_ARG2(%esp)
   10146     call   dvmCheckBefore                    # (dPC, dFP, self)
   10147     movl   rSELF, %eax
   10148 1:
   10149     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10150     jmp    *dvmAsmInstructionStart+(67*4)
   10151 
   10152 /* ------------------------------ */
   10153 .L_ALT_OP_AGET: /* 0x44 */
   10154 /* File: x86/alt_stub.S */
   10155 /*
   10156  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10157  * any interesting requests and then jump to the real instruction
   10158  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10159  * because rIBASE is caller save and we need to reload it.
   10160  *
   10161  * Note that unlike in the Arm implementation, we should never arrive
   10162  * here with a zero breakFlag because we always refresh rIBASE on
   10163  * return.
   10164  */
   10165     EXPORT_PC
   10166     movl   rSELF, %eax
   10167     movl   rPC, OUT_ARG0(%esp)
   10168     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10169     movl   rFP, OUT_ARG1(%esp)
   10170     je     1f                                # reload rIBASE & resume if not
   10171     movl   %eax, OUT_ARG2(%esp)
   10172     call   dvmCheckBefore                    # (dPC, dFP, self)
   10173     movl   rSELF, %eax
   10174 1:
   10175     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10176     jmp    *dvmAsmInstructionStart+(68*4)
   10177 
   10178 /* ------------------------------ */
   10179 .L_ALT_OP_AGET_WIDE: /* 0x45 */
   10180 /* File: x86/alt_stub.S */
   10181 /*
   10182  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10183  * any interesting requests and then jump to the real instruction
   10184  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10185  * because rIBASE is caller save and we need to reload it.
   10186  *
   10187  * Note that unlike in the Arm implementation, we should never arrive
   10188  * here with a zero breakFlag because we always refresh rIBASE on
   10189  * return.
   10190  */
   10191     EXPORT_PC
   10192     movl   rSELF, %eax
   10193     movl   rPC, OUT_ARG0(%esp)
   10194     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10195     movl   rFP, OUT_ARG1(%esp)
   10196     je     1f                                # reload rIBASE & resume if not
   10197     movl   %eax, OUT_ARG2(%esp)
   10198     call   dvmCheckBefore                    # (dPC, dFP, self)
   10199     movl   rSELF, %eax
   10200 1:
   10201     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10202     jmp    *dvmAsmInstructionStart+(69*4)
   10203 
   10204 /* ------------------------------ */
   10205 .L_ALT_OP_AGET_OBJECT: /* 0x46 */
   10206 /* File: x86/alt_stub.S */
   10207 /*
   10208  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10209  * any interesting requests and then jump to the real instruction
   10210  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10211  * because rIBASE is caller save and we need to reload it.
   10212  *
   10213  * Note that unlike in the Arm implementation, we should never arrive
   10214  * here with a zero breakFlag because we always refresh rIBASE on
   10215  * return.
   10216  */
   10217     EXPORT_PC
   10218     movl   rSELF, %eax
   10219     movl   rPC, OUT_ARG0(%esp)
   10220     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10221     movl   rFP, OUT_ARG1(%esp)
   10222     je     1f                                # reload rIBASE & resume if not
   10223     movl   %eax, OUT_ARG2(%esp)
   10224     call   dvmCheckBefore                    # (dPC, dFP, self)
   10225     movl   rSELF, %eax
   10226 1:
   10227     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10228     jmp    *dvmAsmInstructionStart+(70*4)
   10229 
   10230 /* ------------------------------ */
   10231 .L_ALT_OP_AGET_BOOLEAN: /* 0x47 */
   10232 /* File: x86/alt_stub.S */
   10233 /*
   10234  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10235  * any interesting requests and then jump to the real instruction
   10236  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10237  * because rIBASE is caller save and we need to reload it.
   10238  *
   10239  * Note that unlike in the Arm implementation, we should never arrive
   10240  * here with a zero breakFlag because we always refresh rIBASE on
   10241  * return.
   10242  */
   10243     EXPORT_PC
   10244     movl   rSELF, %eax
   10245     movl   rPC, OUT_ARG0(%esp)
   10246     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10247     movl   rFP, OUT_ARG1(%esp)
   10248     je     1f                                # reload rIBASE & resume if not
   10249     movl   %eax, OUT_ARG2(%esp)
   10250     call   dvmCheckBefore                    # (dPC, dFP, self)
   10251     movl   rSELF, %eax
   10252 1:
   10253     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10254     jmp    *dvmAsmInstructionStart+(71*4)
   10255 
   10256 /* ------------------------------ */
   10257 .L_ALT_OP_AGET_BYTE: /* 0x48 */
   10258 /* File: x86/alt_stub.S */
   10259 /*
   10260  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10261  * any interesting requests and then jump to the real instruction
   10262  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10263  * because rIBASE is caller save and we need to reload it.
   10264  *
   10265  * Note that unlike in the Arm implementation, we should never arrive
   10266  * here with a zero breakFlag because we always refresh rIBASE on
   10267  * return.
   10268  */
   10269     EXPORT_PC
   10270     movl   rSELF, %eax
   10271     movl   rPC, OUT_ARG0(%esp)
   10272     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10273     movl   rFP, OUT_ARG1(%esp)
   10274     je     1f                                # reload rIBASE & resume if not
   10275     movl   %eax, OUT_ARG2(%esp)
   10276     call   dvmCheckBefore                    # (dPC, dFP, self)
   10277     movl   rSELF, %eax
   10278 1:
   10279     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10280     jmp    *dvmAsmInstructionStart+(72*4)
   10281 
   10282 /* ------------------------------ */
   10283 .L_ALT_OP_AGET_CHAR: /* 0x49 */
   10284 /* File: x86/alt_stub.S */
   10285 /*
   10286  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10287  * any interesting requests and then jump to the real instruction
   10288  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10289  * because rIBASE is caller save and we need to reload it.
   10290  *
   10291  * Note that unlike in the Arm implementation, we should never arrive
   10292  * here with a zero breakFlag because we always refresh rIBASE on
   10293  * return.
   10294  */
   10295     EXPORT_PC
   10296     movl   rSELF, %eax
   10297     movl   rPC, OUT_ARG0(%esp)
   10298     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10299     movl   rFP, OUT_ARG1(%esp)
   10300     je     1f                                # reload rIBASE & resume if not
   10301     movl   %eax, OUT_ARG2(%esp)
   10302     call   dvmCheckBefore                    # (dPC, dFP, self)
   10303     movl   rSELF, %eax
   10304 1:
   10305     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10306     jmp    *dvmAsmInstructionStart+(73*4)
   10307 
   10308 /* ------------------------------ */
   10309 .L_ALT_OP_AGET_SHORT: /* 0x4a */
   10310 /* File: x86/alt_stub.S */
   10311 /*
   10312  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10313  * any interesting requests and then jump to the real instruction
   10314  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10315  * because rIBASE is caller save and we need to reload it.
   10316  *
   10317  * Note that unlike in the Arm implementation, we should never arrive
   10318  * here with a zero breakFlag because we always refresh rIBASE on
   10319  * return.
   10320  */
   10321     EXPORT_PC
   10322     movl   rSELF, %eax
   10323     movl   rPC, OUT_ARG0(%esp)
   10324     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10325     movl   rFP, OUT_ARG1(%esp)
   10326     je     1f                                # reload rIBASE & resume if not
   10327     movl   %eax, OUT_ARG2(%esp)
   10328     call   dvmCheckBefore                    # (dPC, dFP, self)
   10329     movl   rSELF, %eax
   10330 1:
   10331     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10332     jmp    *dvmAsmInstructionStart+(74*4)
   10333 
   10334 /* ------------------------------ */
   10335 .L_ALT_OP_APUT: /* 0x4b */
   10336 /* File: x86/alt_stub.S */
   10337 /*
   10338  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10339  * any interesting requests and then jump to the real instruction
   10340  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10341  * because rIBASE is caller save and we need to reload it.
   10342  *
   10343  * Note that unlike in the Arm implementation, we should never arrive
   10344  * here with a zero breakFlag because we always refresh rIBASE on
   10345  * return.
   10346  */
   10347     EXPORT_PC
   10348     movl   rSELF, %eax
   10349     movl   rPC, OUT_ARG0(%esp)
   10350     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10351     movl   rFP, OUT_ARG1(%esp)
   10352     je     1f                                # reload rIBASE & resume if not
   10353     movl   %eax, OUT_ARG2(%esp)
   10354     call   dvmCheckBefore                    # (dPC, dFP, self)
   10355     movl   rSELF, %eax
   10356 1:
   10357     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10358     jmp    *dvmAsmInstructionStart+(75*4)
   10359 
   10360 /* ------------------------------ */
   10361 .L_ALT_OP_APUT_WIDE: /* 0x4c */
   10362 /* File: x86/alt_stub.S */
   10363 /*
   10364  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10365  * any interesting requests and then jump to the real instruction
   10366  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10367  * because rIBASE is caller save and we need to reload it.
   10368  *
   10369  * Note that unlike in the Arm implementation, we should never arrive
   10370  * here with a zero breakFlag because we always refresh rIBASE on
   10371  * return.
   10372  */
   10373     EXPORT_PC
   10374     movl   rSELF, %eax
   10375     movl   rPC, OUT_ARG0(%esp)
   10376     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10377     movl   rFP, OUT_ARG1(%esp)
   10378     je     1f                                # reload rIBASE & resume if not
   10379     movl   %eax, OUT_ARG2(%esp)
   10380     call   dvmCheckBefore                    # (dPC, dFP, self)
   10381     movl   rSELF, %eax
   10382 1:
   10383     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10384     jmp    *dvmAsmInstructionStart+(76*4)
   10385 
   10386 /* ------------------------------ */
   10387 .L_ALT_OP_APUT_OBJECT: /* 0x4d */
   10388 /* File: x86/alt_stub.S */
   10389 /*
   10390  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10391  * any interesting requests and then jump to the real instruction
   10392  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10393  * because rIBASE is caller save and we need to reload it.
   10394  *
   10395  * Note that unlike in the Arm implementation, we should never arrive
   10396  * here with a zero breakFlag because we always refresh rIBASE on
   10397  * return.
   10398  */
   10399     EXPORT_PC
   10400     movl   rSELF, %eax
   10401     movl   rPC, OUT_ARG0(%esp)
   10402     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10403     movl   rFP, OUT_ARG1(%esp)
   10404     je     1f                                # reload rIBASE & resume if not
   10405     movl   %eax, OUT_ARG2(%esp)
   10406     call   dvmCheckBefore                    # (dPC, dFP, self)
   10407     movl   rSELF, %eax
   10408 1:
   10409     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10410     jmp    *dvmAsmInstructionStart+(77*4)
   10411 
   10412 /* ------------------------------ */
   10413 .L_ALT_OP_APUT_BOOLEAN: /* 0x4e */
   10414 /* File: x86/alt_stub.S */
   10415 /*
   10416  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10417  * any interesting requests and then jump to the real instruction
   10418  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10419  * because rIBASE is caller save and we need to reload it.
   10420  *
   10421  * Note that unlike in the Arm implementation, we should never arrive
   10422  * here with a zero breakFlag because we always refresh rIBASE on
   10423  * return.
   10424  */
   10425     EXPORT_PC
   10426     movl   rSELF, %eax
   10427     movl   rPC, OUT_ARG0(%esp)
   10428     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10429     movl   rFP, OUT_ARG1(%esp)
   10430     je     1f                                # reload rIBASE & resume if not
   10431     movl   %eax, OUT_ARG2(%esp)
   10432     call   dvmCheckBefore                    # (dPC, dFP, self)
   10433     movl   rSELF, %eax
   10434 1:
   10435     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10436     jmp    *dvmAsmInstructionStart+(78*4)
   10437 
   10438 /* ------------------------------ */
   10439 .L_ALT_OP_APUT_BYTE: /* 0x4f */
   10440 /* File: x86/alt_stub.S */
   10441 /*
   10442  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10443  * any interesting requests and then jump to the real instruction
   10444  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10445  * because rIBASE is caller save and we need to reload it.
   10446  *
   10447  * Note that unlike in the Arm implementation, we should never arrive
   10448  * here with a zero breakFlag because we always refresh rIBASE on
   10449  * return.
   10450  */
   10451     EXPORT_PC
   10452     movl   rSELF, %eax
   10453     movl   rPC, OUT_ARG0(%esp)
   10454     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10455     movl   rFP, OUT_ARG1(%esp)
   10456     je     1f                                # reload rIBASE & resume if not
   10457     movl   %eax, OUT_ARG2(%esp)
   10458     call   dvmCheckBefore                    # (dPC, dFP, self)
   10459     movl   rSELF, %eax
   10460 1:
   10461     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10462     jmp    *dvmAsmInstructionStart+(79*4)
   10463 
   10464 /* ------------------------------ */
   10465 .L_ALT_OP_APUT_CHAR: /* 0x50 */
   10466 /* File: x86/alt_stub.S */
   10467 /*
   10468  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10469  * any interesting requests and then jump to the real instruction
   10470  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10471  * because rIBASE is caller save and we need to reload it.
   10472  *
   10473  * Note that unlike in the Arm implementation, we should never arrive
   10474  * here with a zero breakFlag because we always refresh rIBASE on
   10475  * return.
   10476  */
   10477     EXPORT_PC
   10478     movl   rSELF, %eax
   10479     movl   rPC, OUT_ARG0(%esp)
   10480     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10481     movl   rFP, OUT_ARG1(%esp)
   10482     je     1f                                # reload rIBASE & resume if not
   10483     movl   %eax, OUT_ARG2(%esp)
   10484     call   dvmCheckBefore                    # (dPC, dFP, self)
   10485     movl   rSELF, %eax
   10486 1:
   10487     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10488     jmp    *dvmAsmInstructionStart+(80*4)
   10489 
   10490 /* ------------------------------ */
   10491 .L_ALT_OP_APUT_SHORT: /* 0x51 */
   10492 /* File: x86/alt_stub.S */
   10493 /*
   10494  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10495  * any interesting requests and then jump to the real instruction
   10496  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10497  * because rIBASE is caller save and we need to reload it.
   10498  *
   10499  * Note that unlike in the Arm implementation, we should never arrive
   10500  * here with a zero breakFlag because we always refresh rIBASE on
   10501  * return.
   10502  */
   10503     EXPORT_PC
   10504     movl   rSELF, %eax
   10505     movl   rPC, OUT_ARG0(%esp)
   10506     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10507     movl   rFP, OUT_ARG1(%esp)
   10508     je     1f                                # reload rIBASE & resume if not
   10509     movl   %eax, OUT_ARG2(%esp)
   10510     call   dvmCheckBefore                    # (dPC, dFP, self)
   10511     movl   rSELF, %eax
   10512 1:
   10513     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10514     jmp    *dvmAsmInstructionStart+(81*4)
   10515 
   10516 /* ------------------------------ */
   10517 .L_ALT_OP_IGET: /* 0x52 */
   10518 /* File: x86/alt_stub.S */
   10519 /*
   10520  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10521  * any interesting requests and then jump to the real instruction
   10522  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10523  * because rIBASE is caller save and we need to reload it.
   10524  *
   10525  * Note that unlike in the Arm implementation, we should never arrive
   10526  * here with a zero breakFlag because we always refresh rIBASE on
   10527  * return.
   10528  */
   10529     EXPORT_PC
   10530     movl   rSELF, %eax
   10531     movl   rPC, OUT_ARG0(%esp)
   10532     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10533     movl   rFP, OUT_ARG1(%esp)
   10534     je     1f                                # reload rIBASE & resume if not
   10535     movl   %eax, OUT_ARG2(%esp)
   10536     call   dvmCheckBefore                    # (dPC, dFP, self)
   10537     movl   rSELF, %eax
   10538 1:
   10539     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10540     jmp    *dvmAsmInstructionStart+(82*4)
   10541 
   10542 /* ------------------------------ */
   10543 .L_ALT_OP_IGET_WIDE: /* 0x53 */
   10544 /* File: x86/alt_stub.S */
   10545 /*
   10546  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10547  * any interesting requests and then jump to the real instruction
   10548  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10549  * because rIBASE is caller save and we need to reload it.
   10550  *
   10551  * Note that unlike in the Arm implementation, we should never arrive
   10552  * here with a zero breakFlag because we always refresh rIBASE on
   10553  * return.
   10554  */
   10555     EXPORT_PC
   10556     movl   rSELF, %eax
   10557     movl   rPC, OUT_ARG0(%esp)
   10558     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10559     movl   rFP, OUT_ARG1(%esp)
   10560     je     1f                                # reload rIBASE & resume if not
   10561     movl   %eax, OUT_ARG2(%esp)
   10562     call   dvmCheckBefore                    # (dPC, dFP, self)
   10563     movl   rSELF, %eax
   10564 1:
   10565     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10566     jmp    *dvmAsmInstructionStart+(83*4)
   10567 
   10568 /* ------------------------------ */
   10569 .L_ALT_OP_IGET_OBJECT: /* 0x54 */
   10570 /* File: x86/alt_stub.S */
   10571 /*
   10572  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10573  * any interesting requests and then jump to the real instruction
   10574  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10575  * because rIBASE is caller save and we need to reload it.
   10576  *
   10577  * Note that unlike in the Arm implementation, we should never arrive
   10578  * here with a zero breakFlag because we always refresh rIBASE on
   10579  * return.
   10580  */
   10581     EXPORT_PC
   10582     movl   rSELF, %eax
   10583     movl   rPC, OUT_ARG0(%esp)
   10584     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10585     movl   rFP, OUT_ARG1(%esp)
   10586     je     1f                                # reload rIBASE & resume if not
   10587     movl   %eax, OUT_ARG2(%esp)
   10588     call   dvmCheckBefore                    # (dPC, dFP, self)
   10589     movl   rSELF, %eax
   10590 1:
   10591     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10592     jmp    *dvmAsmInstructionStart+(84*4)
   10593 
   10594 /* ------------------------------ */
   10595 .L_ALT_OP_IGET_BOOLEAN: /* 0x55 */
   10596 /* File: x86/alt_stub.S */
   10597 /*
   10598  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10599  * any interesting requests and then jump to the real instruction
   10600  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10601  * because rIBASE is caller save and we need to reload it.
   10602  *
   10603  * Note that unlike in the Arm implementation, we should never arrive
   10604  * here with a zero breakFlag because we always refresh rIBASE on
   10605  * return.
   10606  */
   10607     EXPORT_PC
   10608     movl   rSELF, %eax
   10609     movl   rPC, OUT_ARG0(%esp)
   10610     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10611     movl   rFP, OUT_ARG1(%esp)
   10612     je     1f                                # reload rIBASE & resume if not
   10613     movl   %eax, OUT_ARG2(%esp)
   10614     call   dvmCheckBefore                    # (dPC, dFP, self)
   10615     movl   rSELF, %eax
   10616 1:
   10617     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10618     jmp    *dvmAsmInstructionStart+(85*4)
   10619 
   10620 /* ------------------------------ */
   10621 .L_ALT_OP_IGET_BYTE: /* 0x56 */
   10622 /* File: x86/alt_stub.S */
   10623 /*
   10624  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10625  * any interesting requests and then jump to the real instruction
   10626  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10627  * because rIBASE is caller save and we need to reload it.
   10628  *
   10629  * Note that unlike in the Arm implementation, we should never arrive
   10630  * here with a zero breakFlag because we always refresh rIBASE on
   10631  * return.
   10632  */
   10633     EXPORT_PC
   10634     movl   rSELF, %eax
   10635     movl   rPC, OUT_ARG0(%esp)
   10636     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10637     movl   rFP, OUT_ARG1(%esp)
   10638     je     1f                                # reload rIBASE & resume if not
   10639     movl   %eax, OUT_ARG2(%esp)
   10640     call   dvmCheckBefore                    # (dPC, dFP, self)
   10641     movl   rSELF, %eax
   10642 1:
   10643     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10644     jmp    *dvmAsmInstructionStart+(86*4)
   10645 
   10646 /* ------------------------------ */
   10647 .L_ALT_OP_IGET_CHAR: /* 0x57 */
   10648 /* File: x86/alt_stub.S */
   10649 /*
   10650  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10651  * any interesting requests and then jump to the real instruction
   10652  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10653  * because rIBASE is caller save and we need to reload it.
   10654  *
   10655  * Note that unlike in the Arm implementation, we should never arrive
   10656  * here with a zero breakFlag because we always refresh rIBASE on
   10657  * return.
   10658  */
   10659     EXPORT_PC
   10660     movl   rSELF, %eax
   10661     movl   rPC, OUT_ARG0(%esp)
   10662     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10663     movl   rFP, OUT_ARG1(%esp)
   10664     je     1f                                # reload rIBASE & resume if not
   10665     movl   %eax, OUT_ARG2(%esp)
   10666     call   dvmCheckBefore                    # (dPC, dFP, self)
   10667     movl   rSELF, %eax
   10668 1:
   10669     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10670     jmp    *dvmAsmInstructionStart+(87*4)
   10671 
   10672 /* ------------------------------ */
   10673 .L_ALT_OP_IGET_SHORT: /* 0x58 */
   10674 /* File: x86/alt_stub.S */
   10675 /*
   10676  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10677  * any interesting requests and then jump to the real instruction
   10678  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10679  * because rIBASE is caller save and we need to reload it.
   10680  *
   10681  * Note that unlike in the Arm implementation, we should never arrive
   10682  * here with a zero breakFlag because we always refresh rIBASE on
   10683  * return.
   10684  */
   10685     EXPORT_PC
   10686     movl   rSELF, %eax
   10687     movl   rPC, OUT_ARG0(%esp)
   10688     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10689     movl   rFP, OUT_ARG1(%esp)
   10690     je     1f                                # reload rIBASE & resume if not
   10691     movl   %eax, OUT_ARG2(%esp)
   10692     call   dvmCheckBefore                    # (dPC, dFP, self)
   10693     movl   rSELF, %eax
   10694 1:
   10695     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10696     jmp    *dvmAsmInstructionStart+(88*4)
   10697 
   10698 /* ------------------------------ */
   10699 .L_ALT_OP_IPUT: /* 0x59 */
   10700 /* File: x86/alt_stub.S */
   10701 /*
   10702  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10703  * any interesting requests and then jump to the real instruction
   10704  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10705  * because rIBASE is caller save and we need to reload it.
   10706  *
   10707  * Note that unlike in the Arm implementation, we should never arrive
   10708  * here with a zero breakFlag because we always refresh rIBASE on
   10709  * return.
   10710  */
   10711     EXPORT_PC
   10712     movl   rSELF, %eax
   10713     movl   rPC, OUT_ARG0(%esp)
   10714     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10715     movl   rFP, OUT_ARG1(%esp)
   10716     je     1f                                # reload rIBASE & resume if not
   10717     movl   %eax, OUT_ARG2(%esp)
   10718     call   dvmCheckBefore                    # (dPC, dFP, self)
   10719     movl   rSELF, %eax
   10720 1:
   10721     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10722     jmp    *dvmAsmInstructionStart+(89*4)
   10723 
   10724 /* ------------------------------ */
   10725 .L_ALT_OP_IPUT_WIDE: /* 0x5a */
   10726 /* File: x86/alt_stub.S */
   10727 /*
   10728  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10729  * any interesting requests and then jump to the real instruction
   10730  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10731  * because rIBASE is caller save and we need to reload it.
   10732  *
   10733  * Note that unlike in the Arm implementation, we should never arrive
   10734  * here with a zero breakFlag because we always refresh rIBASE on
   10735  * return.
   10736  */
   10737     EXPORT_PC
   10738     movl   rSELF, %eax
   10739     movl   rPC, OUT_ARG0(%esp)
   10740     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10741     movl   rFP, OUT_ARG1(%esp)
   10742     je     1f                                # reload rIBASE & resume if not
   10743     movl   %eax, OUT_ARG2(%esp)
   10744     call   dvmCheckBefore                    # (dPC, dFP, self)
   10745     movl   rSELF, %eax
   10746 1:
   10747     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10748     jmp    *dvmAsmInstructionStart+(90*4)
   10749 
   10750 /* ------------------------------ */
   10751 .L_ALT_OP_IPUT_OBJECT: /* 0x5b */
   10752 /* File: x86/alt_stub.S */
   10753 /*
   10754  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10755  * any interesting requests and then jump to the real instruction
   10756  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10757  * because rIBASE is caller save and we need to reload it.
   10758  *
   10759  * Note that unlike in the Arm implementation, we should never arrive
   10760  * here with a zero breakFlag because we always refresh rIBASE on
   10761  * return.
   10762  */
   10763     EXPORT_PC
   10764     movl   rSELF, %eax
   10765     movl   rPC, OUT_ARG0(%esp)
   10766     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10767     movl   rFP, OUT_ARG1(%esp)
   10768     je     1f                                # reload rIBASE & resume if not
   10769     movl   %eax, OUT_ARG2(%esp)
   10770     call   dvmCheckBefore                    # (dPC, dFP, self)
   10771     movl   rSELF, %eax
   10772 1:
   10773     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10774     jmp    *dvmAsmInstructionStart+(91*4)
   10775 
   10776 /* ------------------------------ */
   10777 .L_ALT_OP_IPUT_BOOLEAN: /* 0x5c */
   10778 /* File: x86/alt_stub.S */
   10779 /*
   10780  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10781  * any interesting requests and then jump to the real instruction
   10782  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10783  * because rIBASE is caller save and we need to reload it.
   10784  *
   10785  * Note that unlike in the Arm implementation, we should never arrive
   10786  * here with a zero breakFlag because we always refresh rIBASE on
   10787  * return.
   10788  */
   10789     EXPORT_PC
   10790     movl   rSELF, %eax
   10791     movl   rPC, OUT_ARG0(%esp)
   10792     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10793     movl   rFP, OUT_ARG1(%esp)
   10794     je     1f                                # reload rIBASE & resume if not
   10795     movl   %eax, OUT_ARG2(%esp)
   10796     call   dvmCheckBefore                    # (dPC, dFP, self)
   10797     movl   rSELF, %eax
   10798 1:
   10799     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10800     jmp    *dvmAsmInstructionStart+(92*4)
   10801 
   10802 /* ------------------------------ */
   10803 .L_ALT_OP_IPUT_BYTE: /* 0x5d */
   10804 /* File: x86/alt_stub.S */
   10805 /*
   10806  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10807  * any interesting requests and then jump to the real instruction
   10808  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10809  * because rIBASE is caller save and we need to reload it.
   10810  *
   10811  * Note that unlike in the Arm implementation, we should never arrive
   10812  * here with a zero breakFlag because we always refresh rIBASE on
   10813  * return.
   10814  */
   10815     EXPORT_PC
   10816     movl   rSELF, %eax
   10817     movl   rPC, OUT_ARG0(%esp)
   10818     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10819     movl   rFP, OUT_ARG1(%esp)
   10820     je     1f                                # reload rIBASE & resume if not
   10821     movl   %eax, OUT_ARG2(%esp)
   10822     call   dvmCheckBefore                    # (dPC, dFP, self)
   10823     movl   rSELF, %eax
   10824 1:
   10825     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10826     jmp    *dvmAsmInstructionStart+(93*4)
   10827 
   10828 /* ------------------------------ */
   10829 .L_ALT_OP_IPUT_CHAR: /* 0x5e */
   10830 /* File: x86/alt_stub.S */
   10831 /*
   10832  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10833  * any interesting requests and then jump to the real instruction
   10834  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10835  * because rIBASE is caller save and we need to reload it.
   10836  *
   10837  * Note that unlike in the Arm implementation, we should never arrive
   10838  * here with a zero breakFlag because we always refresh rIBASE on
   10839  * return.
   10840  */
   10841     EXPORT_PC
   10842     movl   rSELF, %eax
   10843     movl   rPC, OUT_ARG0(%esp)
   10844     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10845     movl   rFP, OUT_ARG1(%esp)
   10846     je     1f                                # reload rIBASE & resume if not
   10847     movl   %eax, OUT_ARG2(%esp)
   10848     call   dvmCheckBefore                    # (dPC, dFP, self)
   10849     movl   rSELF, %eax
   10850 1:
   10851     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10852     jmp    *dvmAsmInstructionStart+(94*4)
   10853 
   10854 /* ------------------------------ */
   10855 .L_ALT_OP_IPUT_SHORT: /* 0x5f */
   10856 /* File: x86/alt_stub.S */
   10857 /*
   10858  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10859  * any interesting requests and then jump to the real instruction
   10860  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10861  * because rIBASE is caller save and we need to reload it.
   10862  *
   10863  * Note that unlike in the Arm implementation, we should never arrive
   10864  * here with a zero breakFlag because we always refresh rIBASE on
   10865  * return.
   10866  */
   10867     EXPORT_PC
   10868     movl   rSELF, %eax
   10869     movl   rPC, OUT_ARG0(%esp)
   10870     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10871     movl   rFP, OUT_ARG1(%esp)
   10872     je     1f                                # reload rIBASE & resume if not
   10873     movl   %eax, OUT_ARG2(%esp)
   10874     call   dvmCheckBefore                    # (dPC, dFP, self)
   10875     movl   rSELF, %eax
   10876 1:
   10877     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10878     jmp    *dvmAsmInstructionStart+(95*4)
   10879 
   10880 /* ------------------------------ */
   10881 .L_ALT_OP_SGET: /* 0x60 */
   10882 /* File: x86/alt_stub.S */
   10883 /*
   10884  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10885  * any interesting requests and then jump to the real instruction
   10886  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10887  * because rIBASE is caller save and we need to reload it.
   10888  *
   10889  * Note that unlike in the Arm implementation, we should never arrive
   10890  * here with a zero breakFlag because we always refresh rIBASE on
   10891  * return.
   10892  */
   10893     EXPORT_PC
   10894     movl   rSELF, %eax
   10895     movl   rPC, OUT_ARG0(%esp)
   10896     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10897     movl   rFP, OUT_ARG1(%esp)
   10898     je     1f                                # reload rIBASE & resume if not
   10899     movl   %eax, OUT_ARG2(%esp)
   10900     call   dvmCheckBefore                    # (dPC, dFP, self)
   10901     movl   rSELF, %eax
   10902 1:
   10903     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10904     jmp    *dvmAsmInstructionStart+(96*4)
   10905 
   10906 /* ------------------------------ */
   10907 .L_ALT_OP_SGET_WIDE: /* 0x61 */
   10908 /* File: x86/alt_stub.S */
   10909 /*
   10910  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10911  * any interesting requests and then jump to the real instruction
   10912  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10913  * because rIBASE is caller save and we need to reload it.
   10914  *
   10915  * Note that unlike in the Arm implementation, we should never arrive
   10916  * here with a zero breakFlag because we always refresh rIBASE on
   10917  * return.
   10918  */
   10919     EXPORT_PC
   10920     movl   rSELF, %eax
   10921     movl   rPC, OUT_ARG0(%esp)
   10922     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10923     movl   rFP, OUT_ARG1(%esp)
   10924     je     1f                                # reload rIBASE & resume if not
   10925     movl   %eax, OUT_ARG2(%esp)
   10926     call   dvmCheckBefore                    # (dPC, dFP, self)
   10927     movl   rSELF, %eax
   10928 1:
   10929     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10930     jmp    *dvmAsmInstructionStart+(97*4)
   10931 
   10932 /* ------------------------------ */
   10933 .L_ALT_OP_SGET_OBJECT: /* 0x62 */
   10934 /* File: x86/alt_stub.S */
   10935 /*
   10936  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10937  * any interesting requests and then jump to the real instruction
   10938  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10939  * because rIBASE is caller save and we need to reload it.
   10940  *
   10941  * Note that unlike in the Arm implementation, we should never arrive
   10942  * here with a zero breakFlag because we always refresh rIBASE on
   10943  * return.
   10944  */
   10945     EXPORT_PC
   10946     movl   rSELF, %eax
   10947     movl   rPC, OUT_ARG0(%esp)
   10948     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10949     movl   rFP, OUT_ARG1(%esp)
   10950     je     1f                                # reload rIBASE & resume if not
   10951     movl   %eax, OUT_ARG2(%esp)
   10952     call   dvmCheckBefore                    # (dPC, dFP, self)
   10953     movl   rSELF, %eax
   10954 1:
   10955     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10956     jmp    *dvmAsmInstructionStart+(98*4)
   10957 
   10958 /* ------------------------------ */
   10959 .L_ALT_OP_SGET_BOOLEAN: /* 0x63 */
   10960 /* File: x86/alt_stub.S */
   10961 /*
   10962  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10963  * any interesting requests and then jump to the real instruction
   10964  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10965  * because rIBASE is caller save and we need to reload it.
   10966  *
   10967  * Note that unlike in the Arm implementation, we should never arrive
   10968  * here with a zero breakFlag because we always refresh rIBASE on
   10969  * return.
   10970  */
   10971     EXPORT_PC
   10972     movl   rSELF, %eax
   10973     movl   rPC, OUT_ARG0(%esp)
   10974     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   10975     movl   rFP, OUT_ARG1(%esp)
   10976     je     1f                                # reload rIBASE & resume if not
   10977     movl   %eax, OUT_ARG2(%esp)
   10978     call   dvmCheckBefore                    # (dPC, dFP, self)
   10979     movl   rSELF, %eax
   10980 1:
   10981     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   10982     jmp    *dvmAsmInstructionStart+(99*4)
   10983 
   10984 /* ------------------------------ */
   10985 .L_ALT_OP_SGET_BYTE: /* 0x64 */
   10986 /* File: x86/alt_stub.S */
   10987 /*
   10988  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   10989  * any interesting requests and then jump to the real instruction
   10990  * handler.  Unlike the Arm handler, we can't do this as a tail call
   10991  * because rIBASE is caller save and we need to reload it.
   10992  *
   10993  * Note that unlike in the Arm implementation, we should never arrive
   10994  * here with a zero breakFlag because we always refresh rIBASE on
   10995  * return.
   10996  */
   10997     EXPORT_PC
   10998     movl   rSELF, %eax
   10999     movl   rPC, OUT_ARG0(%esp)
   11000     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11001     movl   rFP, OUT_ARG1(%esp)
   11002     je     1f                                # reload rIBASE & resume if not
   11003     movl   %eax, OUT_ARG2(%esp)
   11004     call   dvmCheckBefore                    # (dPC, dFP, self)
   11005     movl   rSELF, %eax
   11006 1:
   11007     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11008     jmp    *dvmAsmInstructionStart+(100*4)
   11009 
   11010 /* ------------------------------ */
   11011 .L_ALT_OP_SGET_CHAR: /* 0x65 */
   11012 /* File: x86/alt_stub.S */
   11013 /*
   11014  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11015  * any interesting requests and then jump to the real instruction
   11016  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11017  * because rIBASE is caller save and we need to reload it.
   11018  *
   11019  * Note that unlike in the Arm implementation, we should never arrive
   11020  * here with a zero breakFlag because we always refresh rIBASE on
   11021  * return.
   11022  */
   11023     EXPORT_PC
   11024     movl   rSELF, %eax
   11025     movl   rPC, OUT_ARG0(%esp)
   11026     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11027     movl   rFP, OUT_ARG1(%esp)
   11028     je     1f                                # reload rIBASE & resume if not
   11029     movl   %eax, OUT_ARG2(%esp)
   11030     call   dvmCheckBefore                    # (dPC, dFP, self)
   11031     movl   rSELF, %eax
   11032 1:
   11033     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11034     jmp    *dvmAsmInstructionStart+(101*4)
   11035 
   11036 /* ------------------------------ */
   11037 .L_ALT_OP_SGET_SHORT: /* 0x66 */
   11038 /* File: x86/alt_stub.S */
   11039 /*
   11040  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11041  * any interesting requests and then jump to the real instruction
   11042  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11043  * because rIBASE is caller save and we need to reload it.
   11044  *
   11045  * Note that unlike in the Arm implementation, we should never arrive
   11046  * here with a zero breakFlag because we always refresh rIBASE on
   11047  * return.
   11048  */
   11049     EXPORT_PC
   11050     movl   rSELF, %eax
   11051     movl   rPC, OUT_ARG0(%esp)
   11052     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11053     movl   rFP, OUT_ARG1(%esp)
   11054     je     1f                                # reload rIBASE & resume if not
   11055     movl   %eax, OUT_ARG2(%esp)
   11056     call   dvmCheckBefore                    # (dPC, dFP, self)
   11057     movl   rSELF, %eax
   11058 1:
   11059     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11060     jmp    *dvmAsmInstructionStart+(102*4)
   11061 
   11062 /* ------------------------------ */
   11063 .L_ALT_OP_SPUT: /* 0x67 */
   11064 /* File: x86/alt_stub.S */
   11065 /*
   11066  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11067  * any interesting requests and then jump to the real instruction
   11068  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11069  * because rIBASE is caller save and we need to reload it.
   11070  *
   11071  * Note that unlike in the Arm implementation, we should never arrive
   11072  * here with a zero breakFlag because we always refresh rIBASE on
   11073  * return.
   11074  */
   11075     EXPORT_PC
   11076     movl   rSELF, %eax
   11077     movl   rPC, OUT_ARG0(%esp)
   11078     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11079     movl   rFP, OUT_ARG1(%esp)
   11080     je     1f                                # reload rIBASE & resume if not
   11081     movl   %eax, OUT_ARG2(%esp)
   11082     call   dvmCheckBefore                    # (dPC, dFP, self)
   11083     movl   rSELF, %eax
   11084 1:
   11085     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11086     jmp    *dvmAsmInstructionStart+(103*4)
   11087 
   11088 /* ------------------------------ */
   11089 .L_ALT_OP_SPUT_WIDE: /* 0x68 */
   11090 /* File: x86/alt_stub.S */
   11091 /*
   11092  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11093  * any interesting requests and then jump to the real instruction
   11094  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11095  * because rIBASE is caller save and we need to reload it.
   11096  *
   11097  * Note that unlike in the Arm implementation, we should never arrive
   11098  * here with a zero breakFlag because we always refresh rIBASE on
   11099  * return.
   11100  */
   11101     EXPORT_PC
   11102     movl   rSELF, %eax
   11103     movl   rPC, OUT_ARG0(%esp)
   11104     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11105     movl   rFP, OUT_ARG1(%esp)
   11106     je     1f                                # reload rIBASE & resume if not
   11107     movl   %eax, OUT_ARG2(%esp)
   11108     call   dvmCheckBefore                    # (dPC, dFP, self)
   11109     movl   rSELF, %eax
   11110 1:
   11111     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11112     jmp    *dvmAsmInstructionStart+(104*4)
   11113 
   11114 /* ------------------------------ */
   11115 .L_ALT_OP_SPUT_OBJECT: /* 0x69 */
   11116 /* File: x86/alt_stub.S */
   11117 /*
   11118  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11119  * any interesting requests and then jump to the real instruction
   11120  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11121  * because rIBASE is caller save and we need to reload it.
   11122  *
   11123  * Note that unlike in the Arm implementation, we should never arrive
   11124  * here with a zero breakFlag because we always refresh rIBASE on
   11125  * return.
   11126  */
   11127     EXPORT_PC
   11128     movl   rSELF, %eax
   11129     movl   rPC, OUT_ARG0(%esp)
   11130     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11131     movl   rFP, OUT_ARG1(%esp)
   11132     je     1f                                # reload rIBASE & resume if not
   11133     movl   %eax, OUT_ARG2(%esp)
   11134     call   dvmCheckBefore                    # (dPC, dFP, self)
   11135     movl   rSELF, %eax
   11136 1:
   11137     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11138     jmp    *dvmAsmInstructionStart+(105*4)
   11139 
   11140 /* ------------------------------ */
   11141 .L_ALT_OP_SPUT_BOOLEAN: /* 0x6a */
   11142 /* File: x86/alt_stub.S */
   11143 /*
   11144  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11145  * any interesting requests and then jump to the real instruction
   11146  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11147  * because rIBASE is caller save and we need to reload it.
   11148  *
   11149  * Note that unlike in the Arm implementation, we should never arrive
   11150  * here with a zero breakFlag because we always refresh rIBASE on
   11151  * return.
   11152  */
   11153     EXPORT_PC
   11154     movl   rSELF, %eax
   11155     movl   rPC, OUT_ARG0(%esp)
   11156     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11157     movl   rFP, OUT_ARG1(%esp)
   11158     je     1f                                # reload rIBASE & resume if not
   11159     movl   %eax, OUT_ARG2(%esp)
   11160     call   dvmCheckBefore                    # (dPC, dFP, self)
   11161     movl   rSELF, %eax
   11162 1:
   11163     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11164     jmp    *dvmAsmInstructionStart+(106*4)
   11165 
   11166 /* ------------------------------ */
   11167 .L_ALT_OP_SPUT_BYTE: /* 0x6b */
   11168 /* File: x86/alt_stub.S */
   11169 /*
   11170  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11171  * any interesting requests and then jump to the real instruction
   11172  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11173  * because rIBASE is caller save and we need to reload it.
   11174  *
   11175  * Note that unlike in the Arm implementation, we should never arrive
   11176  * here with a zero breakFlag because we always refresh rIBASE on
   11177  * return.
   11178  */
   11179     EXPORT_PC
   11180     movl   rSELF, %eax
   11181     movl   rPC, OUT_ARG0(%esp)
   11182     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11183     movl   rFP, OUT_ARG1(%esp)
   11184     je     1f                                # reload rIBASE & resume if not
   11185     movl   %eax, OUT_ARG2(%esp)
   11186     call   dvmCheckBefore                    # (dPC, dFP, self)
   11187     movl   rSELF, %eax
   11188 1:
   11189     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11190     jmp    *dvmAsmInstructionStart+(107*4)
   11191 
   11192 /* ------------------------------ */
   11193 .L_ALT_OP_SPUT_CHAR: /* 0x6c */
   11194 /* File: x86/alt_stub.S */
   11195 /*
   11196  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11197  * any interesting requests and then jump to the real instruction
   11198  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11199  * because rIBASE is caller save and we need to reload it.
   11200  *
   11201  * Note that unlike in the Arm implementation, we should never arrive
   11202  * here with a zero breakFlag because we always refresh rIBASE on
   11203  * return.
   11204  */
   11205     EXPORT_PC
   11206     movl   rSELF, %eax
   11207     movl   rPC, OUT_ARG0(%esp)
   11208     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11209     movl   rFP, OUT_ARG1(%esp)
   11210     je     1f                                # reload rIBASE & resume if not
   11211     movl   %eax, OUT_ARG2(%esp)
   11212     call   dvmCheckBefore                    # (dPC, dFP, self)
   11213     movl   rSELF, %eax
   11214 1:
   11215     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11216     jmp    *dvmAsmInstructionStart+(108*4)
   11217 
   11218 /* ------------------------------ */
   11219 .L_ALT_OP_SPUT_SHORT: /* 0x6d */
   11220 /* File: x86/alt_stub.S */
   11221 /*
   11222  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11223  * any interesting requests and then jump to the real instruction
   11224  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11225  * because rIBASE is caller save and we need to reload it.
   11226  *
   11227  * Note that unlike in the Arm implementation, we should never arrive
   11228  * here with a zero breakFlag because we always refresh rIBASE on
   11229  * return.
   11230  */
   11231     EXPORT_PC
   11232     movl   rSELF, %eax
   11233     movl   rPC, OUT_ARG0(%esp)
   11234     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11235     movl   rFP, OUT_ARG1(%esp)
   11236     je     1f                                # reload rIBASE & resume if not
   11237     movl   %eax, OUT_ARG2(%esp)
   11238     call   dvmCheckBefore                    # (dPC, dFP, self)
   11239     movl   rSELF, %eax
   11240 1:
   11241     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11242     jmp    *dvmAsmInstructionStart+(109*4)
   11243 
   11244 /* ------------------------------ */
   11245 .L_ALT_OP_INVOKE_VIRTUAL: /* 0x6e */
   11246 /* File: x86/alt_stub.S */
   11247 /*
   11248  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11249  * any interesting requests and then jump to the real instruction
   11250  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11251  * because rIBASE is caller save and we need to reload it.
   11252  *
   11253  * Note that unlike in the Arm implementation, we should never arrive
   11254  * here with a zero breakFlag because we always refresh rIBASE on
   11255  * return.
   11256  */
   11257     EXPORT_PC
   11258     movl   rSELF, %eax
   11259     movl   rPC, OUT_ARG0(%esp)
   11260     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11261     movl   rFP, OUT_ARG1(%esp)
   11262     je     1f                                # reload rIBASE & resume if not
   11263     movl   %eax, OUT_ARG2(%esp)
   11264     call   dvmCheckBefore                    # (dPC, dFP, self)
   11265     movl   rSELF, %eax
   11266 1:
   11267     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11268     jmp    *dvmAsmInstructionStart+(110*4)
   11269 
   11270 /* ------------------------------ */
   11271 .L_ALT_OP_INVOKE_SUPER: /* 0x6f */
   11272 /* File: x86/alt_stub.S */
   11273 /*
   11274  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11275  * any interesting requests and then jump to the real instruction
   11276  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11277  * because rIBASE is caller save and we need to reload it.
   11278  *
   11279  * Note that unlike in the Arm implementation, we should never arrive
   11280  * here with a zero breakFlag because we always refresh rIBASE on
   11281  * return.
   11282  */
   11283     EXPORT_PC
   11284     movl   rSELF, %eax
   11285     movl   rPC, OUT_ARG0(%esp)
   11286     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11287     movl   rFP, OUT_ARG1(%esp)
   11288     je     1f                                # reload rIBASE & resume if not
   11289     movl   %eax, OUT_ARG2(%esp)
   11290     call   dvmCheckBefore                    # (dPC, dFP, self)
   11291     movl   rSELF, %eax
   11292 1:
   11293     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11294     jmp    *dvmAsmInstructionStart+(111*4)
   11295 
   11296 /* ------------------------------ */
   11297 .L_ALT_OP_INVOKE_DIRECT: /* 0x70 */
   11298 /* File: x86/alt_stub.S */
   11299 /*
   11300  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11301  * any interesting requests and then jump to the real instruction
   11302  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11303  * because rIBASE is caller save and we need to reload it.
   11304  *
   11305  * Note that unlike in the Arm implementation, we should never arrive
   11306  * here with a zero breakFlag because we always refresh rIBASE on
   11307  * return.
   11308  */
   11309     EXPORT_PC
   11310     movl   rSELF, %eax
   11311     movl   rPC, OUT_ARG0(%esp)
   11312     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11313     movl   rFP, OUT_ARG1(%esp)
   11314     je     1f                                # reload rIBASE & resume if not
   11315     movl   %eax, OUT_ARG2(%esp)
   11316     call   dvmCheckBefore                    # (dPC, dFP, self)
   11317     movl   rSELF, %eax
   11318 1:
   11319     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11320     jmp    *dvmAsmInstructionStart+(112*4)
   11321 
   11322 /* ------------------------------ */
   11323 .L_ALT_OP_INVOKE_STATIC: /* 0x71 */
   11324 /* File: x86/alt_stub.S */
   11325 /*
   11326  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11327  * any interesting requests and then jump to the real instruction
   11328  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11329  * because rIBASE is caller save and we need to reload it.
   11330  *
   11331  * Note that unlike in the Arm implementation, we should never arrive
   11332  * here with a zero breakFlag because we always refresh rIBASE on
   11333  * return.
   11334  */
   11335     EXPORT_PC
   11336     movl   rSELF, %eax
   11337     movl   rPC, OUT_ARG0(%esp)
   11338     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11339     movl   rFP, OUT_ARG1(%esp)
   11340     je     1f                                # reload rIBASE & resume if not
   11341     movl   %eax, OUT_ARG2(%esp)
   11342     call   dvmCheckBefore                    # (dPC, dFP, self)
   11343     movl   rSELF, %eax
   11344 1:
   11345     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11346     jmp    *dvmAsmInstructionStart+(113*4)
   11347 
   11348 /* ------------------------------ */
   11349 .L_ALT_OP_INVOKE_INTERFACE: /* 0x72 */
   11350 /* File: x86/alt_stub.S */
   11351 /*
   11352  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11353  * any interesting requests and then jump to the real instruction
   11354  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11355  * because rIBASE is caller save and we need to reload it.
   11356  *
   11357  * Note that unlike in the Arm implementation, we should never arrive
   11358  * here with a zero breakFlag because we always refresh rIBASE on
   11359  * return.
   11360  */
   11361     EXPORT_PC
   11362     movl   rSELF, %eax
   11363     movl   rPC, OUT_ARG0(%esp)
   11364     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11365     movl   rFP, OUT_ARG1(%esp)
   11366     je     1f                                # reload rIBASE & resume if not
   11367     movl   %eax, OUT_ARG2(%esp)
   11368     call   dvmCheckBefore                    # (dPC, dFP, self)
   11369     movl   rSELF, %eax
   11370 1:
   11371     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11372     jmp    *dvmAsmInstructionStart+(114*4)
   11373 
   11374 /* ------------------------------ */
   11375 .L_ALT_OP_UNUSED_73: /* 0x73 */
   11376 /* File: x86/alt_stub.S */
   11377 /*
   11378  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11379  * any interesting requests and then jump to the real instruction
   11380  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11381  * because rIBASE is caller save and we need to reload it.
   11382  *
   11383  * Note that unlike in the Arm implementation, we should never arrive
   11384  * here with a zero breakFlag because we always refresh rIBASE on
   11385  * return.
   11386  */
   11387     EXPORT_PC
   11388     movl   rSELF, %eax
   11389     movl   rPC, OUT_ARG0(%esp)
   11390     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11391     movl   rFP, OUT_ARG1(%esp)
   11392     je     1f                                # reload rIBASE & resume if not
   11393     movl   %eax, OUT_ARG2(%esp)
   11394     call   dvmCheckBefore                    # (dPC, dFP, self)
   11395     movl   rSELF, %eax
   11396 1:
   11397     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11398     jmp    *dvmAsmInstructionStart+(115*4)
   11399 
   11400 /* ------------------------------ */
   11401 .L_ALT_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
   11402 /* File: x86/alt_stub.S */
   11403 /*
   11404  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11405  * any interesting requests and then jump to the real instruction
   11406  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11407  * because rIBASE is caller save and we need to reload it.
   11408  *
   11409  * Note that unlike in the Arm implementation, we should never arrive
   11410  * here with a zero breakFlag because we always refresh rIBASE on
   11411  * return.
   11412  */
   11413     EXPORT_PC
   11414     movl   rSELF, %eax
   11415     movl   rPC, OUT_ARG0(%esp)
   11416     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11417     movl   rFP, OUT_ARG1(%esp)
   11418     je     1f                                # reload rIBASE & resume if not
   11419     movl   %eax, OUT_ARG2(%esp)
   11420     call   dvmCheckBefore                    # (dPC, dFP, self)
   11421     movl   rSELF, %eax
   11422 1:
   11423     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11424     jmp    *dvmAsmInstructionStart+(116*4)
   11425 
   11426 /* ------------------------------ */
   11427 .L_ALT_OP_INVOKE_SUPER_RANGE: /* 0x75 */
   11428 /* File: x86/alt_stub.S */
   11429 /*
   11430  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11431  * any interesting requests and then jump to the real instruction
   11432  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11433  * because rIBASE is caller save and we need to reload it.
   11434  *
   11435  * Note that unlike in the Arm implementation, we should never arrive
   11436  * here with a zero breakFlag because we always refresh rIBASE on
   11437  * return.
   11438  */
   11439     EXPORT_PC
   11440     movl   rSELF, %eax
   11441     movl   rPC, OUT_ARG0(%esp)
   11442     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11443     movl   rFP, OUT_ARG1(%esp)
   11444     je     1f                                # reload rIBASE & resume if not
   11445     movl   %eax, OUT_ARG2(%esp)
   11446     call   dvmCheckBefore                    # (dPC, dFP, self)
   11447     movl   rSELF, %eax
   11448 1:
   11449     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11450     jmp    *dvmAsmInstructionStart+(117*4)
   11451 
   11452 /* ------------------------------ */
   11453 .L_ALT_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
   11454 /* File: x86/alt_stub.S */
   11455 /*
   11456  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11457  * any interesting requests and then jump to the real instruction
   11458  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11459  * because rIBASE is caller save and we need to reload it.
   11460  *
   11461  * Note that unlike in the Arm implementation, we should never arrive
   11462  * here with a zero breakFlag because we always refresh rIBASE on
   11463  * return.
   11464  */
   11465     EXPORT_PC
   11466     movl   rSELF, %eax
   11467     movl   rPC, OUT_ARG0(%esp)
   11468     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11469     movl   rFP, OUT_ARG1(%esp)
   11470     je     1f                                # reload rIBASE & resume if not
   11471     movl   %eax, OUT_ARG2(%esp)
   11472     call   dvmCheckBefore                    # (dPC, dFP, self)
   11473     movl   rSELF, %eax
   11474 1:
   11475     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11476     jmp    *dvmAsmInstructionStart+(118*4)
   11477 
   11478 /* ------------------------------ */
   11479 .L_ALT_OP_INVOKE_STATIC_RANGE: /* 0x77 */
   11480 /* File: x86/alt_stub.S */
   11481 /*
   11482  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11483  * any interesting requests and then jump to the real instruction
   11484  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11485  * because rIBASE is caller save and we need to reload it.
   11486  *
   11487  * Note that unlike in the Arm implementation, we should never arrive
   11488  * here with a zero breakFlag because we always refresh rIBASE on
   11489  * return.
   11490  */
   11491     EXPORT_PC
   11492     movl   rSELF, %eax
   11493     movl   rPC, OUT_ARG0(%esp)
   11494     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11495     movl   rFP, OUT_ARG1(%esp)
   11496     je     1f                                # reload rIBASE & resume if not
   11497     movl   %eax, OUT_ARG2(%esp)
   11498     call   dvmCheckBefore                    # (dPC, dFP, self)
   11499     movl   rSELF, %eax
   11500 1:
   11501     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11502     jmp    *dvmAsmInstructionStart+(119*4)
   11503 
   11504 /* ------------------------------ */
   11505 .L_ALT_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
   11506 /* File: x86/alt_stub.S */
   11507 /*
   11508  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11509  * any interesting requests and then jump to the real instruction
   11510  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11511  * because rIBASE is caller save and we need to reload it.
   11512  *
   11513  * Note that unlike in the Arm implementation, we should never arrive
   11514  * here with a zero breakFlag because we always refresh rIBASE on
   11515  * return.
   11516  */
   11517     EXPORT_PC
   11518     movl   rSELF, %eax
   11519     movl   rPC, OUT_ARG0(%esp)
   11520     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11521     movl   rFP, OUT_ARG1(%esp)
   11522     je     1f                                # reload rIBASE & resume if not
   11523     movl   %eax, OUT_ARG2(%esp)
   11524     call   dvmCheckBefore                    # (dPC, dFP, self)
   11525     movl   rSELF, %eax
   11526 1:
   11527     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11528     jmp    *dvmAsmInstructionStart+(120*4)
   11529 
   11530 /* ------------------------------ */
   11531 .L_ALT_OP_UNUSED_79: /* 0x79 */
   11532 /* File: x86/alt_stub.S */
   11533 /*
   11534  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11535  * any interesting requests and then jump to the real instruction
   11536  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11537  * because rIBASE is caller save and we need to reload it.
   11538  *
   11539  * Note that unlike in the Arm implementation, we should never arrive
   11540  * here with a zero breakFlag because we always refresh rIBASE on
   11541  * return.
   11542  */
   11543     EXPORT_PC
   11544     movl   rSELF, %eax
   11545     movl   rPC, OUT_ARG0(%esp)
   11546     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11547     movl   rFP, OUT_ARG1(%esp)
   11548     je     1f                                # reload rIBASE & resume if not
   11549     movl   %eax, OUT_ARG2(%esp)
   11550     call   dvmCheckBefore                    # (dPC, dFP, self)
   11551     movl   rSELF, %eax
   11552 1:
   11553     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11554     jmp    *dvmAsmInstructionStart+(121*4)
   11555 
   11556 /* ------------------------------ */
   11557 .L_ALT_OP_UNUSED_7A: /* 0x7a */
   11558 /* File: x86/alt_stub.S */
   11559 /*
   11560  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11561  * any interesting requests and then jump to the real instruction
   11562  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11563  * because rIBASE is caller save and we need to reload it.
   11564  *
   11565  * Note that unlike in the Arm implementation, we should never arrive
   11566  * here with a zero breakFlag because we always refresh rIBASE on
   11567  * return.
   11568  */
   11569     EXPORT_PC
   11570     movl   rSELF, %eax
   11571     movl   rPC, OUT_ARG0(%esp)
   11572     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11573     movl   rFP, OUT_ARG1(%esp)
   11574     je     1f                                # reload rIBASE & resume if not
   11575     movl   %eax, OUT_ARG2(%esp)
   11576     call   dvmCheckBefore                    # (dPC, dFP, self)
   11577     movl   rSELF, %eax
   11578 1:
   11579     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11580     jmp    *dvmAsmInstructionStart+(122*4)
   11581 
   11582 /* ------------------------------ */
   11583 .L_ALT_OP_NEG_INT: /* 0x7b */
   11584 /* File: x86/alt_stub.S */
   11585 /*
   11586  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11587  * any interesting requests and then jump to the real instruction
   11588  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11589  * because rIBASE is caller save and we need to reload it.
   11590  *
   11591  * Note that unlike in the Arm implementation, we should never arrive
   11592  * here with a zero breakFlag because we always refresh rIBASE on
   11593  * return.
   11594  */
   11595     EXPORT_PC
   11596     movl   rSELF, %eax
   11597     movl   rPC, OUT_ARG0(%esp)
   11598     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11599     movl   rFP, OUT_ARG1(%esp)
   11600     je     1f                                # reload rIBASE & resume if not
   11601     movl   %eax, OUT_ARG2(%esp)
   11602     call   dvmCheckBefore                    # (dPC, dFP, self)
   11603     movl   rSELF, %eax
   11604 1:
   11605     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11606     jmp    *dvmAsmInstructionStart+(123*4)
   11607 
   11608 /* ------------------------------ */
   11609 .L_ALT_OP_NOT_INT: /* 0x7c */
   11610 /* File: x86/alt_stub.S */
   11611 /*
   11612  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11613  * any interesting requests and then jump to the real instruction
   11614  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11615  * because rIBASE is caller save and we need to reload it.
   11616  *
   11617  * Note that unlike in the Arm implementation, we should never arrive
   11618  * here with a zero breakFlag because we always refresh rIBASE on
   11619  * return.
   11620  */
   11621     EXPORT_PC
   11622     movl   rSELF, %eax
   11623     movl   rPC, OUT_ARG0(%esp)
   11624     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11625     movl   rFP, OUT_ARG1(%esp)
   11626     je     1f                                # reload rIBASE & resume if not
   11627     movl   %eax, OUT_ARG2(%esp)
   11628     call   dvmCheckBefore                    # (dPC, dFP, self)
   11629     movl   rSELF, %eax
   11630 1:
   11631     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11632     jmp    *dvmAsmInstructionStart+(124*4)
   11633 
   11634 /* ------------------------------ */
   11635 .L_ALT_OP_NEG_LONG: /* 0x7d */
   11636 /* File: x86/alt_stub.S */
   11637 /*
   11638  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11639  * any interesting requests and then jump to the real instruction
   11640  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11641  * because rIBASE is caller save and we need to reload it.
   11642  *
   11643  * Note that unlike in the Arm implementation, we should never arrive
   11644  * here with a zero breakFlag because we always refresh rIBASE on
   11645  * return.
   11646  */
   11647     EXPORT_PC
   11648     movl   rSELF, %eax
   11649     movl   rPC, OUT_ARG0(%esp)
   11650     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11651     movl   rFP, OUT_ARG1(%esp)
   11652     je     1f                                # reload rIBASE & resume if not
   11653     movl   %eax, OUT_ARG2(%esp)
   11654     call   dvmCheckBefore                    # (dPC, dFP, self)
   11655     movl   rSELF, %eax
   11656 1:
   11657     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11658     jmp    *dvmAsmInstructionStart+(125*4)
   11659 
   11660 /* ------------------------------ */
   11661 .L_ALT_OP_NOT_LONG: /* 0x7e */
   11662 /* File: x86/alt_stub.S */
   11663 /*
   11664  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11665  * any interesting requests and then jump to the real instruction
   11666  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11667  * because rIBASE is caller save and we need to reload it.
   11668  *
   11669  * Note that unlike in the Arm implementation, we should never arrive
   11670  * here with a zero breakFlag because we always refresh rIBASE on
   11671  * return.
   11672  */
   11673     EXPORT_PC
   11674     movl   rSELF, %eax
   11675     movl   rPC, OUT_ARG0(%esp)
   11676     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11677     movl   rFP, OUT_ARG1(%esp)
   11678     je     1f                                # reload rIBASE & resume if not
   11679     movl   %eax, OUT_ARG2(%esp)
   11680     call   dvmCheckBefore                    # (dPC, dFP, self)
   11681     movl   rSELF, %eax
   11682 1:
   11683     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11684     jmp    *dvmAsmInstructionStart+(126*4)
   11685 
   11686 /* ------------------------------ */
   11687 .L_ALT_OP_NEG_FLOAT: /* 0x7f */
   11688 /* File: x86/alt_stub.S */
   11689 /*
   11690  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11691  * any interesting requests and then jump to the real instruction
   11692  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11693  * because rIBASE is caller save and we need to reload it.
   11694  *
   11695  * Note that unlike in the Arm implementation, we should never arrive
   11696  * here with a zero breakFlag because we always refresh rIBASE on
   11697  * return.
   11698  */
   11699     EXPORT_PC
   11700     movl   rSELF, %eax
   11701     movl   rPC, OUT_ARG0(%esp)
   11702     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11703     movl   rFP, OUT_ARG1(%esp)
   11704     je     1f                                # reload rIBASE & resume if not
   11705     movl   %eax, OUT_ARG2(%esp)
   11706     call   dvmCheckBefore                    # (dPC, dFP, self)
   11707     movl   rSELF, %eax
   11708 1:
   11709     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11710     jmp    *dvmAsmInstructionStart+(127*4)
   11711 
   11712 /* ------------------------------ */
   11713 .L_ALT_OP_NEG_DOUBLE: /* 0x80 */
   11714 /* File: x86/alt_stub.S */
   11715 /*
   11716  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11717  * any interesting requests and then jump to the real instruction
   11718  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11719  * because rIBASE is caller save and we need to reload it.
   11720  *
   11721  * Note that unlike in the Arm implementation, we should never arrive
   11722  * here with a zero breakFlag because we always refresh rIBASE on
   11723  * return.
   11724  */
   11725     EXPORT_PC
   11726     movl   rSELF, %eax
   11727     movl   rPC, OUT_ARG0(%esp)
   11728     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11729     movl   rFP, OUT_ARG1(%esp)
   11730     je     1f                                # reload rIBASE & resume if not
   11731     movl   %eax, OUT_ARG2(%esp)
   11732     call   dvmCheckBefore                    # (dPC, dFP, self)
   11733     movl   rSELF, %eax
   11734 1:
   11735     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11736     jmp    *dvmAsmInstructionStart+(128*4)
   11737 
   11738 /* ------------------------------ */
   11739 .L_ALT_OP_INT_TO_LONG: /* 0x81 */
   11740 /* File: x86/alt_stub.S */
   11741 /*
   11742  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11743  * any interesting requests and then jump to the real instruction
   11744  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11745  * because rIBASE is caller save and we need to reload it.
   11746  *
   11747  * Note that unlike in the Arm implementation, we should never arrive
   11748  * here with a zero breakFlag because we always refresh rIBASE on
   11749  * return.
   11750  */
   11751     EXPORT_PC
   11752     movl   rSELF, %eax
   11753     movl   rPC, OUT_ARG0(%esp)
   11754     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11755     movl   rFP, OUT_ARG1(%esp)
   11756     je     1f                                # reload rIBASE & resume if not
   11757     movl   %eax, OUT_ARG2(%esp)
   11758     call   dvmCheckBefore                    # (dPC, dFP, self)
   11759     movl   rSELF, %eax
   11760 1:
   11761     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11762     jmp    *dvmAsmInstructionStart+(129*4)
   11763 
   11764 /* ------------------------------ */
   11765 .L_ALT_OP_INT_TO_FLOAT: /* 0x82 */
   11766 /* File: x86/alt_stub.S */
   11767 /*
   11768  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11769  * any interesting requests and then jump to the real instruction
   11770  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11771  * because rIBASE is caller save and we need to reload it.
   11772  *
   11773  * Note that unlike in the Arm implementation, we should never arrive
   11774  * here with a zero breakFlag because we always refresh rIBASE on
   11775  * return.
   11776  */
   11777     EXPORT_PC
   11778     movl   rSELF, %eax
   11779     movl   rPC, OUT_ARG0(%esp)
   11780     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11781     movl   rFP, OUT_ARG1(%esp)
   11782     je     1f                                # reload rIBASE & resume if not
   11783     movl   %eax, OUT_ARG2(%esp)
   11784     call   dvmCheckBefore                    # (dPC, dFP, self)
   11785     movl   rSELF, %eax
   11786 1:
   11787     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11788     jmp    *dvmAsmInstructionStart+(130*4)
   11789 
   11790 /* ------------------------------ */
   11791 .L_ALT_OP_INT_TO_DOUBLE: /* 0x83 */
   11792 /* File: x86/alt_stub.S */
   11793 /*
   11794  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11795  * any interesting requests and then jump to the real instruction
   11796  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11797  * because rIBASE is caller save and we need to reload it.
   11798  *
   11799  * Note that unlike in the Arm implementation, we should never arrive
   11800  * here with a zero breakFlag because we always refresh rIBASE on
   11801  * return.
   11802  */
   11803     EXPORT_PC
   11804     movl   rSELF, %eax
   11805     movl   rPC, OUT_ARG0(%esp)
   11806     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11807     movl   rFP, OUT_ARG1(%esp)
   11808     je     1f                                # reload rIBASE & resume if not
   11809     movl   %eax, OUT_ARG2(%esp)
   11810     call   dvmCheckBefore                    # (dPC, dFP, self)
   11811     movl   rSELF, %eax
   11812 1:
   11813     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11814     jmp    *dvmAsmInstructionStart+(131*4)
   11815 
   11816 /* ------------------------------ */
   11817 .L_ALT_OP_LONG_TO_INT: /* 0x84 */
   11818 /* File: x86/alt_stub.S */
   11819 /*
   11820  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11821  * any interesting requests and then jump to the real instruction
   11822  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11823  * because rIBASE is caller save and we need to reload it.
   11824  *
   11825  * Note that unlike in the Arm implementation, we should never arrive
   11826  * here with a zero breakFlag because we always refresh rIBASE on
   11827  * return.
   11828  */
   11829     EXPORT_PC
   11830     movl   rSELF, %eax
   11831     movl   rPC, OUT_ARG0(%esp)
   11832     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11833     movl   rFP, OUT_ARG1(%esp)
   11834     je     1f                                # reload rIBASE & resume if not
   11835     movl   %eax, OUT_ARG2(%esp)
   11836     call   dvmCheckBefore                    # (dPC, dFP, self)
   11837     movl   rSELF, %eax
   11838 1:
   11839     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11840     jmp    *dvmAsmInstructionStart+(132*4)
   11841 
   11842 /* ------------------------------ */
   11843 .L_ALT_OP_LONG_TO_FLOAT: /* 0x85 */
   11844 /* File: x86/alt_stub.S */
   11845 /*
   11846  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11847  * any interesting requests and then jump to the real instruction
   11848  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11849  * because rIBASE is caller save and we need to reload it.
   11850  *
   11851  * Note that unlike in the Arm implementation, we should never arrive
   11852  * here with a zero breakFlag because we always refresh rIBASE on
   11853  * return.
   11854  */
   11855     EXPORT_PC
   11856     movl   rSELF, %eax
   11857     movl   rPC, OUT_ARG0(%esp)
   11858     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11859     movl   rFP, OUT_ARG1(%esp)
   11860     je     1f                                # reload rIBASE & resume if not
   11861     movl   %eax, OUT_ARG2(%esp)
   11862     call   dvmCheckBefore                    # (dPC, dFP, self)
   11863     movl   rSELF, %eax
   11864 1:
   11865     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11866     jmp    *dvmAsmInstructionStart+(133*4)
   11867 
   11868 /* ------------------------------ */
   11869 .L_ALT_OP_LONG_TO_DOUBLE: /* 0x86 */
   11870 /* File: x86/alt_stub.S */
   11871 /*
   11872  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11873  * any interesting requests and then jump to the real instruction
   11874  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11875  * because rIBASE is caller save and we need to reload it.
   11876  *
   11877  * Note that unlike in the Arm implementation, we should never arrive
   11878  * here with a zero breakFlag because we always refresh rIBASE on
   11879  * return.
   11880  */
   11881     EXPORT_PC
   11882     movl   rSELF, %eax
   11883     movl   rPC, OUT_ARG0(%esp)
   11884     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11885     movl   rFP, OUT_ARG1(%esp)
   11886     je     1f                                # reload rIBASE & resume if not
   11887     movl   %eax, OUT_ARG2(%esp)
   11888     call   dvmCheckBefore                    # (dPC, dFP, self)
   11889     movl   rSELF, %eax
   11890 1:
   11891     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11892     jmp    *dvmAsmInstructionStart+(134*4)
   11893 
   11894 /* ------------------------------ */
   11895 .L_ALT_OP_FLOAT_TO_INT: /* 0x87 */
   11896 /* File: x86/alt_stub.S */
   11897 /*
   11898  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11899  * any interesting requests and then jump to the real instruction
   11900  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11901  * because rIBASE is caller save and we need to reload it.
   11902  *
   11903  * Note that unlike in the Arm implementation, we should never arrive
   11904  * here with a zero breakFlag because we always refresh rIBASE on
   11905  * return.
   11906  */
   11907     EXPORT_PC
   11908     movl   rSELF, %eax
   11909     movl   rPC, OUT_ARG0(%esp)
   11910     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11911     movl   rFP, OUT_ARG1(%esp)
   11912     je     1f                                # reload rIBASE & resume if not
   11913     movl   %eax, OUT_ARG2(%esp)
   11914     call   dvmCheckBefore                    # (dPC, dFP, self)
   11915     movl   rSELF, %eax
   11916 1:
   11917     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11918     jmp    *dvmAsmInstructionStart+(135*4)
   11919 
   11920 /* ------------------------------ */
   11921 .L_ALT_OP_FLOAT_TO_LONG: /* 0x88 */
   11922 /* File: x86/alt_stub.S */
   11923 /*
   11924  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11925  * any interesting requests and then jump to the real instruction
   11926  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11927  * because rIBASE is caller save and we need to reload it.
   11928  *
   11929  * Note that unlike in the Arm implementation, we should never arrive
   11930  * here with a zero breakFlag because we always refresh rIBASE on
   11931  * return.
   11932  */
   11933     EXPORT_PC
   11934     movl   rSELF, %eax
   11935     movl   rPC, OUT_ARG0(%esp)
   11936     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11937     movl   rFP, OUT_ARG1(%esp)
   11938     je     1f                                # reload rIBASE & resume if not
   11939     movl   %eax, OUT_ARG2(%esp)
   11940     call   dvmCheckBefore                    # (dPC, dFP, self)
   11941     movl   rSELF, %eax
   11942 1:
   11943     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11944     jmp    *dvmAsmInstructionStart+(136*4)
   11945 
   11946 /* ------------------------------ */
   11947 .L_ALT_OP_FLOAT_TO_DOUBLE: /* 0x89 */
   11948 /* File: x86/alt_stub.S */
   11949 /*
   11950  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11951  * any interesting requests and then jump to the real instruction
   11952  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11953  * because rIBASE is caller save and we need to reload it.
   11954  *
   11955  * Note that unlike in the Arm implementation, we should never arrive
   11956  * here with a zero breakFlag because we always refresh rIBASE on
   11957  * return.
   11958  */
   11959     EXPORT_PC
   11960     movl   rSELF, %eax
   11961     movl   rPC, OUT_ARG0(%esp)
   11962     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11963     movl   rFP, OUT_ARG1(%esp)
   11964     je     1f                                # reload rIBASE & resume if not
   11965     movl   %eax, OUT_ARG2(%esp)
   11966     call   dvmCheckBefore                    # (dPC, dFP, self)
   11967     movl   rSELF, %eax
   11968 1:
   11969     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11970     jmp    *dvmAsmInstructionStart+(137*4)
   11971 
   11972 /* ------------------------------ */
   11973 .L_ALT_OP_DOUBLE_TO_INT: /* 0x8a */
   11974 /* File: x86/alt_stub.S */
   11975 /*
   11976  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   11977  * any interesting requests and then jump to the real instruction
   11978  * handler.  Unlike the Arm handler, we can't do this as a tail call
   11979  * because rIBASE is caller save and we need to reload it.
   11980  *
   11981  * Note that unlike in the Arm implementation, we should never arrive
   11982  * here with a zero breakFlag because we always refresh rIBASE on
   11983  * return.
   11984  */
   11985     EXPORT_PC
   11986     movl   rSELF, %eax
   11987     movl   rPC, OUT_ARG0(%esp)
   11988     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   11989     movl   rFP, OUT_ARG1(%esp)
   11990     je     1f                                # reload rIBASE & resume if not
   11991     movl   %eax, OUT_ARG2(%esp)
   11992     call   dvmCheckBefore                    # (dPC, dFP, self)
   11993     movl   rSELF, %eax
   11994 1:
   11995     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   11996     jmp    *dvmAsmInstructionStart+(138*4)
   11997 
   11998 /* ------------------------------ */
   11999 .L_ALT_OP_DOUBLE_TO_LONG: /* 0x8b */
   12000 /* File: x86/alt_stub.S */
   12001 /*
   12002  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12003  * any interesting requests and then jump to the real instruction
   12004  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12005  * because rIBASE is caller save and we need to reload it.
   12006  *
   12007  * Note that unlike in the Arm implementation, we should never arrive
   12008  * here with a zero breakFlag because we always refresh rIBASE on
   12009  * return.
   12010  */
   12011     EXPORT_PC
   12012     movl   rSELF, %eax
   12013     movl   rPC, OUT_ARG0(%esp)
   12014     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12015     movl   rFP, OUT_ARG1(%esp)
   12016     je     1f                                # reload rIBASE & resume if not
   12017     movl   %eax, OUT_ARG2(%esp)
   12018     call   dvmCheckBefore                    # (dPC, dFP, self)
   12019     movl   rSELF, %eax
   12020 1:
   12021     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12022     jmp    *dvmAsmInstructionStart+(139*4)
   12023 
   12024 /* ------------------------------ */
   12025 .L_ALT_OP_DOUBLE_TO_FLOAT: /* 0x8c */
   12026 /* File: x86/alt_stub.S */
   12027 /*
   12028  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12029  * any interesting requests and then jump to the real instruction
   12030  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12031  * because rIBASE is caller save and we need to reload it.
   12032  *
   12033  * Note that unlike in the Arm implementation, we should never arrive
   12034  * here with a zero breakFlag because we always refresh rIBASE on
   12035  * return.
   12036  */
   12037     EXPORT_PC
   12038     movl   rSELF, %eax
   12039     movl   rPC, OUT_ARG0(%esp)
   12040     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12041     movl   rFP, OUT_ARG1(%esp)
   12042     je     1f                                # reload rIBASE & resume if not
   12043     movl   %eax, OUT_ARG2(%esp)
   12044     call   dvmCheckBefore                    # (dPC, dFP, self)
   12045     movl   rSELF, %eax
   12046 1:
   12047     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12048     jmp    *dvmAsmInstructionStart+(140*4)
   12049 
   12050 /* ------------------------------ */
   12051 .L_ALT_OP_INT_TO_BYTE: /* 0x8d */
   12052 /* File: x86/alt_stub.S */
   12053 /*
   12054  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12055  * any interesting requests and then jump to the real instruction
   12056  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12057  * because rIBASE is caller save and we need to reload it.
   12058  *
   12059  * Note that unlike in the Arm implementation, we should never arrive
   12060  * here with a zero breakFlag because we always refresh rIBASE on
   12061  * return.
   12062  */
   12063     EXPORT_PC
   12064     movl   rSELF, %eax
   12065     movl   rPC, OUT_ARG0(%esp)
   12066     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12067     movl   rFP, OUT_ARG1(%esp)
   12068     je     1f                                # reload rIBASE & resume if not
   12069     movl   %eax, OUT_ARG2(%esp)
   12070     call   dvmCheckBefore                    # (dPC, dFP, self)
   12071     movl   rSELF, %eax
   12072 1:
   12073     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12074     jmp    *dvmAsmInstructionStart+(141*4)
   12075 
   12076 /* ------------------------------ */
   12077 .L_ALT_OP_INT_TO_CHAR: /* 0x8e */
   12078 /* File: x86/alt_stub.S */
   12079 /*
   12080  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12081  * any interesting requests and then jump to the real instruction
   12082  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12083  * because rIBASE is caller save and we need to reload it.
   12084  *
   12085  * Note that unlike in the Arm implementation, we should never arrive
   12086  * here with a zero breakFlag because we always refresh rIBASE on
   12087  * return.
   12088  */
   12089     EXPORT_PC
   12090     movl   rSELF, %eax
   12091     movl   rPC, OUT_ARG0(%esp)
   12092     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12093     movl   rFP, OUT_ARG1(%esp)
   12094     je     1f                                # reload rIBASE & resume if not
   12095     movl   %eax, OUT_ARG2(%esp)
   12096     call   dvmCheckBefore                    # (dPC, dFP, self)
   12097     movl   rSELF, %eax
   12098 1:
   12099     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12100     jmp    *dvmAsmInstructionStart+(142*4)
   12101 
   12102 /* ------------------------------ */
   12103 .L_ALT_OP_INT_TO_SHORT: /* 0x8f */
   12104 /* File: x86/alt_stub.S */
   12105 /*
   12106  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12107  * any interesting requests and then jump to the real instruction
   12108  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12109  * because rIBASE is caller save and we need to reload it.
   12110  *
   12111  * Note that unlike in the Arm implementation, we should never arrive
   12112  * here with a zero breakFlag because we always refresh rIBASE on
   12113  * return.
   12114  */
   12115     EXPORT_PC
   12116     movl   rSELF, %eax
   12117     movl   rPC, OUT_ARG0(%esp)
   12118     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12119     movl   rFP, OUT_ARG1(%esp)
   12120     je     1f                                # reload rIBASE & resume if not
   12121     movl   %eax, OUT_ARG2(%esp)
   12122     call   dvmCheckBefore                    # (dPC, dFP, self)
   12123     movl   rSELF, %eax
   12124 1:
   12125     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12126     jmp    *dvmAsmInstructionStart+(143*4)
   12127 
   12128 /* ------------------------------ */
   12129 .L_ALT_OP_ADD_INT: /* 0x90 */
   12130 /* File: x86/alt_stub.S */
   12131 /*
   12132  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12133  * any interesting requests and then jump to the real instruction
   12134  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12135  * because rIBASE is caller save and we need to reload it.
   12136  *
   12137  * Note that unlike in the Arm implementation, we should never arrive
   12138  * here with a zero breakFlag because we always refresh rIBASE on
   12139  * return.
   12140  */
   12141     EXPORT_PC
   12142     movl   rSELF, %eax
   12143     movl   rPC, OUT_ARG0(%esp)
   12144     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12145     movl   rFP, OUT_ARG1(%esp)
   12146     je     1f                                # reload rIBASE & resume if not
   12147     movl   %eax, OUT_ARG2(%esp)
   12148     call   dvmCheckBefore                    # (dPC, dFP, self)
   12149     movl   rSELF, %eax
   12150 1:
   12151     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12152     jmp    *dvmAsmInstructionStart+(144*4)
   12153 
   12154 /* ------------------------------ */
   12155 .L_ALT_OP_SUB_INT: /* 0x91 */
   12156 /* File: x86/alt_stub.S */
   12157 /*
   12158  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12159  * any interesting requests and then jump to the real instruction
   12160  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12161  * because rIBASE is caller save and we need to reload it.
   12162  *
   12163  * Note that unlike in the Arm implementation, we should never arrive
   12164  * here with a zero breakFlag because we always refresh rIBASE on
   12165  * return.
   12166  */
   12167     EXPORT_PC
   12168     movl   rSELF, %eax
   12169     movl   rPC, OUT_ARG0(%esp)
   12170     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12171     movl   rFP, OUT_ARG1(%esp)
   12172     je     1f                                # reload rIBASE & resume if not
   12173     movl   %eax, OUT_ARG2(%esp)
   12174     call   dvmCheckBefore                    # (dPC, dFP, self)
   12175     movl   rSELF, %eax
   12176 1:
   12177     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12178     jmp    *dvmAsmInstructionStart+(145*4)
   12179 
   12180 /* ------------------------------ */
   12181 .L_ALT_OP_MUL_INT: /* 0x92 */
   12182 /* File: x86/alt_stub.S */
   12183 /*
   12184  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12185  * any interesting requests and then jump to the real instruction
   12186  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12187  * because rIBASE is caller save and we need to reload it.
   12188  *
   12189  * Note that unlike in the Arm implementation, we should never arrive
   12190  * here with a zero breakFlag because we always refresh rIBASE on
   12191  * return.
   12192  */
   12193     EXPORT_PC
   12194     movl   rSELF, %eax
   12195     movl   rPC, OUT_ARG0(%esp)
   12196     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12197     movl   rFP, OUT_ARG1(%esp)
   12198     je     1f                                # reload rIBASE & resume if not
   12199     movl   %eax, OUT_ARG2(%esp)
   12200     call   dvmCheckBefore                    # (dPC, dFP, self)
   12201     movl   rSELF, %eax
   12202 1:
   12203     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12204     jmp    *dvmAsmInstructionStart+(146*4)
   12205 
   12206 /* ------------------------------ */
   12207 .L_ALT_OP_DIV_INT: /* 0x93 */
   12208 /* File: x86/alt_stub.S */
   12209 /*
   12210  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12211  * any interesting requests and then jump to the real instruction
   12212  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12213  * because rIBASE is caller save and we need to reload it.
   12214  *
   12215  * Note that unlike in the Arm implementation, we should never arrive
   12216  * here with a zero breakFlag because we always refresh rIBASE on
   12217  * return.
   12218  */
   12219     EXPORT_PC
   12220     movl   rSELF, %eax
   12221     movl   rPC, OUT_ARG0(%esp)
   12222     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12223     movl   rFP, OUT_ARG1(%esp)
   12224     je     1f                                # reload rIBASE & resume if not
   12225     movl   %eax, OUT_ARG2(%esp)
   12226     call   dvmCheckBefore                    # (dPC, dFP, self)
   12227     movl   rSELF, %eax
   12228 1:
   12229     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12230     jmp    *dvmAsmInstructionStart+(147*4)
   12231 
   12232 /* ------------------------------ */
   12233 .L_ALT_OP_REM_INT: /* 0x94 */
   12234 /* File: x86/alt_stub.S */
   12235 /*
   12236  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12237  * any interesting requests and then jump to the real instruction
   12238  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12239  * because rIBASE is caller save and we need to reload it.
   12240  *
   12241  * Note that unlike in the Arm implementation, we should never arrive
   12242  * here with a zero breakFlag because we always refresh rIBASE on
   12243  * return.
   12244  */
   12245     EXPORT_PC
   12246     movl   rSELF, %eax
   12247     movl   rPC, OUT_ARG0(%esp)
   12248     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12249     movl   rFP, OUT_ARG1(%esp)
   12250     je     1f                                # reload rIBASE & resume if not
   12251     movl   %eax, OUT_ARG2(%esp)
   12252     call   dvmCheckBefore                    # (dPC, dFP, self)
   12253     movl   rSELF, %eax
   12254 1:
   12255     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12256     jmp    *dvmAsmInstructionStart+(148*4)
   12257 
   12258 /* ------------------------------ */
   12259 .L_ALT_OP_AND_INT: /* 0x95 */
   12260 /* File: x86/alt_stub.S */
   12261 /*
   12262  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12263  * any interesting requests and then jump to the real instruction
   12264  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12265  * because rIBASE is caller save and we need to reload it.
   12266  *
   12267  * Note that unlike in the Arm implementation, we should never arrive
   12268  * here with a zero breakFlag because we always refresh rIBASE on
   12269  * return.
   12270  */
   12271     EXPORT_PC
   12272     movl   rSELF, %eax
   12273     movl   rPC, OUT_ARG0(%esp)
   12274     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12275     movl   rFP, OUT_ARG1(%esp)
   12276     je     1f                                # reload rIBASE & resume if not
   12277     movl   %eax, OUT_ARG2(%esp)
   12278     call   dvmCheckBefore                    # (dPC, dFP, self)
   12279     movl   rSELF, %eax
   12280 1:
   12281     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12282     jmp    *dvmAsmInstructionStart+(149*4)
   12283 
   12284 /* ------------------------------ */
   12285 .L_ALT_OP_OR_INT: /* 0x96 */
   12286 /* File: x86/alt_stub.S */
   12287 /*
   12288  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12289  * any interesting requests and then jump to the real instruction
   12290  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12291  * because rIBASE is caller save and we need to reload it.
   12292  *
   12293  * Note that unlike in the Arm implementation, we should never arrive
   12294  * here with a zero breakFlag because we always refresh rIBASE on
   12295  * return.
   12296  */
   12297     EXPORT_PC
   12298     movl   rSELF, %eax
   12299     movl   rPC, OUT_ARG0(%esp)
   12300     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12301     movl   rFP, OUT_ARG1(%esp)
   12302     je     1f                                # reload rIBASE & resume if not
   12303     movl   %eax, OUT_ARG2(%esp)
   12304     call   dvmCheckBefore                    # (dPC, dFP, self)
   12305     movl   rSELF, %eax
   12306 1:
   12307     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12308     jmp    *dvmAsmInstructionStart+(150*4)
   12309 
   12310 /* ------------------------------ */
   12311 .L_ALT_OP_XOR_INT: /* 0x97 */
   12312 /* File: x86/alt_stub.S */
   12313 /*
   12314  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12315  * any interesting requests and then jump to the real instruction
   12316  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12317  * because rIBASE is caller save and we need to reload it.
   12318  *
   12319  * Note that unlike in the Arm implementation, we should never arrive
   12320  * here with a zero breakFlag because we always refresh rIBASE on
   12321  * return.
   12322  */
   12323     EXPORT_PC
   12324     movl   rSELF, %eax
   12325     movl   rPC, OUT_ARG0(%esp)
   12326     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12327     movl   rFP, OUT_ARG1(%esp)
   12328     je     1f                                # reload rIBASE & resume if not
   12329     movl   %eax, OUT_ARG2(%esp)
   12330     call   dvmCheckBefore                    # (dPC, dFP, self)
   12331     movl   rSELF, %eax
   12332 1:
   12333     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12334     jmp    *dvmAsmInstructionStart+(151*4)
   12335 
   12336 /* ------------------------------ */
   12337 .L_ALT_OP_SHL_INT: /* 0x98 */
   12338 /* File: x86/alt_stub.S */
   12339 /*
   12340  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12341  * any interesting requests and then jump to the real instruction
   12342  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12343  * because rIBASE is caller save and we need to reload it.
   12344  *
   12345  * Note that unlike in the Arm implementation, we should never arrive
   12346  * here with a zero breakFlag because we always refresh rIBASE on
   12347  * return.
   12348  */
   12349     EXPORT_PC
   12350     movl   rSELF, %eax
   12351     movl   rPC, OUT_ARG0(%esp)
   12352     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12353     movl   rFP, OUT_ARG1(%esp)
   12354     je     1f                                # reload rIBASE & resume if not
   12355     movl   %eax, OUT_ARG2(%esp)
   12356     call   dvmCheckBefore                    # (dPC, dFP, self)
   12357     movl   rSELF, %eax
   12358 1:
   12359     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12360     jmp    *dvmAsmInstructionStart+(152*4)
   12361 
   12362 /* ------------------------------ */
   12363 .L_ALT_OP_SHR_INT: /* 0x99 */
   12364 /* File: x86/alt_stub.S */
   12365 /*
   12366  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12367  * any interesting requests and then jump to the real instruction
   12368  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12369  * because rIBASE is caller save and we need to reload it.
   12370  *
   12371  * Note that unlike in the Arm implementation, we should never arrive
   12372  * here with a zero breakFlag because we always refresh rIBASE on
   12373  * return.
   12374  */
   12375     EXPORT_PC
   12376     movl   rSELF, %eax
   12377     movl   rPC, OUT_ARG0(%esp)
   12378     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12379     movl   rFP, OUT_ARG1(%esp)
   12380     je     1f                                # reload rIBASE & resume if not
   12381     movl   %eax, OUT_ARG2(%esp)
   12382     call   dvmCheckBefore                    # (dPC, dFP, self)
   12383     movl   rSELF, %eax
   12384 1:
   12385     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12386     jmp    *dvmAsmInstructionStart+(153*4)
   12387 
   12388 /* ------------------------------ */
   12389 .L_ALT_OP_USHR_INT: /* 0x9a */
   12390 /* File: x86/alt_stub.S */
   12391 /*
   12392  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12393  * any interesting requests and then jump to the real instruction
   12394  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12395  * because rIBASE is caller save and we need to reload it.
   12396  *
   12397  * Note that unlike in the Arm implementation, we should never arrive
   12398  * here with a zero breakFlag because we always refresh rIBASE on
   12399  * return.
   12400  */
   12401     EXPORT_PC
   12402     movl   rSELF, %eax
   12403     movl   rPC, OUT_ARG0(%esp)
   12404     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12405     movl   rFP, OUT_ARG1(%esp)
   12406     je     1f                                # reload rIBASE & resume if not
   12407     movl   %eax, OUT_ARG2(%esp)
   12408     call   dvmCheckBefore                    # (dPC, dFP, self)
   12409     movl   rSELF, %eax
   12410 1:
   12411     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12412     jmp    *dvmAsmInstructionStart+(154*4)
   12413 
   12414 /* ------------------------------ */
   12415 .L_ALT_OP_ADD_LONG: /* 0x9b */
   12416 /* File: x86/alt_stub.S */
   12417 /*
   12418  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12419  * any interesting requests and then jump to the real instruction
   12420  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12421  * because rIBASE is caller save and we need to reload it.
   12422  *
   12423  * Note that unlike in the Arm implementation, we should never arrive
   12424  * here with a zero breakFlag because we always refresh rIBASE on
   12425  * return.
   12426  */
   12427     EXPORT_PC
   12428     movl   rSELF, %eax
   12429     movl   rPC, OUT_ARG0(%esp)
   12430     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12431     movl   rFP, OUT_ARG1(%esp)
   12432     je     1f                                # reload rIBASE & resume if not
   12433     movl   %eax, OUT_ARG2(%esp)
   12434     call   dvmCheckBefore                    # (dPC, dFP, self)
   12435     movl   rSELF, %eax
   12436 1:
   12437     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12438     jmp    *dvmAsmInstructionStart+(155*4)
   12439 
   12440 /* ------------------------------ */
   12441 .L_ALT_OP_SUB_LONG: /* 0x9c */
   12442 /* File: x86/alt_stub.S */
   12443 /*
   12444  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12445  * any interesting requests and then jump to the real instruction
   12446  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12447  * because rIBASE is caller save and we need to reload it.
   12448  *
   12449  * Note that unlike in the Arm implementation, we should never arrive
   12450  * here with a zero breakFlag because we always refresh rIBASE on
   12451  * return.
   12452  */
   12453     EXPORT_PC
   12454     movl   rSELF, %eax
   12455     movl   rPC, OUT_ARG0(%esp)
   12456     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12457     movl   rFP, OUT_ARG1(%esp)
   12458     je     1f                                # reload rIBASE & resume if not
   12459     movl   %eax, OUT_ARG2(%esp)
   12460     call   dvmCheckBefore                    # (dPC, dFP, self)
   12461     movl   rSELF, %eax
   12462 1:
   12463     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12464     jmp    *dvmAsmInstructionStart+(156*4)
   12465 
   12466 /* ------------------------------ */
   12467 .L_ALT_OP_MUL_LONG: /* 0x9d */
   12468 /* File: x86/alt_stub.S */
   12469 /*
   12470  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12471  * any interesting requests and then jump to the real instruction
   12472  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12473  * because rIBASE is caller save and we need to reload it.
   12474  *
   12475  * Note that unlike in the Arm implementation, we should never arrive
   12476  * here with a zero breakFlag because we always refresh rIBASE on
   12477  * return.
   12478  */
   12479     EXPORT_PC
   12480     movl   rSELF, %eax
   12481     movl   rPC, OUT_ARG0(%esp)
   12482     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12483     movl   rFP, OUT_ARG1(%esp)
   12484     je     1f                                # reload rIBASE & resume if not
   12485     movl   %eax, OUT_ARG2(%esp)
   12486     call   dvmCheckBefore                    # (dPC, dFP, self)
   12487     movl   rSELF, %eax
   12488 1:
   12489     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12490     jmp    *dvmAsmInstructionStart+(157*4)
   12491 
   12492 /* ------------------------------ */
   12493 .L_ALT_OP_DIV_LONG: /* 0x9e */
   12494 /* File: x86/alt_stub.S */
   12495 /*
   12496  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12497  * any interesting requests and then jump to the real instruction
   12498  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12499  * because rIBASE is caller save and we need to reload it.
   12500  *
   12501  * Note that unlike in the Arm implementation, we should never arrive
   12502  * here with a zero breakFlag because we always refresh rIBASE on
   12503  * return.
   12504  */
   12505     EXPORT_PC
   12506     movl   rSELF, %eax
   12507     movl   rPC, OUT_ARG0(%esp)
   12508     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12509     movl   rFP, OUT_ARG1(%esp)
   12510     je     1f                                # reload rIBASE & resume if not
   12511     movl   %eax, OUT_ARG2(%esp)
   12512     call   dvmCheckBefore                    # (dPC, dFP, self)
   12513     movl   rSELF, %eax
   12514 1:
   12515     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12516     jmp    *dvmAsmInstructionStart+(158*4)
   12517 
   12518 /* ------------------------------ */
   12519 .L_ALT_OP_REM_LONG: /* 0x9f */
   12520 /* File: x86/alt_stub.S */
   12521 /*
   12522  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12523  * any interesting requests and then jump to the real instruction
   12524  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12525  * because rIBASE is caller save and we need to reload it.
   12526  *
   12527  * Note that unlike in the Arm implementation, we should never arrive
   12528  * here with a zero breakFlag because we always refresh rIBASE on
   12529  * return.
   12530  */
   12531     EXPORT_PC
   12532     movl   rSELF, %eax
   12533     movl   rPC, OUT_ARG0(%esp)
   12534     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12535     movl   rFP, OUT_ARG1(%esp)
   12536     je     1f                                # reload rIBASE & resume if not
   12537     movl   %eax, OUT_ARG2(%esp)
   12538     call   dvmCheckBefore                    # (dPC, dFP, self)
   12539     movl   rSELF, %eax
   12540 1:
   12541     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12542     jmp    *dvmAsmInstructionStart+(159*4)
   12543 
   12544 /* ------------------------------ */
   12545 .L_ALT_OP_AND_LONG: /* 0xa0 */
   12546 /* File: x86/alt_stub.S */
   12547 /*
   12548  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12549  * any interesting requests and then jump to the real instruction
   12550  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12551  * because rIBASE is caller save and we need to reload it.
   12552  *
   12553  * Note that unlike in the Arm implementation, we should never arrive
   12554  * here with a zero breakFlag because we always refresh rIBASE on
   12555  * return.
   12556  */
   12557     EXPORT_PC
   12558     movl   rSELF, %eax
   12559     movl   rPC, OUT_ARG0(%esp)
   12560     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12561     movl   rFP, OUT_ARG1(%esp)
   12562     je     1f                                # reload rIBASE & resume if not
   12563     movl   %eax, OUT_ARG2(%esp)
   12564     call   dvmCheckBefore                    # (dPC, dFP, self)
   12565     movl   rSELF, %eax
   12566 1:
   12567     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12568     jmp    *dvmAsmInstructionStart+(160*4)
   12569 
   12570 /* ------------------------------ */
   12571 .L_ALT_OP_OR_LONG: /* 0xa1 */
   12572 /* File: x86/alt_stub.S */
   12573 /*
   12574  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12575  * any interesting requests and then jump to the real instruction
   12576  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12577  * because rIBASE is caller save and we need to reload it.
   12578  *
   12579  * Note that unlike in the Arm implementation, we should never arrive
   12580  * here with a zero breakFlag because we always refresh rIBASE on
   12581  * return.
   12582  */
   12583     EXPORT_PC
   12584     movl   rSELF, %eax
   12585     movl   rPC, OUT_ARG0(%esp)
   12586     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12587     movl   rFP, OUT_ARG1(%esp)
   12588     je     1f                                # reload rIBASE & resume if not
   12589     movl   %eax, OUT_ARG2(%esp)
   12590     call   dvmCheckBefore                    # (dPC, dFP, self)
   12591     movl   rSELF, %eax
   12592 1:
   12593     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12594     jmp    *dvmAsmInstructionStart+(161*4)
   12595 
   12596 /* ------------------------------ */
   12597 .L_ALT_OP_XOR_LONG: /* 0xa2 */
   12598 /* File: x86/alt_stub.S */
   12599 /*
   12600  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12601  * any interesting requests and then jump to the real instruction
   12602  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12603  * because rIBASE is caller save and we need to reload it.
   12604  *
   12605  * Note that unlike in the Arm implementation, we should never arrive
   12606  * here with a zero breakFlag because we always refresh rIBASE on
   12607  * return.
   12608  */
   12609     EXPORT_PC
   12610     movl   rSELF, %eax
   12611     movl   rPC, OUT_ARG0(%esp)
   12612     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12613     movl   rFP, OUT_ARG1(%esp)
   12614     je     1f                                # reload rIBASE & resume if not
   12615     movl   %eax, OUT_ARG2(%esp)
   12616     call   dvmCheckBefore                    # (dPC, dFP, self)
   12617     movl   rSELF, %eax
   12618 1:
   12619     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12620     jmp    *dvmAsmInstructionStart+(162*4)
   12621 
   12622 /* ------------------------------ */
   12623 .L_ALT_OP_SHL_LONG: /* 0xa3 */
   12624 /* File: x86/alt_stub.S */
   12625 /*
   12626  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12627  * any interesting requests and then jump to the real instruction
   12628  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12629  * because rIBASE is caller save and we need to reload it.
   12630  *
   12631  * Note that unlike in the Arm implementation, we should never arrive
   12632  * here with a zero breakFlag because we always refresh rIBASE on
   12633  * return.
   12634  */
   12635     EXPORT_PC
   12636     movl   rSELF, %eax
   12637     movl   rPC, OUT_ARG0(%esp)
   12638     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12639     movl   rFP, OUT_ARG1(%esp)
   12640     je     1f                                # reload rIBASE & resume if not
   12641     movl   %eax, OUT_ARG2(%esp)
   12642     call   dvmCheckBefore                    # (dPC, dFP, self)
   12643     movl   rSELF, %eax
   12644 1:
   12645     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12646     jmp    *dvmAsmInstructionStart+(163*4)
   12647 
   12648 /* ------------------------------ */
   12649 .L_ALT_OP_SHR_LONG: /* 0xa4 */
   12650 /* File: x86/alt_stub.S */
   12651 /*
   12652  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12653  * any interesting requests and then jump to the real instruction
   12654  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12655  * because rIBASE is caller save and we need to reload it.
   12656  *
   12657  * Note that unlike in the Arm implementation, we should never arrive
   12658  * here with a zero breakFlag because we always refresh rIBASE on
   12659  * return.
   12660  */
   12661     EXPORT_PC
   12662     movl   rSELF, %eax
   12663     movl   rPC, OUT_ARG0(%esp)
   12664     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12665     movl   rFP, OUT_ARG1(%esp)
   12666     je     1f                                # reload rIBASE & resume if not
   12667     movl   %eax, OUT_ARG2(%esp)
   12668     call   dvmCheckBefore                    # (dPC, dFP, self)
   12669     movl   rSELF, %eax
   12670 1:
   12671     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12672     jmp    *dvmAsmInstructionStart+(164*4)
   12673 
   12674 /* ------------------------------ */
   12675 .L_ALT_OP_USHR_LONG: /* 0xa5 */
   12676 /* File: x86/alt_stub.S */
   12677 /*
   12678  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12679  * any interesting requests and then jump to the real instruction
   12680  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12681  * because rIBASE is caller save and we need to reload it.
   12682  *
   12683  * Note that unlike in the Arm implementation, we should never arrive
   12684  * here with a zero breakFlag because we always refresh rIBASE on
   12685  * return.
   12686  */
   12687     EXPORT_PC
   12688     movl   rSELF, %eax
   12689     movl   rPC, OUT_ARG0(%esp)
   12690     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12691     movl   rFP, OUT_ARG1(%esp)
   12692     je     1f                                # reload rIBASE & resume if not
   12693     movl   %eax, OUT_ARG2(%esp)
   12694     call   dvmCheckBefore                    # (dPC, dFP, self)
   12695     movl   rSELF, %eax
   12696 1:
   12697     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12698     jmp    *dvmAsmInstructionStart+(165*4)
   12699 
   12700 /* ------------------------------ */
   12701 .L_ALT_OP_ADD_FLOAT: /* 0xa6 */
   12702 /* File: x86/alt_stub.S */
   12703 /*
   12704  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12705  * any interesting requests and then jump to the real instruction
   12706  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12707  * because rIBASE is caller save and we need to reload it.
   12708  *
   12709  * Note that unlike in the Arm implementation, we should never arrive
   12710  * here with a zero breakFlag because we always refresh rIBASE on
   12711  * return.
   12712  */
   12713     EXPORT_PC
   12714     movl   rSELF, %eax
   12715     movl   rPC, OUT_ARG0(%esp)
   12716     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12717     movl   rFP, OUT_ARG1(%esp)
   12718     je     1f                                # reload rIBASE & resume if not
   12719     movl   %eax, OUT_ARG2(%esp)
   12720     call   dvmCheckBefore                    # (dPC, dFP, self)
   12721     movl   rSELF, %eax
   12722 1:
   12723     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12724     jmp    *dvmAsmInstructionStart+(166*4)
   12725 
   12726 /* ------------------------------ */
   12727 .L_ALT_OP_SUB_FLOAT: /* 0xa7 */
   12728 /* File: x86/alt_stub.S */
   12729 /*
   12730  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12731  * any interesting requests and then jump to the real instruction
   12732  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12733  * because rIBASE is caller save and we need to reload it.
   12734  *
   12735  * Note that unlike in the Arm implementation, we should never arrive
   12736  * here with a zero breakFlag because we always refresh rIBASE on
   12737  * return.
   12738  */
   12739     EXPORT_PC
   12740     movl   rSELF, %eax
   12741     movl   rPC, OUT_ARG0(%esp)
   12742     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12743     movl   rFP, OUT_ARG1(%esp)
   12744     je     1f                                # reload rIBASE & resume if not
   12745     movl   %eax, OUT_ARG2(%esp)
   12746     call   dvmCheckBefore                    # (dPC, dFP, self)
   12747     movl   rSELF, %eax
   12748 1:
   12749     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12750     jmp    *dvmAsmInstructionStart+(167*4)
   12751 
   12752 /* ------------------------------ */
   12753 .L_ALT_OP_MUL_FLOAT: /* 0xa8 */
   12754 /* File: x86/alt_stub.S */
   12755 /*
   12756  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12757  * any interesting requests and then jump to the real instruction
   12758  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12759  * because rIBASE is caller save and we need to reload it.
   12760  *
   12761  * Note that unlike in the Arm implementation, we should never arrive
   12762  * here with a zero breakFlag because we always refresh rIBASE on
   12763  * return.
   12764  */
   12765     EXPORT_PC
   12766     movl   rSELF, %eax
   12767     movl   rPC, OUT_ARG0(%esp)
   12768     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12769     movl   rFP, OUT_ARG1(%esp)
   12770     je     1f                                # reload rIBASE & resume if not
   12771     movl   %eax, OUT_ARG2(%esp)
   12772     call   dvmCheckBefore                    # (dPC, dFP, self)
   12773     movl   rSELF, %eax
   12774 1:
   12775     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12776     jmp    *dvmAsmInstructionStart+(168*4)
   12777 
   12778 /* ------------------------------ */
   12779 .L_ALT_OP_DIV_FLOAT: /* 0xa9 */
   12780 /* File: x86/alt_stub.S */
   12781 /*
   12782  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12783  * any interesting requests and then jump to the real instruction
   12784  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12785  * because rIBASE is caller save and we need to reload it.
   12786  *
   12787  * Note that unlike in the Arm implementation, we should never arrive
   12788  * here with a zero breakFlag because we always refresh rIBASE on
   12789  * return.
   12790  */
   12791     EXPORT_PC
   12792     movl   rSELF, %eax
   12793     movl   rPC, OUT_ARG0(%esp)
   12794     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12795     movl   rFP, OUT_ARG1(%esp)
   12796     je     1f                                # reload rIBASE & resume if not
   12797     movl   %eax, OUT_ARG2(%esp)
   12798     call   dvmCheckBefore                    # (dPC, dFP, self)
   12799     movl   rSELF, %eax
   12800 1:
   12801     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12802     jmp    *dvmAsmInstructionStart+(169*4)
   12803 
   12804 /* ------------------------------ */
   12805 .L_ALT_OP_REM_FLOAT: /* 0xaa */
   12806 /* File: x86/alt_stub.S */
   12807 /*
   12808  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12809  * any interesting requests and then jump to the real instruction
   12810  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12811  * because rIBASE is caller save and we need to reload it.
   12812  *
   12813  * Note that unlike in the Arm implementation, we should never arrive
   12814  * here with a zero breakFlag because we always refresh rIBASE on
   12815  * return.
   12816  */
   12817     EXPORT_PC
   12818     movl   rSELF, %eax
   12819     movl   rPC, OUT_ARG0(%esp)
   12820     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12821     movl   rFP, OUT_ARG1(%esp)
   12822     je     1f                                # reload rIBASE & resume if not
   12823     movl   %eax, OUT_ARG2(%esp)
   12824     call   dvmCheckBefore                    # (dPC, dFP, self)
   12825     movl   rSELF, %eax
   12826 1:
   12827     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12828     jmp    *dvmAsmInstructionStart+(170*4)
   12829 
   12830 /* ------------------------------ */
   12831 .L_ALT_OP_ADD_DOUBLE: /* 0xab */
   12832 /* File: x86/alt_stub.S */
   12833 /*
   12834  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12835  * any interesting requests and then jump to the real instruction
   12836  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12837  * because rIBASE is caller save and we need to reload it.
   12838  *
   12839  * Note that unlike in the Arm implementation, we should never arrive
   12840  * here with a zero breakFlag because we always refresh rIBASE on
   12841  * return.
   12842  */
   12843     EXPORT_PC
   12844     movl   rSELF, %eax
   12845     movl   rPC, OUT_ARG0(%esp)
   12846     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12847     movl   rFP, OUT_ARG1(%esp)
   12848     je     1f                                # reload rIBASE & resume if not
   12849     movl   %eax, OUT_ARG2(%esp)
   12850     call   dvmCheckBefore                    # (dPC, dFP, self)
   12851     movl   rSELF, %eax
   12852 1:
   12853     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12854     jmp    *dvmAsmInstructionStart+(171*4)
   12855 
   12856 /* ------------------------------ */
   12857 .L_ALT_OP_SUB_DOUBLE: /* 0xac */
   12858 /* File: x86/alt_stub.S */
   12859 /*
   12860  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12861  * any interesting requests and then jump to the real instruction
   12862  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12863  * because rIBASE is caller save and we need to reload it.
   12864  *
   12865  * Note that unlike in the Arm implementation, we should never arrive
   12866  * here with a zero breakFlag because we always refresh rIBASE on
   12867  * return.
   12868  */
   12869     EXPORT_PC
   12870     movl   rSELF, %eax
   12871     movl   rPC, OUT_ARG0(%esp)
   12872     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12873     movl   rFP, OUT_ARG1(%esp)
   12874     je     1f                                # reload rIBASE & resume if not
   12875     movl   %eax, OUT_ARG2(%esp)
   12876     call   dvmCheckBefore                    # (dPC, dFP, self)
   12877     movl   rSELF, %eax
   12878 1:
   12879     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12880     jmp    *dvmAsmInstructionStart+(172*4)
   12881 
   12882 /* ------------------------------ */
   12883 .L_ALT_OP_MUL_DOUBLE: /* 0xad */
   12884 /* File: x86/alt_stub.S */
   12885 /*
   12886  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12887  * any interesting requests and then jump to the real instruction
   12888  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12889  * because rIBASE is caller save and we need to reload it.
   12890  *
   12891  * Note that unlike in the Arm implementation, we should never arrive
   12892  * here with a zero breakFlag because we always refresh rIBASE on
   12893  * return.
   12894  */
   12895     EXPORT_PC
   12896     movl   rSELF, %eax
   12897     movl   rPC, OUT_ARG0(%esp)
   12898     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12899     movl   rFP, OUT_ARG1(%esp)
   12900     je     1f                                # reload rIBASE & resume if not
   12901     movl   %eax, OUT_ARG2(%esp)
   12902     call   dvmCheckBefore                    # (dPC, dFP, self)
   12903     movl   rSELF, %eax
   12904 1:
   12905     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12906     jmp    *dvmAsmInstructionStart+(173*4)
   12907 
   12908 /* ------------------------------ */
   12909 .L_ALT_OP_DIV_DOUBLE: /* 0xae */
   12910 /* File: x86/alt_stub.S */
   12911 /*
   12912  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12913  * any interesting requests and then jump to the real instruction
   12914  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12915  * because rIBASE is caller save and we need to reload it.
   12916  *
   12917  * Note that unlike in the Arm implementation, we should never arrive
   12918  * here with a zero breakFlag because we always refresh rIBASE on
   12919  * return.
   12920  */
   12921     EXPORT_PC
   12922     movl   rSELF, %eax
   12923     movl   rPC, OUT_ARG0(%esp)
   12924     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12925     movl   rFP, OUT_ARG1(%esp)
   12926     je     1f                                # reload rIBASE & resume if not
   12927     movl   %eax, OUT_ARG2(%esp)
   12928     call   dvmCheckBefore                    # (dPC, dFP, self)
   12929     movl   rSELF, %eax
   12930 1:
   12931     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12932     jmp    *dvmAsmInstructionStart+(174*4)
   12933 
   12934 /* ------------------------------ */
   12935 .L_ALT_OP_REM_DOUBLE: /* 0xaf */
   12936 /* File: x86/alt_stub.S */
   12937 /*
   12938  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12939  * any interesting requests and then jump to the real instruction
   12940  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12941  * because rIBASE is caller save and we need to reload it.
   12942  *
   12943  * Note that unlike in the Arm implementation, we should never arrive
   12944  * here with a zero breakFlag because we always refresh rIBASE on
   12945  * return.
   12946  */
   12947     EXPORT_PC
   12948     movl   rSELF, %eax
   12949     movl   rPC, OUT_ARG0(%esp)
   12950     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12951     movl   rFP, OUT_ARG1(%esp)
   12952     je     1f                                # reload rIBASE & resume if not
   12953     movl   %eax, OUT_ARG2(%esp)
   12954     call   dvmCheckBefore                    # (dPC, dFP, self)
   12955     movl   rSELF, %eax
   12956 1:
   12957     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12958     jmp    *dvmAsmInstructionStart+(175*4)
   12959 
   12960 /* ------------------------------ */
   12961 .L_ALT_OP_ADD_INT_2ADDR: /* 0xb0 */
   12962 /* File: x86/alt_stub.S */
   12963 /*
   12964  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12965  * any interesting requests and then jump to the real instruction
   12966  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12967  * because rIBASE is caller save and we need to reload it.
   12968  *
   12969  * Note that unlike in the Arm implementation, we should never arrive
   12970  * here with a zero breakFlag because we always refresh rIBASE on
   12971  * return.
   12972  */
   12973     EXPORT_PC
   12974     movl   rSELF, %eax
   12975     movl   rPC, OUT_ARG0(%esp)
   12976     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   12977     movl   rFP, OUT_ARG1(%esp)
   12978     je     1f                                # reload rIBASE & resume if not
   12979     movl   %eax, OUT_ARG2(%esp)
   12980     call   dvmCheckBefore                    # (dPC, dFP, self)
   12981     movl   rSELF, %eax
   12982 1:
   12983     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   12984     jmp    *dvmAsmInstructionStart+(176*4)
   12985 
   12986 /* ------------------------------ */
   12987 .L_ALT_OP_SUB_INT_2ADDR: /* 0xb1 */
   12988 /* File: x86/alt_stub.S */
   12989 /*
   12990  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   12991  * any interesting requests and then jump to the real instruction
   12992  * handler.  Unlike the Arm handler, we can't do this as a tail call
   12993  * because rIBASE is caller save and we need to reload it.
   12994  *
   12995  * Note that unlike in the Arm implementation, we should never arrive
   12996  * here with a zero breakFlag because we always refresh rIBASE on
   12997  * return.
   12998  */
   12999     EXPORT_PC
   13000     movl   rSELF, %eax
   13001     movl   rPC, OUT_ARG0(%esp)
   13002     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13003     movl   rFP, OUT_ARG1(%esp)
   13004     je     1f                                # reload rIBASE & resume if not
   13005     movl   %eax, OUT_ARG2(%esp)
   13006     call   dvmCheckBefore                    # (dPC, dFP, self)
   13007     movl   rSELF, %eax
   13008 1:
   13009     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13010     jmp    *dvmAsmInstructionStart+(177*4)
   13011 
   13012 /* ------------------------------ */
   13013 .L_ALT_OP_MUL_INT_2ADDR: /* 0xb2 */
   13014 /* File: x86/alt_stub.S */
   13015 /*
   13016  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13017  * any interesting requests and then jump to the real instruction
   13018  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13019  * because rIBASE is caller save and we need to reload it.
   13020  *
   13021  * Note that unlike in the Arm implementation, we should never arrive
   13022  * here with a zero breakFlag because we always refresh rIBASE on
   13023  * return.
   13024  */
   13025     EXPORT_PC
   13026     movl   rSELF, %eax
   13027     movl   rPC, OUT_ARG0(%esp)
   13028     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13029     movl   rFP, OUT_ARG1(%esp)
   13030     je     1f                                # reload rIBASE & resume if not
   13031     movl   %eax, OUT_ARG2(%esp)
   13032     call   dvmCheckBefore                    # (dPC, dFP, self)
   13033     movl   rSELF, %eax
   13034 1:
   13035     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13036     jmp    *dvmAsmInstructionStart+(178*4)
   13037 
   13038 /* ------------------------------ */
   13039 .L_ALT_OP_DIV_INT_2ADDR: /* 0xb3 */
   13040 /* File: x86/alt_stub.S */
   13041 /*
   13042  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13043  * any interesting requests and then jump to the real instruction
   13044  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13045  * because rIBASE is caller save and we need to reload it.
   13046  *
   13047  * Note that unlike in the Arm implementation, we should never arrive
   13048  * here with a zero breakFlag because we always refresh rIBASE on
   13049  * return.
   13050  */
   13051     EXPORT_PC
   13052     movl   rSELF, %eax
   13053     movl   rPC, OUT_ARG0(%esp)
   13054     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13055     movl   rFP, OUT_ARG1(%esp)
   13056     je     1f                                # reload rIBASE & resume if not
   13057     movl   %eax, OUT_ARG2(%esp)
   13058     call   dvmCheckBefore                    # (dPC, dFP, self)
   13059     movl   rSELF, %eax
   13060 1:
   13061     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13062     jmp    *dvmAsmInstructionStart+(179*4)
   13063 
   13064 /* ------------------------------ */
   13065 .L_ALT_OP_REM_INT_2ADDR: /* 0xb4 */
   13066 /* File: x86/alt_stub.S */
   13067 /*
   13068  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13069  * any interesting requests and then jump to the real instruction
   13070  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13071  * because rIBASE is caller save and we need to reload it.
   13072  *
   13073  * Note that unlike in the Arm implementation, we should never arrive
   13074  * here with a zero breakFlag because we always refresh rIBASE on
   13075  * return.
   13076  */
   13077     EXPORT_PC
   13078     movl   rSELF, %eax
   13079     movl   rPC, OUT_ARG0(%esp)
   13080     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13081     movl   rFP, OUT_ARG1(%esp)
   13082     je     1f                                # reload rIBASE & resume if not
   13083     movl   %eax, OUT_ARG2(%esp)
   13084     call   dvmCheckBefore                    # (dPC, dFP, self)
   13085     movl   rSELF, %eax
   13086 1:
   13087     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13088     jmp    *dvmAsmInstructionStart+(180*4)
   13089 
   13090 /* ------------------------------ */
   13091 .L_ALT_OP_AND_INT_2ADDR: /* 0xb5 */
   13092 /* File: x86/alt_stub.S */
   13093 /*
   13094  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13095  * any interesting requests and then jump to the real instruction
   13096  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13097  * because rIBASE is caller save and we need to reload it.
   13098  *
   13099  * Note that unlike in the Arm implementation, we should never arrive
   13100  * here with a zero breakFlag because we always refresh rIBASE on
   13101  * return.
   13102  */
   13103     EXPORT_PC
   13104     movl   rSELF, %eax
   13105     movl   rPC, OUT_ARG0(%esp)
   13106     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13107     movl   rFP, OUT_ARG1(%esp)
   13108     je     1f                                # reload rIBASE & resume if not
   13109     movl   %eax, OUT_ARG2(%esp)
   13110     call   dvmCheckBefore                    # (dPC, dFP, self)
   13111     movl   rSELF, %eax
   13112 1:
   13113     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13114     jmp    *dvmAsmInstructionStart+(181*4)
   13115 
   13116 /* ------------------------------ */
   13117 .L_ALT_OP_OR_INT_2ADDR: /* 0xb6 */
   13118 /* File: x86/alt_stub.S */
   13119 /*
   13120  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13121  * any interesting requests and then jump to the real instruction
   13122  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13123  * because rIBASE is caller save and we need to reload it.
   13124  *
   13125  * Note that unlike in the Arm implementation, we should never arrive
   13126  * here with a zero breakFlag because we always refresh rIBASE on
   13127  * return.
   13128  */
   13129     EXPORT_PC
   13130     movl   rSELF, %eax
   13131     movl   rPC, OUT_ARG0(%esp)
   13132     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13133     movl   rFP, OUT_ARG1(%esp)
   13134     je     1f                                # reload rIBASE & resume if not
   13135     movl   %eax, OUT_ARG2(%esp)
   13136     call   dvmCheckBefore                    # (dPC, dFP, self)
   13137     movl   rSELF, %eax
   13138 1:
   13139     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13140     jmp    *dvmAsmInstructionStart+(182*4)
   13141 
   13142 /* ------------------------------ */
   13143 .L_ALT_OP_XOR_INT_2ADDR: /* 0xb7 */
   13144 /* File: x86/alt_stub.S */
   13145 /*
   13146  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13147  * any interesting requests and then jump to the real instruction
   13148  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13149  * because rIBASE is caller save and we need to reload it.
   13150  *
   13151  * Note that unlike in the Arm implementation, we should never arrive
   13152  * here with a zero breakFlag because we always refresh rIBASE on
   13153  * return.
   13154  */
   13155     EXPORT_PC
   13156     movl   rSELF, %eax
   13157     movl   rPC, OUT_ARG0(%esp)
   13158     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13159     movl   rFP, OUT_ARG1(%esp)
   13160     je     1f                                # reload rIBASE & resume if not
   13161     movl   %eax, OUT_ARG2(%esp)
   13162     call   dvmCheckBefore                    # (dPC, dFP, self)
   13163     movl   rSELF, %eax
   13164 1:
   13165     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13166     jmp    *dvmAsmInstructionStart+(183*4)
   13167 
   13168 /* ------------------------------ */
   13169 .L_ALT_OP_SHL_INT_2ADDR: /* 0xb8 */
   13170 /* File: x86/alt_stub.S */
   13171 /*
   13172  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13173  * any interesting requests and then jump to the real instruction
   13174  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13175  * because rIBASE is caller save and we need to reload it.
   13176  *
   13177  * Note that unlike in the Arm implementation, we should never arrive
   13178  * here with a zero breakFlag because we always refresh rIBASE on
   13179  * return.
   13180  */
   13181     EXPORT_PC
   13182     movl   rSELF, %eax
   13183     movl   rPC, OUT_ARG0(%esp)
   13184     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13185     movl   rFP, OUT_ARG1(%esp)
   13186     je     1f                                # reload rIBASE & resume if not
   13187     movl   %eax, OUT_ARG2(%esp)
   13188     call   dvmCheckBefore                    # (dPC, dFP, self)
   13189     movl   rSELF, %eax
   13190 1:
   13191     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13192     jmp    *dvmAsmInstructionStart+(184*4)
   13193 
   13194 /* ------------------------------ */
   13195 .L_ALT_OP_SHR_INT_2ADDR: /* 0xb9 */
   13196 /* File: x86/alt_stub.S */
   13197 /*
   13198  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13199  * any interesting requests and then jump to the real instruction
   13200  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13201  * because rIBASE is caller save and we need to reload it.
   13202  *
   13203  * Note that unlike in the Arm implementation, we should never arrive
   13204  * here with a zero breakFlag because we always refresh rIBASE on
   13205  * return.
   13206  */
   13207     EXPORT_PC
   13208     movl   rSELF, %eax
   13209     movl   rPC, OUT_ARG0(%esp)
   13210     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13211     movl   rFP, OUT_ARG1(%esp)
   13212     je     1f                                # reload rIBASE & resume if not
   13213     movl   %eax, OUT_ARG2(%esp)
   13214     call   dvmCheckBefore                    # (dPC, dFP, self)
   13215     movl   rSELF, %eax
   13216 1:
   13217     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13218     jmp    *dvmAsmInstructionStart+(185*4)
   13219 
   13220 /* ------------------------------ */
   13221 .L_ALT_OP_USHR_INT_2ADDR: /* 0xba */
   13222 /* File: x86/alt_stub.S */
   13223 /*
   13224  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13225  * any interesting requests and then jump to the real instruction
   13226  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13227  * because rIBASE is caller save and we need to reload it.
   13228  *
   13229  * Note that unlike in the Arm implementation, we should never arrive
   13230  * here with a zero breakFlag because we always refresh rIBASE on
   13231  * return.
   13232  */
   13233     EXPORT_PC
   13234     movl   rSELF, %eax
   13235     movl   rPC, OUT_ARG0(%esp)
   13236     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13237     movl   rFP, OUT_ARG1(%esp)
   13238     je     1f                                # reload rIBASE & resume if not
   13239     movl   %eax, OUT_ARG2(%esp)
   13240     call   dvmCheckBefore                    # (dPC, dFP, self)
   13241     movl   rSELF, %eax
   13242 1:
   13243     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13244     jmp    *dvmAsmInstructionStart+(186*4)
   13245 
   13246 /* ------------------------------ */
   13247 .L_ALT_OP_ADD_LONG_2ADDR: /* 0xbb */
   13248 /* File: x86/alt_stub.S */
   13249 /*
   13250  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13251  * any interesting requests and then jump to the real instruction
   13252  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13253  * because rIBASE is caller save and we need to reload it.
   13254  *
   13255  * Note that unlike in the Arm implementation, we should never arrive
   13256  * here with a zero breakFlag because we always refresh rIBASE on
   13257  * return.
   13258  */
   13259     EXPORT_PC
   13260     movl   rSELF, %eax
   13261     movl   rPC, OUT_ARG0(%esp)
   13262     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13263     movl   rFP, OUT_ARG1(%esp)
   13264     je     1f                                # reload rIBASE & resume if not
   13265     movl   %eax, OUT_ARG2(%esp)
   13266     call   dvmCheckBefore                    # (dPC, dFP, self)
   13267     movl   rSELF, %eax
   13268 1:
   13269     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13270     jmp    *dvmAsmInstructionStart+(187*4)
   13271 
   13272 /* ------------------------------ */
   13273 .L_ALT_OP_SUB_LONG_2ADDR: /* 0xbc */
   13274 /* File: x86/alt_stub.S */
   13275 /*
   13276  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13277  * any interesting requests and then jump to the real instruction
   13278  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13279  * because rIBASE is caller save and we need to reload it.
   13280  *
   13281  * Note that unlike in the Arm implementation, we should never arrive
   13282  * here with a zero breakFlag because we always refresh rIBASE on
   13283  * return.
   13284  */
   13285     EXPORT_PC
   13286     movl   rSELF, %eax
   13287     movl   rPC, OUT_ARG0(%esp)
   13288     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13289     movl   rFP, OUT_ARG1(%esp)
   13290     je     1f                                # reload rIBASE & resume if not
   13291     movl   %eax, OUT_ARG2(%esp)
   13292     call   dvmCheckBefore                    # (dPC, dFP, self)
   13293     movl   rSELF, %eax
   13294 1:
   13295     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13296     jmp    *dvmAsmInstructionStart+(188*4)
   13297 
   13298 /* ------------------------------ */
   13299 .L_ALT_OP_MUL_LONG_2ADDR: /* 0xbd */
   13300 /* File: x86/alt_stub.S */
   13301 /*
   13302  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13303  * any interesting requests and then jump to the real instruction
   13304  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13305  * because rIBASE is caller save and we need to reload it.
   13306  *
   13307  * Note that unlike in the Arm implementation, we should never arrive
   13308  * here with a zero breakFlag because we always refresh rIBASE on
   13309  * return.
   13310  */
   13311     EXPORT_PC
   13312     movl   rSELF, %eax
   13313     movl   rPC, OUT_ARG0(%esp)
   13314     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13315     movl   rFP, OUT_ARG1(%esp)
   13316     je     1f                                # reload rIBASE & resume if not
   13317     movl   %eax, OUT_ARG2(%esp)
   13318     call   dvmCheckBefore                    # (dPC, dFP, self)
   13319     movl   rSELF, %eax
   13320 1:
   13321     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13322     jmp    *dvmAsmInstructionStart+(189*4)
   13323 
   13324 /* ------------------------------ */
   13325 .L_ALT_OP_DIV_LONG_2ADDR: /* 0xbe */
   13326 /* File: x86/alt_stub.S */
   13327 /*
   13328  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13329  * any interesting requests and then jump to the real instruction
   13330  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13331  * because rIBASE is caller save and we need to reload it.
   13332  *
   13333  * Note that unlike in the Arm implementation, we should never arrive
   13334  * here with a zero breakFlag because we always refresh rIBASE on
   13335  * return.
   13336  */
   13337     EXPORT_PC
   13338     movl   rSELF, %eax
   13339     movl   rPC, OUT_ARG0(%esp)
   13340     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13341     movl   rFP, OUT_ARG1(%esp)
   13342     je     1f                                # reload rIBASE & resume if not
   13343     movl   %eax, OUT_ARG2(%esp)
   13344     call   dvmCheckBefore                    # (dPC, dFP, self)
   13345     movl   rSELF, %eax
   13346 1:
   13347     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13348     jmp    *dvmAsmInstructionStart+(190*4)
   13349 
   13350 /* ------------------------------ */
   13351 .L_ALT_OP_REM_LONG_2ADDR: /* 0xbf */
   13352 /* File: x86/alt_stub.S */
   13353 /*
   13354  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13355  * any interesting requests and then jump to the real instruction
   13356  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13357  * because rIBASE is caller save and we need to reload it.
   13358  *
   13359  * Note that unlike in the Arm implementation, we should never arrive
   13360  * here with a zero breakFlag because we always refresh rIBASE on
   13361  * return.
   13362  */
   13363     EXPORT_PC
   13364     movl   rSELF, %eax
   13365     movl   rPC, OUT_ARG0(%esp)
   13366     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13367     movl   rFP, OUT_ARG1(%esp)
   13368     je     1f                                # reload rIBASE & resume if not
   13369     movl   %eax, OUT_ARG2(%esp)
   13370     call   dvmCheckBefore                    # (dPC, dFP, self)
   13371     movl   rSELF, %eax
   13372 1:
   13373     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13374     jmp    *dvmAsmInstructionStart+(191*4)
   13375 
   13376 /* ------------------------------ */
   13377 .L_ALT_OP_AND_LONG_2ADDR: /* 0xc0 */
   13378 /* File: x86/alt_stub.S */
   13379 /*
   13380  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13381  * any interesting requests and then jump to the real instruction
   13382  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13383  * because rIBASE is caller save and we need to reload it.
   13384  *
   13385  * Note that unlike in the Arm implementation, we should never arrive
   13386  * here with a zero breakFlag because we always refresh rIBASE on
   13387  * return.
   13388  */
   13389     EXPORT_PC
   13390     movl   rSELF, %eax
   13391     movl   rPC, OUT_ARG0(%esp)
   13392     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13393     movl   rFP, OUT_ARG1(%esp)
   13394     je     1f                                # reload rIBASE & resume if not
   13395     movl   %eax, OUT_ARG2(%esp)
   13396     call   dvmCheckBefore                    # (dPC, dFP, self)
   13397     movl   rSELF, %eax
   13398 1:
   13399     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13400     jmp    *dvmAsmInstructionStart+(192*4)
   13401 
   13402 /* ------------------------------ */
   13403 .L_ALT_OP_OR_LONG_2ADDR: /* 0xc1 */
   13404 /* File: x86/alt_stub.S */
   13405 /*
   13406  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13407  * any interesting requests and then jump to the real instruction
   13408  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13409  * because rIBASE is caller save and we need to reload it.
   13410  *
   13411  * Note that unlike in the Arm implementation, we should never arrive
   13412  * here with a zero breakFlag because we always refresh rIBASE on
   13413  * return.
   13414  */
   13415     EXPORT_PC
   13416     movl   rSELF, %eax
   13417     movl   rPC, OUT_ARG0(%esp)
   13418     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13419     movl   rFP, OUT_ARG1(%esp)
   13420     je     1f                                # reload rIBASE & resume if not
   13421     movl   %eax, OUT_ARG2(%esp)
   13422     call   dvmCheckBefore                    # (dPC, dFP, self)
   13423     movl   rSELF, %eax
   13424 1:
   13425     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13426     jmp    *dvmAsmInstructionStart+(193*4)
   13427 
   13428 /* ------------------------------ */
   13429 .L_ALT_OP_XOR_LONG_2ADDR: /* 0xc2 */
   13430 /* File: x86/alt_stub.S */
   13431 /*
   13432  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13433  * any interesting requests and then jump to the real instruction
   13434  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13435  * because rIBASE is caller save and we need to reload it.
   13436  *
   13437  * Note that unlike in the Arm implementation, we should never arrive
   13438  * here with a zero breakFlag because we always refresh rIBASE on
   13439  * return.
   13440  */
   13441     EXPORT_PC
   13442     movl   rSELF, %eax
   13443     movl   rPC, OUT_ARG0(%esp)
   13444     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13445     movl   rFP, OUT_ARG1(%esp)
   13446     je     1f                                # reload rIBASE & resume if not
   13447     movl   %eax, OUT_ARG2(%esp)
   13448     call   dvmCheckBefore                    # (dPC, dFP, self)
   13449     movl   rSELF, %eax
   13450 1:
   13451     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13452     jmp    *dvmAsmInstructionStart+(194*4)
   13453 
   13454 /* ------------------------------ */
   13455 .L_ALT_OP_SHL_LONG_2ADDR: /* 0xc3 */
   13456 /* File: x86/alt_stub.S */
   13457 /*
   13458  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13459  * any interesting requests and then jump to the real instruction
   13460  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13461  * because rIBASE is caller save and we need to reload it.
   13462  *
   13463  * Note that unlike in the Arm implementation, we should never arrive
   13464  * here with a zero breakFlag because we always refresh rIBASE on
   13465  * return.
   13466  */
   13467     EXPORT_PC
   13468     movl   rSELF, %eax
   13469     movl   rPC, OUT_ARG0(%esp)
   13470     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13471     movl   rFP, OUT_ARG1(%esp)
   13472     je     1f                                # reload rIBASE & resume if not
   13473     movl   %eax, OUT_ARG2(%esp)
   13474     call   dvmCheckBefore                    # (dPC, dFP, self)
   13475     movl   rSELF, %eax
   13476 1:
   13477     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13478     jmp    *dvmAsmInstructionStart+(195*4)
   13479 
   13480 /* ------------------------------ */
   13481 .L_ALT_OP_SHR_LONG_2ADDR: /* 0xc4 */
   13482 /* File: x86/alt_stub.S */
   13483 /*
   13484  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13485  * any interesting requests and then jump to the real instruction
   13486  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13487  * because rIBASE is caller save and we need to reload it.
   13488  *
   13489  * Note that unlike in the Arm implementation, we should never arrive
   13490  * here with a zero breakFlag because we always refresh rIBASE on
   13491  * return.
   13492  */
   13493     EXPORT_PC
   13494     movl   rSELF, %eax
   13495     movl   rPC, OUT_ARG0(%esp)
   13496     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13497     movl   rFP, OUT_ARG1(%esp)
   13498     je     1f                                # reload rIBASE & resume if not
   13499     movl   %eax, OUT_ARG2(%esp)
   13500     call   dvmCheckBefore                    # (dPC, dFP, self)
   13501     movl   rSELF, %eax
   13502 1:
   13503     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13504     jmp    *dvmAsmInstructionStart+(196*4)
   13505 
   13506 /* ------------------------------ */
   13507 .L_ALT_OP_USHR_LONG_2ADDR: /* 0xc5 */
   13508 /* File: x86/alt_stub.S */
   13509 /*
   13510  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13511  * any interesting requests and then jump to the real instruction
   13512  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13513  * because rIBASE is caller save and we need to reload it.
   13514  *
   13515  * Note that unlike in the Arm implementation, we should never arrive
   13516  * here with a zero breakFlag because we always refresh rIBASE on
   13517  * return.
   13518  */
   13519     EXPORT_PC
   13520     movl   rSELF, %eax
   13521     movl   rPC, OUT_ARG0(%esp)
   13522     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13523     movl   rFP, OUT_ARG1(%esp)
   13524     je     1f                                # reload rIBASE & resume if not
   13525     movl   %eax, OUT_ARG2(%esp)
   13526     call   dvmCheckBefore                    # (dPC, dFP, self)
   13527     movl   rSELF, %eax
   13528 1:
   13529     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13530     jmp    *dvmAsmInstructionStart+(197*4)
   13531 
   13532 /* ------------------------------ */
   13533 .L_ALT_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
   13534 /* File: x86/alt_stub.S */
   13535 /*
   13536  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13537  * any interesting requests and then jump to the real instruction
   13538  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13539  * because rIBASE is caller save and we need to reload it.
   13540  *
   13541  * Note that unlike in the Arm implementation, we should never arrive
   13542  * here with a zero breakFlag because we always refresh rIBASE on
   13543  * return.
   13544  */
   13545     EXPORT_PC
   13546     movl   rSELF, %eax
   13547     movl   rPC, OUT_ARG0(%esp)
   13548     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13549     movl   rFP, OUT_ARG1(%esp)
   13550     je     1f                                # reload rIBASE & resume if not
   13551     movl   %eax, OUT_ARG2(%esp)
   13552     call   dvmCheckBefore                    # (dPC, dFP, self)
   13553     movl   rSELF, %eax
   13554 1:
   13555     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13556     jmp    *dvmAsmInstructionStart+(198*4)
   13557 
   13558 /* ------------------------------ */
   13559 .L_ALT_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
   13560 /* File: x86/alt_stub.S */
   13561 /*
   13562  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13563  * any interesting requests and then jump to the real instruction
   13564  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13565  * because rIBASE is caller save and we need to reload it.
   13566  *
   13567  * Note that unlike in the Arm implementation, we should never arrive
   13568  * here with a zero breakFlag because we always refresh rIBASE on
   13569  * return.
   13570  */
   13571     EXPORT_PC
   13572     movl   rSELF, %eax
   13573     movl   rPC, OUT_ARG0(%esp)
   13574     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13575     movl   rFP, OUT_ARG1(%esp)
   13576     je     1f                                # reload rIBASE & resume if not
   13577     movl   %eax, OUT_ARG2(%esp)
   13578     call   dvmCheckBefore                    # (dPC, dFP, self)
   13579     movl   rSELF, %eax
   13580 1:
   13581     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13582     jmp    *dvmAsmInstructionStart+(199*4)
   13583 
   13584 /* ------------------------------ */
   13585 .L_ALT_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
   13586 /* File: x86/alt_stub.S */
   13587 /*
   13588  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13589  * any interesting requests and then jump to the real instruction
   13590  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13591  * because rIBASE is caller save and we need to reload it.
   13592  *
   13593  * Note that unlike in the Arm implementation, we should never arrive
   13594  * here with a zero breakFlag because we always refresh rIBASE on
   13595  * return.
   13596  */
   13597     EXPORT_PC
   13598     movl   rSELF, %eax
   13599     movl   rPC, OUT_ARG0(%esp)
   13600     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13601     movl   rFP, OUT_ARG1(%esp)
   13602     je     1f                                # reload rIBASE & resume if not
   13603     movl   %eax, OUT_ARG2(%esp)
   13604     call   dvmCheckBefore                    # (dPC, dFP, self)
   13605     movl   rSELF, %eax
   13606 1:
   13607     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13608     jmp    *dvmAsmInstructionStart+(200*4)
   13609 
   13610 /* ------------------------------ */
   13611 .L_ALT_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
   13612 /* File: x86/alt_stub.S */
   13613 /*
   13614  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13615  * any interesting requests and then jump to the real instruction
   13616  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13617  * because rIBASE is caller save and we need to reload it.
   13618  *
   13619  * Note that unlike in the Arm implementation, we should never arrive
   13620  * here with a zero breakFlag because we always refresh rIBASE on
   13621  * return.
   13622  */
   13623     EXPORT_PC
   13624     movl   rSELF, %eax
   13625     movl   rPC, OUT_ARG0(%esp)
   13626     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13627     movl   rFP, OUT_ARG1(%esp)
   13628     je     1f                                # reload rIBASE & resume if not
   13629     movl   %eax, OUT_ARG2(%esp)
   13630     call   dvmCheckBefore                    # (dPC, dFP, self)
   13631     movl   rSELF, %eax
   13632 1:
   13633     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13634     jmp    *dvmAsmInstructionStart+(201*4)
   13635 
   13636 /* ------------------------------ */
   13637 .L_ALT_OP_REM_FLOAT_2ADDR: /* 0xca */
   13638 /* File: x86/alt_stub.S */
   13639 /*
   13640  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13641  * any interesting requests and then jump to the real instruction
   13642  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13643  * because rIBASE is caller save and we need to reload it.
   13644  *
   13645  * Note that unlike in the Arm implementation, we should never arrive
   13646  * here with a zero breakFlag because we always refresh rIBASE on
   13647  * return.
   13648  */
   13649     EXPORT_PC
   13650     movl   rSELF, %eax
   13651     movl   rPC, OUT_ARG0(%esp)
   13652     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13653     movl   rFP, OUT_ARG1(%esp)
   13654     je     1f                                # reload rIBASE & resume if not
   13655     movl   %eax, OUT_ARG2(%esp)
   13656     call   dvmCheckBefore                    # (dPC, dFP, self)
   13657     movl   rSELF, %eax
   13658 1:
   13659     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13660     jmp    *dvmAsmInstructionStart+(202*4)
   13661 
   13662 /* ------------------------------ */
   13663 .L_ALT_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
   13664 /* File: x86/alt_stub.S */
   13665 /*
   13666  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13667  * any interesting requests and then jump to the real instruction
   13668  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13669  * because rIBASE is caller save and we need to reload it.
   13670  *
   13671  * Note that unlike in the Arm implementation, we should never arrive
   13672  * here with a zero breakFlag because we always refresh rIBASE on
   13673  * return.
   13674  */
   13675     EXPORT_PC
   13676     movl   rSELF, %eax
   13677     movl   rPC, OUT_ARG0(%esp)
   13678     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13679     movl   rFP, OUT_ARG1(%esp)
   13680     je     1f                                # reload rIBASE & resume if not
   13681     movl   %eax, OUT_ARG2(%esp)
   13682     call   dvmCheckBefore                    # (dPC, dFP, self)
   13683     movl   rSELF, %eax
   13684 1:
   13685     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13686     jmp    *dvmAsmInstructionStart+(203*4)
   13687 
   13688 /* ------------------------------ */
   13689 .L_ALT_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
   13690 /* File: x86/alt_stub.S */
   13691 /*
   13692  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13693  * any interesting requests and then jump to the real instruction
   13694  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13695  * because rIBASE is caller save and we need to reload it.
   13696  *
   13697  * Note that unlike in the Arm implementation, we should never arrive
   13698  * here with a zero breakFlag because we always refresh rIBASE on
   13699  * return.
   13700  */
   13701     EXPORT_PC
   13702     movl   rSELF, %eax
   13703     movl   rPC, OUT_ARG0(%esp)
   13704     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13705     movl   rFP, OUT_ARG1(%esp)
   13706     je     1f                                # reload rIBASE & resume if not
   13707     movl   %eax, OUT_ARG2(%esp)
   13708     call   dvmCheckBefore                    # (dPC, dFP, self)
   13709     movl   rSELF, %eax
   13710 1:
   13711     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13712     jmp    *dvmAsmInstructionStart+(204*4)
   13713 
   13714 /* ------------------------------ */
   13715 .L_ALT_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
   13716 /* File: x86/alt_stub.S */
   13717 /*
   13718  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13719  * any interesting requests and then jump to the real instruction
   13720  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13721  * because rIBASE is caller save and we need to reload it.
   13722  *
   13723  * Note that unlike in the Arm implementation, we should never arrive
   13724  * here with a zero breakFlag because we always refresh rIBASE on
   13725  * return.
   13726  */
   13727     EXPORT_PC
   13728     movl   rSELF, %eax
   13729     movl   rPC, OUT_ARG0(%esp)
   13730     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13731     movl   rFP, OUT_ARG1(%esp)
   13732     je     1f                                # reload rIBASE & resume if not
   13733     movl   %eax, OUT_ARG2(%esp)
   13734     call   dvmCheckBefore                    # (dPC, dFP, self)
   13735     movl   rSELF, %eax
   13736 1:
   13737     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13738     jmp    *dvmAsmInstructionStart+(205*4)
   13739 
   13740 /* ------------------------------ */
   13741 .L_ALT_OP_DIV_DOUBLE_2ADDR: /* 0xce */
   13742 /* File: x86/alt_stub.S */
   13743 /*
   13744  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13745  * any interesting requests and then jump to the real instruction
   13746  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13747  * because rIBASE is caller save and we need to reload it.
   13748  *
   13749  * Note that unlike in the Arm implementation, we should never arrive
   13750  * here with a zero breakFlag because we always refresh rIBASE on
   13751  * return.
   13752  */
   13753     EXPORT_PC
   13754     movl   rSELF, %eax
   13755     movl   rPC, OUT_ARG0(%esp)
   13756     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13757     movl   rFP, OUT_ARG1(%esp)
   13758     je     1f                                # reload rIBASE & resume if not
   13759     movl   %eax, OUT_ARG2(%esp)
   13760     call   dvmCheckBefore                    # (dPC, dFP, self)
   13761     movl   rSELF, %eax
   13762 1:
   13763     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13764     jmp    *dvmAsmInstructionStart+(206*4)
   13765 
   13766 /* ------------------------------ */
   13767 .L_ALT_OP_REM_DOUBLE_2ADDR: /* 0xcf */
   13768 /* File: x86/alt_stub.S */
   13769 /*
   13770  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13771  * any interesting requests and then jump to the real instruction
   13772  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13773  * because rIBASE is caller save and we need to reload it.
   13774  *
   13775  * Note that unlike in the Arm implementation, we should never arrive
   13776  * here with a zero breakFlag because we always refresh rIBASE on
   13777  * return.
   13778  */
   13779     EXPORT_PC
   13780     movl   rSELF, %eax
   13781     movl   rPC, OUT_ARG0(%esp)
   13782     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13783     movl   rFP, OUT_ARG1(%esp)
   13784     je     1f                                # reload rIBASE & resume if not
   13785     movl   %eax, OUT_ARG2(%esp)
   13786     call   dvmCheckBefore                    # (dPC, dFP, self)
   13787     movl   rSELF, %eax
   13788 1:
   13789     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13790     jmp    *dvmAsmInstructionStart+(207*4)
   13791 
   13792 /* ------------------------------ */
   13793 .L_ALT_OP_ADD_INT_LIT16: /* 0xd0 */
   13794 /* File: x86/alt_stub.S */
   13795 /*
   13796  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13797  * any interesting requests and then jump to the real instruction
   13798  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13799  * because rIBASE is caller save and we need to reload it.
   13800  *
   13801  * Note that unlike in the Arm implementation, we should never arrive
   13802  * here with a zero breakFlag because we always refresh rIBASE on
   13803  * return.
   13804  */
   13805     EXPORT_PC
   13806     movl   rSELF, %eax
   13807     movl   rPC, OUT_ARG0(%esp)
   13808     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13809     movl   rFP, OUT_ARG1(%esp)
   13810     je     1f                                # reload rIBASE & resume if not
   13811     movl   %eax, OUT_ARG2(%esp)
   13812     call   dvmCheckBefore                    # (dPC, dFP, self)
   13813     movl   rSELF, %eax
   13814 1:
   13815     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13816     jmp    *dvmAsmInstructionStart+(208*4)
   13817 
   13818 /* ------------------------------ */
   13819 .L_ALT_OP_RSUB_INT: /* 0xd1 */
   13820 /* File: x86/alt_stub.S */
   13821 /*
   13822  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13823  * any interesting requests and then jump to the real instruction
   13824  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13825  * because rIBASE is caller save and we need to reload it.
   13826  *
   13827  * Note that unlike in the Arm implementation, we should never arrive
   13828  * here with a zero breakFlag because we always refresh rIBASE on
   13829  * return.
   13830  */
   13831     EXPORT_PC
   13832     movl   rSELF, %eax
   13833     movl   rPC, OUT_ARG0(%esp)
   13834     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13835     movl   rFP, OUT_ARG1(%esp)
   13836     je     1f                                # reload rIBASE & resume if not
   13837     movl   %eax, OUT_ARG2(%esp)
   13838     call   dvmCheckBefore                    # (dPC, dFP, self)
   13839     movl   rSELF, %eax
   13840 1:
   13841     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13842     jmp    *dvmAsmInstructionStart+(209*4)
   13843 
   13844 /* ------------------------------ */
   13845 .L_ALT_OP_MUL_INT_LIT16: /* 0xd2 */
   13846 /* File: x86/alt_stub.S */
   13847 /*
   13848  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13849  * any interesting requests and then jump to the real instruction
   13850  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13851  * because rIBASE is caller save and we need to reload it.
   13852  *
   13853  * Note that unlike in the Arm implementation, we should never arrive
   13854  * here with a zero breakFlag because we always refresh rIBASE on
   13855  * return.
   13856  */
   13857     EXPORT_PC
   13858     movl   rSELF, %eax
   13859     movl   rPC, OUT_ARG0(%esp)
   13860     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13861     movl   rFP, OUT_ARG1(%esp)
   13862     je     1f                                # reload rIBASE & resume if not
   13863     movl   %eax, OUT_ARG2(%esp)
   13864     call   dvmCheckBefore                    # (dPC, dFP, self)
   13865     movl   rSELF, %eax
   13866 1:
   13867     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13868     jmp    *dvmAsmInstructionStart+(210*4)
   13869 
   13870 /* ------------------------------ */
   13871 .L_ALT_OP_DIV_INT_LIT16: /* 0xd3 */
   13872 /* File: x86/alt_stub.S */
   13873 /*
   13874  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13875  * any interesting requests and then jump to the real instruction
   13876  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13877  * because rIBASE is caller save and we need to reload it.
   13878  *
   13879  * Note that unlike in the Arm implementation, we should never arrive
   13880  * here with a zero breakFlag because we always refresh rIBASE on
   13881  * return.
   13882  */
   13883     EXPORT_PC
   13884     movl   rSELF, %eax
   13885     movl   rPC, OUT_ARG0(%esp)
   13886     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13887     movl   rFP, OUT_ARG1(%esp)
   13888     je     1f                                # reload rIBASE & resume if not
   13889     movl   %eax, OUT_ARG2(%esp)
   13890     call   dvmCheckBefore                    # (dPC, dFP, self)
   13891     movl   rSELF, %eax
   13892 1:
   13893     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13894     jmp    *dvmAsmInstructionStart+(211*4)
   13895 
   13896 /* ------------------------------ */
   13897 .L_ALT_OP_REM_INT_LIT16: /* 0xd4 */
   13898 /* File: x86/alt_stub.S */
   13899 /*
   13900  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13901  * any interesting requests and then jump to the real instruction
   13902  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13903  * because rIBASE is caller save and we need to reload it.
   13904  *
   13905  * Note that unlike in the Arm implementation, we should never arrive
   13906  * here with a zero breakFlag because we always refresh rIBASE on
   13907  * return.
   13908  */
   13909     EXPORT_PC
   13910     movl   rSELF, %eax
   13911     movl   rPC, OUT_ARG0(%esp)
   13912     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13913     movl   rFP, OUT_ARG1(%esp)
   13914     je     1f                                # reload rIBASE & resume if not
   13915     movl   %eax, OUT_ARG2(%esp)
   13916     call   dvmCheckBefore                    # (dPC, dFP, self)
   13917     movl   rSELF, %eax
   13918 1:
   13919     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13920     jmp    *dvmAsmInstructionStart+(212*4)
   13921 
   13922 /* ------------------------------ */
   13923 .L_ALT_OP_AND_INT_LIT16: /* 0xd5 */
   13924 /* File: x86/alt_stub.S */
   13925 /*
   13926  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13927  * any interesting requests and then jump to the real instruction
   13928  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13929  * because rIBASE is caller save and we need to reload it.
   13930  *
   13931  * Note that unlike in the Arm implementation, we should never arrive
   13932  * here with a zero breakFlag because we always refresh rIBASE on
   13933  * return.
   13934  */
   13935     EXPORT_PC
   13936     movl   rSELF, %eax
   13937     movl   rPC, OUT_ARG0(%esp)
   13938     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13939     movl   rFP, OUT_ARG1(%esp)
   13940     je     1f                                # reload rIBASE & resume if not
   13941     movl   %eax, OUT_ARG2(%esp)
   13942     call   dvmCheckBefore                    # (dPC, dFP, self)
   13943     movl   rSELF, %eax
   13944 1:
   13945     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13946     jmp    *dvmAsmInstructionStart+(213*4)
   13947 
   13948 /* ------------------------------ */
   13949 .L_ALT_OP_OR_INT_LIT16: /* 0xd6 */
   13950 /* File: x86/alt_stub.S */
   13951 /*
   13952  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13953  * any interesting requests and then jump to the real instruction
   13954  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13955  * because rIBASE is caller save and we need to reload it.
   13956  *
   13957  * Note that unlike in the Arm implementation, we should never arrive
   13958  * here with a zero breakFlag because we always refresh rIBASE on
   13959  * return.
   13960  */
   13961     EXPORT_PC
   13962     movl   rSELF, %eax
   13963     movl   rPC, OUT_ARG0(%esp)
   13964     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13965     movl   rFP, OUT_ARG1(%esp)
   13966     je     1f                                # reload rIBASE & resume if not
   13967     movl   %eax, OUT_ARG2(%esp)
   13968     call   dvmCheckBefore                    # (dPC, dFP, self)
   13969     movl   rSELF, %eax
   13970 1:
   13971     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13972     jmp    *dvmAsmInstructionStart+(214*4)
   13973 
   13974 /* ------------------------------ */
   13975 .L_ALT_OP_XOR_INT_LIT16: /* 0xd7 */
   13976 /* File: x86/alt_stub.S */
   13977 /*
   13978  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   13979  * any interesting requests and then jump to the real instruction
   13980  * handler.  Unlike the Arm handler, we can't do this as a tail call
   13981  * because rIBASE is caller save and we need to reload it.
   13982  *
   13983  * Note that unlike in the Arm implementation, we should never arrive
   13984  * here with a zero breakFlag because we always refresh rIBASE on
   13985  * return.
   13986  */
   13987     EXPORT_PC
   13988     movl   rSELF, %eax
   13989     movl   rPC, OUT_ARG0(%esp)
   13990     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   13991     movl   rFP, OUT_ARG1(%esp)
   13992     je     1f                                # reload rIBASE & resume if not
   13993     movl   %eax, OUT_ARG2(%esp)
   13994     call   dvmCheckBefore                    # (dPC, dFP, self)
   13995     movl   rSELF, %eax
   13996 1:
   13997     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   13998     jmp    *dvmAsmInstructionStart+(215*4)
   13999 
   14000 /* ------------------------------ */
   14001 .L_ALT_OP_ADD_INT_LIT8: /* 0xd8 */
   14002 /* File: x86/alt_stub.S */
   14003 /*
   14004  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14005  * any interesting requests and then jump to the real instruction
   14006  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14007  * because rIBASE is caller save and we need to reload it.
   14008  *
   14009  * Note that unlike in the Arm implementation, we should never arrive
   14010  * here with a zero breakFlag because we always refresh rIBASE on
   14011  * return.
   14012  */
   14013     EXPORT_PC
   14014     movl   rSELF, %eax
   14015     movl   rPC, OUT_ARG0(%esp)
   14016     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14017     movl   rFP, OUT_ARG1(%esp)
   14018     je     1f                                # reload rIBASE & resume if not
   14019     movl   %eax, OUT_ARG2(%esp)
   14020     call   dvmCheckBefore                    # (dPC, dFP, self)
   14021     movl   rSELF, %eax
   14022 1:
   14023     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14024     jmp    *dvmAsmInstructionStart+(216*4)
   14025 
   14026 /* ------------------------------ */
   14027 .L_ALT_OP_RSUB_INT_LIT8: /* 0xd9 */
   14028 /* File: x86/alt_stub.S */
   14029 /*
   14030  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14031  * any interesting requests and then jump to the real instruction
   14032  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14033  * because rIBASE is caller save and we need to reload it.
   14034  *
   14035  * Note that unlike in the Arm implementation, we should never arrive
   14036  * here with a zero breakFlag because we always refresh rIBASE on
   14037  * return.
   14038  */
   14039     EXPORT_PC
   14040     movl   rSELF, %eax
   14041     movl   rPC, OUT_ARG0(%esp)
   14042     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14043     movl   rFP, OUT_ARG1(%esp)
   14044     je     1f                                # reload rIBASE & resume if not
   14045     movl   %eax, OUT_ARG2(%esp)
   14046     call   dvmCheckBefore                    # (dPC, dFP, self)
   14047     movl   rSELF, %eax
   14048 1:
   14049     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14050     jmp    *dvmAsmInstructionStart+(217*4)
   14051 
   14052 /* ------------------------------ */
   14053 .L_ALT_OP_MUL_INT_LIT8: /* 0xda */
   14054 /* File: x86/alt_stub.S */
   14055 /*
   14056  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14057  * any interesting requests and then jump to the real instruction
   14058  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14059  * because rIBASE is caller save and we need to reload it.
   14060  *
   14061  * Note that unlike in the Arm implementation, we should never arrive
   14062  * here with a zero breakFlag because we always refresh rIBASE on
   14063  * return.
   14064  */
   14065     EXPORT_PC
   14066     movl   rSELF, %eax
   14067     movl   rPC, OUT_ARG0(%esp)
   14068     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14069     movl   rFP, OUT_ARG1(%esp)
   14070     je     1f                                # reload rIBASE & resume if not
   14071     movl   %eax, OUT_ARG2(%esp)
   14072     call   dvmCheckBefore                    # (dPC, dFP, self)
   14073     movl   rSELF, %eax
   14074 1:
   14075     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14076     jmp    *dvmAsmInstructionStart+(218*4)
   14077 
   14078 /* ------------------------------ */
   14079 .L_ALT_OP_DIV_INT_LIT8: /* 0xdb */
   14080 /* File: x86/alt_stub.S */
   14081 /*
   14082  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14083  * any interesting requests and then jump to the real instruction
   14084  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14085  * because rIBASE is caller save and we need to reload it.
   14086  *
   14087  * Note that unlike in the Arm implementation, we should never arrive
   14088  * here with a zero breakFlag because we always refresh rIBASE on
   14089  * return.
   14090  */
   14091     EXPORT_PC
   14092     movl   rSELF, %eax
   14093     movl   rPC, OUT_ARG0(%esp)
   14094     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14095     movl   rFP, OUT_ARG1(%esp)
   14096     je     1f                                # reload rIBASE & resume if not
   14097     movl   %eax, OUT_ARG2(%esp)
   14098     call   dvmCheckBefore                    # (dPC, dFP, self)
   14099     movl   rSELF, %eax
   14100 1:
   14101     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14102     jmp    *dvmAsmInstructionStart+(219*4)
   14103 
   14104 /* ------------------------------ */
   14105 .L_ALT_OP_REM_INT_LIT8: /* 0xdc */
   14106 /* File: x86/alt_stub.S */
   14107 /*
   14108  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14109  * any interesting requests and then jump to the real instruction
   14110  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14111  * because rIBASE is caller save and we need to reload it.
   14112  *
   14113  * Note that unlike in the Arm implementation, we should never arrive
   14114  * here with a zero breakFlag because we always refresh rIBASE on
   14115  * return.
   14116  */
   14117     EXPORT_PC
   14118     movl   rSELF, %eax
   14119     movl   rPC, OUT_ARG0(%esp)
   14120     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14121     movl   rFP, OUT_ARG1(%esp)
   14122     je     1f                                # reload rIBASE & resume if not
   14123     movl   %eax, OUT_ARG2(%esp)
   14124     call   dvmCheckBefore                    # (dPC, dFP, self)
   14125     movl   rSELF, %eax
   14126 1:
   14127     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14128     jmp    *dvmAsmInstructionStart+(220*4)
   14129 
   14130 /* ------------------------------ */
   14131 .L_ALT_OP_AND_INT_LIT8: /* 0xdd */
   14132 /* File: x86/alt_stub.S */
   14133 /*
   14134  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14135  * any interesting requests and then jump to the real instruction
   14136  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14137  * because rIBASE is caller save and we need to reload it.
   14138  *
   14139  * Note that unlike in the Arm implementation, we should never arrive
   14140  * here with a zero breakFlag because we always refresh rIBASE on
   14141  * return.
   14142  */
   14143     EXPORT_PC
   14144     movl   rSELF, %eax
   14145     movl   rPC, OUT_ARG0(%esp)
   14146     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14147     movl   rFP, OUT_ARG1(%esp)
   14148     je     1f                                # reload rIBASE & resume if not
   14149     movl   %eax, OUT_ARG2(%esp)
   14150     call   dvmCheckBefore                    # (dPC, dFP, self)
   14151     movl   rSELF, %eax
   14152 1:
   14153     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14154     jmp    *dvmAsmInstructionStart+(221*4)
   14155 
   14156 /* ------------------------------ */
   14157 .L_ALT_OP_OR_INT_LIT8: /* 0xde */
   14158 /* File: x86/alt_stub.S */
   14159 /*
   14160  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14161  * any interesting requests and then jump to the real instruction
   14162  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14163  * because rIBASE is caller save and we need to reload it.
   14164  *
   14165  * Note that unlike in the Arm implementation, we should never arrive
   14166  * here with a zero breakFlag because we always refresh rIBASE on
   14167  * return.
   14168  */
   14169     EXPORT_PC
   14170     movl   rSELF, %eax
   14171     movl   rPC, OUT_ARG0(%esp)
   14172     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14173     movl   rFP, OUT_ARG1(%esp)
   14174     je     1f                                # reload rIBASE & resume if not
   14175     movl   %eax, OUT_ARG2(%esp)
   14176     call   dvmCheckBefore                    # (dPC, dFP, self)
   14177     movl   rSELF, %eax
   14178 1:
   14179     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14180     jmp    *dvmAsmInstructionStart+(222*4)
   14181 
   14182 /* ------------------------------ */
   14183 .L_ALT_OP_XOR_INT_LIT8: /* 0xdf */
   14184 /* File: x86/alt_stub.S */
   14185 /*
   14186  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14187  * any interesting requests and then jump to the real instruction
   14188  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14189  * because rIBASE is caller save and we need to reload it.
   14190  *
   14191  * Note that unlike in the Arm implementation, we should never arrive
   14192  * here with a zero breakFlag because we always refresh rIBASE on
   14193  * return.
   14194  */
   14195     EXPORT_PC
   14196     movl   rSELF, %eax
   14197     movl   rPC, OUT_ARG0(%esp)
   14198     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14199     movl   rFP, OUT_ARG1(%esp)
   14200     je     1f                                # reload rIBASE & resume if not
   14201     movl   %eax, OUT_ARG2(%esp)
   14202     call   dvmCheckBefore                    # (dPC, dFP, self)
   14203     movl   rSELF, %eax
   14204 1:
   14205     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14206     jmp    *dvmAsmInstructionStart+(223*4)
   14207 
   14208 /* ------------------------------ */
   14209 .L_ALT_OP_SHL_INT_LIT8: /* 0xe0 */
   14210 /* File: x86/alt_stub.S */
   14211 /*
   14212  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14213  * any interesting requests and then jump to the real instruction
   14214  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14215  * because rIBASE is caller save and we need to reload it.
   14216  *
   14217  * Note that unlike in the Arm implementation, we should never arrive
   14218  * here with a zero breakFlag because we always refresh rIBASE on
   14219  * return.
   14220  */
   14221     EXPORT_PC
   14222     movl   rSELF, %eax
   14223     movl   rPC, OUT_ARG0(%esp)
   14224     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14225     movl   rFP, OUT_ARG1(%esp)
   14226     je     1f                                # reload rIBASE & resume if not
   14227     movl   %eax, OUT_ARG2(%esp)
   14228     call   dvmCheckBefore                    # (dPC, dFP, self)
   14229     movl   rSELF, %eax
   14230 1:
   14231     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14232     jmp    *dvmAsmInstructionStart+(224*4)
   14233 
   14234 /* ------------------------------ */
   14235 .L_ALT_OP_SHR_INT_LIT8: /* 0xe1 */
   14236 /* File: x86/alt_stub.S */
   14237 /*
   14238  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14239  * any interesting requests and then jump to the real instruction
   14240  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14241  * because rIBASE is caller save and we need to reload it.
   14242  *
   14243  * Note that unlike in the Arm implementation, we should never arrive
   14244  * here with a zero breakFlag because we always refresh rIBASE on
   14245  * return.
   14246  */
   14247     EXPORT_PC
   14248     movl   rSELF, %eax
   14249     movl   rPC, OUT_ARG0(%esp)
   14250     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14251     movl   rFP, OUT_ARG1(%esp)
   14252     je     1f                                # reload rIBASE & resume if not
   14253     movl   %eax, OUT_ARG2(%esp)
   14254     call   dvmCheckBefore                    # (dPC, dFP, self)
   14255     movl   rSELF, %eax
   14256 1:
   14257     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14258     jmp    *dvmAsmInstructionStart+(225*4)
   14259 
   14260 /* ------------------------------ */
   14261 .L_ALT_OP_USHR_INT_LIT8: /* 0xe2 */
   14262 /* File: x86/alt_stub.S */
   14263 /*
   14264  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14265  * any interesting requests and then jump to the real instruction
   14266  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14267  * because rIBASE is caller save and we need to reload it.
   14268  *
   14269  * Note that unlike in the Arm implementation, we should never arrive
   14270  * here with a zero breakFlag because we always refresh rIBASE on
   14271  * return.
   14272  */
   14273     EXPORT_PC
   14274     movl   rSELF, %eax
   14275     movl   rPC, OUT_ARG0(%esp)
   14276     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14277     movl   rFP, OUT_ARG1(%esp)
   14278     je     1f                                # reload rIBASE & resume if not
   14279     movl   %eax, OUT_ARG2(%esp)
   14280     call   dvmCheckBefore                    # (dPC, dFP, self)
   14281     movl   rSELF, %eax
   14282 1:
   14283     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14284     jmp    *dvmAsmInstructionStart+(226*4)
   14285 
   14286 /* ------------------------------ */
   14287 .L_ALT_OP_IGET_VOLATILE: /* 0xe3 */
   14288 /* File: x86/alt_stub.S */
   14289 /*
   14290  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14291  * any interesting requests and then jump to the real instruction
   14292  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14293  * because rIBASE is caller save and we need to reload it.
   14294  *
   14295  * Note that unlike in the Arm implementation, we should never arrive
   14296  * here with a zero breakFlag because we always refresh rIBASE on
   14297  * return.
   14298  */
   14299     EXPORT_PC
   14300     movl   rSELF, %eax
   14301     movl   rPC, OUT_ARG0(%esp)
   14302     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14303     movl   rFP, OUT_ARG1(%esp)
   14304     je     1f                                # reload rIBASE & resume if not
   14305     movl   %eax, OUT_ARG2(%esp)
   14306     call   dvmCheckBefore                    # (dPC, dFP, self)
   14307     movl   rSELF, %eax
   14308 1:
   14309     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14310     jmp    *dvmAsmInstructionStart+(227*4)
   14311 
   14312 /* ------------------------------ */
   14313 .L_ALT_OP_IPUT_VOLATILE: /* 0xe4 */
   14314 /* File: x86/alt_stub.S */
   14315 /*
   14316  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14317  * any interesting requests and then jump to the real instruction
   14318  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14319  * because rIBASE is caller save and we need to reload it.
   14320  *
   14321  * Note that unlike in the Arm implementation, we should never arrive
   14322  * here with a zero breakFlag because we always refresh rIBASE on
   14323  * return.
   14324  */
   14325     EXPORT_PC
   14326     movl   rSELF, %eax
   14327     movl   rPC, OUT_ARG0(%esp)
   14328     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14329     movl   rFP, OUT_ARG1(%esp)
   14330     je     1f                                # reload rIBASE & resume if not
   14331     movl   %eax, OUT_ARG2(%esp)
   14332     call   dvmCheckBefore                    # (dPC, dFP, self)
   14333     movl   rSELF, %eax
   14334 1:
   14335     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14336     jmp    *dvmAsmInstructionStart+(228*4)
   14337 
   14338 /* ------------------------------ */
   14339 .L_ALT_OP_SGET_VOLATILE: /* 0xe5 */
   14340 /* File: x86/alt_stub.S */
   14341 /*
   14342  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14343  * any interesting requests and then jump to the real instruction
   14344  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14345  * because rIBASE is caller save and we need to reload it.
   14346  *
   14347  * Note that unlike in the Arm implementation, we should never arrive
   14348  * here with a zero breakFlag because we always refresh rIBASE on
   14349  * return.
   14350  */
   14351     EXPORT_PC
   14352     movl   rSELF, %eax
   14353     movl   rPC, OUT_ARG0(%esp)
   14354     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14355     movl   rFP, OUT_ARG1(%esp)
   14356     je     1f                                # reload rIBASE & resume if not
   14357     movl   %eax, OUT_ARG2(%esp)
   14358     call   dvmCheckBefore                    # (dPC, dFP, self)
   14359     movl   rSELF, %eax
   14360 1:
   14361     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14362     jmp    *dvmAsmInstructionStart+(229*4)
   14363 
   14364 /* ------------------------------ */
   14365 .L_ALT_OP_SPUT_VOLATILE: /* 0xe6 */
   14366 /* File: x86/alt_stub.S */
   14367 /*
   14368  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14369  * any interesting requests and then jump to the real instruction
   14370  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14371  * because rIBASE is caller save and we need to reload it.
   14372  *
   14373  * Note that unlike in the Arm implementation, we should never arrive
   14374  * here with a zero breakFlag because we always refresh rIBASE on
   14375  * return.
   14376  */
   14377     EXPORT_PC
   14378     movl   rSELF, %eax
   14379     movl   rPC, OUT_ARG0(%esp)
   14380     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14381     movl   rFP, OUT_ARG1(%esp)
   14382     je     1f                                # reload rIBASE & resume if not
   14383     movl   %eax, OUT_ARG2(%esp)
   14384     call   dvmCheckBefore                    # (dPC, dFP, self)
   14385     movl   rSELF, %eax
   14386 1:
   14387     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14388     jmp    *dvmAsmInstructionStart+(230*4)
   14389 
   14390 /* ------------------------------ */
   14391 .L_ALT_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
   14392 /* File: x86/alt_stub.S */
   14393 /*
   14394  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14395  * any interesting requests and then jump to the real instruction
   14396  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14397  * because rIBASE is caller save and we need to reload it.
   14398  *
   14399  * Note that unlike in the Arm implementation, we should never arrive
   14400  * here with a zero breakFlag because we always refresh rIBASE on
   14401  * return.
   14402  */
   14403     EXPORT_PC
   14404     movl   rSELF, %eax
   14405     movl   rPC, OUT_ARG0(%esp)
   14406     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14407     movl   rFP, OUT_ARG1(%esp)
   14408     je     1f                                # reload rIBASE & resume if not
   14409     movl   %eax, OUT_ARG2(%esp)
   14410     call   dvmCheckBefore                    # (dPC, dFP, self)
   14411     movl   rSELF, %eax
   14412 1:
   14413     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14414     jmp    *dvmAsmInstructionStart+(231*4)
   14415 
   14416 /* ------------------------------ */
   14417 .L_ALT_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
   14418 /* File: x86/alt_stub.S */
   14419 /*
   14420  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14421  * any interesting requests and then jump to the real instruction
   14422  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14423  * because rIBASE is caller save and we need to reload it.
   14424  *
   14425  * Note that unlike in the Arm implementation, we should never arrive
   14426  * here with a zero breakFlag because we always refresh rIBASE on
   14427  * return.
   14428  */
   14429     EXPORT_PC
   14430     movl   rSELF, %eax
   14431     movl   rPC, OUT_ARG0(%esp)
   14432     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14433     movl   rFP, OUT_ARG1(%esp)
   14434     je     1f                                # reload rIBASE & resume if not
   14435     movl   %eax, OUT_ARG2(%esp)
   14436     call   dvmCheckBefore                    # (dPC, dFP, self)
   14437     movl   rSELF, %eax
   14438 1:
   14439     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14440     jmp    *dvmAsmInstructionStart+(232*4)
   14441 
   14442 /* ------------------------------ */
   14443 .L_ALT_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
   14444 /* File: x86/alt_stub.S */
   14445 /*
   14446  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14447  * any interesting requests and then jump to the real instruction
   14448  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14449  * because rIBASE is caller save and we need to reload it.
   14450  *
   14451  * Note that unlike in the Arm implementation, we should never arrive
   14452  * here with a zero breakFlag because we always refresh rIBASE on
   14453  * return.
   14454  */
   14455     EXPORT_PC
   14456     movl   rSELF, %eax
   14457     movl   rPC, OUT_ARG0(%esp)
   14458     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14459     movl   rFP, OUT_ARG1(%esp)
   14460     je     1f                                # reload rIBASE & resume if not
   14461     movl   %eax, OUT_ARG2(%esp)
   14462     call   dvmCheckBefore                    # (dPC, dFP, self)
   14463     movl   rSELF, %eax
   14464 1:
   14465     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14466     jmp    *dvmAsmInstructionStart+(233*4)
   14467 
   14468 /* ------------------------------ */
   14469 .L_ALT_OP_SGET_WIDE_VOLATILE: /* 0xea */
   14470 /* File: x86/alt_stub.S */
   14471 /*
   14472  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14473  * any interesting requests and then jump to the real instruction
   14474  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14475  * because rIBASE is caller save and we need to reload it.
   14476  *
   14477  * Note that unlike in the Arm implementation, we should never arrive
   14478  * here with a zero breakFlag because we always refresh rIBASE on
   14479  * return.
   14480  */
   14481     EXPORT_PC
   14482     movl   rSELF, %eax
   14483     movl   rPC, OUT_ARG0(%esp)
   14484     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14485     movl   rFP, OUT_ARG1(%esp)
   14486     je     1f                                # reload rIBASE & resume if not
   14487     movl   %eax, OUT_ARG2(%esp)
   14488     call   dvmCheckBefore                    # (dPC, dFP, self)
   14489     movl   rSELF, %eax
   14490 1:
   14491     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14492     jmp    *dvmAsmInstructionStart+(234*4)
   14493 
   14494 /* ------------------------------ */
   14495 .L_ALT_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
   14496 /* File: x86/alt_stub.S */
   14497 /*
   14498  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14499  * any interesting requests and then jump to the real instruction
   14500  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14501  * because rIBASE is caller save and we need to reload it.
   14502  *
   14503  * Note that unlike in the Arm implementation, we should never arrive
   14504  * here with a zero breakFlag because we always refresh rIBASE on
   14505  * return.
   14506  */
   14507     EXPORT_PC
   14508     movl   rSELF, %eax
   14509     movl   rPC, OUT_ARG0(%esp)
   14510     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14511     movl   rFP, OUT_ARG1(%esp)
   14512     je     1f                                # reload rIBASE & resume if not
   14513     movl   %eax, OUT_ARG2(%esp)
   14514     call   dvmCheckBefore                    # (dPC, dFP, self)
   14515     movl   rSELF, %eax
   14516 1:
   14517     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14518     jmp    *dvmAsmInstructionStart+(235*4)
   14519 
   14520 /* ------------------------------ */
   14521 .L_ALT_OP_BREAKPOINT: /* 0xec */
   14522 /* File: x86/alt_stub.S */
   14523 /*
   14524  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14525  * any interesting requests and then jump to the real instruction
   14526  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14527  * because rIBASE is caller save and we need to reload it.
   14528  *
   14529  * Note that unlike in the Arm implementation, we should never arrive
   14530  * here with a zero breakFlag because we always refresh rIBASE on
   14531  * return.
   14532  */
   14533     EXPORT_PC
   14534     movl   rSELF, %eax
   14535     movl   rPC, OUT_ARG0(%esp)
   14536     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14537     movl   rFP, OUT_ARG1(%esp)
   14538     je     1f                                # reload rIBASE & resume if not
   14539     movl   %eax, OUT_ARG2(%esp)
   14540     call   dvmCheckBefore                    # (dPC, dFP, self)
   14541     movl   rSELF, %eax
   14542 1:
   14543     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14544     jmp    *dvmAsmInstructionStart+(236*4)
   14545 
   14546 /* ------------------------------ */
   14547 .L_ALT_OP_THROW_VERIFICATION_ERROR: /* 0xed */
   14548 /* File: x86/alt_stub.S */
   14549 /*
   14550  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14551  * any interesting requests and then jump to the real instruction
   14552  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14553  * because rIBASE is caller save and we need to reload it.
   14554  *
   14555  * Note that unlike in the Arm implementation, we should never arrive
   14556  * here with a zero breakFlag because we always refresh rIBASE on
   14557  * return.
   14558  */
   14559     EXPORT_PC
   14560     movl   rSELF, %eax
   14561     movl   rPC, OUT_ARG0(%esp)
   14562     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14563     movl   rFP, OUT_ARG1(%esp)
   14564     je     1f                                # reload rIBASE & resume if not
   14565     movl   %eax, OUT_ARG2(%esp)
   14566     call   dvmCheckBefore                    # (dPC, dFP, self)
   14567     movl   rSELF, %eax
   14568 1:
   14569     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14570     jmp    *dvmAsmInstructionStart+(237*4)
   14571 
   14572 /* ------------------------------ */
   14573 .L_ALT_OP_EXECUTE_INLINE: /* 0xee */
   14574 /* File: x86/alt_stub.S */
   14575 /*
   14576  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14577  * any interesting requests and then jump to the real instruction
   14578  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14579  * because rIBASE is caller save and we need to reload it.
   14580  *
   14581  * Note that unlike in the Arm implementation, we should never arrive
   14582  * here with a zero breakFlag because we always refresh rIBASE on
   14583  * return.
   14584  */
   14585     EXPORT_PC
   14586     movl   rSELF, %eax
   14587     movl   rPC, OUT_ARG0(%esp)
   14588     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14589     movl   rFP, OUT_ARG1(%esp)
   14590     je     1f                                # reload rIBASE & resume if not
   14591     movl   %eax, OUT_ARG2(%esp)
   14592     call   dvmCheckBefore                    # (dPC, dFP, self)
   14593     movl   rSELF, %eax
   14594 1:
   14595     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14596     jmp    *dvmAsmInstructionStart+(238*4)
   14597 
   14598 /* ------------------------------ */
   14599 .L_ALT_OP_EXECUTE_INLINE_RANGE: /* 0xef */
   14600 /* File: x86/alt_stub.S */
   14601 /*
   14602  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14603  * any interesting requests and then jump to the real instruction
   14604  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14605  * because rIBASE is caller save and we need to reload it.
   14606  *
   14607  * Note that unlike in the Arm implementation, we should never arrive
   14608  * here with a zero breakFlag because we always refresh rIBASE on
   14609  * return.
   14610  */
   14611     EXPORT_PC
   14612     movl   rSELF, %eax
   14613     movl   rPC, OUT_ARG0(%esp)
   14614     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14615     movl   rFP, OUT_ARG1(%esp)
   14616     je     1f                                # reload rIBASE & resume if not
   14617     movl   %eax, OUT_ARG2(%esp)
   14618     call   dvmCheckBefore                    # (dPC, dFP, self)
   14619     movl   rSELF, %eax
   14620 1:
   14621     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14622     jmp    *dvmAsmInstructionStart+(239*4)
   14623 
   14624 /* ------------------------------ */
   14625 .L_ALT_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */
   14626 /* File: x86/alt_stub.S */
   14627 /*
   14628  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14629  * any interesting requests and then jump to the real instruction
   14630  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14631  * because rIBASE is caller save and we need to reload it.
   14632  *
   14633  * Note that unlike in the Arm implementation, we should never arrive
   14634  * here with a zero breakFlag because we always refresh rIBASE on
   14635  * return.
   14636  */
   14637     EXPORT_PC
   14638     movl   rSELF, %eax
   14639     movl   rPC, OUT_ARG0(%esp)
   14640     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14641     movl   rFP, OUT_ARG1(%esp)
   14642     je     1f                                # reload rIBASE & resume if not
   14643     movl   %eax, OUT_ARG2(%esp)
   14644     call   dvmCheckBefore                    # (dPC, dFP, self)
   14645     movl   rSELF, %eax
   14646 1:
   14647     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14648     jmp    *dvmAsmInstructionStart+(240*4)
   14649 
   14650 /* ------------------------------ */
   14651 .L_ALT_OP_RETURN_VOID_BARRIER: /* 0xf1 */
   14652 /* File: x86/alt_stub.S */
   14653 /*
   14654  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14655  * any interesting requests and then jump to the real instruction
   14656  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14657  * because rIBASE is caller save and we need to reload it.
   14658  *
   14659  * Note that unlike in the Arm implementation, we should never arrive
   14660  * here with a zero breakFlag because we always refresh rIBASE on
   14661  * return.
   14662  */
   14663     EXPORT_PC
   14664     movl   rSELF, %eax
   14665     movl   rPC, OUT_ARG0(%esp)
   14666     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14667     movl   rFP, OUT_ARG1(%esp)
   14668     je     1f                                # reload rIBASE & resume if not
   14669     movl   %eax, OUT_ARG2(%esp)
   14670     call   dvmCheckBefore                    # (dPC, dFP, self)
   14671     movl   rSELF, %eax
   14672 1:
   14673     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14674     jmp    *dvmAsmInstructionStart+(241*4)
   14675 
   14676 /* ------------------------------ */
   14677 .L_ALT_OP_IGET_QUICK: /* 0xf2 */
   14678 /* File: x86/alt_stub.S */
   14679 /*
   14680  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14681  * any interesting requests and then jump to the real instruction
   14682  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14683  * because rIBASE is caller save and we need to reload it.
   14684  *
   14685  * Note that unlike in the Arm implementation, we should never arrive
   14686  * here with a zero breakFlag because we always refresh rIBASE on
   14687  * return.
   14688  */
   14689     EXPORT_PC
   14690     movl   rSELF, %eax
   14691     movl   rPC, OUT_ARG0(%esp)
   14692     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14693     movl   rFP, OUT_ARG1(%esp)
   14694     je     1f                                # reload rIBASE & resume if not
   14695     movl   %eax, OUT_ARG2(%esp)
   14696     call   dvmCheckBefore                    # (dPC, dFP, self)
   14697     movl   rSELF, %eax
   14698 1:
   14699     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14700     jmp    *dvmAsmInstructionStart+(242*4)
   14701 
   14702 /* ------------------------------ */
   14703 .L_ALT_OP_IGET_WIDE_QUICK: /* 0xf3 */
   14704 /* File: x86/alt_stub.S */
   14705 /*
   14706  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14707  * any interesting requests and then jump to the real instruction
   14708  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14709  * because rIBASE is caller save and we need to reload it.
   14710  *
   14711  * Note that unlike in the Arm implementation, we should never arrive
   14712  * here with a zero breakFlag because we always refresh rIBASE on
   14713  * return.
   14714  */
   14715     EXPORT_PC
   14716     movl   rSELF, %eax
   14717     movl   rPC, OUT_ARG0(%esp)
   14718     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14719     movl   rFP, OUT_ARG1(%esp)
   14720     je     1f                                # reload rIBASE & resume if not
   14721     movl   %eax, OUT_ARG2(%esp)
   14722     call   dvmCheckBefore                    # (dPC, dFP, self)
   14723     movl   rSELF, %eax
   14724 1:
   14725     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14726     jmp    *dvmAsmInstructionStart+(243*4)
   14727 
   14728 /* ------------------------------ */
   14729 .L_ALT_OP_IGET_OBJECT_QUICK: /* 0xf4 */
   14730 /* File: x86/alt_stub.S */
   14731 /*
   14732  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14733  * any interesting requests and then jump to the real instruction
   14734  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14735  * because rIBASE is caller save and we need to reload it.
   14736  *
   14737  * Note that unlike in the Arm implementation, we should never arrive
   14738  * here with a zero breakFlag because we always refresh rIBASE on
   14739  * return.
   14740  */
   14741     EXPORT_PC
   14742     movl   rSELF, %eax
   14743     movl   rPC, OUT_ARG0(%esp)
   14744     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14745     movl   rFP, OUT_ARG1(%esp)
   14746     je     1f                                # reload rIBASE & resume if not
   14747     movl   %eax, OUT_ARG2(%esp)
   14748     call   dvmCheckBefore                    # (dPC, dFP, self)
   14749     movl   rSELF, %eax
   14750 1:
   14751     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14752     jmp    *dvmAsmInstructionStart+(244*4)
   14753 
   14754 /* ------------------------------ */
   14755 .L_ALT_OP_IPUT_QUICK: /* 0xf5 */
   14756 /* File: x86/alt_stub.S */
   14757 /*
   14758  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14759  * any interesting requests and then jump to the real instruction
   14760  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14761  * because rIBASE is caller save and we need to reload it.
   14762  *
   14763  * Note that unlike in the Arm implementation, we should never arrive
   14764  * here with a zero breakFlag because we always refresh rIBASE on
   14765  * return.
   14766  */
   14767     EXPORT_PC
   14768     movl   rSELF, %eax
   14769     movl   rPC, OUT_ARG0(%esp)
   14770     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14771     movl   rFP, OUT_ARG1(%esp)
   14772     je     1f                                # reload rIBASE & resume if not
   14773     movl   %eax, OUT_ARG2(%esp)
   14774     call   dvmCheckBefore                    # (dPC, dFP, self)
   14775     movl   rSELF, %eax
   14776 1:
   14777     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14778     jmp    *dvmAsmInstructionStart+(245*4)
   14779 
   14780 /* ------------------------------ */
   14781 .L_ALT_OP_IPUT_WIDE_QUICK: /* 0xf6 */
   14782 /* File: x86/alt_stub.S */
   14783 /*
   14784  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14785  * any interesting requests and then jump to the real instruction
   14786  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14787  * because rIBASE is caller save and we need to reload it.
   14788  *
   14789  * Note that unlike in the Arm implementation, we should never arrive
   14790  * here with a zero breakFlag because we always refresh rIBASE on
   14791  * return.
   14792  */
   14793     EXPORT_PC
   14794     movl   rSELF, %eax
   14795     movl   rPC, OUT_ARG0(%esp)
   14796     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14797     movl   rFP, OUT_ARG1(%esp)
   14798     je     1f                                # reload rIBASE & resume if not
   14799     movl   %eax, OUT_ARG2(%esp)
   14800     call   dvmCheckBefore                    # (dPC, dFP, self)
   14801     movl   rSELF, %eax
   14802 1:
   14803     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14804     jmp    *dvmAsmInstructionStart+(246*4)
   14805 
   14806 /* ------------------------------ */
   14807 .L_ALT_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
   14808 /* File: x86/alt_stub.S */
   14809 /*
   14810  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14811  * any interesting requests and then jump to the real instruction
   14812  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14813  * because rIBASE is caller save and we need to reload it.
   14814  *
   14815  * Note that unlike in the Arm implementation, we should never arrive
   14816  * here with a zero breakFlag because we always refresh rIBASE on
   14817  * return.
   14818  */
   14819     EXPORT_PC
   14820     movl   rSELF, %eax
   14821     movl   rPC, OUT_ARG0(%esp)
   14822     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14823     movl   rFP, OUT_ARG1(%esp)
   14824     je     1f                                # reload rIBASE & resume if not
   14825     movl   %eax, OUT_ARG2(%esp)
   14826     call   dvmCheckBefore                    # (dPC, dFP, self)
   14827     movl   rSELF, %eax
   14828 1:
   14829     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14830     jmp    *dvmAsmInstructionStart+(247*4)
   14831 
   14832 /* ------------------------------ */
   14833 .L_ALT_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
   14834 /* File: x86/alt_stub.S */
   14835 /*
   14836  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14837  * any interesting requests and then jump to the real instruction
   14838  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14839  * because rIBASE is caller save and we need to reload it.
   14840  *
   14841  * Note that unlike in the Arm implementation, we should never arrive
   14842  * here with a zero breakFlag because we always refresh rIBASE on
   14843  * return.
   14844  */
   14845     EXPORT_PC
   14846     movl   rSELF, %eax
   14847     movl   rPC, OUT_ARG0(%esp)
   14848     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14849     movl   rFP, OUT_ARG1(%esp)
   14850     je     1f                                # reload rIBASE & resume if not
   14851     movl   %eax, OUT_ARG2(%esp)
   14852     call   dvmCheckBefore                    # (dPC, dFP, self)
   14853     movl   rSELF, %eax
   14854 1:
   14855     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14856     jmp    *dvmAsmInstructionStart+(248*4)
   14857 
   14858 /* ------------------------------ */
   14859 .L_ALT_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
   14860 /* File: x86/alt_stub.S */
   14861 /*
   14862  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14863  * any interesting requests and then jump to the real instruction
   14864  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14865  * because rIBASE is caller save and we need to reload it.
   14866  *
   14867  * Note that unlike in the Arm implementation, we should never arrive
   14868  * here with a zero breakFlag because we always refresh rIBASE on
   14869  * return.
   14870  */
   14871     EXPORT_PC
   14872     movl   rSELF, %eax
   14873     movl   rPC, OUT_ARG0(%esp)
   14874     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14875     movl   rFP, OUT_ARG1(%esp)
   14876     je     1f                                # reload rIBASE & resume if not
   14877     movl   %eax, OUT_ARG2(%esp)
   14878     call   dvmCheckBefore                    # (dPC, dFP, self)
   14879     movl   rSELF, %eax
   14880 1:
   14881     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14882     jmp    *dvmAsmInstructionStart+(249*4)
   14883 
   14884 /* ------------------------------ */
   14885 .L_ALT_OP_INVOKE_SUPER_QUICK: /* 0xfa */
   14886 /* File: x86/alt_stub.S */
   14887 /*
   14888  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14889  * any interesting requests and then jump to the real instruction
   14890  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14891  * because rIBASE is caller save and we need to reload it.
   14892  *
   14893  * Note that unlike in the Arm implementation, we should never arrive
   14894  * here with a zero breakFlag because we always refresh rIBASE on
   14895  * return.
   14896  */
   14897     EXPORT_PC
   14898     movl   rSELF, %eax
   14899     movl   rPC, OUT_ARG0(%esp)
   14900     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14901     movl   rFP, OUT_ARG1(%esp)
   14902     je     1f                                # reload rIBASE & resume if not
   14903     movl   %eax, OUT_ARG2(%esp)
   14904     call   dvmCheckBefore                    # (dPC, dFP, self)
   14905     movl   rSELF, %eax
   14906 1:
   14907     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14908     jmp    *dvmAsmInstructionStart+(250*4)
   14909 
   14910 /* ------------------------------ */
   14911 .L_ALT_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
   14912 /* File: x86/alt_stub.S */
   14913 /*
   14914  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14915  * any interesting requests and then jump to the real instruction
   14916  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14917  * because rIBASE is caller save and we need to reload it.
   14918  *
   14919  * Note that unlike in the Arm implementation, we should never arrive
   14920  * here with a zero breakFlag because we always refresh rIBASE on
   14921  * return.
   14922  */
   14923     EXPORT_PC
   14924     movl   rSELF, %eax
   14925     movl   rPC, OUT_ARG0(%esp)
   14926     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14927     movl   rFP, OUT_ARG1(%esp)
   14928     je     1f                                # reload rIBASE & resume if not
   14929     movl   %eax, OUT_ARG2(%esp)
   14930     call   dvmCheckBefore                    # (dPC, dFP, self)
   14931     movl   rSELF, %eax
   14932 1:
   14933     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14934     jmp    *dvmAsmInstructionStart+(251*4)
   14935 
   14936 /* ------------------------------ */
   14937 .L_ALT_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
   14938 /* File: x86/alt_stub.S */
   14939 /*
   14940  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14941  * any interesting requests and then jump to the real instruction
   14942  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14943  * because rIBASE is caller save and we need to reload it.
   14944  *
   14945  * Note that unlike in the Arm implementation, we should never arrive
   14946  * here with a zero breakFlag because we always refresh rIBASE on
   14947  * return.
   14948  */
   14949     EXPORT_PC
   14950     movl   rSELF, %eax
   14951     movl   rPC, OUT_ARG0(%esp)
   14952     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14953     movl   rFP, OUT_ARG1(%esp)
   14954     je     1f                                # reload rIBASE & resume if not
   14955     movl   %eax, OUT_ARG2(%esp)
   14956     call   dvmCheckBefore                    # (dPC, dFP, self)
   14957     movl   rSELF, %eax
   14958 1:
   14959     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14960     jmp    *dvmAsmInstructionStart+(252*4)
   14961 
   14962 /* ------------------------------ */
   14963 .L_ALT_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
   14964 /* File: x86/alt_stub.S */
   14965 /*
   14966  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14967  * any interesting requests and then jump to the real instruction
   14968  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14969  * because rIBASE is caller save and we need to reload it.
   14970  *
   14971  * Note that unlike in the Arm implementation, we should never arrive
   14972  * here with a zero breakFlag because we always refresh rIBASE on
   14973  * return.
   14974  */
   14975     EXPORT_PC
   14976     movl   rSELF, %eax
   14977     movl   rPC, OUT_ARG0(%esp)
   14978     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   14979     movl   rFP, OUT_ARG1(%esp)
   14980     je     1f                                # reload rIBASE & resume if not
   14981     movl   %eax, OUT_ARG2(%esp)
   14982     call   dvmCheckBefore                    # (dPC, dFP, self)
   14983     movl   rSELF, %eax
   14984 1:
   14985     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   14986     jmp    *dvmAsmInstructionStart+(253*4)
   14987 
   14988 /* ------------------------------ */
   14989 .L_ALT_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
   14990 /* File: x86/alt_stub.S */
   14991 /*
   14992  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   14993  * any interesting requests and then jump to the real instruction
   14994  * handler.  Unlike the Arm handler, we can't do this as a tail call
   14995  * because rIBASE is caller save and we need to reload it.
   14996  *
   14997  * Note that unlike in the Arm implementation, we should never arrive
   14998  * here with a zero breakFlag because we always refresh rIBASE on
   14999  * return.
   15000  */
   15001     EXPORT_PC
   15002     movl   rSELF, %eax
   15003     movl   rPC, OUT_ARG0(%esp)
   15004     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   15005     movl   rFP, OUT_ARG1(%esp)
   15006     je     1f                                # reload rIBASE & resume if not
   15007     movl   %eax, OUT_ARG2(%esp)
   15008     call   dvmCheckBefore                    # (dPC, dFP, self)
   15009     movl   rSELF, %eax
   15010 1:
   15011     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   15012     jmp    *dvmAsmInstructionStart+(254*4)
   15013 
   15014 /* ------------------------------ */
   15015 .L_ALT_OP_UNUSED_FF: /* 0xff */
   15016 /* File: x86/alt_stub.S */
   15017 /*
   15018  * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
   15019  * any interesting requests and then jump to the real instruction
   15020  * handler.  Unlike the Arm handler, we can't do this as a tail call
   15021  * because rIBASE is caller save and we need to reload it.
   15022  *
   15023  * Note that unlike in the Arm implementation, we should never arrive
   15024  * here with a zero breakFlag because we always refresh rIBASE on
   15025  * return.
   15026  */
   15027     EXPORT_PC
   15028     movl   rSELF, %eax
   15029     movl   rPC, OUT_ARG0(%esp)
   15030     cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
   15031     movl   rFP, OUT_ARG1(%esp)
   15032     je     1f                                # reload rIBASE & resume if not
   15033     movl   %eax, OUT_ARG2(%esp)
   15034     call   dvmCheckBefore                    # (dPC, dFP, self)
   15035     movl   rSELF, %eax
   15036 1:
   15037     movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
   15038     jmp    *dvmAsmInstructionStart+(255*4)
   15039 
   15040     .size   dvmAsmAltInstructionStartCode, .-dvmAsmAltInstructionStartCode
   15041     .global dvmAsmAltInstructionEndCode
   15042 dvmAsmAltInstructionEndCode:
   15043 
   15044     .global dvmAsmInstructionStart
   15045     .text
   15046 dvmAsmInstructionStart:
   15047     .long .L_OP_NOP /* 0x00 */
   15048     .long .L_OP_MOVE /* 0x01 */
   15049     .long .L_OP_MOVE_FROM16 /* 0x02 */
   15050     .long .L_OP_MOVE_16 /* 0x03 */
   15051     .long .L_OP_MOVE_WIDE /* 0x04 */
   15052     .long .L_OP_MOVE_WIDE_FROM16 /* 0x05 */
   15053     .long .L_OP_MOVE_WIDE_16 /* 0x06 */
   15054     .long .L_OP_MOVE_OBJECT /* 0x07 */
   15055     .long .L_OP_MOVE_OBJECT_FROM16 /* 0x08 */
   15056     .long .L_OP_MOVE_OBJECT_16 /* 0x09 */
   15057     .long .L_OP_MOVE_RESULT /* 0x0a */
   15058     .long .L_OP_MOVE_RESULT_WIDE /* 0x0b */
   15059     .long .L_OP_MOVE_RESULT_OBJECT /* 0x0c */
   15060     .long .L_OP_MOVE_EXCEPTION /* 0x0d */
   15061     .long .L_OP_RETURN_VOID /* 0x0e */
   15062     .long .L_OP_RETURN /* 0x0f */
   15063     .long .L_OP_RETURN_WIDE /* 0x10 */
   15064     .long .L_OP_RETURN_OBJECT /* 0x11 */
   15065     .long .L_OP_CONST_4 /* 0x12 */
   15066     .long .L_OP_CONST_16 /* 0x13 */
   15067     .long .L_OP_CONST /* 0x14 */
   15068     .long .L_OP_CONST_HIGH16 /* 0x15 */
   15069     .long .L_OP_CONST_WIDE_16 /* 0x16 */
   15070     .long .L_OP_CONST_WIDE_32 /* 0x17 */
   15071     .long .L_OP_CONST_WIDE /* 0x18 */
   15072     .long .L_OP_CONST_WIDE_HIGH16 /* 0x19 */
   15073     .long .L_OP_CONST_STRING /* 0x1a */
   15074     .long .L_OP_CONST_STRING_JUMBO /* 0x1b */
   15075     .long .L_OP_CONST_CLASS /* 0x1c */
   15076     .long .L_OP_MONITOR_ENTER /* 0x1d */
   15077     .long .L_OP_MONITOR_EXIT /* 0x1e */
   15078     .long .L_OP_CHECK_CAST /* 0x1f */
   15079     .long .L_OP_INSTANCE_OF /* 0x20 */
   15080     .long .L_OP_ARRAY_LENGTH /* 0x21 */
   15081     .long .L_OP_NEW_INSTANCE /* 0x22 */
   15082     .long .L_OP_NEW_ARRAY /* 0x23 */
   15083     .long .L_OP_FILLED_NEW_ARRAY /* 0x24 */
   15084     .long .L_OP_FILLED_NEW_ARRAY_RANGE /* 0x25 */
   15085     .long .L_OP_FILL_ARRAY_DATA /* 0x26 */
   15086     .long .L_OP_THROW /* 0x27 */
   15087     .long .L_OP_GOTO /* 0x28 */
   15088     .long .L_OP_GOTO_16 /* 0x29 */
   15089     .long .L_OP_GOTO_32 /* 0x2a */
   15090     .long .L_OP_PACKED_SWITCH /* 0x2b */
   15091     .long .L_OP_SPARSE_SWITCH /* 0x2c */
   15092     .long .L_OP_CMPL_FLOAT /* 0x2d */
   15093     .long .L_OP_CMPG_FLOAT /* 0x2e */
   15094     .long .L_OP_CMPL_DOUBLE /* 0x2f */
   15095     .long .L_OP_CMPG_DOUBLE /* 0x30 */
   15096     .long .L_OP_CMP_LONG /* 0x31 */
   15097     .long .L_OP_IF_EQ /* 0x32 */
   15098     .long .L_OP_IF_NE /* 0x33 */
   15099     .long .L_OP_IF_LT /* 0x34 */
   15100     .long .L_OP_IF_GE /* 0x35 */
   15101     .long .L_OP_IF_GT /* 0x36 */
   15102     .long .L_OP_IF_LE /* 0x37 */
   15103     .long .L_OP_IF_EQZ /* 0x38 */
   15104     .long .L_OP_IF_NEZ /* 0x39 */
   15105     .long .L_OP_IF_LTZ /* 0x3a */
   15106     .long .L_OP_IF_GEZ /* 0x3b */
   15107     .long .L_OP_IF_GTZ /* 0x3c */
   15108     .long .L_OP_IF_LEZ /* 0x3d */
   15109     .long .L_OP_UNUSED_3E /* 0x3e */
   15110     .long .L_OP_UNUSED_3F /* 0x3f */
   15111     .long .L_OP_UNUSED_40 /* 0x40 */
   15112     .long .L_OP_UNUSED_41 /* 0x41 */
   15113     .long .L_OP_UNUSED_42 /* 0x42 */
   15114     .long .L_OP_UNUSED_43 /* 0x43 */
   15115     .long .L_OP_AGET /* 0x44 */
   15116     .long .L_OP_AGET_WIDE /* 0x45 */
   15117     .long .L_OP_AGET_OBJECT /* 0x46 */
   15118     .long .L_OP_AGET_BOOLEAN /* 0x47 */
   15119     .long .L_OP_AGET_BYTE /* 0x48 */
   15120     .long .L_OP_AGET_CHAR /* 0x49 */
   15121     .long .L_OP_AGET_SHORT /* 0x4a */
   15122     .long .L_OP_APUT /* 0x4b */
   15123     .long .L_OP_APUT_WIDE /* 0x4c */
   15124     .long .L_OP_APUT_OBJECT /* 0x4d */
   15125     .long .L_OP_APUT_BOOLEAN /* 0x4e */
   15126     .long .L_OP_APUT_BYTE /* 0x4f */
   15127     .long .L_OP_APUT_CHAR /* 0x50 */
   15128     .long .L_OP_APUT_SHORT /* 0x51 */
   15129     .long .L_OP_IGET /* 0x52 */
   15130     .long .L_OP_IGET_WIDE /* 0x53 */
   15131     .long .L_OP_IGET_OBJECT /* 0x54 */
   15132     .long .L_OP_IGET_BOOLEAN /* 0x55 */
   15133     .long .L_OP_IGET_BYTE /* 0x56 */
   15134     .long .L_OP_IGET_CHAR /* 0x57 */
   15135     .long .L_OP_IGET_SHORT /* 0x58 */
   15136     .long .L_OP_IPUT /* 0x59 */
   15137     .long .L_OP_IPUT_WIDE /* 0x5a */
   15138     .long .L_OP_IPUT_OBJECT /* 0x5b */
   15139     .long .L_OP_IPUT_BOOLEAN /* 0x5c */
   15140     .long .L_OP_IPUT_BYTE /* 0x5d */
   15141     .long .L_OP_IPUT_CHAR /* 0x5e */
   15142     .long .L_OP_IPUT_SHORT /* 0x5f */
   15143     .long .L_OP_SGET /* 0x60 */
   15144     .long .L_OP_SGET_WIDE /* 0x61 */
   15145     .long .L_OP_SGET_OBJECT /* 0x62 */
   15146     .long .L_OP_SGET_BOOLEAN /* 0x63 */
   15147     .long .L_OP_SGET_BYTE /* 0x64 */
   15148     .long .L_OP_SGET_CHAR /* 0x65 */
   15149     .long .L_OP_SGET_SHORT /* 0x66 */
   15150     .long .L_OP_SPUT /* 0x67 */
   15151     .long .L_OP_SPUT_WIDE /* 0x68 */
   15152     .long .L_OP_SPUT_OBJECT /* 0x69 */
   15153     .long .L_OP_SPUT_BOOLEAN /* 0x6a */
   15154     .long .L_OP_SPUT_BYTE /* 0x6b */
   15155     .long .L_OP_SPUT_CHAR /* 0x6c */
   15156     .long .L_OP_SPUT_SHORT /* 0x6d */
   15157     .long .L_OP_INVOKE_VIRTUAL /* 0x6e */
   15158     .long .L_OP_INVOKE_SUPER /* 0x6f */
   15159     .long .L_OP_INVOKE_DIRECT /* 0x70 */
   15160     .long .L_OP_INVOKE_STATIC /* 0x71 */
   15161     .long .L_OP_INVOKE_INTERFACE /* 0x72 */
   15162     .long .L_OP_UNUSED_73 /* 0x73 */
   15163     .long .L_OP_INVOKE_VIRTUAL_RANGE /* 0x74 */
   15164     .long .L_OP_INVOKE_SUPER_RANGE /* 0x75 */
   15165     .long .L_OP_INVOKE_DIRECT_RANGE /* 0x76 */
   15166     .long .L_OP_INVOKE_STATIC_RANGE /* 0x77 */
   15167     .long .L_OP_INVOKE_INTERFACE_RANGE /* 0x78 */
   15168     .long .L_OP_UNUSED_79 /* 0x79 */
   15169     .long .L_OP_UNUSED_7A /* 0x7a */
   15170     .long .L_OP_NEG_INT /* 0x7b */
   15171     .long .L_OP_NOT_INT /* 0x7c */
   15172     .long .L_OP_NEG_LONG /* 0x7d */
   15173     .long .L_OP_NOT_LONG /* 0x7e */
   15174     .long .L_OP_NEG_FLOAT /* 0x7f */
   15175     .long .L_OP_NEG_DOUBLE /* 0x80 */
   15176     .long .L_OP_INT_TO_LONG /* 0x81 */
   15177     .long .L_OP_INT_TO_FLOAT /* 0x82 */
   15178     .long .L_OP_INT_TO_DOUBLE /* 0x83 */
   15179     .long .L_OP_LONG_TO_INT /* 0x84 */
   15180     .long .L_OP_LONG_TO_FLOAT /* 0x85 */
   15181     .long .L_OP_LONG_TO_DOUBLE /* 0x86 */
   15182     .long .L_OP_FLOAT_TO_INT /* 0x87 */
   15183     .long .L_OP_FLOAT_TO_LONG /* 0x88 */
   15184     .long .L_OP_FLOAT_TO_DOUBLE /* 0x89 */
   15185     .long .L_OP_DOUBLE_TO_INT /* 0x8a */
   15186     .long .L_OP_DOUBLE_TO_LONG /* 0x8b */
   15187     .long .L_OP_DOUBLE_TO_FLOAT /* 0x8c */
   15188     .long .L_OP_INT_TO_BYTE /* 0x8d */
   15189     .long .L_OP_INT_TO_CHAR /* 0x8e */
   15190     .long .L_OP_INT_TO_SHORT /* 0x8f */
   15191     .long .L_OP_ADD_INT /* 0x90 */
   15192     .long .L_OP_SUB_INT /* 0x91 */
   15193     .long .L_OP_MUL_INT /* 0x92 */
   15194     .long .L_OP_DIV_INT /* 0x93 */
   15195     .long .L_OP_REM_INT /* 0x94 */
   15196     .long .L_OP_AND_INT /* 0x95 */
   15197     .long .L_OP_OR_INT /* 0x96 */
   15198     .long .L_OP_XOR_INT /* 0x97 */
   15199     .long .L_OP_SHL_INT /* 0x98 */
   15200     .long .L_OP_SHR_INT /* 0x99 */
   15201     .long .L_OP_USHR_INT /* 0x9a */
   15202     .long .L_OP_ADD_LONG /* 0x9b */
   15203     .long .L_OP_SUB_LONG /* 0x9c */
   15204     .long .L_OP_MUL_LONG /* 0x9d */
   15205     .long .L_OP_DIV_LONG /* 0x9e */
   15206     .long .L_OP_REM_LONG /* 0x9f */
   15207     .long .L_OP_AND_LONG /* 0xa0 */
   15208     .long .L_OP_OR_LONG /* 0xa1 */
   15209     .long .L_OP_XOR_LONG /* 0xa2 */
   15210     .long .L_OP_SHL_LONG /* 0xa3 */
   15211     .long .L_OP_SHR_LONG /* 0xa4 */
   15212     .long .L_OP_USHR_LONG /* 0xa5 */
   15213     .long .L_OP_ADD_FLOAT /* 0xa6 */
   15214     .long .L_OP_SUB_FLOAT /* 0xa7 */
   15215     .long .L_OP_MUL_FLOAT /* 0xa8 */
   15216     .long .L_OP_DIV_FLOAT /* 0xa9 */
   15217     .long .L_OP_REM_FLOAT /* 0xaa */
   15218     .long .L_OP_ADD_DOUBLE /* 0xab */
   15219     .long .L_OP_SUB_DOUBLE /* 0xac */
   15220     .long .L_OP_MUL_DOUBLE /* 0xad */
   15221     .long .L_OP_DIV_DOUBLE /* 0xae */
   15222     .long .L_OP_REM_DOUBLE /* 0xaf */
   15223     .long .L_OP_ADD_INT_2ADDR /* 0xb0 */
   15224     .long .L_OP_SUB_INT_2ADDR /* 0xb1 */
   15225     .long .L_OP_MUL_INT_2ADDR /* 0xb2 */
   15226     .long .L_OP_DIV_INT_2ADDR /* 0xb3 */
   15227     .long .L_OP_REM_INT_2ADDR /* 0xb4 */
   15228     .long .L_OP_AND_INT_2ADDR /* 0xb5 */
   15229     .long .L_OP_OR_INT_2ADDR /* 0xb6 */
   15230     .long .L_OP_XOR_INT_2ADDR /* 0xb7 */
   15231     .long .L_OP_SHL_INT_2ADDR /* 0xb8 */
   15232     .long .L_OP_SHR_INT_2ADDR /* 0xb9 */
   15233     .long .L_OP_USHR_INT_2ADDR /* 0xba */
   15234     .long .L_OP_ADD_LONG_2ADDR /* 0xbb */
   15235     .long .L_OP_SUB_LONG_2ADDR /* 0xbc */
   15236     .long .L_OP_MUL_LONG_2ADDR /* 0xbd */
   15237     .long .L_OP_DIV_LONG_2ADDR /* 0xbe */
   15238     .long .L_OP_REM_LONG_2ADDR /* 0xbf */
   15239     .long .L_OP_AND_LONG_2ADDR /* 0xc0 */
   15240     .long .L_OP_OR_LONG_2ADDR /* 0xc1 */
   15241     .long .L_OP_XOR_LONG_2ADDR /* 0xc2 */
   15242     .long .L_OP_SHL_LONG_2ADDR /* 0xc3 */
   15243     .long .L_OP_SHR_LONG_2ADDR /* 0xc4 */
   15244     .long .L_OP_USHR_LONG_2ADDR /* 0xc5 */
   15245     .long .L_OP_ADD_FLOAT_2ADDR /* 0xc6 */
   15246     .long .L_OP_SUB_FLOAT_2ADDR /* 0xc7 */
   15247     .long .L_OP_MUL_FLOAT_2ADDR /* 0xc8 */
   15248     .long .L_OP_DIV_FLOAT_2ADDR /* 0xc9 */
   15249     .long .L_OP_REM_FLOAT_2ADDR /* 0xca */
   15250     .long .L_OP_ADD_DOUBLE_2ADDR /* 0xcb */
   15251     .long .L_OP_SUB_DOUBLE_2ADDR /* 0xcc */
   15252     .long .L_OP_MUL_DOUBLE_2ADDR /* 0xcd */
   15253     .long .L_OP_DIV_DOUBLE_2ADDR /* 0xce */
   15254     .long .L_OP_REM_DOUBLE_2ADDR /* 0xcf */
   15255     .long .L_OP_ADD_INT_LIT16 /* 0xd0 */
   15256     .long .L_OP_RSUB_INT /* 0xd1 */
   15257     .long .L_OP_MUL_INT_LIT16 /* 0xd2 */
   15258     .long .L_OP_DIV_INT_LIT16 /* 0xd3 */
   15259     .long .L_OP_REM_INT_LIT16 /* 0xd4 */
   15260     .long .L_OP_AND_INT_LIT16 /* 0xd5 */
   15261     .long .L_OP_OR_INT_LIT16 /* 0xd6 */
   15262     .long .L_OP_XOR_INT_LIT16 /* 0xd7 */
   15263     .long .L_OP_ADD_INT_LIT8 /* 0xd8 */
   15264     .long .L_OP_RSUB_INT_LIT8 /* 0xd9 */
   15265     .long .L_OP_MUL_INT_LIT8 /* 0xda */
   15266     .long .L_OP_DIV_INT_LIT8 /* 0xdb */
   15267     .long .L_OP_REM_INT_LIT8 /* 0xdc */
   15268     .long .L_OP_AND_INT_LIT8 /* 0xdd */
   15269     .long .L_OP_OR_INT_LIT8 /* 0xde */
   15270     .long .L_OP_XOR_INT_LIT8 /* 0xdf */
   15271     .long .L_OP_SHL_INT_LIT8 /* 0xe0 */
   15272     .long .L_OP_SHR_INT_LIT8 /* 0xe1 */
   15273     .long .L_OP_USHR_INT_LIT8 /* 0xe2 */
   15274     .long .L_OP_IGET_VOLATILE /* 0xe3 */
   15275     .long .L_OP_IPUT_VOLATILE /* 0xe4 */
   15276     .long .L_OP_SGET_VOLATILE /* 0xe5 */
   15277     .long .L_OP_SPUT_VOLATILE /* 0xe6 */
   15278     .long .L_OP_IGET_OBJECT_VOLATILE /* 0xe7 */
   15279     .long .L_OP_IGET_WIDE_VOLATILE /* 0xe8 */
   15280     .long .L_OP_IPUT_WIDE_VOLATILE /* 0xe9 */
   15281     .long .L_OP_SGET_WIDE_VOLATILE /* 0xea */
   15282     .long .L_OP_SPUT_WIDE_VOLATILE /* 0xeb */
   15283     .long .L_OP_BREAKPOINT /* 0xec */
   15284     .long .L_OP_THROW_VERIFICATION_ERROR /* 0xed */
   15285     .long .L_OP_EXECUTE_INLINE /* 0xee */
   15286     .long .L_OP_EXECUTE_INLINE_RANGE /* 0xef */
   15287     .long .L_OP_INVOKE_OBJECT_INIT_RANGE /* 0xf0 */
   15288     .long .L_OP_RETURN_VOID_BARRIER /* 0xf1 */
   15289     .long .L_OP_IGET_QUICK /* 0xf2 */
   15290     .long .L_OP_IGET_WIDE_QUICK /* 0xf3 */
   15291     .long .L_OP_IGET_OBJECT_QUICK /* 0xf4 */
   15292     .long .L_OP_IPUT_QUICK /* 0xf5 */
   15293     .long .L_OP_IPUT_WIDE_QUICK /* 0xf6 */
   15294     .long .L_OP_IPUT_OBJECT_QUICK /* 0xf7 */
   15295     .long .L_OP_INVOKE_VIRTUAL_QUICK /* 0xf8 */
   15296     .long .L_OP_INVOKE_VIRTUAL_QUICK_RANGE /* 0xf9 */
   15297     .long .L_OP_INVOKE_SUPER_QUICK /* 0xfa */
   15298     .long .L_OP_INVOKE_SUPER_QUICK_RANGE /* 0xfb */
   15299     .long .L_OP_IPUT_OBJECT_VOLATILE /* 0xfc */
   15300     .long .L_OP_SGET_OBJECT_VOLATILE /* 0xfd */
   15301     .long .L_OP_SPUT_OBJECT_VOLATILE /* 0xfe */
   15302     .long .L_OP_UNUSED_FF /* 0xff */
   15303 
   15304     .global dvmAsmAltInstructionStart
   15305     .text
   15306 dvmAsmAltInstructionStart:
   15307     .long .L_ALT_OP_NOP /* 0x00 */
   15308     .long .L_ALT_OP_MOVE /* 0x01 */
   15309     .long .L_ALT_OP_MOVE_FROM16 /* 0x02 */
   15310     .long .L_ALT_OP_MOVE_16 /* 0x03 */
   15311     .long .L_ALT_OP_MOVE_WIDE /* 0x04 */
   15312     .long .L_ALT_OP_MOVE_WIDE_FROM16 /* 0x05 */
   15313     .long .L_ALT_OP_MOVE_WIDE_16 /* 0x06 */
   15314     .long .L_ALT_OP_MOVE_OBJECT /* 0x07 */
   15315     .long .L_ALT_OP_MOVE_OBJECT_FROM16 /* 0x08 */
   15316     .long .L_ALT_OP_MOVE_OBJECT_16 /* 0x09 */
   15317     .long .L_ALT_OP_MOVE_RESULT /* 0x0a */
   15318     .long .L_ALT_OP_MOVE_RESULT_WIDE /* 0x0b */
   15319     .long .L_ALT_OP_MOVE_RESULT_OBJECT /* 0x0c */
   15320     .long .L_ALT_OP_MOVE_EXCEPTION /* 0x0d */
   15321     .long .L_ALT_OP_RETURN_VOID /* 0x0e */
   15322     .long .L_ALT_OP_RETURN /* 0x0f */
   15323     .long .L_ALT_OP_RETURN_WIDE /* 0x10 */
   15324     .long .L_ALT_OP_RETURN_OBJECT /* 0x11 */
   15325     .long .L_ALT_OP_CONST_4 /* 0x12 */
   15326     .long .L_ALT_OP_CONST_16 /* 0x13 */
   15327     .long .L_ALT_OP_CONST /* 0x14 */
   15328     .long .L_ALT_OP_CONST_HIGH16 /* 0x15 */
   15329     .long .L_ALT_OP_CONST_WIDE_16 /* 0x16 */
   15330     .long .L_ALT_OP_CONST_WIDE_32 /* 0x17 */
   15331     .long .L_ALT_OP_CONST_WIDE /* 0x18 */
   15332     .long .L_ALT_OP_CONST_WIDE_HIGH16 /* 0x19 */
   15333     .long .L_ALT_OP_CONST_STRING /* 0x1a */
   15334     .long .L_ALT_OP_CONST_STRING_JUMBO /* 0x1b */
   15335     .long .L_ALT_OP_CONST_CLASS /* 0x1c */
   15336     .long .L_ALT_OP_MONITOR_ENTER /* 0x1d */
   15337     .long .L_ALT_OP_MONITOR_EXIT /* 0x1e */
   15338     .long .L_ALT_OP_CHECK_CAST /* 0x1f */
   15339     .long .L_ALT_OP_INSTANCE_OF /* 0x20 */
   15340     .long .L_ALT_OP_ARRAY_LENGTH /* 0x21 */
   15341     .long .L_ALT_OP_NEW_INSTANCE /* 0x22 */
   15342     .long .L_ALT_OP_NEW_ARRAY /* 0x23 */
   15343     .long .L_ALT_OP_FILLED_NEW_ARRAY /* 0x24 */
   15344     .long .L_ALT_OP_FILLED_NEW_ARRAY_RANGE /* 0x25 */
   15345     .long .L_ALT_OP_FILL_ARRAY_DATA /* 0x26 */
   15346     .long .L_ALT_OP_THROW /* 0x27 */
   15347     .long .L_ALT_OP_GOTO /* 0x28 */
   15348     .long .L_ALT_OP_GOTO_16 /* 0x29 */
   15349     .long .L_ALT_OP_GOTO_32 /* 0x2a */
   15350     .long .L_ALT_OP_PACKED_SWITCH /* 0x2b */
   15351     .long .L_ALT_OP_SPARSE_SWITCH /* 0x2c */
   15352     .long .L_ALT_OP_CMPL_FLOAT /* 0x2d */
   15353     .long .L_ALT_OP_CMPG_FLOAT /* 0x2e */
   15354     .long .L_ALT_OP_CMPL_DOUBLE /* 0x2f */
   15355     .long .L_ALT_OP_CMPG_DOUBLE /* 0x30 */
   15356     .long .L_ALT_OP_CMP_LONG /* 0x31 */
   15357     .long .L_ALT_OP_IF_EQ /* 0x32 */
   15358     .long .L_ALT_OP_IF_NE /* 0x33 */
   15359     .long .L_ALT_OP_IF_LT /* 0x34 */
   15360     .long .L_ALT_OP_IF_GE /* 0x35 */
   15361     .long .L_ALT_OP_IF_GT /* 0x36 */
   15362     .long .L_ALT_OP_IF_LE /* 0x37 */
   15363     .long .L_ALT_OP_IF_EQZ /* 0x38 */
   15364     .long .L_ALT_OP_IF_NEZ /* 0x39 */
   15365     .long .L_ALT_OP_IF_LTZ /* 0x3a */
   15366     .long .L_ALT_OP_IF_GEZ /* 0x3b */
   15367     .long .L_ALT_OP_IF_GTZ /* 0x3c */
   15368     .long .L_ALT_OP_IF_LEZ /* 0x3d */
   15369     .long .L_ALT_OP_UNUSED_3E /* 0x3e */
   15370     .long .L_ALT_OP_UNUSED_3F /* 0x3f */
   15371     .long .L_ALT_OP_UNUSED_40 /* 0x40 */
   15372     .long .L_ALT_OP_UNUSED_41 /* 0x41 */
   15373     .long .L_ALT_OP_UNUSED_42 /* 0x42 */
   15374     .long .L_ALT_OP_UNUSED_43 /* 0x43 */
   15375     .long .L_ALT_OP_AGET /* 0x44 */
   15376     .long .L_ALT_OP_AGET_WIDE /* 0x45 */
   15377     .long .L_ALT_OP_AGET_OBJECT /* 0x46 */
   15378     .long .L_ALT_OP_AGET_BOOLEAN /* 0x47 */
   15379     .long .L_ALT_OP_AGET_BYTE /* 0x48 */
   15380     .long .L_ALT_OP_AGET_CHAR /* 0x49 */
   15381     .long .L_ALT_OP_AGET_SHORT /* 0x4a */
   15382     .long .L_ALT_OP_APUT /* 0x4b */
   15383     .long .L_ALT_OP_APUT_WIDE /* 0x4c */
   15384     .long .L_ALT_OP_APUT_OBJECT /* 0x4d */
   15385     .long .L_ALT_OP_APUT_BOOLEAN /* 0x4e */
   15386     .long .L_ALT_OP_APUT_BYTE /* 0x4f */
   15387     .long .L_ALT_OP_APUT_CHAR /* 0x50 */
   15388     .long .L_ALT_OP_APUT_SHORT /* 0x51 */
   15389     .long .L_ALT_OP_IGET /* 0x52 */
   15390     .long .L_ALT_OP_IGET_WIDE /* 0x53 */
   15391     .long .L_ALT_OP_IGET_OBJECT /* 0x54 */
   15392     .long .L_ALT_OP_IGET_BOOLEAN /* 0x55 */
   15393     .long .L_ALT_OP_IGET_BYTE /* 0x56 */
   15394     .long .L_ALT_OP_IGET_CHAR /* 0x57 */
   15395     .long .L_ALT_OP_IGET_SHORT /* 0x58 */
   15396     .long .L_ALT_OP_IPUT /* 0x59 */
   15397     .long .L_ALT_OP_IPUT_WIDE /* 0x5a */
   15398     .long .L_ALT_OP_IPUT_OBJECT /* 0x5b */
   15399     .long .L_ALT_OP_IPUT_BOOLEAN /* 0x5c */
   15400     .long .L_ALT_OP_IPUT_BYTE /* 0x5d */
   15401     .long .L_ALT_OP_IPUT_CHAR /* 0x5e */
   15402     .long .L_ALT_OP_IPUT_SHORT /* 0x5f */
   15403     .long .L_ALT_OP_SGET /* 0x60 */
   15404     .long .L_ALT_OP_SGET_WIDE /* 0x61 */
   15405     .long .L_ALT_OP_SGET_OBJECT /* 0x62 */
   15406     .long .L_ALT_OP_SGET_BOOLEAN /* 0x63 */
   15407     .long .L_ALT_OP_SGET_BYTE /* 0x64 */
   15408     .long .L_ALT_OP_SGET_CHAR /* 0x65 */
   15409     .long .L_ALT_OP_SGET_SHORT /* 0x66 */
   15410     .long .L_ALT_OP_SPUT /* 0x67 */
   15411     .long .L_ALT_OP_SPUT_WIDE /* 0x68 */
   15412     .long .L_ALT_OP_SPUT_OBJECT /* 0x69 */
   15413     .long .L_ALT_OP_SPUT_BOOLEAN /* 0x6a */
   15414     .long .L_ALT_OP_SPUT_BYTE /* 0x6b */
   15415     .long .L_ALT_OP_SPUT_CHAR /* 0x6c */
   15416     .long .L_ALT_OP_SPUT_SHORT /* 0x6d */
   15417     .long .L_ALT_OP_INVOKE_VIRTUAL /* 0x6e */
   15418     .long .L_ALT_OP_INVOKE_SUPER /* 0x6f */
   15419     .long .L_ALT_OP_INVOKE_DIRECT /* 0x70 */
   15420     .long .L_ALT_OP_INVOKE_STATIC /* 0x71 */
   15421     .long .L_ALT_OP_INVOKE_INTERFACE /* 0x72 */
   15422     .long .L_ALT_OP_UNUSED_73 /* 0x73 */
   15423     .long .L_ALT_OP_INVOKE_VIRTUAL_RANGE /* 0x74 */
   15424     .long .L_ALT_OP_INVOKE_SUPER_RANGE /* 0x75 */
   15425     .long .L_ALT_OP_INVOKE_DIRECT_RANGE /* 0x76 */
   15426     .long .L_ALT_OP_INVOKE_STATIC_RANGE /* 0x77 */
   15427     .long .L_ALT_OP_INVOKE_INTERFACE_RANGE /* 0x78 */
   15428     .long .L_ALT_OP_UNUSED_79 /* 0x79 */
   15429     .long .L_ALT_OP_UNUSED_7A /* 0x7a */
   15430     .long .L_ALT_OP_NEG_INT /* 0x7b */
   15431     .long .L_ALT_OP_NOT_INT /* 0x7c */
   15432     .long .L_ALT_OP_NEG_LONG /* 0x7d */
   15433     .long .L_ALT_OP_NOT_LONG /* 0x7e */
   15434     .long .L_ALT_OP_NEG_FLOAT /* 0x7f */
   15435     .long .L_ALT_OP_NEG_DOUBLE /* 0x80 */
   15436     .long .L_ALT_OP_INT_TO_LONG /* 0x81 */
   15437     .long .L_ALT_OP_INT_TO_FLOAT /* 0x82 */
   15438     .long .L_ALT_OP_INT_TO_DOUBLE /* 0x83 */
   15439     .long .L_ALT_OP_LONG_TO_INT /* 0x84 */
   15440     .long .L_ALT_OP_LONG_TO_FLOAT /* 0x85 */
   15441     .long .L_ALT_OP_LONG_TO_DOUBLE /* 0x86 */
   15442     .long .L_ALT_OP_FLOAT_TO_INT /* 0x87 */
   15443     .long .L_ALT_OP_FLOAT_TO_LONG /* 0x88 */
   15444     .long .L_ALT_OP_FLOAT_TO_DOUBLE /* 0x89 */
   15445     .long .L_ALT_OP_DOUBLE_TO_INT /* 0x8a */
   15446     .long .L_ALT_OP_DOUBLE_TO_LONG /* 0x8b */
   15447     .long .L_ALT_OP_DOUBLE_TO_FLOAT /* 0x8c */
   15448     .long .L_ALT_OP_INT_TO_BYTE /* 0x8d */
   15449     .long .L_ALT_OP_INT_TO_CHAR /* 0x8e */
   15450     .long .L_ALT_OP_INT_TO_SHORT /* 0x8f */
   15451     .long .L_ALT_OP_ADD_INT /* 0x90 */
   15452     .long .L_ALT_OP_SUB_INT /* 0x91 */
   15453     .long .L_ALT_OP_MUL_INT /* 0x92 */
   15454     .long .L_ALT_OP_DIV_INT /* 0x93 */
   15455     .long .L_ALT_OP_REM_INT /* 0x94 */
   15456     .long .L_ALT_OP_AND_INT /* 0x95 */
   15457     .long .L_ALT_OP_OR_INT /* 0x96 */
   15458     .long .L_ALT_OP_XOR_INT /* 0x97 */
   15459     .long .L_ALT_OP_SHL_INT /* 0x98 */
   15460     .long .L_ALT_OP_SHR_INT /* 0x99 */
   15461     .long .L_ALT_OP_USHR_INT /* 0x9a */
   15462     .long .L_ALT_OP_ADD_LONG /* 0x9b */
   15463     .long .L_ALT_OP_SUB_LONG /* 0x9c */
   15464     .long .L_ALT_OP_MUL_LONG /* 0x9d */
   15465     .long .L_ALT_OP_DIV_LONG /* 0x9e */
   15466     .long .L_ALT_OP_REM_LONG /* 0x9f */
   15467     .long .L_ALT_OP_AND_LONG /* 0xa0 */
   15468     .long .L_ALT_OP_OR_LONG /* 0xa1 */
   15469     .long .L_ALT_OP_XOR_LONG /* 0xa2 */
   15470     .long .L_ALT_OP_SHL_LONG /* 0xa3 */
   15471     .long .L_ALT_OP_SHR_LONG /* 0xa4 */
   15472     .long .L_ALT_OP_USHR_LONG /* 0xa5 */
   15473     .long .L_ALT_OP_ADD_FLOAT /* 0xa6 */
   15474     .long .L_ALT_OP_SUB_FLOAT /* 0xa7 */
   15475     .long .L_ALT_OP_MUL_FLOAT /* 0xa8 */
   15476     .long .L_ALT_OP_DIV_FLOAT /* 0xa9 */
   15477     .long .L_ALT_OP_REM_FLOAT /* 0xaa */
   15478     .long .L_ALT_OP_ADD_DOUBLE /* 0xab */
   15479     .long .L_ALT_OP_SUB_DOUBLE /* 0xac */
   15480     .long .L_ALT_OP_MUL_DOUBLE /* 0xad */
   15481     .long .L_ALT_OP_DIV_DOUBLE /* 0xae */
   15482     .long .L_ALT_OP_REM_DOUBLE /* 0xaf */
   15483     .long .L_ALT_OP_ADD_INT_2ADDR /* 0xb0 */
   15484     .long .L_ALT_OP_SUB_INT_2ADDR /* 0xb1 */
   15485     .long .L_ALT_OP_MUL_INT_2ADDR /* 0xb2 */
   15486     .long .L_ALT_OP_DIV_INT_2ADDR /* 0xb3 */
   15487     .long .L_ALT_OP_REM_INT_2ADDR /* 0xb4 */
   15488     .long .L_ALT_OP_AND_INT_2ADDR /* 0xb5 */
   15489     .long .L_ALT_OP_OR_INT_2ADDR /* 0xb6 */
   15490     .long .L_ALT_OP_XOR_INT_2ADDR /* 0xb7 */
   15491     .long .L_ALT_OP_SHL_INT_2ADDR /* 0xb8 */
   15492     .long .L_ALT_OP_SHR_INT_2ADDR /* 0xb9 */
   15493     .long .L_ALT_OP_USHR_INT_2ADDR /* 0xba */
   15494     .long .L_ALT_OP_ADD_LONG_2ADDR /* 0xbb */
   15495     .long .L_ALT_OP_SUB_LONG_2ADDR /* 0xbc */
   15496     .long .L_ALT_OP_MUL_LONG_2ADDR /* 0xbd */
   15497     .long .L_ALT_OP_DIV_LONG_2ADDR /* 0xbe */
   15498     .long .L_ALT_OP_REM_LONG_2ADDR /* 0xbf */
   15499     .long .L_ALT_OP_AND_LONG_2ADDR /* 0xc0 */
   15500     .long .L_ALT_OP_OR_LONG_2ADDR /* 0xc1 */
   15501     .long .L_ALT_OP_XOR_LONG_2ADDR /* 0xc2 */
   15502     .long .L_ALT_OP_SHL_LONG_2ADDR /* 0xc3 */
   15503     .long .L_ALT_OP_SHR_LONG_2ADDR /* 0xc4 */
   15504     .long .L_ALT_OP_USHR_LONG_2ADDR /* 0xc5 */
   15505     .long .L_ALT_OP_ADD_FLOAT_2ADDR /* 0xc6 */
   15506     .long .L_ALT_OP_SUB_FLOAT_2ADDR /* 0xc7 */
   15507     .long .L_ALT_OP_MUL_FLOAT_2ADDR /* 0xc8 */
   15508     .long .L_ALT_OP_DIV_FLOAT_2ADDR /* 0xc9 */
   15509     .long .L_ALT_OP_REM_FLOAT_2ADDR /* 0xca */
   15510     .long .L_ALT_OP_ADD_DOUBLE_2ADDR /* 0xcb */
   15511     .long .L_ALT_OP_SUB_DOUBLE_2ADDR /* 0xcc */
   15512     .long .L_ALT_OP_MUL_DOUBLE_2ADDR /* 0xcd */
   15513     .long .L_ALT_OP_DIV_DOUBLE_2ADDR /* 0xce */
   15514     .long .L_ALT_OP_REM_DOUBLE_2ADDR /* 0xcf */
   15515     .long .L_ALT_OP_ADD_INT_LIT16 /* 0xd0 */
   15516     .long .L_ALT_OP_RSUB_INT /* 0xd1 */
   15517     .long .L_ALT_OP_MUL_INT_LIT16 /* 0xd2 */
   15518     .long .L_ALT_OP_DIV_INT_LIT16 /* 0xd3 */
   15519     .long .L_ALT_OP_REM_INT_LIT16 /* 0xd4 */
   15520     .long .L_ALT_OP_AND_INT_LIT16 /* 0xd5 */
   15521     .long .L_ALT_OP_OR_INT_LIT16 /* 0xd6 */
   15522     .long .L_ALT_OP_XOR_INT_LIT16 /* 0xd7 */
   15523     .long .L_ALT_OP_ADD_INT_LIT8 /* 0xd8 */
   15524     .long .L_ALT_OP_RSUB_INT_LIT8 /* 0xd9 */
   15525     .long .L_ALT_OP_MUL_INT_LIT8 /* 0xda */
   15526     .long .L_ALT_OP_DIV_INT_LIT8 /* 0xdb */
   15527     .long .L_ALT_OP_REM_INT_LIT8 /* 0xdc */
   15528     .long .L_ALT_OP_AND_INT_LIT8 /* 0xdd */
   15529     .long .L_ALT_OP_OR_INT_LIT8 /* 0xde */
   15530     .long .L_ALT_OP_XOR_INT_LIT8 /* 0xdf */
   15531     .long .L_ALT_OP_SHL_INT_LIT8 /* 0xe0 */
   15532     .long .L_ALT_OP_SHR_INT_LIT8 /* 0xe1 */
   15533     .long .L_ALT_OP_USHR_INT_LIT8 /* 0xe2 */
   15534     .long .L_ALT_OP_IGET_VOLATILE /* 0xe3 */
   15535     .long .L_ALT_OP_IPUT_VOLATILE /* 0xe4 */
   15536     .long .L_ALT_OP_SGET_VOLATILE /* 0xe5 */
   15537     .long .L_ALT_OP_SPUT_VOLATILE /* 0xe6 */
   15538     .long .L_ALT_OP_IGET_OBJECT_VOLATILE /* 0xe7 */
   15539     .long .L_ALT_OP_IGET_WIDE_VOLATILE /* 0xe8 */
   15540     .long .L_ALT_OP_IPUT_WIDE_VOLATILE /* 0xe9 */
   15541     .long .L_ALT_OP_SGET_WIDE_VOLATILE /* 0xea */
   15542     .long .L_ALT_OP_SPUT_WIDE_VOLATILE /* 0xeb */
   15543     .long .L_ALT_OP_BREAKPOINT /* 0xec */
   15544     .long .L_ALT_OP_THROW_VERIFICATION_ERROR /* 0xed */
   15545     .long .L_ALT_OP_EXECUTE_INLINE /* 0xee */
   15546     .long .L_ALT_OP_EXECUTE_INLINE_RANGE /* 0xef */
   15547     .long .L_ALT_OP_INVOKE_OBJECT_INIT_RANGE /* 0xf0 */
   15548     .long .L_ALT_OP_RETURN_VOID_BARRIER /* 0xf1 */
   15549     .long .L_ALT_OP_IGET_QUICK /* 0xf2 */
   15550     .long .L_ALT_OP_IGET_WIDE_QUICK /* 0xf3 */
   15551     .long .L_ALT_OP_IGET_OBJECT_QUICK /* 0xf4 */
   15552     .long .L_ALT_OP_IPUT_QUICK /* 0xf5 */
   15553     .long .L_ALT_OP_IPUT_WIDE_QUICK /* 0xf6 */
   15554     .long .L_ALT_OP_IPUT_OBJECT_QUICK /* 0xf7 */
   15555     .long .L_ALT_OP_INVOKE_VIRTUAL_QUICK /* 0xf8 */
   15556     .long .L_ALT_OP_INVOKE_VIRTUAL_QUICK_RANGE /* 0xf9 */
   15557     .long .L_ALT_OP_INVOKE_SUPER_QUICK /* 0xfa */
   15558     .long .L_ALT_OP_INVOKE_SUPER_QUICK_RANGE /* 0xfb */
   15559     .long .L_ALT_OP_IPUT_OBJECT_VOLATILE /* 0xfc */
   15560     .long .L_ALT_OP_SGET_OBJECT_VOLATILE /* 0xfd */
   15561     .long .L_ALT_OP_SPUT_OBJECT_VOLATILE /* 0xfe */
   15562     .long .L_ALT_OP_UNUSED_FF /* 0xff */
   15563 /* File: x86/entry.S */
   15564 /*
   15565  * Copyright (C) 2008 The Android Open Source Project
   15566  *
   15567  * Licensed under the Apache License, Version 2.0 (the "License");
   15568  * you may not use this file except in compliance with the License.
   15569  * You may obtain a copy of the License at
   15570  *
   15571  *      http://www.apache.org/licenses/LICENSE-2.0
   15572  *
   15573  * Unless required by applicable law or agreed to in writing, software
   15574  * distributed under the License is distributed on an "AS IS" BASIS,
   15575  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   15576  * See the License for the specific language governing permissions and
   15577  * limitations under the License.
   15578  */
   15579 
   15580 
   15581     .text
   15582     .global dvmMterpStdRun
   15583     .type   dvmMterpStdRun, %function
   15584 /*
   15585  * bool dvmMterpStdRun(Thread* self)
   15586  *
   15587  * Interpreter entry point.  Returns changeInterp.
   15588  *
   15589  */
   15590 dvmMterpStdRun:
   15591     push    %ebp                 # save caller base pointer
   15592     movl    %esp, %ebp           # set our %ebp
   15593     movl    rSELF, %ecx          # get incoming rSELF
   15594 /*
   15595  * At this point we've allocated one slot on the stack
   15596  * via push and stack is 8-byte aligned.  Allocate space
   15597  * for 9 spill slots, 4 local slots, 5 arg slots to bring
   15598  * us to 16-byte alignment
   15599  */
   15600     subl    $(FRAME_SIZE-4), %esp
   15601 
   15602 /* Spill callee save regs */
   15603     movl    %edi,EDI_SPILL(%ebp)
   15604     movl    %esi,ESI_SPILL(%ebp)
   15605     movl    %ebx,EBX_SPILL(%ebp)
   15606 
   15607 /* Set up "named" registers */
   15608     movl    offThread_pc(%ecx),rPC
   15609     movl    offThread_curFrame(%ecx),rFP
   15610     movl    offThread_curHandlerTable(%ecx),rIBASE
   15611 
   15612     /* Remember %esp for future "longjmp" */
   15613     movl    %esp,offThread_bailPtr(%ecx)
   15614 
   15615     /* Fetch next instruction before potential jump */
   15616     FETCH_INST
   15617 #if defined(WITH_JIT)
   15618     GET_JIT_PROF_TABLE %ecx %eax
   15619     movl        $0, offThread_inJitCodeCache(%ecx)
   15620     cmpl        $0, %eax
   15621     jne         common_updateProfile # set up %ebx & %edx & rPC
   15622 #endif
   15623 
   15624    /* Normal case: start executing the instruction at rPC */
   15625     GOTO_NEXT
   15626 
   15627     .global dvmMterpStdBail
   15628     .type   dvmMterpStdBail, %function
   15629 /*
   15630  * void dvmMterpStdBail(Thread* self, bool changeInterp)
   15631  *
   15632  * Restore the stack pointer and PC from the save point established on entry.
   15633  * This is essentially the same as a longjmp, but should be cheaper.  The
   15634  * last instruction causes us to return to whoever called dvmMterpStdRun.
   15635  *
   15636  * We're not going to build a standard frame here, so the arg accesses will
   15637  * look a little strange.
   15638  *
   15639  * On entry:
   15640  *  esp+4 (arg0)  Thread* self
   15641  *  esp+8 (arg1)  bool changeInterp
   15642  */
   15643 dvmMterpStdBail:
   15644     movl    4(%esp),%ecx                 # grab self
   15645     movl    8(%esp),%eax                 # changeInterp to return reg
   15646     movl    offThread_bailPtr(%ecx),%esp # Restore "setjmp" esp
   15647     movl    %esp,%ebp
   15648     addl    $(FRAME_SIZE-4), %ebp       # Restore %ebp at point of setjmp
   15649     movl    EDI_SPILL(%ebp),%edi
   15650     movl    ESI_SPILL(%ebp),%esi
   15651     movl    EBX_SPILL(%ebp),%ebx
   15652     movl    %ebp, %esp                   # strip frame
   15653     pop     %ebp                         # restore caller's ebp
   15654     ret                                  # return to dvmMterpStdRun's caller
   15655 
   15656 
   15657 #ifdef WITH_JIT
   15658     .global     dvmNcgInvokeInterpreter
   15659     .type       dvmNcgInvokeInterpreter, %function
   15660 /* input: start of method in %eax */
   15661 dvmNcgInvokeInterpreter:
   15662     movl        %eax, rPC
   15663     movl   rSELF, %ecx
   15664     movl   offThread_curHandlerTable(%ecx),rIBASE
   15665     FETCH_INST_R %ecx                    # %edx<- opcode
   15666     GOTO_NEXT_R %ecx                    # start executing the instruction at rPC
   15667 #endif
   15668 
   15669 /*
   15670  * Strings
   15671  */
   15672     .section    .rodata
   15673 .LstrBadEntryPoint:
   15674     .asciz  "Bad entry point %d\n"
   15675 
   15676 
   15677 /* File: x86/footer.S */
   15678 /*
   15679  * Copyright (C) 2008 The Android Open Source Project
   15680  *
   15681  * Licensed under the Apache License, Version 2.0 (the "License");
   15682  * you may not use this file except in compliance with the License.
   15683  * You may obtain a copy of the License at
   15684  *
   15685  *      http://www.apache.org/licenses/LICENSE-2.0
   15686  *
   15687  * Unless required by applicable law or agreed to in writing, software
   15688  * distributed under the License is distributed on an "AS IS" BASIS,
   15689  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   15690  * See the License for the specific language governing permissions and
   15691  * limitations under the License.
   15692  */
   15693 /*
   15694  * Common subroutines and data.
   15695  */
   15696 
   15697 #if defined(WITH_JIT)
   15698 /*
   15699  * JIT-related re-entries into the interpreter.  In general, if the
   15700  * exit from a translation can at some point be chained, the entry
   15701  * here requires that control arrived via a call, and that the "rp"
   15702  * on TOS is actually a pointer to a 32-bit cell containing the Dalvik PC
   15703  * of the next insn to handle.  If no chaining will happen, the entry
   15704  * should be reached via a direct jump and rPC set beforehand.
   15705  */
   15706 
   15707     .global dvmJitToInterpPunt
   15708 /*
   15709  * The compiler will generate a jump to this entry point when it is
   15710  * having difficulty translating a Dalvik instruction.  We must skip
   15711  * the code cache lookup & prevent chaining to avoid bouncing between
   15712  * the interpreter and code cache. rPC must be set on entry.
   15713  */
   15714 dvmJitToInterpPunt:
   15715     GET_PC
   15716 #if defined(WITH_JIT_TUNING)
   15717     movl   rPC, OUT_ARG0(%esp)
   15718     call   dvmBumpPunt
   15719 #endif
   15720     movl   rSELF, %ecx
   15721     movl   offThread_curHandlerTable(%ecx),rIBASE
   15722     movl        $0, offThread_inJitCodeCache(%ecx)
   15723     FETCH_INST_R %ecx
   15724     GOTO_NEXT_R %ecx
   15725 
   15726     .global dvmJitToInterpSingleStep
   15727 /*
   15728  * Return to the interpreter to handle a single instruction.
   15729  * Should be reached via a call.
   15730  * On entry:
   15731  *   0(%esp)          <= native return address within trace
   15732  *   rPC              <= Dalvik PC of this instruction
   15733  *   OUT_ARG0+4(%esp) <= Dalvik PC of next instruction
   15734  */
   15735 dvmJitToInterpSingleStep:
   15736 /* TODO */
   15737     call     dvmAbort
   15738 #if 0
   15739     pop    %eax
   15740     movl   rSELF, %ecx
   15741     movl   OUT_ARG0(%esp), %edx
   15742     movl   %eax,offThread_jitResumeNPC(%ecx)
   15743     movl   %edx,offThread_jitResumeDPC(%ecx)
   15744     movl   $kInterpEntryInstr,offThread_entryPoint(%ecx)
   15745     movl   $1,rINST     # changeInterp <= true
   15746     jmp    common_gotoBail
   15747 #endif
   15748 
   15749     .global dvmJitToInterpNoChainNoProfile
   15750 /*
   15751  * Return from the translation cache to the interpreter to do method
   15752  * invocation.  Check if the translation exists for the callee, but don't
   15753  * chain to it. rPC must be set on entry.
   15754  */
   15755 dvmJitToInterpNoChainNoProfile:
   15756 #if defined(WITH_JIT_TUNING)
   15757     SPILL_TMP1(%eax)
   15758     call   dvmBumpNoChain
   15759     UNSPILL_TMP1(%eax)
   15760 #endif
   15761     movl   %eax, rPC
   15762     movl   rSELF, %eax
   15763     movl   rPC,OUT_ARG0(%esp)
   15764     movl   %eax,OUT_ARG1(%esp)
   15765     call   dvmJitGetTraceAddrThread  # (pc, self)
   15766     movl   rSELF,%ecx                # ecx <- self
   15767     movl   %eax,offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
   15768     cmpl   $0, %eax
   15769     jz     1f
   15770     jmp    *%eax                     # exec translation if we've got one
   15771     # won't return
   15772 1:
   15773     EXPORT_PC
   15774     movl   rSELF, %ecx
   15775     movl   offThread_curHandlerTable(%ecx),rIBASE
   15776     FETCH_INST_R %ecx
   15777     GOTO_NEXT_R %ecx
   15778 
   15779 /*
   15780  * Return from the translation cache and immediately request a
   15781  * translation from the exit target, but don't attempt to chain.
   15782  * rPC set on entry.
   15783  */
   15784     .global dvmJitToInterpTraceSelectNoChain
   15785 dvmJitToInterpTraceSelectNoChain:
   15786 #if defined(WITH_JIT_TUNING)
   15787     movl   %edx, OUT_ARG0(%esp)
   15788     call   dvmBumpNoChain
   15789 #endif
   15790     movl   %ebx, rPC
   15791     lea    4(%esp), %esp #to recover the esp update due to function call
   15792     movl   rSELF, %eax
   15793     movl   rPC,OUT_ARG0(%esp)
   15794     movl   %eax,OUT_ARG1(%esp)
   15795     call   dvmJitGetTraceAddrThread  # (pc, self)
   15796     movl   rSELF,%ecx
   15797     cmpl   $0,%eax
   15798     movl   %eax,offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
   15799     jz     1f
   15800     jmp    *%eax              # jump to tranlation
   15801     # won't return
   15802 
   15803 /* No Translation - request one */
   15804 1:
   15805     GET_JIT_PROF_TABLE %ecx %eax
   15806     cmpl   $0, %eax          # JIT enabled?
   15807     jnz    2f                 # Request one if so
   15808     movl   rSELF, %ecx
   15809     movl   offThread_curHandlerTable(%ecx),rIBASE
   15810     FETCH_INST_R %ecx         # Continue interpreting if not
   15811     GOTO_NEXT_R %ecx
   15812 2:
   15813     ## Looks like an EXPORT_PC is needed here. Now jmp to common_selectTrace2
   15814     movl   $kJitTSelectRequestHot,%eax # ask for trace select
   15815     jmp    common_selectTrace
   15816 
   15817 /*
   15818  * Return from the translation cache and immediately request a
   15819  * translation for the exit target.  Reached via a call, and
   15820  * (TOS)->rPC.
   15821  */
   15822     .global dvmJitToInterpTraceSelect
   15823 dvmJitToInterpTraceSelect:
   15824     movl   0(%esp), %eax          # get return address
   15825     movl   %ebx, rPC              # get first argument (target rPC)
   15826 
   15827     ## TODO, need to clean up stack manipulation ... this isn't signal safe and
   15828     ## doesn't use the calling conventions of header.S
   15829     lea    4(%esp), %esp #to recover the esp update due to function call
   15830 
   15831     ## An additional 5B instruction "jump 0" was added for a thread-safe
   15832     ## chaining cell update in JIT code cache. So the offset is now -17=-12-5.
   15833     lea    -17(%eax), %ebx #$JIT_OFFSET_CHAIN_START(%eax), %ebx
   15834     lea    -4(%esp), %esp
   15835     movl   rSELF, %eax
   15836     movl   rPC,OUT_ARG0(%esp)
   15837     movl   %eax,OUT_ARG1(%esp)
   15838     call   dvmJitGetTraceAddrThread # (pc, self)
   15839     lea    4(%esp), %esp
   15840     cmpl   $0,%eax
   15841     movl   rSELF, %ecx
   15842     movl   %eax,offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
   15843     jz     1b                 # no - ask for one
   15844     movl   %eax,OUT_ARG0(%esp)
   15845     movl   rINST,OUT_ARG1(%esp)
   15846     call   dvmJitChain        # Attempt dvmJitChain(codeAddr,chainAddr)
   15847     cmpl   $0,%eax           # Success?
   15848     jz     toInterpreter      # didn't chain - interpret
   15849     jmp    *%eax
   15850     # won't return
   15851 
   15852 /*
   15853  * Placeholder entries for x86 JIT
   15854  */
   15855     .global dvmJitToInterpBackwardBranch
   15856 dvmJitToInterpBackwardBranch:
   15857 
   15858     .global     dvmJitToExceptionThrown
   15859 dvmJitToExceptionThrown: //rPC in
   15860     movl   rSELF, %edx
   15861     GET_PC
   15862     movl   $0, offThread_inJitCodeCache(%edx)
   15863     jmp common_exceptionThrown
   15864 
   15865     .global dvmJitToInterpNormal
   15866 dvmJitToInterpNormal:
   15867 /* one input: the target rPC value */
   15868     movl        0(%esp), %eax          # get return address
   15869     movl        %ebx, rPC              # get first argument (target rPC)
   15870 
   15871     ## TODO, need to clean up stack manipulation ... this isn't signal safe and
   15872     ## doesn't use the calling conventions of header.S
   15873 
   15874     ## An additional 5B instruction "jump 0" was added for a thread-safe
   15875     ## chaining cell update in JIT code cache. So the offset is now -17=-12-5.
   15876     lea         -17(%eax), %ebx #$JIT_OFFSET_CHAIN_START(%eax), %ebx
   15877     lea         4(%esp), %esp
   15878     movl        rPC, OUT_ARG0(%esp)
   15879     movl        rSELF, %ecx
   15880     movl        %ecx, OUT_ARG1(%esp)
   15881     call        dvmJitGetTraceAddrThread
   15882     ## Here is the change from using rGLUE to rSELF for accessing the
   15883     ## JIT code cache flag
   15884     movl        rSELF, %ecx
   15885     movl        %eax, offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
   15886     #lea         4(%esp), %esp
   15887     cmp         $0, %eax
   15888     je          toInterpreter
   15889     #lea         -8(%esp), %esp
   15890     movl        %ebx, OUT_ARG1(%esp)    # %ebx live thorugh dvmJitGetTraceAddrThread
   15891     movl        %eax, OUT_ARG0(%esp)    # first argument
   15892     call        dvmJitChain
   15893     #lea         8(%esp), %esp
   15894     cmp         $0, %eax
   15895     je          toInterpreter
   15896     jmp         *%eax                   #to native address
   15897 
   15898     .global dvmJitToInterpNoChain
   15899 dvmJitToInterpNoChain:
   15900 dvmJitToInterpNoChain: #rPC in eax
   15901 #if defined(WITH_JIT_TUNING)
   15902     SPILL_TMP1(%eax)
   15903     call   dvmBumpNoChain
   15904     UNSPILL_TMP1(%eax)
   15905 #endif
   15906     ## TODO, need to clean up stack manipulation ... this isn't signal safe and
   15907     ## doesn't use the calling conventions of header.S
   15908     movl        %eax, rPC
   15909     movl        rPC, OUT_ARG0(%esp)
   15910     movl        rSELF, %ecx
   15911     movl        %ecx, OUT_ARG1(%esp)
   15912     call        dvmJitGetTraceAddrThread
   15913     ## Here is the change from using rGLUE to rSELF for accessing the
   15914     ## JIT code cache flag
   15915     movl        rSELF, %ecx
   15916     movl        %eax, offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
   15917     cmp         $0, %eax
   15918     je          toInterpreter
   15919     jmp         *%eax                   #to native address
   15920 
   15921 toInterpreter:
   15922     EXPORT_PC
   15923     movl        rSELF, %ecx
   15924     movl        offThread_curHandlerTable(%ecx), rIBASE
   15925     FETCH_INST
   15926     movl        offThread_pJitProfTable(%ecx), %eax
   15927     #Fallthrough
   15928 
   15929 /* ebx holds the pointer to the jit profile table
   15930    edx has the opCode */
   15931 common_testUpdateProfile:
   15932     cmp         $0, %eax
   15933     je          4f
   15934 /* eax holds the pointer to the jit profile table
   15935    edx has the opCode
   15936    rPC points to the next bytecode */
   15937 
   15938 common_updateProfile:
   15939     # quick & dirty hash
   15940     movl   rPC, %ecx
   15941     shrl   $12, %ecx
   15942     xorl   rPC, %ecx
   15943     andl   $((1<<JIT_PROF_SIZE_LOG_2)-1), %ecx
   15944     decb   (%ecx,%eax)
   15945     #jmp    1f # remove
   15946     jz     2f
   15947 1:
   15948     GOTO_NEXT
   15949 2:
   15950 common_Profile:
   15951 /*
   15952  * Here, we switch to the debug interpreter to request
   15953  * trace selection.  First, though, check to see if there
   15954  * is already a native translation in place (and, if so,
   15955  * jump to it now.
   15956  */
   15957     SPILL(rIBASE)
   15958     SPILL_TMP1(rINST)
   15959     movl        rSELF, rIBASE
   15960     GET_JIT_THRESHOLD rIBASE rINST  # leaves rSELF in %ecx
   15961     EXPORT_PC
   15962     movb   rINSTbl,(%ecx,%eax)   # reset counter
   15963     movl   rIBASE,rINST            # preserve rSELF
   15964     movl   rSELF, %eax
   15965     movl   rPC,OUT_ARG0(%esp)
   15966     movl   rIBASE,OUT_ARG1(%esp)
   15967     call   dvmJitGetTraceAddrThread  # (pc, self)
   15968     UNSPILL(rIBASE)
   15969     movl   %eax,offThread_inJitCodeCache(rINST)   # set the inJitCodeCache flag
   15970     UNSPILL_TMP1(rINST)
   15971     cmpl   $0,%eax
   15972     #jmp    1f # remove
   15973     jz     1f
   15974     jmp   *%eax        # TODO: decide call vs/ jmp!.  No return either way
   15975 1:
   15976     movl   $kJitTSelectRequest,%eax
   15977     # On entry, eax<- jitState, rPC valid
   15978 common_selectTrace:
   15979     mov         %ebx, EBX_SPILL(%ebp)
   15980     movl        rSELF, %ebx
   15981     movzwl      offThread_subMode(%ebx), %ecx
   15982     and         $(kSubModeJitTraceBuild | kSubModeJitSV), %ecx
   15983     jne         3f                     # already doing JIT work, continue
   15984     movl        %eax, offThread_jitState(%ebx)
   15985     movl        rSELF, %eax
   15986     movl       %eax, OUT_ARG0(%esp)
   15987 
   15988 /*
   15989  * Call out to validate trace-building request. If successful, rIBASE will be swapped
   15990  * to send us into single-steppign trace building mode, so we need to refresh before
   15991  * we continue.
   15992  */
   15993 
   15994    EXPORT_PC
   15995    SAVE_PC_FP_TO_SELF %ecx
   15996    call dvmJitCheckTraceRequest
   15997 3:
   15998    mov          EBX_SPILL(%ebp), %ebx
   15999    FETCH_INST
   16000    movl rSELF, %ecx
   16001    movl offThread_curHandlerTable(%ecx), rIBASE
   16002 4:
   16003    GOTO_NEXT
   16004 
   16005 common_selectTrace2:
   16006     mov         %ebx, EBX_SPILL(%ebp)
   16007     movl        rSELF, %ebx
   16008     movl        %ebx, OUT_ARG0(%esp)
   16009     movl        %eax, offThread_jitState(%ebx)
   16010     movzwl      offThread_subMode(%ebx), %ecx
   16011     mov         EBX_SPILL(%ebp), %ebx
   16012     and         (kSubModeJitTraceBuild | kSubModeJitSV), %ecx
   16013     jne         3f                     # already doing JIT work, continue
   16014 
   16015 
   16016 
   16017 /*
   16018  * Call out to validate trace-building request. If successful, rIBASE will be swapped
   16019  * to send us into single-steppign trace building mode, so we need to refresh before
   16020  * we continue.
   16021  */
   16022 
   16023    EXPORT_PC
   16024    SAVE_PC_FP_TO_SELF %ecx
   16025    call dvmJitCheckTraceRequest
   16026 3:
   16027    FETCH_INST
   16028    movl rSELF, %ecx
   16029    movl offThread_curHandlerTable(%ecx), rIBASE
   16030 4:
   16031    GOTO_NEXT
   16032 
   16033 #endif
   16034 
   16035 /*
   16036  * For the invoke codes we need to know what register holds the "this" pointer. However
   16037  * it seems the this pointer is assigned consistently most times it is in %ecx but other
   16038  * times it is in OP_INVOKE_INTERFACE, OP_INVOKE_SUPER_QUICK, or OP_INVOKE_VIRTUAL_QUICK.
   16039 */
   16040 
   16041 /*
   16042  * Common code for method invocation with range.
   16043  *
   16044  * On entry:
   16045  *   eax = Method* methodToCall
   16046  *   ecx = "this"
   16047  *   rINSTw trashed, must reload
   16048  *   rIBASE trashed, must reload before resuming interpreter
   16049  */
   16050 
   16051 common_invokeMethodRange:
   16052 .LinvokeNewRange:
   16053 #if defined(WITH_JIT)
   16054     SPILL_TMP1(%edx)
   16055     SPILL_TMP2(%ebx)
   16056     movl        rSELF, %edx
   16057     movzwl      offThread_subMode(%edx), %ebx
   16058     and         $kSubModeJitTraceBuild, %ebx
   16059     jz          6f
   16060     call        save_callsiteinfo
   16061 6:
   16062     UNSPILL_TMP2(%ebx)
   16063     UNSPILL_TMP1(%edx)
   16064 #endif
   16065    /*
   16066     * prepare to copy args to "outs" area of current frame
   16067     */
   16068 
   16069     movzbl      1(rPC),rINST       # rINST<- AA
   16070     movzwl      4(rPC), %ecx            # %ecx<- CCCC
   16071     SAVEAREA_FROM_FP %edx               # %edx<- &StackSaveArea
   16072     test        rINST, rINST
   16073     movl        rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- AA
   16074     jz          .LinvokeArgsDone        # no args; jump to args done
   16075 
   16076 
   16077    /*
   16078     * %eax=methodToCall, %ecx=CCCC, LOCAL0_OFFSET(%ebp)=count,
   16079     * %edx=&outs (&stackSaveArea).  (very few methods have > 10 args;
   16080     * could unroll for common cases)
   16081     */
   16082 
   16083 .LinvokeRangeArgs:
   16084     movl        %ebx, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- save %ebx
   16085     lea         (rFP, %ecx, 4), %ecx    # %ecx<- &vCCCC
   16086     shll        $2, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- offset
   16087     subl        LOCAL0_OFFSET(%ebp), %edx       # %edx<- update &outs
   16088     shrl        $2, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- offset
   16089 1:
   16090     movl        (%ecx), %ebx            # %ebx<- vCCCC
   16091     lea         4(%ecx), %ecx           # %ecx<- &vCCCC++
   16092     subl        $1, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET<- LOCAL0_OFFSET--
   16093     movl        %ebx, (%edx)            # *outs<- vCCCC
   16094     lea         4(%edx), %edx           # outs++
   16095     jne         1b                      # loop if count (LOCAL0_OFFSET(%ebp)) not zero
   16096     movl        LOCAL1_OFFSET(%ebp), %ebx       # %ebx<- restore %ebx
   16097     jmp         .LinvokeArgsDone        # continue
   16098 
   16099    /*
   16100     * %eax is "Method* methodToCall", the method we're trying to call
   16101     * prepare to copy args to "outs" area of current frame
   16102     * rIBASE trashed, must reload before resuming interpreter
   16103     */
   16104 
   16105 common_invokeMethodNoRange:
   16106 #if defined(WITH_JIT)
   16107     SPILL_TMP1(%edx)
   16108     SPILL_TMP2(%ebx)
   16109     movl        rSELF, %edx
   16110     movzwl      offThread_subMode(%edx), %ebx
   16111     and         $kSubModeJitTraceBuild, %ebx
   16112     jz          6f
   16113     call        save_callsiteinfo
   16114 6:
   16115     UNSPILL_TMP2(%ebx)
   16116     UNSPILL_TMP1(%edx)
   16117 #endif
   16118 .LinvokeNewNoRange:
   16119     movzbl      1(rPC),rINST       # rINST<- BA
   16120     movl        rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- BA
   16121     shrl        $4, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- B
   16122     je          .LinvokeArgsDone        # no args; jump to args done
   16123     movzwl      4(rPC), %ecx            # %ecx<- GFED
   16124     SAVEAREA_FROM_FP %edx               # %edx<- &StackSaveArea
   16125 
   16126    /*
   16127     * %eax=methodToCall, %ecx=GFED, LOCAL0_OFFSET(%ebp)=count, %edx=outs
   16128     */
   16129 
   16130 .LinvokeNonRange:
   16131     cmp         $2, LOCAL0_OFFSET(%ebp)        # compare LOCAL0_OFFSET(%ebp) to 2
   16132     movl        %ecx, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- GFED
   16133     jl          1f                      # handle 1 arg
   16134     je          2f                      # handle 2 args
   16135     cmp         $4, LOCAL0_OFFSET(%ebp)        # compare LOCAL0_OFFSET(%ebp) to 4
   16136     jl          3f                      # handle 3 args
   16137     je          4f                      # handle 4 args
   16138 5:
   16139     andl        $15, rINST             # rINSTw<- A
   16140     lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
   16141     movl        (rFP, rINST, 4), %ecx   # %ecx<- vA
   16142     movl        %ecx, (%edx)            # *outs<- vA
   16143     movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
   16144 4:
   16145     shr         $12, %ecx              # %ecx<- G
   16146     lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
   16147     movl        (rFP, %ecx, 4), %ecx    # %ecx<- vG
   16148     movl        %ecx, (%edx)            # *outs<- vG
   16149     movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
   16150 3:
   16151     and         $0x0f00, %ecx          # %ecx<- 0F00
   16152     shr         $8, %ecx               # %ecx<- F
   16153     lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
   16154     movl        (rFP, %ecx, 4), %ecx    # %ecx<- vF
   16155     movl        %ecx, (%edx)            # *outs<- vF
   16156     movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
   16157 2:
   16158     and         $0x00f0, %ecx          # %ecx<- 00E0
   16159     shr         $4, %ecx               # %ecx<- E
   16160     lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
   16161     movl        (rFP, %ecx, 4), %ecx    # %ecx<- vE
   16162     movl        %ecx, (%edx)            # *outs<- vE
   16163     movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
   16164 1:
   16165     and         $0x000f, %ecx          # %ecx<- 000D
   16166     movl        (rFP, %ecx, 4), %ecx    # %ecx<- vD
   16167     movl        %ecx, -4(%edx)          # *--outs<- vD
   16168 0:
   16169 
   16170    /*
   16171     * %eax is "Method* methodToCall", the method we're trying to call
   16172     * find space for the new stack frame, check for overflow
   16173     */
   16174 
   16175 .LinvokeArgsDone:
   16176     movzwl      offMethod_registersSize(%eax), %edx # %edx<- methodToCall->regsSize
   16177     movzwl      offMethod_outsSize(%eax), %ecx # %ecx<- methodToCall->outsSize
   16178     movl        %eax, LOCAL0_OFFSET(%ebp)       # LOCAL0_OFFSET<- methodToCall
   16179     shl         $2, %edx               # %edx<- update offset
   16180     SAVEAREA_FROM_FP %eax               # %eax<- &StackSaveArea
   16181     subl        %edx, %eax              # %eax<- newFP; (old savearea - regsSize)
   16182     movl        rSELF,%edx              # %edx<- pthread
   16183     movl        %eax, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- &outs
   16184     subl        $sizeofStackSaveArea, %eax # %eax<- newSaveArea (stack save area using newFP)
   16185     movl        offThread_interpStackEnd(%edx), %edx # %edx<- self->interpStackEnd
   16186     movl        %edx, TMP_SPILL1(%ebp)  # spill self->interpStackEnd
   16187     shl         $2, %ecx               # %ecx<- update offset for outsSize
   16188     movl        %eax, %edx              # %edx<- newSaveArea
   16189     sub         %ecx, %eax              # %eax<- bottom; (newSaveArea - outsSize)
   16190     cmp         TMP_SPILL1(%ebp), %eax  # compare interpStackEnd and bottom
   16191     movl        LOCAL0_OFFSET(%ebp), %eax       # %eax<- restore methodToCall
   16192     jl          .LstackOverflow         # handle frame overflow
   16193 
   16194    /*
   16195     * set up newSaveArea
   16196     */
   16197 
   16198 #ifdef EASY_GDB
   16199     SAVEAREA_FROM_FP %ecx               # %ecx<- &StackSaveArea
   16200     movl        %ecx, offStackSaveArea_prevSave(%edx) # newSaveArea->prevSave<- &outs
   16201 #endif
   16202     movl        rSELF,%ecx              # %ecx<- pthread
   16203     movl        rFP, offStackSaveArea_prevFrame(%edx) # newSaveArea->prevFrame<- rFP
   16204     movl        rPC, offStackSaveArea_savedPc(%edx) # newSaveArea->savedPc<- rPC
   16205 #if defined(WITH_JIT)
   16206     movl        $0, offStackSaveArea_returnAddr(%edx)
   16207 #endif
   16208 
   16209     /* Any special actions to take? */
   16210     cmpw        $0, offThread_subMode(%ecx)
   16211     jne         2f                     # Yes - handle them
   16212 1:
   16213     testl       $ACC_NATIVE, offMethod_accessFlags(%eax) # check for native call
   16214     movl        %eax, offStackSaveArea_method(%edx) # newSaveArea->method<- method to call
   16215     jne         .LinvokeNative          # handle native call
   16216 
   16217    /*
   16218     * Update "self" values for the new method
   16219     * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFp
   16220     */
   16221     movl        offMethod_clazz(%eax), %edx # %edx<- method->clazz
   16222     movl        offClassObject_pDvmDex(%edx), %edx # %edx<- method->clazz->pDvmDex
   16223     movl        %eax, offThread_method(%ecx) # self->method<- methodToCall
   16224     movl        %edx, offThread_methodClassDex(%ecx) # self->methodClassDex<- method->clazz->pDvmDex
   16225     movl        offMethod_insns(%eax), rPC # rPC<- methodToCall->insns
   16226     movl        $1, offThread_debugIsMethodEntry(%ecx)
   16227     movl        LOCAL1_OFFSET(%ebp), rFP # rFP<- newFP
   16228     movl        rFP, offThread_curFrame(%ecx) # curFrame<-newFP
   16229     movl        offThread_curHandlerTable(%ecx),rIBASE
   16230     FETCH_INST
   16231 #if defined(WITH_JIT)
   16232     /* rPC is already updated */
   16233     GET_JIT_PROF_TABLE %ecx %eax
   16234     cmp         $0, %eax
   16235     jne         common_updateProfile # set up %ebx & %edx & rPC
   16236 #endif
   16237     GOTO_NEXT                           # jump to methodToCall->insns
   16238 
   16239 2:
   16240     /*
   16241      * On entry, preserve all:
   16242      *  %eax: method
   16243      *  %ecx: self
   16244      *  %edx: new save area
   16245      */
   16246     SPILL_TMP1(%eax)                   # preserve methodToCall
   16247     SPILL_TMP2(%edx)                   # preserve newSaveArea
   16248     movl        rPC, offThread_pc(%ecx) # update interpSave.pc
   16249     movl        %ecx, OUT_ARG0(%esp)
   16250     movl        %eax, OUT_ARG1(%esp)
   16251     call        dvmReportInvoke        # (self, method)
   16252     UNSPILL_TMP1(%eax)
   16253     UNSPILL_TMP2(%edx)
   16254     movl        rSELF,%ecx             # restore rSELF
   16255     jmp         1b
   16256 
   16257    /*
   16258     * Prep for the native call
   16259     * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFP, %edx=newSaveArea, %ecx=self
   16260     */
   16261 
   16262 .LinvokeNative:
   16263     movl        offThread_jniLocal_topCookie(%ecx), rINST # rINST<- self->localRef->...
   16264     movl        rINST, offStackSaveArea_localRefCookie(%edx) # newSaveArea->localRefCookie<- top
   16265     movl        %edx, LOCAL2_OFFSET(%ebp)  # save newSaveArea
   16266     movl        LOCAL1_OFFSET(%ebp), rINST # rINST<- newFP
   16267     movl        rINST, offThread_curFrame(%ecx)  # curFrame<- newFP
   16268     cmpw        $0, offThread_subMode(%ecx)  # Anything special going on?
   16269     jne         11f                     # yes - handle it
   16270     movl        %ecx, OUT_ARG3(%esp)    # push parameter self
   16271     movl        %eax, OUT_ARG2(%esp)    # push parameter methodToCall
   16272     lea         offThread_retval(%ecx), %ecx # %ecx<- &retval
   16273     movl        %ecx, OUT_ARG1(%esp)    # push parameter &retval
   16274     movl        rINST, OUT_ARG0(%esp)    # push parameter newFP
   16275     call        *offMethod_nativeFunc(%eax) # call methodToCall->nativeFunc
   16276 7:
   16277     movl        LOCAL2_OFFSET(%ebp), %ecx    # %ecx<- newSaveArea
   16278     movl        rSELF, %eax             # %eax<- self
   16279     movl        offStackSaveArea_localRefCookie(%ecx), %edx # %edx<- old top
   16280     cmp         $0, offThread_exception(%eax) # check for exception
   16281     movl        rFP, offThread_curFrame(%eax) # curFrame<- rFP
   16282     movl        %edx, offThread_jniLocal_topCookie(%eax) # new top <- old top
   16283     jne         common_exceptionThrown  # handle exception
   16284     movl        offThread_curHandlerTable(%eax),rIBASE
   16285     FETCH_INST_OPCODE 3 %ecx
   16286     ADVANCE_PC 3
   16287     GOTO_NEXT_R %ecx                    # jump to next instruction
   16288 
   16289 11:
   16290     /*
   16291      * Handle any special subMode actions
   16292      * %eax=methodToCall, rINST=newFP, %ecx=self
   16293      */
   16294     SPILL_TMP1(%eax)                    # save methodTocall
   16295     movl        rPC, offThread_pc(%ecx)
   16296     movl        %ecx, OUT_ARG1(%esp)
   16297     movl        %eax, OUT_ARG0(%esp)
   16298     movl        rFP, OUT_ARG2(%esp)
   16299     call        dvmReportPreNativeInvoke # (methodToCall, self, fp)
   16300     UNSPILL_TMP1(%eax)                  # restore methodToCall
   16301     movl        rSELF,%ecx              # restore self
   16302 
   16303     /* Do the native call */
   16304     movl        %ecx, OUT_ARG3(%esp)    # push parameter self
   16305     lea         offThread_retval(%ecx), %ecx # %ecx<- &retval
   16306     movl        %eax, OUT_ARG2(%esp)    # push parameter methodToCall
   16307     movl        %ecx, OUT_ARG1(%esp)    # push parameter &retval
   16308     movl        rINST, OUT_ARG0(%esp)   # push parameter newFP
   16309     call        *offMethod_nativeFunc(%eax) # call methodToCall->nativeFunc
   16310 
   16311     UNSPILL_TMP1(%eax)                  # restore methodToCall
   16312     movl        rSELF, %ecx
   16313     movl        %ecx, OUT_ARG1(%esp)
   16314     movl        %eax, OUT_ARG0(%esp)
   16315     movl        rFP, OUT_ARG2(%esp)
   16316     call        dvmReportPostNativeInvoke # (methodToCall, self, fp)
   16317     jmp         7b                      # rejoin
   16318 
   16319 .LstackOverflow:    # eax=methodToCall
   16320     movl        %eax, OUT_ARG1(%esp)    # push parameter methodToCall
   16321     movl        rSELF,%eax              # %eax<- self
   16322     movl        %eax, OUT_ARG0(%esp)    # push parameter self
   16323     call        dvmHandleStackOverflow  # call: (Thread* self, Method* meth)
   16324     jmp         common_exceptionThrown  # handle exception
   16325 
   16326 
   16327 /*
   16328  * Common code for handling a return instruction
   16329  */
   16330 common_returnFromMethod:
   16331     movl    rSELF, %ecx
   16332     SAVEAREA_FROM_FP %eax                       # %eax<- saveArea(old)
   16333     cmpw    $0, offThread_subMode(%ecx)          # special action needed?
   16334     jne     19f                                   # go if so
   16335 14:
   16336 
   16337     movl        offStackSaveArea_prevFrame(%eax), rFP # rFP<- saveArea->PrevFrame
   16338     movl        (offStackSaveArea_method - sizeofStackSaveArea)(rFP), rINST # rINST<- method we are returning to
   16339     cmpl        $0, rINST               # check for break frame
   16340     je          common_gotoBail         # bail if break frame
   16341     movl        offThread_curHandlerTable(%ecx),rIBASE
   16342     movl        offStackSaveArea_savedPc(%eax), rPC # rPC<- saveAreaOld->savedPc
   16343 #if defined(WITH_JIT)
   16344     movl        offStackSaveArea_returnAddr(%eax), %ecx
   16345 #endif
   16346     movl        rSELF, %eax
   16347     movl        rINST, offThread_method(%eax) # glue->method<- newSave->method
   16348     movl        offMethod_clazz(rINST), rINST # rINST<- method->clazz
   16349     movl        rFP, offThread_curFrame(%eax) # glue->self->curFrame<- rFP
   16350 #if defined(WITH_JIT)
   16351     //update self->offThread_inJitCodeCache
   16352     movl        %ecx, offThread_inJitCodeCache(%eax)
   16353 #endif
   16354     movl        offClassObject_pDvmDex(rINST), rINST # rINST<- method->clazz->pDvmDex
   16355     movl        rINST, offThread_methodClassDex(%eax) # glue->pDvmDex<- method->clazz->pDvmDex
   16356 #if defined(WITH_JIT)
   16357     cmp         $0, %ecx
   16358     je          .returnToBC
   16359     movl        %ecx, %eax
   16360     jmp         *%eax
   16361 #endif
   16362 
   16363 .returnToBC:
   16364 
   16365 #if defined(WITH_JIT)
   16366     FETCH_INST_OPCODE  3, %ecx                 # %eax<- next instruction hi; fetch, advance
   16367     // %ecx has the opcode
   16368     addl         $6, rPC               # 3*2 = 6
   16369     SPILL_TMP1   (%ecx)
   16370     movl         rSELF, %ecx
   16371     FETCH_INST
   16372     UNSPILL_TMP1   (%ecx)
   16373     movzbl      1(rPC), rINST
   16374     jmp     *(rIBASE,%ecx,4)
   16375 #else
   16376     FETCH_INST_WORD 3
   16377     ADVANCE_PC 3
   16378     GOTO_NEXT
   16379 #endif
   16380 
   16381 19:
   16382     /*
   16383      * Handle special subMode actions
   16384      * On entry, rFP: prevFP, %ecx: self, %eax: saveArea
   16385      */
   16386     SPILL_TMP1(%ebx)
   16387     movl     offStackSaveArea_prevFrame(%eax), %ebx # %ebx<- saveArea->PrevFrame
   16388     movl     rPC, offThread_pc(%ecx)          # update interpSave.pc
   16389     movl     %ebx, offThread_curFrame(%ecx)    # update interpSave.curFrame
   16390     movl     %ecx, OUT_ARG0(%esp)             # parameter self
   16391     call     dvmReportReturn                  # (self)
   16392     UNSPILL_TMP1(%ebx)
   16393     movl     rSELF, %ecx                      # restore self
   16394     SAVEAREA_FROM_FP %eax                     # restore saveArea
   16395     jmp      14b
   16396 
   16397 
   16398 /*
   16399  * Prepare to strip the current frame and "longjump" back to caller of
   16400  * dvmMterpStdRun.
   16401  *
   16402  * on entry:
   16403  *    rINST holds changeInterp
   16404  *    ecx holds self pointer
   16405  *
   16406  * expected profile: dvmMterpStdBail(Thread *self, bool changeInterp)
   16407  */
   16408 common_gotoBail:
   16409     movl   rPC,offThread_pc(%ecx)     # export state to self
   16410     movl   rFP,offThread_curFrame(%ecx)
   16411     movl   %ecx,OUT_ARG0(%esp)      # self in arg0
   16412     movl   rINST,OUT_ARG1(%esp)     # changeInterp in arg1
   16413     call   dvmMterpStdBail          # bail out....
   16414 
   16415 /*
   16416  * The JIT's invoke method needs to remember the callsite class and
   16417  * target pair.  Save them here so that they are available to
   16418  * dvmCheckJit following the interpretation of this invoke.
   16419  *
   16420  * eax = Method* methodToCall
   16421  * ecx = "this"
   16422  * edx = rSELF
   16423  * ebx = free to use
   16424  */
   16425 #if defined(WITH_JIT)
   16426 save_callsiteinfo:
   16427     cmp     $0, %ecx
   16428     je      2f
   16429     movl    offObject_clazz(%ecx), %ecx
   16430 2:
   16431     movl    rSELF, %ebx
   16432     movl    %eax, offThread_methodToCall(%ebx)
   16433     movl    %ecx, offThread_callsiteClass(%ebx)
   16434     ret
   16435 #endif
   16436 
   16437 #if defined(WITH_JIT)
   16438 
   16439     /*
   16440      * If the JIT is actively building a trace we need to make sure
   16441      * that the field is fully resolved before including the current
   16442      * instruction.
   16443      *
   16444      * On entry:
   16445      *     %ecx: &dvmDex->pResFields[field]
   16446      *     %eax:  field pointer (must preserve)
   16447      */
   16448 common_verifyField:
   16449     movl    %ebx, TMP_SPILL1(%ebp)
   16450     movl     rSELF, %ebx
   16451     movzwl   offThread_subMode(%ebx), %ebx
   16452     andl     $kSubModeJitTraceBuild, %ebx
   16453     movl    TMP_SPILL1(%ebp), %ebx
   16454     jne      1f
   16455     ret
   16456 1:
   16457     movl    (%ecx), %ecx
   16458     cmp     $0, %ecx
   16459     je      1f
   16460     ret
   16461 1:
   16462     SPILL_TMP1(%eax)
   16463     SPILL_TMP2(%edx)
   16464     movl     rSELF, %ecx
   16465     # Because we call into this helper from a bytecode, we have
   16466     # to be careful not to write over the return address when using
   16467     # the OUT_ARG macros
   16468     lea      -8(%esp), %esp
   16469     movl     %ecx, OUT_ARG0(%esp)
   16470     movl     rPC, OUT_ARG1(%esp)
   16471     call     dvmJitEndTraceSelect
   16472     lea      8(%esp), %esp
   16473     UNSPILL_TMP2(%edx)
   16474     UNSPILL_TMP1(%eax)
   16475     ret
   16476 #endif
   16477 
   16478 /*
   16479  * After returning from a "selfd" function, pull out the updated values
   16480  * and start executing at the next instruction.
   16481  */
   16482 common_resumeAfterGlueCall:
   16483      movl  rSELF, %eax
   16484      movl  offThread_pc(%eax),rPC
   16485      movl  offThread_curFrame(%eax),rFP
   16486      movl  offThread_curHandlerTable(%eax),rIBASE
   16487      FETCH_INST
   16488      GOTO_NEXT
   16489 
   16490 /*
   16491  * Integer divide or mod by zero
   16492  */
   16493 common_errDivideByZero:
   16494     EXPORT_PC
   16495     movl    $.LstrDivideByZero,%eax
   16496     movl    %eax,OUT_ARG0(%esp)
   16497     call    dvmThrowArithmeticException
   16498     jmp     common_exceptionThrown
   16499 
   16500 /*
   16501  * Attempt to allocate an array with a negative size.
   16502  * On entry, len in eax
   16503  */
   16504 common_errNegativeArraySize:
   16505     EXPORT_PC
   16506     movl    %eax,OUT_ARG0(%esp)                  # arg0<- len
   16507     call    dvmThrowNegativeArraySizeException   # (len)
   16508     jmp     common_exceptionThrown
   16509 
   16510 /*
   16511  * Attempt to allocate an array with a negative size.
   16512  * On entry, method name in eax
   16513  */
   16514 common_errNoSuchMethod:
   16515     EXPORT_PC
   16516     movl    %eax,OUT_ARG0(%esp)
   16517     call    dvmThrowNoSuchMethodError
   16518     jmp     common_exceptionThrown
   16519 
   16520 /*
   16521  * Hit a null object when we weren't expecting one.  Export the PC, throw a
   16522  * NullPointerException and goto the exception processing code.
   16523  */
   16524 common_errNullObject:
   16525     EXPORT_PC
   16526     xorl    %eax,%eax
   16527     movl    %eax,OUT_ARG0(%esp)
   16528     call    dvmThrowNullPointerException
   16529     jmp     common_exceptionThrown
   16530 
   16531 /*
   16532  * Array index exceeds max.
   16533  * On entry:
   16534  *    eax <- array object
   16535  *    ecx <- index
   16536  */
   16537 common_errArrayIndex:
   16538     EXPORT_PC
   16539     movl    offArrayObject_length(%eax), %eax
   16540     movl    %eax,OUT_ARG0(%esp)
   16541     movl    %ecx,OUT_ARG1(%esp)
   16542     call    dvmThrowArrayIndexOutOfBoundsException   # args (length, index)
   16543     jmp     common_exceptionThrown
   16544 
   16545 /*
   16546  * Somebody has thrown an exception.  Handle it.
   16547  *
   16548  * If the exception processing code returns to us (instead of falling
   16549  * out of the interpreter), continue with whatever the next instruction
   16550  * now happens to be.
   16551  *
   16552  * NOTE: special subMode handling done in dvmMterp_exceptionThrown
   16553  *
   16554  * This does not return.
   16555  */
   16556 common_exceptionThrown:
   16557 .LexceptionNew:
   16558 
   16559     EXPORT_PC
   16560     movl       rSELF, %ecx
   16561     movl       %ecx, OUT_ARG0(%esp)
   16562     call       dvmCheckSuspendPending
   16563 
   16564     movl       rSELF, %ecx
   16565     movl       offThread_exception(%ecx), %edx   # %edx <- self->exception
   16566     movl       %edx, OUT_ARG0(%esp)
   16567     movl       %ecx, OUT_ARG1(%esp)
   16568     SPILL_TMP1(%edx)
   16569     call       dvmAddTrackedAlloc      # don't let the exception be GCed
   16570     UNSPILL_TMP1(%edx)
   16571     movl       rSELF, %ecx
   16572     movl       offThread_subMode(%ecx), %eax    # get subMode flags
   16573     movl       $0, offThread_exception(%ecx)
   16574 
   16575     # Special subMode?
   16576     cmpl       $0, %eax                # any special subMode handling needed?
   16577     je         8f                      # go if so
   16578 
   16579     # Manage debugger bookkeeping
   16580     movl       rPC, offThread_pc(%ecx) # update interpSave.pc
   16581     movl       rFP, offThread_curFrame(%ecx) # update interpSave.curFrame
   16582     movl       %ecx, OUT_ARG0(%esp)
   16583     movl       %edx, OUT_ARG1(%esp)
   16584     SPILL_TMP1(%edx)
   16585     call       dvmReportExceptionThrow # (self, exception)
   16586     UNSPILL_TMP1(%edx)
   16587     movl       rSELF, %ecx
   16588 
   16589 8:
   16590     /*
   16591     * set up args and a local for &fp
   16592     */
   16593     lea        20(%esp), %esp          # raise %esp
   16594     movl       rFP, (%esp)               # save fp
   16595     movl       %esp, %eax              # %eax = &fp
   16596     lea        -20(%esp), %esp         # reset %esp
   16597     movl       %eax, OUT_ARG4(%esp)    # Arg 4 = &fp
   16598     movl       $0, OUT_ARG3(%esp)      # Arg 3 = false
   16599     movl       %edx, OUT_ARG2(%esp)    # Arg 2 = exception
   16600     movl       %ecx, OUT_ARG0(%esp)    # Arg 0 = self
   16601 
   16602     movl       offThread_method(%ecx), %eax # %eax = self->method
   16603     movl       offMethod_insns(%eax), %eax  # %eax = self->method->insn
   16604     movl       rPC, %ecx
   16605     subl       %eax, %ecx              # %ecx = pc - self->method->insn
   16606     sar        $1, %ecx                # adjust %ecx for code offset
   16607     movl       %ecx, OUT_ARG1(%esp)    # Arg 1 = %ecx
   16608 
   16609     /* call, %eax gets catchRelPc (a code-unit offset) */
   16610     SPILL_TMP1(%edx)                   # save exception
   16611     call       dvmFindCatchBlock       # call(self, relPc, exc, scan?, &fp)
   16612     UNSPILL_TMP1(%edx)                 # restore exception
   16613 
   16614     /* fix earlier stack overflow if necessary; may trash rFP */
   16615     movl       rSELF, %ecx
   16616     cmpl       $0, offThread_stackOverflowed(%ecx) # did we overflow?
   16617     je         1f                         # no, skip ahead
   16618     movl       %eax, rFP                  # save relPc result in rFP
   16619     movl       %ecx, OUT_ARG0(%esp)       # Arg 0 = self
   16620     movl       %edx, OUT_ARG1(%esp)       # Arg 1 = exception
   16621     SPILL_TMP1(%edx)
   16622     call       dvmCleanupStackOverflow    # call(self, exception)
   16623     UNSPILL_TMP1(%edx)
   16624     movl       rFP, %eax                  # restore result
   16625     movl       rSELF, %ecx
   16626 1:
   16627 
   16628     /* update frame pointer and check result from dvmFindCatchBlock */
   16629     movl       20(%esp), rFP              # retrieve the updated rFP
   16630     cmpl       $0, %eax                  # is catchRelPc < 0?
   16631     jl         .LnotCaughtLocally
   16632 
   16633     /* adjust locals to match self->interpSave.curFrame and updated PC */
   16634     SAVEAREA_FROM_FP rINST             # rINST<- new save area
   16635     movl       offStackSaveArea_method(rINST), rINST # rINST<- new method
   16636     movl       rINST, offThread_method(%ecx)         # self->method = new method
   16637     movl       offMethod_clazz(rINST), %ecx          # %ecx = method->clazz
   16638     movl       offMethod_insns(rINST), rINST         # rINST = method->insn
   16639     movl       offClassObject_pDvmDex(%ecx), %ecx    # %ecx = method->clazz->pDvmDex
   16640     lea        (rINST, %eax, 2), rPC      # rPC<- method->insns + catchRelPc
   16641     movl       rSELF, rINST
   16642     movl       %ecx, offThread_methodClassDex(rINST) # self->pDvmDex = method->clazz->pDvmDex
   16643 
   16644     /* release the tracked alloc on the exception */
   16645     movl       %edx, OUT_ARG0(%esp)       # Arg 0 = exception
   16646     movl       rINST, OUT_ARG1(%esp)      # Arg 1 = self
   16647     SPILL_TMP1(%edx)
   16648     call       dvmReleaseTrackedAlloc     # release the exception
   16649     UNSPILL_TMP1(%edx)
   16650 
   16651     /* restore the exception if the handler wants it */
   16652     movl       rSELF, %ecx
   16653     FETCH_INST
   16654     movzbl     rINSTbl, %eax
   16655     cmpl       $OP_MOVE_EXCEPTION, %eax   # is it "move-exception"?
   16656     jne        1f
   16657     movl       %edx, offThread_exception(%ecx) # restore exception
   16658 1:
   16659     movl       offThread_curHandlerTable(%ecx), rIBASE # refresh rIBASE
   16660     GOTO_NEXT
   16661 
   16662 .LnotCaughtLocally: # %edx = exception
   16663     /* fix stack overflow if necessary */
   16664     movl       rSELF, %ecx
   16665     movl       offThread_stackOverflowed(%ecx), %eax
   16666     cmpl       $0, %eax                   # did we overflow earlier?
   16667     je         1f
   16668     movl       %ecx, OUT_ARG0(%esp)
   16669     movl       %edx, OUT_ARG1(%esp)
   16670     SPILL_TMP1(%edx)
   16671     call       dvmCleanupStackOverflow
   16672     UNSPILL_TMP1(%edx)
   16673 
   16674 1:
   16675     movl       rSELF, %ecx
   16676     movl       %edx, offThread_exception(%ecx) #restore exception
   16677     movl       %edx, OUT_ARG0(%esp)
   16678     movl       %ecx, OUT_ARG1(%esp)
   16679     call       dvmReleaseTrackedAlloc     # release the exception
   16680     movl       rSELF, %ecx
   16681     jmp        common_gotoBail            # bail out
   16682 
   16683 common_abort:
   16684     movl    $0xdeadf00d,%eax
   16685     call     *%eax
   16686 
   16687 
   16688 /*
   16689  * Strings
   16690  */
   16691 
   16692     .section     .rodata
   16693 .LstrDivideByZero:
   16694     .asciz  "divide by zero"
   16695 .LstrFilledNewArrayNotImplA:
   16696     .asciz  "filled-new-array only implemented for 'int'"
   16697 
   16698