InterpAsm-x86.S revision cb3081f675109049e63380170b60871e8275f9a8
1/*
2 * This file was generated automatically by gen-mterp.py for 'x86'.
3 *
4 * --> DO NOT EDIT <--
5 */
6
7/* File: x86/header.S */
8/*
9 * Copyright (C) 2008 The Android Open Source Project
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 *      http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 */
23/*
24 * 32-bit x86 definitions and declarations.
25 */
26
27/*
28386 ABI general notes:
29
30Caller save set:
31   eax, edx, ecx, st(0)-st(7)
32Callee save set:
33   ebx, esi, edi, ebp
34Return regs:
35   32-bit in eax
36   64-bit in edx:eax (low-order 32 in eax)
37   fp on top of fp stack st(0)
38
39Parameters passed on stack, pushed right-to-left.  On entry to target, first
40parm is at 4(%esp).  Traditional entry code is:
41
42functEntry:
43    push    %ebp             # save old frame pointer
44    mov     %ebp,%esp        # establish new frame pointer
45    sub     FrameSize,%esp   # Allocate storage for spill, locals & outs
46
47Once past the prologue, arguments are referenced at ((argno + 2)*4)(%ebp)
48
49Alignment of stack not strictly required, but should be for performance.  We'll
50align frame sizes to 16-byte multiples.
51
52If we're not doing variable stack allocation (alloca), the frame pointer can be
53eliminated and all arg references adjusted to be esp relative.
54
55Mterp notes:
56
57Some key interpreter variables will be assigned to registers.  Note that each
58will also have an associated spill location (mostly useful for those assigned
59to callee save registers).
60
61  nick     reg   purpose
62  rPC      edi   interpreted program counter, used for fetching instructions
63  rFP      esi   interpreted frame pointer, used for accessing locals and args
64  rINSTw   bx    first 16-bit code of current instruction
65  rINSTbl  bl    opcode portion of instruction word
66  rINSTbh  bh    high byte of inst word, usually contains src/tgt reg names
67
68Notes:
69   o High order 16 bits of ebx must be zero on entry to handler
70   o rPC, rFP, rINSTw/rINSTbl valid on handler entry and exit
71   o eax, edx and ecx are scratch, rINSTw/ebx sometimes scratch
72
73*/
74
75#define rGLUE    (%ebp)
76#define rPC      %esi
77#define rFP      %edi
78#define rINST    %ebx
79#define rINSTw   %bx
80#define rINSTbh  %bh
81#define rINSTbl  %bl
82
83
84/* Frame diagram while executing dvmMterpStdRun, high to low addresses */
85#define IN_ARG0        ( 12)
86#define CALLER_RP      (  8)
87#define PREV_FP        (  4)
88#define rGLUE_SPILL    (  0) /* <- dvmMterpStdRun ebp */
89/* Spill offsets relative to %ebp */
90#define EDI_SPILL      ( -4)
91#define ESI_SPILL      ( -8)
92#define EBX_SPILL      (-12) /* <- esp following dmMterpStdRun header */
93#define rPC_SPILL      (-16)
94#define rFP_SPILL      (-20)
95#define rINST_SPILL    (-24)
96#define TMP_SPILL1     (-28)
97#define TMP_SPILL2     (-32)
98#define TMP_SPILL3     (-36)
99#define LOCAL0_OFFSET  (-40)
100#define LOCAL1_OFFSET  (-44)
101#define LOCAL2_OFFSET  (-48)
102#define LOCAL3_OFFSET  (-52)
103/* Out Arg offsets, relative to %sp */
104#define OUT_ARG4       ( 16)
105#define OUT_ARG3       ( 12)
106#define OUT_ARG2       (  8)
107#define OUT_ARG1       (  4)
108#define OUT_ARG0       (  0)  /* <- dvmMterpStdRun esp */
109#define FRAME_SIZE     80
110
111#define SPILL(reg) movl reg##,reg##_SPILL(%ebp)
112#define UNSPILL(reg) movl reg##_SPILL(%ebp),reg
113#define SPILL_TMP1(reg) movl reg,TMP_SPILL1(%ebp)
114#define UNSPILL_TMP1(reg) movl TMP_SPILL1(%ebp),reg
115#define SPILL_TMP2(reg) movl reg,TMP_SPILL2(%ebp)
116#define UNSPILL_TMP2(reg) movl TMP_SPILL2(%ebp),reg
117#define SPILL_TMP3(reg) movl reg,TMP_SPILL3(%ebp)
118#define UNSPILL_TMP3(reg) movl TMP_SPILL3(%ebp),reg
119
120#if defined(WITH_JIT)
121.macro GET_JIT_PROF_TABLE _glue _reg
122    movl    offGlue_pJitProfTable(\_glue),\_reg
123.endm
124.macro GET_JIT_THRESHOLD _glue _reg
125    movl    offGlue_jitThreshold(\_glue),\_reg
126.endm
127#endif
128
129/* save/restore the PC and/or FP from the glue struct */
130.macro SAVE_PC_FP_TO_GLUE _reg
131    movl     rGLUE,\_reg
132    movl     rPC,offGlue_pc(\_reg)
133    movl     rFP,offGlue_fp(\_reg)
134.endm
135
136.macro LOAD_PC_FP_FROM_GLUE
137    movl    rGLUE,rFP
138    movl    offGlue_pc(rFP),rPC
139    movl    offGlue_fp(rFP),rFP
140.endm
141
142/* The interpreter assumes a properly aligned stack on entry, and
143 * will preserve 16-byte alignment.
144 */
145
146/*
147 * "export" the PC to the interpreted stack frame, f/b/o future exception
148 * objects.  Must * be done *before* something calls dvmThrowException.
149 *
150 * In C this is "SAVEAREA_FROM_FP(fp)->xtra.currentPc = pc", i.e.
151 * fp - sizeof(StackSaveArea) + offsetof(SaveArea, xtra.currentPc)
152 *
153 * It's okay to do this more than once.
154 */
155.macro EXPORT_PC
156    movl     rPC, (-sizeofStackSaveArea + offStackSaveArea_currentPc)(rFP)
157.endm
158
159/*
160 * Given a frame pointer, find the stack save area.
161 *
162 * In C this is "((StackSaveArea*)(_fp) -1)".
163 */
164.macro SAVEAREA_FROM_FP _reg
165    leal    -sizeofStackSaveArea(rFP), \_reg
166.endm
167
168/*
169 * Fetch the next instruction from rPC into rINSTw.  Does not advance rPC.
170 */
171.macro FETCH_INST
172    movzwl    (rPC),rINST
173.endm
174
175/*
176 * Fetch the opcode byte and zero-extend it into _reg.  Must be used
177 * in conjunction with GOTO_NEXT_R
178 */
179.macro FETCH_INST_R _reg
180    movzbl    (rPC),\_reg
181.endm
182
183/*
184 * Fetch the opcode byte at _count words offset from rPC and zero-extend
185 * it into _reg.  Must be used in conjunction with GOTO_NEXT_R
186 */
187.macro FETCH_INST_OPCODE _count _reg
188    movzbl  \_count*2(rPC),\_reg
189.endm
190
191/*
192 * Fetch the nth instruction word from rPC into rINSTw.  Does not advance
193 * rPC, and _count is in words
194 */
195.macro FETCH_INST_WORD _count
196    movzwl  \_count*2(rPC),rINST
197.endm
198
199/*
200 * Fetch instruction word indexed (used for branching).
201 * Index is in instruction word units.
202 */
203.macro FETCH_INST_INDEXED _reg
204    movzwl  (rPC,\_reg,2),rINST
205.endm
206
207/*
208 * Advance rPC by instruction count
209 */
210.macro ADVANCE_PC _count
211    leal  2*\_count(rPC),rPC
212.endm
213
214/*
215 * Advance rPC by branch offset in register
216 */
217.macro ADVANCE_PC_INDEXED _reg
218    leal (rPC,\_reg,2),rPC
219.endm
220
221.macro GOTO_NEXT
222     movzx   rINSTbl,%eax
223     movzbl  rINSTbh,rINST
224     jmp     *dvmAsmInstructionJmpTable(,%eax,4)
225.endm
226
227   /*
228    * Version of GOTO_NEXT that assumes _reg preloaded with opcode.
229    * Should be paired with FETCH_INST_R
230    */
231.macro GOTO_NEXT_R _reg
232     movzbl  1(rPC),rINST
233     jmp     *dvmAsmInstructionJmpTable(,\_reg,4)
234.endm
235
236   /*
237    * Jumbo version of GOTO_NEXT that assumes _reg preloaded with table
238    * offset of the jumbo instruction, which is the top half of the extended
239    * opcode + 0x100.  Loads rINST with BBBB field, similar to GOTO_NEXT_R
240    */
241.macro GOTO_NEXT_JUMBO_R _reg
242     movzwl  6(rPC),rINST
243     jmp     *dvmAsmInstructionJmpTable(,\_reg,4)
244.endm
245
246/*
247 * Get/set the 32-bit value from a Dalvik register.
248 */
249.macro GET_VREG_R _reg _vreg
250    movl     (rFP,\_vreg,4),\_reg
251.endm
252
253.macro SET_VREG _reg _vreg
254    movl     \_reg,(rFP,\_vreg,4)
255.endm
256
257.macro GET_VREG_WORD _reg _vreg _offset
258    movl     4*(\_offset)(rFP,\_vreg,4),\_reg
259.endm
260
261.macro SET_VREG_WORD _reg _vreg _offset
262    movl     \_reg,4*(\_offset)(rFP,\_vreg,4)
263.endm
264
265#if 1
266
267#define rFinish %edx
268
269/* Macros for x86-atom handlers */
270    /*
271    * Get the 32-bit value from a dalvik register.
272    */
273
274    .macro      GET_VREG _vreg
275    movl        (rFP,\_vreg, 4), \_vreg
276    .endm
277
278   /*
279    * Fetch the next instruction from the specified offset. Advances rPC
280    * to point to the next instruction. "_count" is in 16-bit code units.
281    *
282    * This must come AFTER anything that can throw an exception, or the
283    * exception catch may miss. (This also implies that it must come after
284    * EXPORT_PC())
285    */
286
287    .macro      FETCH_ADVANCE_INST _count
288    add         $(\_count*2), rPC
289    movzwl      (rPC), rINST
290    .endm
291
292   /*
293    * Fetch the next instruction from an offset specified by _reg. Updates
294    * rPC to point to the next instruction. "_reg" must specify the distance
295    * in bytes, *not* 16-bit code units, and may be a signed value.
296    */
297
298    .macro      FETCH_ADVANCE_INST_RB _reg
299    addl        \_reg, rPC
300    movzwl      (rPC), rINST
301    .endm
302
303   /*
304    * Fetch a half-word code unit from an offset past the current PC. The
305    * "_count" value is in 16-bit code units. Does not advance rPC.
306    * For example, given instruction of format: AA|op BBBB, it
307    * fetches BBBB.
308    */
309
310    .macro      FETCH _count _reg
311    movzwl      (\_count*2)(rPC), \_reg
312    .endm
313
314   /*
315    * Fetch a half-word code unit from an offset past the current PC. The
316    * "_count" value is in 16-bit code units. Does not advance rPC.
317    * This variant treats the value as signed.
318    */
319
320    .macro      FETCHs _count _reg
321    movswl      (\_count*2)(rPC), \_reg
322    .endm
323
324   /*
325    * Fetch the first byte from an offset past the current PC. The
326    * "_count" value is in 16-bit code units. Does not advance rPC.
327    * For example, given instruction of format: AA|op CC|BB, it
328    * fetches BB.
329    */
330
331    .macro      FETCH_BB _count _reg
332    movzbl      (\_count*2)(rPC), \_reg
333    .endm
334
335    /*
336    * Fetch the second byte from an offset past the current PC. The
337    * "_count" value is in 16-bit code units. Does not advance rPC.
338    * For example, given instruction of format: AA|op CC|BB, it
339    * fetches CC.
340    */
341
342    .macro      FETCH_CC _count _reg
343    movzbl      (\_count*2 + 1)(rPC), \_reg
344    .endm
345
346   /*
347    * Fetch the second byte from an offset past the current PC. The
348    * "_count" value is in 16-bit code units. Does not advance rPC.
349    * This variant treats the value as signed.
350    */
351
352    .macro      FETCH_CCs _count _reg
353    movsbl      (\_count*2 + 1)(rPC), \_reg
354    .endm
355
356
357   /*
358    * Fetch one byte from an offset past the current PC.  Pass in the same
359    * "_count" as you would for FETCH, and an additional 0/1 indicating which
360    * byte of the halfword you want (lo/hi).
361    */
362
363    .macro      FETCH_B _reg  _count  _byte
364    movzbl      (\_count*2+\_byte)(rPC), \_reg
365    .endm
366
367   /*
368    * Put the instruction's opcode field into the specified register.
369    */
370
371    .macro      GET_INST_OPCODE _reg
372    movzbl      rINSTbl, \_reg
373    .endm
374
375   /*
376    * Begin executing the opcode in _reg.
377    */
378
379    .macro      GOTO_OPCODE _reg
380    shl         $6, \_reg
381    addl        $dvmAsmInstructionStart,\_reg
382    jmp         *\_reg
383    .endm
384
385
386
387   /*
388    * Macros pair attempts to speed up FETCH_INST, GET_INST_OPCODE and GOTO_OPCODE
389    * by using a jump table. _rFinish should must be the same register for
390    * both macros.
391    */
392
393    .macro      FFETCH _rFinish
394    movzbl      (rPC), \_rFinish
395    .endm
396
397    .macro      FGETOP_JMPa _rFinish
398    movzbl      1(rPC), rINST
399    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
400    .endm
401
402   /*
403    * Macro pair attempts to speed up FETCH_INST, GET_INST_OPCODE and GOTO_OPCODE
404    * by using a jump table. _rFinish and _count should must be the same register for
405    * both macros.
406    */
407
408    .macro      FFETCH_ADV _count _rFinish
409    movzbl      (\_count*2)(rPC), \_rFinish
410    .endm
411
412    .macro      FGETOP_JMP _count _rFinish
413    movzbl      (\_count*2 + 1)(rPC), rINST
414    addl        $(\_count*2), rPC
415    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
416    .endm
417
418    .macro      FGETOP_JMP2 _rFinish
419    movzbl      1(rPC), rINST
420    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
421    .endm
422
423    .macro      OLD_JMP_1 _count _rFinish
424    movzbl      (\_count*2)(rPC), \_rFinish
425    shl         $6, \_rFinish
426    .endm
427
428    .macro      OLD_JMP_2 _rFinish
429    addl        $dvmAsmInstructionStart,\_rFinish
430    .endm
431
432    .macro      OLD_JMP_3 _count
433    addl        $(\_count*2), rPC
434    .endm
435
436    .macro      OLD_JMP_4 _rFinish
437    movzbl      1(rPC), rINST
438    jmp         *\_rFinish
439    .endm
440
441    .macro      OLD_JMP_A_1 _reg _rFinish
442    movzbl      (rPC, \_reg), \_rFinish
443    shl         $6, \_rFinish
444    .endm
445
446    .macro      OLD_JMP_A_2 _rFinish
447    addl        $dvmAsmInstructionStart,\_rFinish
448    .endm
449
450    .macro      OLD_JMP_A_3 _reg _rFinish
451    addl        \_reg, rPC
452    movzbl      1(rPC, \_reg), rINST
453    jmp         *\_rFinish
454    .endm
455
456   /*
457    * Macro pair attempts to speed up FETCH_INST, GET_INST_OPCODE and GOTO_OPCODE
458    * by using a jump table. _rFinish and _reg should must be the same register for
459    * both macros.
460    */
461
462    .macro      FFETCH_ADV_RB _reg _rFinish
463    movzbl      (\_reg, rPC), \_rFinish
464    .endm
465
466    .macro      FGETOP_RB_JMP _reg _rFinish
467    movzbl      1(\_reg, rPC), rINST
468    addl        \_reg, rPC
469    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
470    .endm
471
472   /*
473    * Attempts to speed up FETCH_INST, GET_INST_OPCODE using
474    * a jump table. This macro should be called before FINISH_JMP where
475    * rFinish should be the same register containing the opcode value.
476    * This is an attempt to split up FINISH in order to reduce or remove
477    * potential stalls due to the wait for rFINISH.
478    */
479
480    .macro      FINISH_FETCH _rFinish
481    movzbl      (rPC), \_rFinish
482    movzbl      1(rPC), rINST
483    .endm
484
485
486   /*
487    * Attempts to speed up FETCH_ADVANCE_INST, GET_INST_OPCODE using
488    * a jump table. This macro should be called before FINISH_JMP where
489    * rFinish should be the same register containing the opcode value.
490    * This is an attempt to split up FINISH in order to reduce or remove
491    * potential stalls due to the wait for rFINISH.
492    */
493
494    .macro      FINISH_FETCH_ADVANCE _count _rFinish
495    movzbl      (\_count*2)(rPC), \_rFinish
496    movzbl      (\_count*2 + 1)(rPC), rINST
497    addl        $(\_count*2), rPC
498    .endm
499
500   /*
501    * Attempts to speed up FETCH_ADVANCE_INST_RB, GET_INST_OPCODE using
502    * a jump table. This macro should be called before FINISH_JMP where
503    * rFinish should be the same register containing the opcode value.
504    * This is an attempt to split up FINISH in order to reduce or remove
505    * potential stalls due to the wait for rFINISH.
506    */
507
508    .macro      FINISH_FETCH_ADVANCE_RB _reg _rFinish
509    movzbl      (\_reg, rPC), \_rFinish
510    movzbl      1(\_reg, rPC), rINST
511    addl        \_reg, rPC
512    .endm
513
514   /*
515    * Attempts to speed up GOTO_OPCODE using a jump table. This macro should
516    * be called after a FINISH_FETCH* instruction where rFinish should be the
517    * same register containing the opcode value. This is an attempt to split up
518    * FINISH in order to reduce or remove potential stalls due to the wait for rFINISH.
519    */
520
521    .macro      FINISH_JMP _rFinish
522    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
523    .endm
524
525   /*
526    * Attempts to speed up FETCH_INST, GET_INST_OPCODE, GOTO_OPCODE by using
527    * a jump table. Uses a single macro - but it should be faster if we
528    * split up the fetch for rFinish and the jump using rFinish.
529    */
530
531    .macro      FINISH_A
532    movzbl      (rPC), rFinish
533    movzbl      1(rPC), rINST
534    jmp         *dvmAsmInstructionJmpTable(,rFinish, 4)
535    .endm
536
537   /*
538    * Attempts to speed up FETCH_ADVANCE_INST, GET_INST_OPCODE,
539    * GOTO_OPCODE by using a jump table. Uses a single macro -
540    * but it should be faster if we split up the fetch for rFinish
541    * and the jump using rFinish.
542    */
543
544    .macro      FINISH _count
545    movzbl      (\_count*2)(rPC), rFinish
546    movzbl      (\_count*2 + 1)(rPC), rINST
547    addl        $(\_count*2), rPC
548    jmp         *dvmAsmInstructionJmpTable(,rFinish, 4)
549    .endm
550
551   /*
552    * Attempts to speed up FETCH_ADVANCE_INST_RB, GET_INST_OPCODE,
553    * GOTO_OPCODE by using a jump table. Uses a single macro -
554    * but it should be faster if we split up the fetch for rFinish
555    * and the jump using rFinish.
556    */
557
558    .macro      FINISH_RB _reg _rFinish
559    movzbl      (\_reg, rPC), \_rFinish
560    movzbl      1(\_reg, rPC), rINST
561    addl        \_reg, rPC
562    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
563    .endm
564
565#define sReg0 LOCAL0_OFFSET(%ebp)
566#define sReg1 LOCAL1_OFFSET(%ebp)
567#define sReg2 LOCAL2_OFFSET(%ebp)
568#define sReg3 LOCAL3_OFFSET(%ebp)
569
570   /*
571    * Hard coded helper values.
572    */
573
574.balign 16
575
576.LdoubNeg:
577    .quad       0x8000000000000000
578
579.L64bits:
580    .quad       0xFFFFFFFFFFFFFFFF
581
582.LshiftMask2:
583    .quad       0x0000000000000000
584.LshiftMask:
585    .quad       0x000000000000003F
586
587.Lvalue64:
588    .quad       0x0000000000000040
589
590.LvaluePosInfLong:
591    .quad       0x7FFFFFFFFFFFFFFF
592
593.LvalueNegInfLong:
594    .quad       0x8000000000000000
595
596.LvalueNanLong:
597    .quad       0x0000000000000000
598
599.LintMin:
600.long   0x80000000
601
602.LintMax:
603.long   0x7FFFFFFF
604#endif
605
606
607/*
608 * This is a #include, not a %include, because we want the C pre-processor
609 * to expand the macros into assembler assignment statements.
610 */
611#include "../common/asm-constants.h"
612
613#if defined(WITH_JIT)
614#include "../common/jit-config.h"
615#endif
616
617
618    .global dvmAsmInstructionStart
619    .type   dvmAsmInstructionStart, %function
620dvmAsmInstructionStart = .L_OP_NOP
621    .text
622
623/* ------------------------------ */
624    .balign 64
625.L_OP_NOP: /* 0x00 */
626/* File: x86/OP_NOP.S */
627    FETCH_INST_OPCODE 1 %edx
628    ADVANCE_PC 1
629    GOTO_NEXT_R %edx
630
631/* ------------------------------ */
632    .balign 64
633.L_OP_MOVE: /* 0x01 */
634/* File: x86/OP_MOVE.S */
635    /* for move, move-object, long-to-int */
636    /* op vA, vB */
637    movzbl rINSTbl,%eax          # eax<- BA
638    andb   $0xf,%al             # eax<- A
639    shrl   $4,rINST            # rINST<- B
640    GET_VREG_R %ecx rINST
641    FETCH_INST_OPCODE 1 %edx
642    ADVANCE_PC 1
643    SET_VREG %ecx %eax           # fp[A]<-fp[B]
644    GOTO_NEXT_R %edx
645
646/* ------------------------------ */
647    .balign 64
648.L_OP_MOVE_FROM16: /* 0x02 */
649/* File: x86/OP_MOVE_FROM16.S */
650    /* for: move/from16, move-object/from16 */
651    /* op vAA, vBBBB */
652    movzx    rINSTbl,%eax              # eax <= AA
653    movw     2(rPC),rINSTw             # rINSTw <= BBBB
654    GET_VREG_R %ecx rINST              # ecx<- fp[BBBB]
655    FETCH_INST_OPCODE 2 %edx
656    ADVANCE_PC 2
657    SET_VREG %ecx %eax                # fp[AA]<- ecx]
658    GOTO_NEXT_R %edx
659
660/* ------------------------------ */
661    .balign 64
662.L_OP_MOVE_16: /* 0x03 */
663/* File: x86/OP_MOVE_16.S */
664    /* for: move/16, move-object/16 */
665    /* op vAAAA, vBBBB */
666    movzwl    4(rPC),%ecx              # ecx<- BBBB
667    movzwl    2(rPC),%eax              # eax<- AAAA
668    GET_VREG_R  %ecx %ecx
669    FETCH_INST_OPCODE 3 %edx
670    ADVANCE_PC 3
671    SET_VREG  %ecx %eax
672    GOTO_NEXT_R %edx
673
674/* ------------------------------ */
675    .balign 64
676.L_OP_MOVE_WIDE: /* 0x04 */
677/* File: x86/OP_MOVE_WIDE.S */
678    /* move-wide vA, vB */
679    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
680    movzbl    rINSTbl,%ecx                # ecx <- BA
681    sarl      $4,rINST                   # rINST<- B
682    GET_VREG_WORD %eax rINST 0            # eax<- v[B+0]
683    GET_VREG_WORD rINST rINST 1           # rINST<- v[B+1]
684    andb      $0xf,%cl                   # ecx <- A
685    FETCH_INST_OPCODE 1 %edx
686    SET_VREG_WORD rINST %ecx 1            # v[A+1]<- rINST
687    ADVANCE_PC 1
688    SET_VREG_WORD %eax %ecx 0             # v[A+0]<- eax
689    GOTO_NEXT_R %edx
690
691/* ------------------------------ */
692    .balign 64
693.L_OP_MOVE_WIDE_FROM16: /* 0x05 */
694/* File: x86/OP_MOVE_WIDE_FROM16.S */
695    /* move-wide/from16 vAA, vBBBB */
696    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
697    movzwl    2(rPC),%ecx              # ecx<- BBBB
698    movzbl    rINSTbl,%eax             # eax<- AAAA
699    GET_VREG_WORD rINST %ecx 0         # rINST<- v[BBBB+0]
700    GET_VREG_WORD %ecx %ecx 1          # ecx<- v[BBBB+1]
701    FETCH_INST_OPCODE 2 %edx
702    ADVANCE_PC 2
703    SET_VREG_WORD rINST %eax 0         # v[AAAA+0]<- rINST
704    SET_VREG_WORD %ecx %eax 1          # v[AAAA+1]<- eax
705    GOTO_NEXT_R %edx
706
707/* ------------------------------ */
708    .balign 64
709.L_OP_MOVE_WIDE_16: /* 0x06 */
710/* File: x86/OP_MOVE_WIDE_16.S */
711    /* move-wide/16 vAAAA, vBBBB */
712    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
713    movzwl    4(rPC),%ecx            # ecx<- BBBB
714    movzwl    2(rPC),%eax            # eax<- AAAA
715    GET_VREG_WORD rINST %ecx 0       # rINSTw_WORD<- v[BBBB+0]
716    GET_VREG_WORD %ecx %ecx 1        # ecx<- v[BBBB+1]
717    FETCH_INST_OPCODE 3 %edx
718    SET_VREG_WORD rINST %eax 0       # v[AAAA+0]<- rINST
719    ADVANCE_PC 3
720    SET_VREG_WORD %ecx %eax 1        # v[AAAA+1]<- ecx
721    GOTO_NEXT_R %edx
722
723/* ------------------------------ */
724    .balign 64
725.L_OP_MOVE_OBJECT: /* 0x07 */
726/* File: x86/OP_MOVE_OBJECT.S */
727/* File: x86/OP_MOVE.S */
728    /* for move, move-object, long-to-int */
729    /* op vA, vB */
730    movzbl rINSTbl,%eax          # eax<- BA
731    andb   $0xf,%al             # eax<- A
732    shrl   $4,rINST            # rINST<- B
733    GET_VREG_R %ecx rINST
734    FETCH_INST_OPCODE 1 %edx
735    ADVANCE_PC 1
736    SET_VREG %ecx %eax           # fp[A]<-fp[B]
737    GOTO_NEXT_R %edx
738
739
740/* ------------------------------ */
741    .balign 64
742.L_OP_MOVE_OBJECT_FROM16: /* 0x08 */
743/* File: x86/OP_MOVE_OBJECT_FROM16.S */
744/* File: x86/OP_MOVE_FROM16.S */
745    /* for: move/from16, move-object/from16 */
746    /* op vAA, vBBBB */
747    movzx    rINSTbl,%eax              # eax <= AA
748    movw     2(rPC),rINSTw             # rINSTw <= BBBB
749    GET_VREG_R %ecx rINST              # ecx<- fp[BBBB]
750    FETCH_INST_OPCODE 2 %edx
751    ADVANCE_PC 2
752    SET_VREG %ecx %eax                # fp[AA]<- ecx]
753    GOTO_NEXT_R %edx
754
755
756/* ------------------------------ */
757    .balign 64
758.L_OP_MOVE_OBJECT_16: /* 0x09 */
759/* File: x86/OP_MOVE_OBJECT_16.S */
760/* File: x86/OP_MOVE_16.S */
761    /* for: move/16, move-object/16 */
762    /* op vAAAA, vBBBB */
763    movzwl    4(rPC),%ecx              # ecx<- BBBB
764    movzwl    2(rPC),%eax              # eax<- AAAA
765    GET_VREG_R  %ecx %ecx
766    FETCH_INST_OPCODE 3 %edx
767    ADVANCE_PC 3
768    SET_VREG  %ecx %eax
769    GOTO_NEXT_R %edx
770
771
772/* ------------------------------ */
773    .balign 64
774.L_OP_MOVE_RESULT: /* 0x0a */
775/* File: x86/OP_MOVE_RESULT.S */
776    /* for: move-result, move-result-object */
777    /* op vAA */
778    movl     rGLUE,%eax                    # eax<- rGLUE
779    movzx    rINSTbl,%ecx                  # ecx<- AA
780    movl     offGlue_retval(%eax),%eax     # eax<- glue->retval.l
781    FETCH_INST_OPCODE 1 %edx
782    ADVANCE_PC 1
783    SET_VREG  %eax %ecx                    # fp[AA]<- retval.l
784    GOTO_NEXT_R %edx
785
786/* ------------------------------ */
787    .balign 64
788.L_OP_MOVE_RESULT_WIDE: /* 0x0b */
789/* File: x86/OP_MOVE_RESULT_WIDE.S */
790    /* move-result-wide vAA */
791    movl    rGLUE,%ecx
792    movl    offGlue_retval(%ecx),%eax
793    movl    4+offGlue_retval(%ecx),%ecx
794    FETCH_INST_OPCODE 1 %edx
795    SET_VREG_WORD %eax rINST 0     # v[AA+0] <- eax
796    SET_VREG_WORD %ecx rINST 1     # v[AA+1] <- ecx
797    ADVANCE_PC 1
798    GOTO_NEXT_R %edx
799
800/* ------------------------------ */
801    .balign 64
802.L_OP_MOVE_RESULT_OBJECT: /* 0x0c */
803/* File: x86/OP_MOVE_RESULT_OBJECT.S */
804/* File: x86/OP_MOVE_RESULT.S */
805    /* for: move-result, move-result-object */
806    /* op vAA */
807    movl     rGLUE,%eax                    # eax<- rGLUE
808    movzx    rINSTbl,%ecx                  # ecx<- AA
809    movl     offGlue_retval(%eax),%eax     # eax<- glue->retval.l
810    FETCH_INST_OPCODE 1 %edx
811    ADVANCE_PC 1
812    SET_VREG  %eax %ecx                    # fp[AA]<- retval.l
813    GOTO_NEXT_R %edx
814
815
816/* ------------------------------ */
817    .balign 64
818.L_OP_MOVE_EXCEPTION: /* 0x0d */
819/* File: x86/OP_MOVE_EXCEPTION.S */
820    /* move-exception vAA */
821    movl    rGLUE,%ecx
822    movl    offGlue_self(%ecx),%ecx    # ecx<- glue->self
823    movl    offThread_exception(%ecx),%eax # eax<- dvmGetException bypass
824    SET_VREG %eax rINST                # fp[AA]<- exception object
825    FETCH_INST_OPCODE 1 %edx
826    ADVANCE_PC 1
827    movl    $0,offThread_exception(%ecx) # dvmClearException bypass
828    GOTO_NEXT_R %edx
829
830/* ------------------------------ */
831    .balign 64
832.L_OP_RETURN_VOID: /* 0x0e */
833/* File: x86/OP_RETURN_VOID.S */
834    jmp       common_returnFromMethod
835
836/* ------------------------------ */
837    .balign 64
838.L_OP_RETURN: /* 0x0f */
839/* File: x86/OP_RETURN.S */
840    /*
841     * Return a 32-bit value.  Copies the return value into the "glue"
842     * structure, then jumps to the return handler.
843     *
844     * for: return, return-object
845     */
846    /* op vAA */
847    movl    rGLUE,%ecx
848    GET_VREG_R %eax rINST               # eax<- vAA
849    movl    %eax,offGlue_retval(%ecx)   # retval.i <- AA
850    jmp     common_returnFromMethod
851
852/* ------------------------------ */
853    .balign 64
854.L_OP_RETURN_WIDE: /* 0x10 */
855/* File: x86/OP_RETURN_WIDE.S */
856    /*
857     * Return a 64-bit value.  Copies the return value into the "glue"
858     * structure, then jumps to the return handler.
859     */
860    /* return-wide vAA */
861    movl    rGLUE,%ecx
862    GET_VREG_WORD %eax rINST 0       # eax<- v[AA+0]
863    GET_VREG_WORD rINST rINST 1      # rINST<- v[AA+1]
864    movl    %eax,offGlue_retval(%ecx)
865    movl    rINST,4+offGlue_retval(%ecx)
866    jmp     common_returnFromMethod
867
868/* ------------------------------ */
869    .balign 64
870.L_OP_RETURN_OBJECT: /* 0x11 */
871/* File: x86/OP_RETURN_OBJECT.S */
872/* File: x86/OP_RETURN.S */
873    /*
874     * Return a 32-bit value.  Copies the return value into the "glue"
875     * structure, then jumps to the return handler.
876     *
877     * for: return, return-object
878     */
879    /* op vAA */
880    movl    rGLUE,%ecx
881    GET_VREG_R %eax rINST               # eax<- vAA
882    movl    %eax,offGlue_retval(%ecx)   # retval.i <- AA
883    jmp     common_returnFromMethod
884
885
886/* ------------------------------ */
887    .balign 64
888.L_OP_CONST_4: /* 0x12 */
889/* File: x86/OP_CONST_4.S */
890    /* const/4 vA, #+B */
891    movsx   rINSTbl,%eax              # eax<-ssssssBx
892    movl    $0xf,%ecx
893    andl    %eax,%ecx                 # ecx<- A
894    FETCH_INST_OPCODE 1 %edx
895    ADVANCE_PC 1
896    sarl    $4,%eax
897    SET_VREG %eax %ecx
898    GOTO_NEXT_R %edx
899
900/* ------------------------------ */
901    .balign 64
902.L_OP_CONST_16: /* 0x13 */
903/* File: x86/OP_CONST_16.S */
904    /* const/16 vAA, #+BBBB */
905    movswl  2(rPC),%ecx                # ecx<- ssssBBBB
906    movl    rINST,%eax                 # eax<- AA
907    FETCH_INST_OPCODE 2 %edx
908    ADVANCE_PC 2
909    SET_VREG %ecx %eax                 # vAA<- ssssBBBB
910    GOTO_NEXT_R %edx
911
912/* ------------------------------ */
913    .balign 64
914.L_OP_CONST: /* 0x14 */
915/* File: x86/OP_CONST.S */
916    /* const vAA, #+BBBBbbbb */
917    movl      2(rPC),%eax             # grab all 32 bits at once
918    movl      rINST,%ecx              # ecx<- AA
919    FETCH_INST_OPCODE 3 %edx
920    ADVANCE_PC 3
921    SET_VREG %eax %ecx                # vAA<- eax
922    GOTO_NEXT_R %edx
923
924/* ------------------------------ */
925    .balign 64
926.L_OP_CONST_HIGH16: /* 0x15 */
927/* File: x86/OP_CONST_HIGH16.S */
928    /* const/high16 vAA, #+BBBB0000 */
929    movzwl     2(rPC),%eax                # eax<- 0000BBBB
930    movl       rINST,%ecx                 # ecx<- AA
931    FETCH_INST_OPCODE 2 %edx
932    ADVANCE_PC 2
933    sall       $16,%eax                  # eax<- BBBB0000
934    SET_VREG %eax %ecx                    # vAA<- eax
935    GOTO_NEXT_R %edx
936
937/* ------------------------------ */
938    .balign 64
939.L_OP_CONST_WIDE_16: /* 0x16 */
940/* File: x86/OP_CONST_WIDE_16.S */
941    /* const-wide/16 vAA, #+BBBB */
942    movswl    2(rPC),%eax               # eax<- ssssBBBB
943    cltd                                # rPC:eax<- ssssssssssssBBBB
944    SET_VREG_WORD %edx rINST 1          # store msw
945    FETCH_INST_OPCODE 2 %edx
946    SET_VREG_WORD %eax rINST 0          # store lsw
947    ADVANCE_PC 2
948    GOTO_NEXT_R %edx
949
950/* ------------------------------ */
951    .balign 64
952.L_OP_CONST_WIDE_32: /* 0x17 */
953/* File: x86/OP_CONST_WIDE_32.S */
954    /* const-wide/32 vAA, #+BBBBbbbb */
955    movl     2(rPC),%eax                # eax<- BBBBbbbb
956    cltd                                # rPC:eax<- ssssssssssssBBBB
957    SET_VREG_WORD %edx rINST,1          # store msw
958    FETCH_INST_OPCODE 3 %edx
959    SET_VREG_WORD %eax rINST 0          # store lsw
960    ADVANCE_PC 3
961    GOTO_NEXT_R %edx
962
963/* ------------------------------ */
964    .balign 64
965.L_OP_CONST_WIDE: /* 0x18 */
966/* File: x86/OP_CONST_WIDE.S */
967    /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
968    movl      2(rPC),%eax         # eax<- lsw
969    movzbl    rINSTbl,%ecx        # ecx<- AA
970    movl      6(rPC),rINST        # rINST<- msw
971    leal      (rFP,%ecx,4),%ecx   # dst addr
972    movl      rINST,4(%ecx)
973    FETCH_INST_OPCODE 5 %edx
974    movl      %eax,(%ecx)
975    ADVANCE_PC 5
976    GOTO_NEXT_R %edx
977
978/* ------------------------------ */
979    .balign 64
980.L_OP_CONST_WIDE_HIGH16: /* 0x19 */
981/* File: x86/OP_CONST_WIDE_HIGH16.S */
982    /* const-wide/high16 vAA, #+BBBB000000000000 */
983    movzwl     2(rPC),%eax                # eax<- 0000BBBB
984    FETCH_INST_OPCODE 2 %edx
985    ADVANCE_PC 2
986    sall       $16,%eax                  # eax<- BBBB0000
987    SET_VREG_WORD %eax rINST 1            # v[AA+1]<- eax
988    xorl       %eax,%eax
989    SET_VREG_WORD %eax rINST 0            # v[AA+0]<- eax
990    GOTO_NEXT_R %edx
991
992/* ------------------------------ */
993    .balign 64
994.L_OP_CONST_STRING: /* 0x1a */
995/* File: x86/OP_CONST_STRING.S */
996
997    /* const/string vAA, String@BBBB */
998    movl      rGLUE,%ecx
999    movzwl    2(rPC),%eax              # eax<- BBBB
1000    movl      offGlue_methodClassDex(%ecx),%ecx# ecx<- glue->methodClassDex
1001    movl      offDvmDex_pResStrings(%ecx),%ecx # ecx<- dvmDex->pResStrings
1002    movl      (%ecx,%eax,4),%eax       # eax<- rResString[BBBB]
1003    movl      rINST,%ecx
1004    FETCH_INST_OPCODE 2 %edx
1005    testl     %eax,%eax                # resolved yet?
1006    je        .LOP_CONST_STRING_resolve
1007    SET_VREG  %eax %ecx                # vAA<- rResString[BBBB]
1008    ADVANCE_PC 2
1009    GOTO_NEXT_R %edx
1010
1011/* ------------------------------ */
1012    .balign 64
1013.L_OP_CONST_STRING_JUMBO: /* 0x1b */
1014/* File: x86/OP_CONST_STRING_JUMBO.S */
1015
1016    /* const/string vAA, String@BBBBBBBB */
1017    movl      rGLUE,%ecx
1018    movl      2(rPC),%eax              # eax<- BBBBBBBB
1019    movl      offGlue_methodClassDex(%ecx),%ecx# ecx<- glue->methodClassDex
1020    movl      offDvmDex_pResStrings(%ecx),%ecx # ecx<- dvmDex->pResStrings
1021    movl      (%ecx,%eax,4),%eax       # eax<- rResString[BBBB]
1022    movl      rINST,%ecx
1023    FETCH_INST_OPCODE 3 %edx
1024    testl     %eax,%eax                # resolved yet?
1025    je        .LOP_CONST_STRING_JUMBO_resolve
1026    SET_VREG  %eax %ecx                # vAA<- rResString[BBBB]
1027    ADVANCE_PC 3
1028    GOTO_NEXT_R %edx
1029
1030/* ------------------------------ */
1031    .balign 64
1032.L_OP_CONST_CLASS: /* 0x1c */
1033/* File: x86/OP_CONST_CLASS.S */
1034
1035    /* const/class vAA, Class@BBBB */
1036    movl      rGLUE,%ecx
1037    movzwl    2(rPC),%eax              # eax<- BBBB
1038    movl      offGlue_methodClassDex(%ecx),%ecx# ecx<- glue->methodClassDex
1039    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- dvmDex->pResClasses
1040    movl      (%ecx,%eax,4),%eax       # eax<- rResClasses[BBBB]
1041    movl      rINST,%ecx
1042    FETCH_INST_OPCODE 2 %edx
1043    testl     %eax,%eax                # resolved yet?
1044    je        .LOP_CONST_CLASS_resolve
1045    SET_VREG  %eax %ecx                # vAA<- rResClasses[BBBB]
1046    ADVANCE_PC 2
1047    GOTO_NEXT_R %edx
1048
1049/* ------------------------------ */
1050    .balign 64
1051.L_OP_MONITOR_ENTER: /* 0x1d */
1052/* File: x86/OP_MONITOR_ENTER.S */
1053    /*
1054     * Synchronize on an object.
1055     */
1056    /* monitor-enter vAA */
1057    movl    rGLUE,%ecx
1058    GET_VREG_R %eax rINST               # eax<- vAA
1059    movl    offGlue_self(%ecx),%ecx     # ecx<- glue->self
1060    FETCH_INST_WORD 1
1061    testl   %eax,%eax                   # null object?
1062    EXPORT_PC                           # need for precise GC, MONITOR_TRACKING
1063    jne     .LOP_MONITOR_ENTER_continue
1064    jmp     common_errNullObject
1065
1066/* ------------------------------ */
1067    .balign 64
1068.L_OP_MONITOR_EXIT: /* 0x1e */
1069/* File: x86/OP_MONITOR_EXIT.S */
1070    /*
1071     * Unlock an object.
1072     *
1073     * Exceptions that occur when unlocking a monitor need to appear as
1074     * if they happened at the following instruction.  See the Dalvik
1075     * instruction spec.
1076     */
1077    /* monitor-exit vAA */
1078    GET_VREG_R %eax rINST
1079    movl    rGLUE,%ecx
1080    EXPORT_PC
1081    testl   %eax,%eax                   # null object?
1082    je      .LOP_MONITOR_EXIT_errNullObject   # go if so
1083    movl    offGlue_self(%ecx),%ecx     # ecx<- glue->self
1084    movl    %eax,OUT_ARG1(%esp)
1085    movl    %ecx,OUT_ARG0(%esp)
1086    jmp     .LOP_MONITOR_EXIT_continue
1087
1088/* ------------------------------ */
1089    .balign 64
1090.L_OP_CHECK_CAST: /* 0x1f */
1091/* File: x86/OP_CHECK_CAST.S */
1092    /*
1093     * Check to see if a cast from one class to another is allowed.
1094     */
1095    /* check-cast vAA, class@BBBB */
1096    movl      rGLUE,%ecx
1097    GET_VREG_R  rINST,rINST             # rINST<- vAA (object)
1098    movzwl    2(rPC),%eax               # eax<- BBBB
1099    movl      offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
1100    testl     rINST,rINST               # is oject null?
1101    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
1102    je        .LOP_CHECK_CAST_okay          # null obj, cast always succeeds
1103    movl      (%ecx,%eax,4),%eax        # eax<- resolved class
1104    movl      offObject_clazz(rINST),%ecx # ecx<- obj->clazz
1105    testl     %eax,%eax                 # have we resolved this before?
1106    je        .LOP_CHECK_CAST_resolve       # no, go do it now
1107.LOP_CHECK_CAST_resolved:
1108    cmpl      %eax,%ecx                 # same class (trivial success)?
1109    jne       .LOP_CHECK_CAST_fullcheck     # no, do full check
1110.LOP_CHECK_CAST_okay:
1111    FETCH_INST_OPCODE 2 %edx
1112    ADVANCE_PC 2
1113    GOTO_NEXT_R %edx
1114
1115/* ------------------------------ */
1116    .balign 64
1117.L_OP_INSTANCE_OF: /* 0x20 */
1118/* File: x86/OP_INSTANCE_OF.S */
1119    /*
1120     * Check to see if an object reference is an instance of a class.
1121     *
1122     * Most common situation is a non-null object, being compared against
1123     * an already-resolved class.
1124     */
1125    /* instance-of vA, vB, class@CCCC */
1126    movl    rINST,%eax                # eax<- BA
1127    sarl    $4,%eax                    # eax<- B
1128    GET_VREG_R %eax %eax                # eax<- vB (obj)
1129    movl    rGLUE,%ecx
1130    testl   %eax,%eax                   # object null?
1131    movl    offGlue_methodClassDex(%ecx),%ecx  # ecx<- pDvmDex
1132    je      .LOP_INSTANCE_OF_store           # null obj, not instance, store it
1133    movzwl  2(rPC),%edx                 # edx<- CCCC
1134    movl    offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
1135    movl    (%ecx,%edx,4),%ecx          # ecx<- resolved class
1136    movl    offObject_clazz(%eax),%eax  # eax<- obj->clazz
1137    testl   %ecx,%ecx                   # have we resolved this before?
1138    je      .LOP_INSTANCE_OF_resolve         # not resolved, do it now
1139.LOP_INSTANCE_OF_resolved:  # eax<- obj->clazz, ecx<- resolved class
1140    cmpl    %eax,%ecx                   # same class (trivial success)?
1141    je      .LOP_INSTANCE_OF_trivial         # yes, trivial finish
1142    jmp     .LOP_INSTANCE_OF_fullcheck       # no, do full check
1143
1144/* ------------------------------ */
1145    .balign 64
1146.L_OP_ARRAY_LENGTH: /* 0x21 */
1147/* File: x86/OP_ARRAY_LENGTH.S */
1148    /*
1149     * Return the length of an array.
1150     */
1151   mov      rINST,%eax                # eax<- BA
1152   sarl     $4,rINST                 # rINST<- B
1153   GET_VREG_R %ecx rINST              # ecx<- vB (object ref)
1154   andb     $0xf,%al                 # eax<- A
1155   testl    %ecx,%ecx                 # is null?
1156   je       common_errNullObject
1157   FETCH_INST_OPCODE 1 %edx
1158   movl     offArrayObject_length(%ecx),%ecx
1159   ADVANCE_PC 1
1160   SET_VREG %ecx %eax
1161   GOTO_NEXT_R %edx
1162
1163/* ------------------------------ */
1164    .balign 64
1165.L_OP_NEW_INSTANCE: /* 0x22 */
1166/* File: x86/OP_NEW_INSTANCE.S */
1167    /*
1168     * Create a new instance of a class.
1169     */
1170    /* new-instance vAA, class@BBBB */
1171    movl      rGLUE,%ecx
1172    movzwl    2(rPC),%eax               # eax<- BBBB
1173    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- pDvmDex
1174    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
1175    EXPORT_PC
1176    movl      (%ecx,%eax,4),%ecx        # ecx<- resolved class
1177    testl     %ecx,%ecx                 # resolved?
1178    je        .LOP_NEW_INSTANCE_resolve       # no, go do it
1179.LOP_NEW_INSTANCE_resolved:  # on entry, ecx<- class
1180    cmpb      $CLASS_INITIALIZED,offClassObject_status(%ecx)
1181    je        .LOP_NEW_INSTANCE_initialized
1182    jmp       .LOP_NEW_INSTANCE_needinit
1183
1184/* ------------------------------ */
1185    .balign 64
1186.L_OP_NEW_ARRAY: /* 0x23 */
1187/* File: x86/OP_NEW_ARRAY.S */
1188    /*
1189     * Allocate an array of objects, specified with the array class
1190     * and a count.
1191     *
1192     * The verifier guarantees that this is an array class, so we don't
1193     * check for it here.
1194     */
1195    /* new-array vA, vB, class@CCCC */
1196    movl    rGLUE,%ecx
1197    EXPORT_PC
1198    movl    offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
1199    movzwl  2(rPC),%eax                       # eax<- CCCC
1200    movl    offDvmDex_pResClasses(%ecx),%ecx  # ecx<- pDvmDex->pResClasses
1201    movl    (%ecx,%eax,4),%ecx                # ecx<- resolved class
1202    movzbl  rINSTbl,%eax
1203    sarl    $4,%eax                          # eax<- B
1204    GET_VREG_R %eax %eax                      # eax<- vB (array length)
1205    andb    $0xf,rINSTbl                     # rINST<- A
1206    testl   %eax,%eax
1207    js      common_errNegativeArraySize       # bail
1208    testl   %ecx,%ecx                         # already resolved?
1209    jne     .LOP_NEW_ARRAY_finish                # yes, fast path
1210    jmp     .LOP_NEW_ARRAY_resolve               # resolve now
1211
1212/* ------------------------------ */
1213    .balign 64
1214.L_OP_FILLED_NEW_ARRAY: /* 0x24 */
1215/* File: x86/OP_FILLED_NEW_ARRAY.S */
1216    /*
1217     * Create a new array with elements filled from registers.
1218     *
1219     * for: filled-new-array, filled-new-array/range
1220     */
1221    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1222    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1223    movl    rGLUE,%eax
1224    movl    offGlue_methodClassDex(%eax),%eax # eax<- pDvmDex
1225    movzwl  2(rPC),%ecx                       # ecx<- BBBB
1226    movl    offDvmDex_pResClasses(%eax),%eax  # eax<- pDvmDex->pResClasses
1227    movl    (%eax,%ecx,4),%eax                # eax<- resolved class
1228    EXPORT_PC
1229    testl   %eax,%eax                         # already resolved?
1230    jne     .LOP_FILLED_NEW_ARRAY_continue              # yes, continue
1231    # less frequent path, so we'll redo some work
1232    movl    rGLUE,%eax
1233    movl    $0,OUT_ARG2(%esp)                # arg2<- false
1234    movl    %ecx,OUT_ARG1(%esp)               # arg1<- BBBB
1235    movl    offGlue_method(%eax),%eax         # eax<- glue->method
1236    jmp     .LOP_FILLED_NEW_ARRAY_more
1237
1238/* ------------------------------ */
1239    .balign 64
1240.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
1241/* File: x86/OP_FILLED_NEW_ARRAY_RANGE.S */
1242/* File: x86/OP_FILLED_NEW_ARRAY.S */
1243    /*
1244     * Create a new array with elements filled from registers.
1245     *
1246     * for: filled-new-array, filled-new-array/range
1247     */
1248    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1249    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1250    movl    rGLUE,%eax
1251    movl    offGlue_methodClassDex(%eax),%eax # eax<- pDvmDex
1252    movzwl  2(rPC),%ecx                       # ecx<- BBBB
1253    movl    offDvmDex_pResClasses(%eax),%eax  # eax<- pDvmDex->pResClasses
1254    movl    (%eax,%ecx,4),%eax                # eax<- resolved class
1255    EXPORT_PC
1256    testl   %eax,%eax                         # already resolved?
1257    jne     .LOP_FILLED_NEW_ARRAY_RANGE_continue              # yes, continue
1258    # less frequent path, so we'll redo some work
1259    movl    rGLUE,%eax
1260    movl    $0,OUT_ARG2(%esp)                # arg2<- false
1261    movl    %ecx,OUT_ARG1(%esp)               # arg1<- BBBB
1262    movl    offGlue_method(%eax),%eax         # eax<- glue->method
1263    jmp     .LOP_FILLED_NEW_ARRAY_RANGE_more
1264
1265
1266/* ------------------------------ */
1267    .balign 64
1268.L_OP_FILL_ARRAY_DATA: /* 0x26 */
1269/* File: x86/OP_FILL_ARRAY_DATA.S */
1270    /* fill-array-data vAA, +BBBBBBBB */
1271    movl    2(rPC),%ecx                # ecx<- BBBBbbbb
1272    leal    (rPC,%ecx,2),%ecx          # ecx<- PC + BBBBbbbb*2
1273    GET_VREG_R %eax rINST
1274    EXPORT_PC
1275    movl    %eax,OUT_ARG0(%esp)
1276    movl    %ecx,OUT_ARG1(%esp)
1277    call    dvmInterpHandleFillArrayData
1278    FETCH_INST_OPCODE 3 %edx
1279    testl   %eax,%eax                   # exception thrown?
1280    je      common_exceptionThrown
1281    ADVANCE_PC 3
1282    GOTO_NEXT_R %edx
1283
1284/* ------------------------------ */
1285    .balign 64
1286.L_OP_THROW: /* 0x27 */
1287/* File: x86/OP_THROW.S */
1288    /*
1289     * Throw an exception object in the current thread.
1290     */
1291    /* throw vAA */
1292    movl     rGLUE,%ecx
1293    EXPORT_PC
1294    GET_VREG_R %eax rINST              # eax<- exception object
1295    movl     offGlue_self(%ecx),%ecx   # ecx<- glue->self
1296    testl    %eax,%eax                 # null object?
1297    je       common_errNullObject
1298    movl     %eax,offThread_exception(%ecx) # thread->exception<- obj
1299    jmp      common_exceptionThrown
1300
1301/* ------------------------------ */
1302    .balign 64
1303.L_OP_GOTO: /* 0x28 */
1304/* File: x86/OP_GOTO.S */
1305    /*
1306     * Unconditional branch, 8-bit offset.
1307     *
1308     * The branch distance is a signed code-unit offset, which we need to
1309     * double to get a byte offset.
1310     */
1311    /* goto +AA */
1312    movsbl  rINSTbl,rINST         # ebx<- ssssssAA
1313    testl   rINST,rINST           # test for <0
1314    js      common_backwardBranch
1315    movl    rINST,%eax
1316    FETCH_INST_INDEXED %eax
1317    ADVANCE_PC_INDEXED %eax
1318    GOTO_NEXT
1319
1320/* ------------------------------ */
1321    .balign 64
1322.L_OP_GOTO_16: /* 0x29 */
1323/* File: x86/OP_GOTO_16.S */
1324    /*
1325     * Unconditional branch, 16-bit offset.
1326     *
1327     * The branch distance is a signed code-unit offset
1328     */
1329    /* goto/16 +AAAA */
1330    movswl  2(rPC),rINST           # rINST<- ssssAAAA
1331    testl   rINST,rINST            # test for <0
1332    js      common_backwardBranch
1333    movl    rINST,%eax
1334    FETCH_INST_INDEXED %eax
1335    ADVANCE_PC_INDEXED %eax
1336    GOTO_NEXT
1337
1338/* ------------------------------ */
1339    .balign 64
1340.L_OP_GOTO_32: /* 0x2a */
1341/* File: x86/OP_GOTO_32.S */
1342    /*
1343     * Unconditional branch, 32-bit offset.
1344     *
1345     * The branch distance is a signed code-unit offset.
1346     *
1347     * Unlike most opcodes, this one is allowed to branch to itself, so
1348     * our "backward branch" test must be "<=0" instead of "<0".
1349     */
1350    /* goto/32 AAAAAAAA */
1351    movl    2(rPC),rINST           # rINST<- AAAAAAAA
1352    cmpl    $0,rINST              # test for <= 0
1353    jle     common_backwardBranch
1354    movl    rINST,%eax
1355    FETCH_INST_INDEXED %eax
1356    ADVANCE_PC_INDEXED %eax
1357    GOTO_NEXT
1358
1359/* ------------------------------ */
1360    .balign 64
1361.L_OP_PACKED_SWITCH: /* 0x2b */
1362/* File: x86/OP_PACKED_SWITCH.S */
1363    /*
1364     * Handle a packed-switch or sparse-switch instruction.  In both cases
1365     * we decode it and hand it off to a helper function.
1366     *
1367     * We don't really expect backward branches in a switch statement, but
1368     * they're perfectly legal, so we check for them here.
1369     *
1370     * for: packed-switch, sparse-switch
1371     */
1372    /* op vAA, +BBBB */
1373    movl    2(rPC),%ecx           # ecx<- BBBBbbbb
1374    GET_VREG_R %eax rINST         # eax<- vAA
1375    leal    (rPC,%ecx,2),%ecx     # ecx<- PC + BBBBbbbb*2
1376    movl    %eax,OUT_ARG1(%esp)   # ARG1<- vAA
1377    movl    %ecx,OUT_ARG0(%esp)   # ARG0<- switchData
1378    call    dvmInterpHandlePackedSwitch
1379    testl   %eax,%eax
1380    movl    %eax,rINST            # set up word offset
1381    jle     common_backwardBranch # check on special actions
1382    ADVANCE_PC_INDEXED rINST
1383    FETCH_INST
1384    GOTO_NEXT
1385
1386/* ------------------------------ */
1387    .balign 64
1388.L_OP_SPARSE_SWITCH: /* 0x2c */
1389/* File: x86/OP_SPARSE_SWITCH.S */
1390/* File: x86/OP_PACKED_SWITCH.S */
1391    /*
1392     * Handle a packed-switch or sparse-switch instruction.  In both cases
1393     * we decode it and hand it off to a helper function.
1394     *
1395     * We don't really expect backward branches in a switch statement, but
1396     * they're perfectly legal, so we check for them here.
1397     *
1398     * for: packed-switch, sparse-switch
1399     */
1400    /* op vAA, +BBBB */
1401    movl    2(rPC),%ecx           # ecx<- BBBBbbbb
1402    GET_VREG_R %eax rINST         # eax<- vAA
1403    leal    (rPC,%ecx,2),%ecx     # ecx<- PC + BBBBbbbb*2
1404    movl    %eax,OUT_ARG1(%esp)   # ARG1<- vAA
1405    movl    %ecx,OUT_ARG0(%esp)   # ARG0<- switchData
1406    call    dvmInterpHandleSparseSwitch
1407    testl   %eax,%eax
1408    movl    %eax,rINST            # set up word offset
1409    jle     common_backwardBranch # check on special actions
1410    ADVANCE_PC_INDEXED rINST
1411    FETCH_INST
1412    GOTO_NEXT
1413
1414
1415/* ------------------------------ */
1416    .balign 64
1417.L_OP_CMPL_FLOAT: /* 0x2d */
1418/* File: x86/OP_CMPL_FLOAT.S */
1419/* File: x86/OP_CMPG_DOUBLE.S */
1420    /* float/double_cmp[gl] vAA, vBB, vCC */
1421    movzbl    3(rPC),%eax             # eax<- CC
1422    movzbl    2(rPC),%ecx             # ecx<- BB
1423    .if 0
1424    fldl     (rFP,%eax,4)
1425    fldl     (rFP,%ecx,4)
1426    .else
1427    flds     (rFP,%eax,4)
1428    flds     (rFP,%ecx,4)
1429    .endif
1430    xorl     %ecx,%ecx
1431    fucompp     # z if equal, p set if NaN, c set if st0 < st1
1432    fnstsw   %ax
1433    sahf
1434    movl      rINST,%eax
1435    FETCH_INST_OPCODE 2 %edx
1436    jp       .LOP_CMPL_FLOAT_isNaN
1437    je       .LOP_CMPL_FLOAT_finish
1438    sbbl     %ecx,%ecx
1439    jb       .LOP_CMPL_FLOAT_finish
1440    incl     %ecx
1441.LOP_CMPL_FLOAT_finish:
1442    SET_VREG %ecx %eax
1443    ADVANCE_PC 2
1444    GOTO_NEXT_R %edx
1445
1446
1447/* ------------------------------ */
1448    .balign 64
1449.L_OP_CMPG_FLOAT: /* 0x2e */
1450/* File: x86/OP_CMPG_FLOAT.S */
1451/* File: x86/OP_CMPG_DOUBLE.S */
1452    /* float/double_cmp[gl] vAA, vBB, vCC */
1453    movzbl    3(rPC),%eax             # eax<- CC
1454    movzbl    2(rPC),%ecx             # ecx<- BB
1455    .if 0
1456    fldl     (rFP,%eax,4)
1457    fldl     (rFP,%ecx,4)
1458    .else
1459    flds     (rFP,%eax,4)
1460    flds     (rFP,%ecx,4)
1461    .endif
1462    xorl     %ecx,%ecx
1463    fucompp     # z if equal, p set if NaN, c set if st0 < st1
1464    fnstsw   %ax
1465    sahf
1466    movl      rINST,%eax
1467    FETCH_INST_OPCODE 2 %edx
1468    jp       .LOP_CMPG_FLOAT_isNaN
1469    je       .LOP_CMPG_FLOAT_finish
1470    sbbl     %ecx,%ecx
1471    jb       .LOP_CMPG_FLOAT_finish
1472    incl     %ecx
1473.LOP_CMPG_FLOAT_finish:
1474    SET_VREG %ecx %eax
1475    ADVANCE_PC 2
1476    GOTO_NEXT_R %edx
1477
1478
1479/* ------------------------------ */
1480    .balign 64
1481.L_OP_CMPL_DOUBLE: /* 0x2f */
1482/* File: x86/OP_CMPL_DOUBLE.S */
1483/* File: x86/OP_CMPG_DOUBLE.S */
1484    /* float/double_cmp[gl] vAA, vBB, vCC */
1485    movzbl    3(rPC),%eax             # eax<- CC
1486    movzbl    2(rPC),%ecx             # ecx<- BB
1487    .if 1
1488    fldl     (rFP,%eax,4)
1489    fldl     (rFP,%ecx,4)
1490    .else
1491    flds     (rFP,%eax,4)
1492    flds     (rFP,%ecx,4)
1493    .endif
1494    xorl     %ecx,%ecx
1495    fucompp     # z if equal, p set if NaN, c set if st0 < st1
1496    fnstsw   %ax
1497    sahf
1498    movl      rINST,%eax
1499    FETCH_INST_OPCODE 2 %edx
1500    jp       .LOP_CMPL_DOUBLE_isNaN
1501    je       .LOP_CMPL_DOUBLE_finish
1502    sbbl     %ecx,%ecx
1503    jb       .LOP_CMPL_DOUBLE_finish
1504    incl     %ecx
1505.LOP_CMPL_DOUBLE_finish:
1506    SET_VREG %ecx %eax
1507    ADVANCE_PC 2
1508    GOTO_NEXT_R %edx
1509
1510
1511/* ------------------------------ */
1512    .balign 64
1513.L_OP_CMPG_DOUBLE: /* 0x30 */
1514/* File: x86/OP_CMPG_DOUBLE.S */
1515    /* float/double_cmp[gl] vAA, vBB, vCC */
1516    movzbl    3(rPC),%eax             # eax<- CC
1517    movzbl    2(rPC),%ecx             # ecx<- BB
1518    .if 1
1519    fldl     (rFP,%eax,4)
1520    fldl     (rFP,%ecx,4)
1521    .else
1522    flds     (rFP,%eax,4)
1523    flds     (rFP,%ecx,4)
1524    .endif
1525    xorl     %ecx,%ecx
1526    fucompp     # z if equal, p set if NaN, c set if st0 < st1
1527    fnstsw   %ax
1528    sahf
1529    movl      rINST,%eax
1530    FETCH_INST_OPCODE 2 %edx
1531    jp       .LOP_CMPG_DOUBLE_isNaN
1532    je       .LOP_CMPG_DOUBLE_finish
1533    sbbl     %ecx,%ecx
1534    jb       .LOP_CMPG_DOUBLE_finish
1535    incl     %ecx
1536.LOP_CMPG_DOUBLE_finish:
1537    SET_VREG %ecx %eax
1538    ADVANCE_PC 2
1539    GOTO_NEXT_R %edx
1540
1541/* ------------------------------ */
1542    .balign 64
1543.L_OP_CMP_LONG: /* 0x31 */
1544/* File: x86/OP_CMP_LONG.S */
1545    /*
1546     * Compare two 64-bit values.  Puts 0, 1, or -1 into the destination
1547     * register based on the results of the comparison.
1548     */
1549    /* cmp-long vAA, vBB, vCC */
1550    movzbl    2(rPC),%ecx              # ecx<- BB
1551    movzbl    3(rPC),%edx              # edx<- CC
1552    GET_VREG_WORD %eax %ecx,1          # eax<- v[BB+1]
1553    GET_VREG_WORD %ecx %ecx 0          # ecx<- v[BB+0]
1554    cmpl      4(rFP,%edx,4),%eax
1555    jl        .LOP_CMP_LONG_smaller
1556    jg        .LOP_CMP_LONG_bigger
1557    sub       (rFP,%edx,4),%ecx
1558    ja        .LOP_CMP_LONG_bigger
1559    jb        .LOP_CMP_LONG_smaller
1560    jmp       .LOP_CMP_LONG_finish
1561
1562/* ------------------------------ */
1563    .balign 64
1564.L_OP_IF_EQ: /* 0x32 */
1565/* File: x86/OP_IF_EQ.S */
1566/* File: x86/bincmp.S */
1567    /*
1568     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1569     * fragment that specifies the *reverse* comparison to perform, e.g.
1570     * for "if-le" you would use "gt".
1571     *
1572     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1573     */
1574    /* if-cmp vA, vB, +CCCC */
1575    movzx    rINSTbl,%ecx          # ecx <- A+
1576    andb     $0xf,%cl             # ecx <- A
1577    GET_VREG_R %eax %ecx           # eax <- vA
1578    sarl     $4,rINST            # rINST<- B
1579    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1580    movswl   2(rPC),rINST          # Get signed branch offset
1581    movl     $2,%eax              # assume not taken
1582    jne   1f
1583    testl    rINST,rINST
1584    js       common_backwardBranch
1585    movl     rINST,%eax
15861:
1587    FETCH_INST_INDEXED %eax
1588    ADVANCE_PC_INDEXED %eax
1589    GOTO_NEXT
1590
1591
1592/* ------------------------------ */
1593    .balign 64
1594.L_OP_IF_NE: /* 0x33 */
1595/* File: x86/OP_IF_NE.S */
1596/* File: x86/bincmp.S */
1597    /*
1598     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1599     * fragment that specifies the *reverse* comparison to perform, e.g.
1600     * for "if-le" you would use "gt".
1601     *
1602     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1603     */
1604    /* if-cmp vA, vB, +CCCC */
1605    movzx    rINSTbl,%ecx          # ecx <- A+
1606    andb     $0xf,%cl             # ecx <- A
1607    GET_VREG_R %eax %ecx           # eax <- vA
1608    sarl     $4,rINST            # rINST<- B
1609    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1610    movswl   2(rPC),rINST          # Get signed branch offset
1611    movl     $2,%eax              # assume not taken
1612    je   1f
1613    testl    rINST,rINST
1614    js       common_backwardBranch
1615    movl     rINST,%eax
16161:
1617    FETCH_INST_INDEXED %eax
1618    ADVANCE_PC_INDEXED %eax
1619    GOTO_NEXT
1620
1621
1622/* ------------------------------ */
1623    .balign 64
1624.L_OP_IF_LT: /* 0x34 */
1625/* File: x86/OP_IF_LT.S */
1626/* File: x86/bincmp.S */
1627    /*
1628     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1629     * fragment that specifies the *reverse* comparison to perform, e.g.
1630     * for "if-le" you would use "gt".
1631     *
1632     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1633     */
1634    /* if-cmp vA, vB, +CCCC */
1635    movzx    rINSTbl,%ecx          # ecx <- A+
1636    andb     $0xf,%cl             # ecx <- A
1637    GET_VREG_R %eax %ecx           # eax <- vA
1638    sarl     $4,rINST            # rINST<- B
1639    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1640    movswl   2(rPC),rINST          # Get signed branch offset
1641    movl     $2,%eax              # assume not taken
1642    jge   1f
1643    testl    rINST,rINST
1644    js       common_backwardBranch
1645    movl     rINST,%eax
16461:
1647    FETCH_INST_INDEXED %eax
1648    ADVANCE_PC_INDEXED %eax
1649    GOTO_NEXT
1650
1651
1652/* ------------------------------ */
1653    .balign 64
1654.L_OP_IF_GE: /* 0x35 */
1655/* File: x86/OP_IF_GE.S */
1656/* File: x86/bincmp.S */
1657    /*
1658     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1659     * fragment that specifies the *reverse* comparison to perform, e.g.
1660     * for "if-le" you would use "gt".
1661     *
1662     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1663     */
1664    /* if-cmp vA, vB, +CCCC */
1665    movzx    rINSTbl,%ecx          # ecx <- A+
1666    andb     $0xf,%cl             # ecx <- A
1667    GET_VREG_R %eax %ecx           # eax <- vA
1668    sarl     $4,rINST            # rINST<- B
1669    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1670    movswl   2(rPC),rINST          # Get signed branch offset
1671    movl     $2,%eax              # assume not taken
1672    jl   1f
1673    testl    rINST,rINST
1674    js       common_backwardBranch
1675    movl     rINST,%eax
16761:
1677    FETCH_INST_INDEXED %eax
1678    ADVANCE_PC_INDEXED %eax
1679    GOTO_NEXT
1680
1681
1682/* ------------------------------ */
1683    .balign 64
1684.L_OP_IF_GT: /* 0x36 */
1685/* File: x86/OP_IF_GT.S */
1686/* File: x86/bincmp.S */
1687    /*
1688     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1689     * fragment that specifies the *reverse* comparison to perform, e.g.
1690     * for "if-le" you would use "gt".
1691     *
1692     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1693     */
1694    /* if-cmp vA, vB, +CCCC */
1695    movzx    rINSTbl,%ecx          # ecx <- A+
1696    andb     $0xf,%cl             # ecx <- A
1697    GET_VREG_R %eax %ecx           # eax <- vA
1698    sarl     $4,rINST            # rINST<- B
1699    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1700    movswl   2(rPC),rINST          # Get signed branch offset
1701    movl     $2,%eax              # assume not taken
1702    jle   1f
1703    testl    rINST,rINST
1704    js       common_backwardBranch
1705    movl     rINST,%eax
17061:
1707    FETCH_INST_INDEXED %eax
1708    ADVANCE_PC_INDEXED %eax
1709    GOTO_NEXT
1710
1711
1712/* ------------------------------ */
1713    .balign 64
1714.L_OP_IF_LE: /* 0x37 */
1715/* File: x86/OP_IF_LE.S */
1716/* File: x86/bincmp.S */
1717    /*
1718     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1719     * fragment that specifies the *reverse* comparison to perform, e.g.
1720     * for "if-le" you would use "gt".
1721     *
1722     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1723     */
1724    /* if-cmp vA, vB, +CCCC */
1725    movzx    rINSTbl,%ecx          # ecx <- A+
1726    andb     $0xf,%cl             # ecx <- A
1727    GET_VREG_R %eax %ecx           # eax <- vA
1728    sarl     $4,rINST            # rINST<- B
1729    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1730    movswl   2(rPC),rINST          # Get signed branch offset
1731    movl     $2,%eax              # assume not taken
1732    jg   1f
1733    testl    rINST,rINST
1734    js       common_backwardBranch
1735    movl     rINST,%eax
17361:
1737    FETCH_INST_INDEXED %eax
1738    ADVANCE_PC_INDEXED %eax
1739    GOTO_NEXT
1740
1741
1742/* ------------------------------ */
1743    .balign 64
1744.L_OP_IF_EQZ: /* 0x38 */
1745/* File: x86/OP_IF_EQZ.S */
1746/* File: x86/zcmp.S */
1747    /*
1748     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1749     * fragment that specifies the *reverse* comparison to perform, e.g.
1750     * for "if-le" you would use "gt".
1751     *
1752     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1753     */
1754    /* if-cmp vAA, +BBBB */
1755    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
1756    movswl   2(rPC),rINST         # fetch signed displacement
1757    movl     $2,%eax             # assume branch not taken
1758    jne   1f
1759    testl    rINST,rINST
1760    js       common_backwardBranch
1761    movl     rINST,%eax
17621:
1763    FETCH_INST_INDEXED %eax
1764    ADVANCE_PC_INDEXED %eax
1765    GOTO_NEXT
1766
1767
1768/* ------------------------------ */
1769    .balign 64
1770.L_OP_IF_NEZ: /* 0x39 */
1771/* File: x86/OP_IF_NEZ.S */
1772/* File: x86/zcmp.S */
1773    /*
1774     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1775     * fragment that specifies the *reverse* comparison to perform, e.g.
1776     * for "if-le" you would use "gt".
1777     *
1778     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1779     */
1780    /* if-cmp vAA, +BBBB */
1781    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
1782    movswl   2(rPC),rINST         # fetch signed displacement
1783    movl     $2,%eax             # assume branch not taken
1784    je   1f
1785    testl    rINST,rINST
1786    js       common_backwardBranch
1787    movl     rINST,%eax
17881:
1789    FETCH_INST_INDEXED %eax
1790    ADVANCE_PC_INDEXED %eax
1791    GOTO_NEXT
1792
1793
1794/* ------------------------------ */
1795    .balign 64
1796.L_OP_IF_LTZ: /* 0x3a */
1797/* File: x86/OP_IF_LTZ.S */
1798/* File: x86/zcmp.S */
1799    /*
1800     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1801     * fragment that specifies the *reverse* comparison to perform, e.g.
1802     * for "if-le" you would use "gt".
1803     *
1804     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1805     */
1806    /* if-cmp vAA, +BBBB */
1807    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
1808    movswl   2(rPC),rINST         # fetch signed displacement
1809    movl     $2,%eax             # assume branch not taken
1810    jge   1f
1811    testl    rINST,rINST
1812    js       common_backwardBranch
1813    movl     rINST,%eax
18141:
1815    FETCH_INST_INDEXED %eax
1816    ADVANCE_PC_INDEXED %eax
1817    GOTO_NEXT
1818
1819
1820/* ------------------------------ */
1821    .balign 64
1822.L_OP_IF_GEZ: /* 0x3b */
1823/* File: x86/OP_IF_GEZ.S */
1824/* File: x86/zcmp.S */
1825    /*
1826     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1827     * fragment that specifies the *reverse* comparison to perform, e.g.
1828     * for "if-le" you would use "gt".
1829     *
1830     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1831     */
1832    /* if-cmp vAA, +BBBB */
1833    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
1834    movswl   2(rPC),rINST         # fetch signed displacement
1835    movl     $2,%eax             # assume branch not taken
1836    jl   1f
1837    testl    rINST,rINST
1838    js       common_backwardBranch
1839    movl     rINST,%eax
18401:
1841    FETCH_INST_INDEXED %eax
1842    ADVANCE_PC_INDEXED %eax
1843    GOTO_NEXT
1844
1845
1846/* ------------------------------ */
1847    .balign 64
1848.L_OP_IF_GTZ: /* 0x3c */
1849/* File: x86/OP_IF_GTZ.S */
1850/* File: x86/zcmp.S */
1851    /*
1852     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1853     * fragment that specifies the *reverse* comparison to perform, e.g.
1854     * for "if-le" you would use "gt".
1855     *
1856     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1857     */
1858    /* if-cmp vAA, +BBBB */
1859    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
1860    movswl   2(rPC),rINST         # fetch signed displacement
1861    movl     $2,%eax             # assume branch not taken
1862    jle   1f
1863    testl    rINST,rINST
1864    js       common_backwardBranch
1865    movl     rINST,%eax
18661:
1867    FETCH_INST_INDEXED %eax
1868    ADVANCE_PC_INDEXED %eax
1869    GOTO_NEXT
1870
1871
1872/* ------------------------------ */
1873    .balign 64
1874.L_OP_IF_LEZ: /* 0x3d */
1875/* File: x86/OP_IF_LEZ.S */
1876/* File: x86/zcmp.S */
1877    /*
1878     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1879     * fragment that specifies the *reverse* comparison to perform, e.g.
1880     * for "if-le" you would use "gt".
1881     *
1882     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1883     */
1884    /* if-cmp vAA, +BBBB */
1885    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
1886    movswl   2(rPC),rINST         # fetch signed displacement
1887    movl     $2,%eax             # assume branch not taken
1888    jg   1f
1889    testl    rINST,rINST
1890    js       common_backwardBranch
1891    movl     rINST,%eax
18921:
1893    FETCH_INST_INDEXED %eax
1894    ADVANCE_PC_INDEXED %eax
1895    GOTO_NEXT
1896
1897
1898/* ------------------------------ */
1899    .balign 64
1900.L_OP_UNUSED_3E: /* 0x3e */
1901/* File: x86/OP_UNUSED_3E.S */
1902/* File: x86/unused.S */
1903    jmp     common_abort
1904
1905
1906/* ------------------------------ */
1907    .balign 64
1908.L_OP_UNUSED_3F: /* 0x3f */
1909/* File: x86/OP_UNUSED_3F.S */
1910/* File: x86/unused.S */
1911    jmp     common_abort
1912
1913
1914/* ------------------------------ */
1915    .balign 64
1916.L_OP_UNUSED_40: /* 0x40 */
1917/* File: x86/OP_UNUSED_40.S */
1918/* File: x86/unused.S */
1919    jmp     common_abort
1920
1921
1922/* ------------------------------ */
1923    .balign 64
1924.L_OP_UNUSED_41: /* 0x41 */
1925/* File: x86/OP_UNUSED_41.S */
1926/* File: x86/unused.S */
1927    jmp     common_abort
1928
1929
1930/* ------------------------------ */
1931    .balign 64
1932.L_OP_UNUSED_42: /* 0x42 */
1933/* File: x86/OP_UNUSED_42.S */
1934/* File: x86/unused.S */
1935    jmp     common_abort
1936
1937
1938/* ------------------------------ */
1939    .balign 64
1940.L_OP_UNUSED_43: /* 0x43 */
1941/* File: x86/OP_UNUSED_43.S */
1942/* File: x86/unused.S */
1943    jmp     common_abort
1944
1945
1946/* ------------------------------ */
1947    .balign 64
1948.L_OP_AGET: /* 0x44 */
1949/* File: x86/OP_AGET.S */
1950    /*
1951     * Array get, 32 bits or less.  vAA <- vBB[vCC].
1952     *
1953     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
1954     */
1955    /* op vAA, vBB, vCC */
1956    movzbl    2(rPC),%eax               # eax<- BB
1957    movzbl    3(rPC),%ecx               # ecx<- CC
1958    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
1959    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
1960    testl     %eax,%eax                 # null array object?
1961    je        common_errNullObject      # bail if so
1962    cmpl      offArrayObject_length(%eax),%ecx
1963    jae       common_errArrayIndex      # index >= length, bail.  Expects
1964                                        #    arrayObj in eax
1965                                        #    index in ecx
1966    movl     offArrayObject_contents(%eax,%ecx,4),%eax
1967.LOP_AGET_finish:
1968    FETCH_INST_OPCODE 2 %edx
1969    SET_VREG  %eax rINST
1970    ADVANCE_PC 2
1971    GOTO_NEXT_R %edx
1972
1973/* ------------------------------ */
1974    .balign 64
1975.L_OP_AGET_WIDE: /* 0x45 */
1976/* File: x86/OP_AGET_WIDE.S */
1977    /*
1978     * Array get, 64 bits.  vAA <- vBB[vCC].
1979     *
1980     */
1981    /* op vAA, vBB, vCC */
1982    movzbl    2(rPC),%eax               # eax<- BB
1983    movzbl    3(rPC),%ecx               # ecx<- CC
1984    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
1985    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
1986    testl     %eax,%eax                 # null array object?
1987    je        common_errNullObject      # bail if so
1988    cmpl      offArrayObject_length(%eax),%ecx
1989    jb        .LOP_AGET_WIDE_finish        # index < length, OK
1990    jmp       common_errArrayIndex      # index >= length, bail.  Expects
1991                                        #    arrayObj in eax
1992                                        #    index in ecx
1993
1994/* ------------------------------ */
1995    .balign 64
1996.L_OP_AGET_OBJECT: /* 0x46 */
1997/* File: x86/OP_AGET_OBJECT.S */
1998/* File: x86/OP_AGET.S */
1999    /*
2000     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2001     *
2002     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2003     */
2004    /* op vAA, vBB, vCC */
2005    movzbl    2(rPC),%eax               # eax<- BB
2006    movzbl    3(rPC),%ecx               # ecx<- CC
2007    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2008    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2009    testl     %eax,%eax                 # null array object?
2010    je        common_errNullObject      # bail if so
2011    cmpl      offArrayObject_length(%eax),%ecx
2012    jae       common_errArrayIndex      # index >= length, bail.  Expects
2013                                        #    arrayObj in eax
2014                                        #    index in ecx
2015    movl     offArrayObject_contents(%eax,%ecx,4),%eax
2016.LOP_AGET_OBJECT_finish:
2017    FETCH_INST_OPCODE 2 %edx
2018    SET_VREG  %eax rINST
2019    ADVANCE_PC 2
2020    GOTO_NEXT_R %edx
2021
2022
2023/* ------------------------------ */
2024    .balign 64
2025.L_OP_AGET_BOOLEAN: /* 0x47 */
2026/* File: x86/OP_AGET_BOOLEAN.S */
2027/* File: x86/OP_AGET.S */
2028    /*
2029     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2030     *
2031     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2032     */
2033    /* op vAA, vBB, vCC */
2034    movzbl    2(rPC),%eax               # eax<- BB
2035    movzbl    3(rPC),%ecx               # ecx<- CC
2036    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2037    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2038    testl     %eax,%eax                 # null array object?
2039    je        common_errNullObject      # bail if so
2040    cmpl      offArrayObject_length(%eax),%ecx
2041    jae       common_errArrayIndex      # index >= length, bail.  Expects
2042                                        #    arrayObj in eax
2043                                        #    index in ecx
2044    movzbl     offArrayObject_contents(%eax,%ecx,1),%eax
2045.LOP_AGET_BOOLEAN_finish:
2046    FETCH_INST_OPCODE 2 %edx
2047    SET_VREG  %eax rINST
2048    ADVANCE_PC 2
2049    GOTO_NEXT_R %edx
2050
2051
2052/* ------------------------------ */
2053    .balign 64
2054.L_OP_AGET_BYTE: /* 0x48 */
2055/* File: x86/OP_AGET_BYTE.S */
2056/* File: x86/OP_AGET.S */
2057    /*
2058     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2059     *
2060     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2061     */
2062    /* op vAA, vBB, vCC */
2063    movzbl    2(rPC),%eax               # eax<- BB
2064    movzbl    3(rPC),%ecx               # ecx<- CC
2065    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2066    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2067    testl     %eax,%eax                 # null array object?
2068    je        common_errNullObject      # bail if so
2069    cmpl      offArrayObject_length(%eax),%ecx
2070    jae       common_errArrayIndex      # index >= length, bail.  Expects
2071                                        #    arrayObj in eax
2072                                        #    index in ecx
2073    movsbl     offArrayObject_contents(%eax,%ecx,1),%eax
2074.LOP_AGET_BYTE_finish:
2075    FETCH_INST_OPCODE 2 %edx
2076    SET_VREG  %eax rINST
2077    ADVANCE_PC 2
2078    GOTO_NEXT_R %edx
2079
2080
2081/* ------------------------------ */
2082    .balign 64
2083.L_OP_AGET_CHAR: /* 0x49 */
2084/* File: x86/OP_AGET_CHAR.S */
2085/* File: x86/OP_AGET.S */
2086    /*
2087     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2088     *
2089     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2090     */
2091    /* op vAA, vBB, vCC */
2092    movzbl    2(rPC),%eax               # eax<- BB
2093    movzbl    3(rPC),%ecx               # ecx<- CC
2094    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2095    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2096    testl     %eax,%eax                 # null array object?
2097    je        common_errNullObject      # bail if so
2098    cmpl      offArrayObject_length(%eax),%ecx
2099    jae       common_errArrayIndex      # index >= length, bail.  Expects
2100                                        #    arrayObj in eax
2101                                        #    index in ecx
2102    movzwl     offArrayObject_contents(%eax,%ecx,2),%eax
2103.LOP_AGET_CHAR_finish:
2104    FETCH_INST_OPCODE 2 %edx
2105    SET_VREG  %eax rINST
2106    ADVANCE_PC 2
2107    GOTO_NEXT_R %edx
2108
2109
2110/* ------------------------------ */
2111    .balign 64
2112.L_OP_AGET_SHORT: /* 0x4a */
2113/* File: x86/OP_AGET_SHORT.S */
2114/* File: x86/OP_AGET.S */
2115    /*
2116     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2117     *
2118     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2119     */
2120    /* op vAA, vBB, vCC */
2121    movzbl    2(rPC),%eax               # eax<- BB
2122    movzbl    3(rPC),%ecx               # ecx<- CC
2123    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2124    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2125    testl     %eax,%eax                 # null array object?
2126    je        common_errNullObject      # bail if so
2127    cmpl      offArrayObject_length(%eax),%ecx
2128    jae       common_errArrayIndex      # index >= length, bail.  Expects
2129                                        #    arrayObj in eax
2130                                        #    index in ecx
2131    movswl     offArrayObject_contents(%eax,%ecx,2),%eax
2132.LOP_AGET_SHORT_finish:
2133    FETCH_INST_OPCODE 2 %edx
2134    SET_VREG  %eax rINST
2135    ADVANCE_PC 2
2136    GOTO_NEXT_R %edx
2137
2138
2139/* ------------------------------ */
2140    .balign 64
2141.L_OP_APUT: /* 0x4b */
2142/* File: x86/OP_APUT.S */
2143    /*
2144     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2145     *
2146     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2147     */
2148    /* op vAA, vBB, vCC */
2149    movzbl    2(rPC),%eax               # eax<- BB
2150    movzbl    3(rPC),%ecx               # ecx<- CC
2151    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2152    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2153    testl     %eax,%eax                 # null array object?
2154    je        common_errNullObject      # bail if so
2155    cmpl      offArrayObject_length(%eax),%ecx
2156    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2157                                        #   arrayObj in eax
2158                                        #   index in ecx
2159    leal      offArrayObject_contents(%eax,%ecx,4),%eax
2160.LOP_APUT_finish:
2161    GET_VREG_R  %ecx rINST
2162    FETCH_INST_OPCODE 2 %edx
2163    movl     %ecx,(%eax)
2164    ADVANCE_PC 2
2165    GOTO_NEXT_R %edx
2166
2167/* ------------------------------ */
2168    .balign 64
2169.L_OP_APUT_WIDE: /* 0x4c */
2170/* File: x86/OP_APUT_WIDE.S */
2171    /*
2172     * Array put, 64 bits.  vBB[vCC]<-vAA.
2173     *
2174     */
2175    /* op vAA, vBB, vCC */
2176    movzbl    2(rPC),%eax               # eax<- BB
2177    movzbl    3(rPC),%ecx               # ecx<- CC
2178    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2179    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2180    testl     %eax,%eax                 # null array object?
2181    je        common_errNullObject      # bail if so
2182    cmpl      offArrayObject_length(%eax),%ecx
2183    jb        .LOP_APUT_WIDE_finish        # index < length, OK
2184    jmp       common_errArrayIndex      # index >= length, bail.  Expects:
2185                                        #   arrayObj in eax
2186                                        #   index in ecx
2187
2188/* ------------------------------ */
2189    .balign 64
2190.L_OP_APUT_OBJECT: /* 0x4d */
2191/* File: x86/OP_APUT_OBJECT.S */
2192    /*
2193     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2194     *
2195     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2196     */
2197    /* op vAA, vBB, vCC */
2198    movzbl    2(rPC),%eax               # eax<- BB
2199    movzbl    3(rPC),%ecx               # ecx<- CC
2200    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2201    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2202    GET_VREG_R  rINST rINST             # rINST<- vAA
2203    testl     %eax,%eax                 # null array object?
2204    je        common_errNullObject      # bail if so
2205    cmpl      offArrayObject_length(%eax),%ecx
2206    jb        .LOP_APUT_OBJECT_continue
2207    jmp       common_errArrayIndex      # index >= length, bail.  Expects
2208                                        #    arrayObj in eax
2209                                        #    index in ecx
2210
2211/* ------------------------------ */
2212    .balign 64
2213.L_OP_APUT_BOOLEAN: /* 0x4e */
2214/* File: x86/OP_APUT_BOOLEAN.S */
2215/* File: x86/OP_APUT.S */
2216    /*
2217     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2218     *
2219     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2220     */
2221    /* op vAA, vBB, vCC */
2222    movzbl    2(rPC),%eax               # eax<- BB
2223    movzbl    3(rPC),%ecx               # ecx<- CC
2224    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2225    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2226    testl     %eax,%eax                 # null array object?
2227    je        common_errNullObject      # bail if so
2228    cmpl      offArrayObject_length(%eax),%ecx
2229    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2230                                        #   arrayObj in eax
2231                                        #   index in ecx
2232    leal      offArrayObject_contents(%eax,%ecx,1),%eax
2233.LOP_APUT_BOOLEAN_finish:
2234    GET_VREG_R  %ecx rINST
2235    FETCH_INST_OPCODE 2 %edx
2236    movb     %cl,(%eax)
2237    ADVANCE_PC 2
2238    GOTO_NEXT_R %edx
2239
2240
2241/* ------------------------------ */
2242    .balign 64
2243.L_OP_APUT_BYTE: /* 0x4f */
2244/* File: x86/OP_APUT_BYTE.S */
2245/* File: x86/OP_APUT.S */
2246    /*
2247     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2248     *
2249     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2250     */
2251    /* op vAA, vBB, vCC */
2252    movzbl    2(rPC),%eax               # eax<- BB
2253    movzbl    3(rPC),%ecx               # ecx<- CC
2254    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2255    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2256    testl     %eax,%eax                 # null array object?
2257    je        common_errNullObject      # bail if so
2258    cmpl      offArrayObject_length(%eax),%ecx
2259    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2260                                        #   arrayObj in eax
2261                                        #   index in ecx
2262    leal      offArrayObject_contents(%eax,%ecx,1),%eax
2263.LOP_APUT_BYTE_finish:
2264    GET_VREG_R  %ecx rINST
2265    FETCH_INST_OPCODE 2 %edx
2266    movb     %cl,(%eax)
2267    ADVANCE_PC 2
2268    GOTO_NEXT_R %edx
2269
2270
2271/* ------------------------------ */
2272    .balign 64
2273.L_OP_APUT_CHAR: /* 0x50 */
2274/* File: x86/OP_APUT_CHAR.S */
2275/* File: x86/OP_APUT.S */
2276    /*
2277     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2278     *
2279     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2280     */
2281    /* op vAA, vBB, vCC */
2282    movzbl    2(rPC),%eax               # eax<- BB
2283    movzbl    3(rPC),%ecx               # ecx<- CC
2284    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2285    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2286    testl     %eax,%eax                 # null array object?
2287    je        common_errNullObject      # bail if so
2288    cmpl      offArrayObject_length(%eax),%ecx
2289    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2290                                        #   arrayObj in eax
2291                                        #   index in ecx
2292    leal      offArrayObject_contents(%eax,%ecx,2),%eax
2293.LOP_APUT_CHAR_finish:
2294    GET_VREG_R  %ecx rINST
2295    FETCH_INST_OPCODE 2 %edx
2296    movw     %cx,(%eax)
2297    ADVANCE_PC 2
2298    GOTO_NEXT_R %edx
2299
2300
2301/* ------------------------------ */
2302    .balign 64
2303.L_OP_APUT_SHORT: /* 0x51 */
2304/* File: x86/OP_APUT_SHORT.S */
2305/* File: x86/OP_APUT.S */
2306    /*
2307     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2308     *
2309     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2310     */
2311    /* op vAA, vBB, vCC */
2312    movzbl    2(rPC),%eax               # eax<- BB
2313    movzbl    3(rPC),%ecx               # ecx<- CC
2314    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2315    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2316    testl     %eax,%eax                 # null array object?
2317    je        common_errNullObject      # bail if so
2318    cmpl      offArrayObject_length(%eax),%ecx
2319    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2320                                        #   arrayObj in eax
2321                                        #   index in ecx
2322    leal      offArrayObject_contents(%eax,%ecx,2),%eax
2323.LOP_APUT_SHORT_finish:
2324    GET_VREG_R  %ecx rINST
2325    FETCH_INST_OPCODE 2 %edx
2326    movw     %cx,(%eax)
2327    ADVANCE_PC 2
2328    GOTO_NEXT_R %edx
2329
2330
2331/* ------------------------------ */
2332    .balign 64
2333.L_OP_IGET: /* 0x52 */
2334/* File: x86/OP_IGET.S */
2335    /*
2336     * General 32-bit instance field get.
2337     *
2338     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2339     */
2340    /* op vA, vB, field@CCCC */
2341    movl    rGLUE,%ecx
2342    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
2343    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
2344    movzbl  rINSTbl,%ecx                        # ecx<- BA
2345    sarl    $4,%ecx                            # ecx<- B
2346    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2347    andb    $0xf,rINSTbl                       # rINST<- A
2348    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2349    movl    (%eax,%edx,4),%eax                  # resolved entry
2350    testl   %eax,%eax                           # is resolved entry null?
2351    jne     .LOP_IGET_finish                  # no, already resolved
2352    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
2353    movl    rGLUE,%edx
2354    jmp     .LOP_IGET_resolve
2355
2356/* ------------------------------ */
2357    .balign 64
2358.L_OP_IGET_WIDE: /* 0x53 */
2359/* File: x86/OP_IGET_WIDE.S */
2360    /*
2361     * 64-bit instance field get.
2362     *
2363     */
2364    /* op vA, vB, field@CCCC */
2365    movl    rGLUE,%ecx
2366    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
2367    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
2368    movzbl  rINSTbl,%ecx                        # ecx<- BA
2369    sarl    $4,%ecx                            # ecx<- B
2370    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2371    andb    $0xf,rINSTbl                       # rINST<- A
2372    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2373    movl    (%eax,%edx,4),%eax                  # resolved entry
2374    testl   %eax,%eax                           # is resolved entry null?
2375    jne     .LOP_IGET_WIDE_finish                  # no, already resolved
2376    movl    %edx,OUT_ARG1(%esp)                 # for dvmResolveInstField
2377    movl    rGLUE,%edx
2378    jmp     .LOP_IGET_WIDE_resolve
2379
2380/* ------------------------------ */
2381    .balign 64
2382.L_OP_IGET_OBJECT: /* 0x54 */
2383/* File: x86/OP_IGET_OBJECT.S */
2384/* File: x86/OP_IGET.S */
2385    /*
2386     * General 32-bit instance field get.
2387     *
2388     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2389     */
2390    /* op vA, vB, field@CCCC */
2391    movl    rGLUE,%ecx
2392    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
2393    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
2394    movzbl  rINSTbl,%ecx                        # ecx<- BA
2395    sarl    $4,%ecx                            # ecx<- B
2396    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2397    andb    $0xf,rINSTbl                       # rINST<- A
2398    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2399    movl    (%eax,%edx,4),%eax                  # resolved entry
2400    testl   %eax,%eax                           # is resolved entry null?
2401    jne     .LOP_IGET_OBJECT_finish                  # no, already resolved
2402    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
2403    movl    rGLUE,%edx
2404    jmp     .LOP_IGET_OBJECT_resolve
2405
2406
2407/* ------------------------------ */
2408    .balign 64
2409.L_OP_IGET_BOOLEAN: /* 0x55 */
2410/* File: x86/OP_IGET_BOOLEAN.S */
2411/* File: x86/OP_IGET.S */
2412    /*
2413     * General 32-bit instance field get.
2414     *
2415     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2416     */
2417    /* op vA, vB, field@CCCC */
2418    movl    rGLUE,%ecx
2419    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
2420    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
2421    movzbl  rINSTbl,%ecx                        # ecx<- BA
2422    sarl    $4,%ecx                            # ecx<- B
2423    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2424    andb    $0xf,rINSTbl                       # rINST<- A
2425    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2426    movl    (%eax,%edx,4),%eax                  # resolved entry
2427    testl   %eax,%eax                           # is resolved entry null?
2428    jne     .LOP_IGET_BOOLEAN_finish                  # no, already resolved
2429    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
2430    movl    rGLUE,%edx
2431    jmp     .LOP_IGET_BOOLEAN_resolve
2432
2433
2434/* ------------------------------ */
2435    .balign 64
2436.L_OP_IGET_BYTE: /* 0x56 */
2437/* File: x86/OP_IGET_BYTE.S */
2438/* File: x86/OP_IGET.S */
2439    /*
2440     * General 32-bit instance field get.
2441     *
2442     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2443     */
2444    /* op vA, vB, field@CCCC */
2445    movl    rGLUE,%ecx
2446    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
2447    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
2448    movzbl  rINSTbl,%ecx                        # ecx<- BA
2449    sarl    $4,%ecx                            # ecx<- B
2450    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2451    andb    $0xf,rINSTbl                       # rINST<- A
2452    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2453    movl    (%eax,%edx,4),%eax                  # resolved entry
2454    testl   %eax,%eax                           # is resolved entry null?
2455    jne     .LOP_IGET_BYTE_finish                  # no, already resolved
2456    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
2457    movl    rGLUE,%edx
2458    jmp     .LOP_IGET_BYTE_resolve
2459
2460
2461/* ------------------------------ */
2462    .balign 64
2463.L_OP_IGET_CHAR: /* 0x57 */
2464/* File: x86/OP_IGET_CHAR.S */
2465/* File: x86/OP_IGET.S */
2466    /*
2467     * General 32-bit instance field get.
2468     *
2469     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2470     */
2471    /* op vA, vB, field@CCCC */
2472    movl    rGLUE,%ecx
2473    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
2474    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
2475    movzbl  rINSTbl,%ecx                        # ecx<- BA
2476    sarl    $4,%ecx                            # ecx<- B
2477    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2478    andb    $0xf,rINSTbl                       # rINST<- A
2479    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2480    movl    (%eax,%edx,4),%eax                  # resolved entry
2481    testl   %eax,%eax                           # is resolved entry null?
2482    jne     .LOP_IGET_CHAR_finish                  # no, already resolved
2483    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
2484    movl    rGLUE,%edx
2485    jmp     .LOP_IGET_CHAR_resolve
2486
2487
2488/* ------------------------------ */
2489    .balign 64
2490.L_OP_IGET_SHORT: /* 0x58 */
2491/* File: x86/OP_IGET_SHORT.S */
2492/* File: x86/OP_IGET.S */
2493    /*
2494     * General 32-bit instance field get.
2495     *
2496     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2497     */
2498    /* op vA, vB, field@CCCC */
2499    movl    rGLUE,%ecx
2500    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
2501    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
2502    movzbl  rINSTbl,%ecx                        # ecx<- BA
2503    sarl    $4,%ecx                            # ecx<- B
2504    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2505    andb    $0xf,rINSTbl                       # rINST<- A
2506    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2507    movl    (%eax,%edx,4),%eax                  # resolved entry
2508    testl   %eax,%eax                           # is resolved entry null?
2509    jne     .LOP_IGET_SHORT_finish                  # no, already resolved
2510    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
2511    movl    rGLUE,%edx
2512    jmp     .LOP_IGET_SHORT_resolve
2513
2514
2515/* ------------------------------ */
2516    .balign 64
2517.L_OP_IPUT: /* 0x59 */
2518/* File: x86/OP_IPUT.S */
2519
2520    /*
2521     * General 32-bit instance field put.
2522     *
2523     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
2524     */
2525    /* op vA, vB, field@CCCC */
2526    movl    rGLUE,%ecx
2527    movzwl  2(rPC),%edx                         # %edx<- 0000CCCC
2528    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
2529    movzbl  rINSTbl,%ecx                        # ecx<- BA
2530    sarl    $4,%ecx                            # ecx<- B
2531    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2532    andb    $0xf,rINSTbl                       # rINST<- A
2533    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2534    movl    (%eax,%edx,4),%eax                  # resolved entry
2535    testl   %eax,%eax                           # is resolved entry null?
2536    jne     .LOP_IPUT_finish                  # no, already resolved
2537    movl    %edx,OUT_ARG1(%esp)
2538    movl    rGLUE,%edx
2539    jmp     .LOP_IPUT_resolve
2540
2541/* ------------------------------ */
2542    .balign 64
2543.L_OP_IPUT_WIDE: /* 0x5a */
2544/* File: x86/OP_IPUT_WIDE.S */
2545    /*
2546     * 64-bit instance field put.
2547     *
2548     */
2549    /* op vA, vB, field@CCCC */
2550    movl    rGLUE,%ecx
2551    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
2552    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
2553    movzbl  rINSTbl,%ecx                        # ecx<- BA
2554    sarl    $4,%ecx                            # ecx<- B
2555    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2556    andb    $0xf,rINSTbl                       # rINST<- A
2557    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2558    movl    (%eax,%edx,4),%eax                  # resolved entry
2559    testl   %eax,%eax                           # is resolved entry null?
2560    jne     .LOP_IPUT_WIDE_finish                  # no, already resolved
2561    movl    %edx,OUT_ARG1(%esp)
2562    movl    rGLUE,%edx
2563    jmp     .LOP_IPUT_WIDE_resolve
2564
2565/* ------------------------------ */
2566    .balign 64
2567.L_OP_IPUT_OBJECT: /* 0x5b */
2568/* File: x86/OP_IPUT_OBJECT.S */
2569    /*
2570     * Object field put.
2571     *
2572     * for: iput-object
2573     */
2574    /* op vA, vB, field@CCCC */
2575    movl    rGLUE,%ecx
2576    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
2577    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
2578    movzbl  rINSTbl,%ecx                        # ecx<- BA
2579    sarl    $4,%ecx                            # ecx<- B
2580    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2581    andb    $0xf,rINSTbl                       # rINST<- A
2582    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2583    movl    (%eax,%edx,4),%eax                  # resolved entry
2584    testl   %eax,%eax                           # is resolved entry null?
2585    jne     .LOP_IPUT_OBJECT_finish                  # no, already resolved
2586    movl    %edx,OUT_ARG1(%esp)
2587    movl    rGLUE,%edx
2588    jmp     .LOP_IPUT_OBJECT_resolve
2589
2590/* ------------------------------ */
2591    .balign 64
2592.L_OP_IPUT_BOOLEAN: /* 0x5c */
2593/* File: x86/OP_IPUT_BOOLEAN.S */
2594/* File: x86/OP_IPUT.S */
2595
2596    /*
2597     * General 32-bit instance field put.
2598     *
2599     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
2600     */
2601    /* op vA, vB, field@CCCC */
2602    movl    rGLUE,%ecx
2603    movzwl  2(rPC),%edx                         # %edx<- 0000CCCC
2604    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
2605    movzbl  rINSTbl,%ecx                        # ecx<- BA
2606    sarl    $4,%ecx                            # ecx<- B
2607    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2608    andb    $0xf,rINSTbl                       # rINST<- A
2609    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2610    movl    (%eax,%edx,4),%eax                  # resolved entry
2611    testl   %eax,%eax                           # is resolved entry null?
2612    jne     .LOP_IPUT_BOOLEAN_finish                  # no, already resolved
2613    movl    %edx,OUT_ARG1(%esp)
2614    movl    rGLUE,%edx
2615    jmp     .LOP_IPUT_BOOLEAN_resolve
2616
2617
2618/* ------------------------------ */
2619    .balign 64
2620.L_OP_IPUT_BYTE: /* 0x5d */
2621/* File: x86/OP_IPUT_BYTE.S */
2622/* File: x86/OP_IPUT.S */
2623
2624    /*
2625     * General 32-bit instance field put.
2626     *
2627     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
2628     */
2629    /* op vA, vB, field@CCCC */
2630    movl    rGLUE,%ecx
2631    movzwl  2(rPC),%edx                         # %edx<- 0000CCCC
2632    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
2633    movzbl  rINSTbl,%ecx                        # ecx<- BA
2634    sarl    $4,%ecx                            # ecx<- B
2635    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2636    andb    $0xf,rINSTbl                       # rINST<- A
2637    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2638    movl    (%eax,%edx,4),%eax                  # resolved entry
2639    testl   %eax,%eax                           # is resolved entry null?
2640    jne     .LOP_IPUT_BYTE_finish                  # no, already resolved
2641    movl    %edx,OUT_ARG1(%esp)
2642    movl    rGLUE,%edx
2643    jmp     .LOP_IPUT_BYTE_resolve
2644
2645
2646/* ------------------------------ */
2647    .balign 64
2648.L_OP_IPUT_CHAR: /* 0x5e */
2649/* File: x86/OP_IPUT_CHAR.S */
2650/* File: x86/OP_IPUT.S */
2651
2652    /*
2653     * General 32-bit instance field put.
2654     *
2655     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
2656     */
2657    /* op vA, vB, field@CCCC */
2658    movl    rGLUE,%ecx
2659    movzwl  2(rPC),%edx                         # %edx<- 0000CCCC
2660    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
2661    movzbl  rINSTbl,%ecx                        # ecx<- BA
2662    sarl    $4,%ecx                            # ecx<- B
2663    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2664    andb    $0xf,rINSTbl                       # rINST<- A
2665    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2666    movl    (%eax,%edx,4),%eax                  # resolved entry
2667    testl   %eax,%eax                           # is resolved entry null?
2668    jne     .LOP_IPUT_CHAR_finish                  # no, already resolved
2669    movl    %edx,OUT_ARG1(%esp)
2670    movl    rGLUE,%edx
2671    jmp     .LOP_IPUT_CHAR_resolve
2672
2673
2674/* ------------------------------ */
2675    .balign 64
2676.L_OP_IPUT_SHORT: /* 0x5f */
2677/* File: x86/OP_IPUT_SHORT.S */
2678/* File: x86/OP_IPUT.S */
2679
2680    /*
2681     * General 32-bit instance field put.
2682     *
2683     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
2684     */
2685    /* op vA, vB, field@CCCC */
2686    movl    rGLUE,%ecx
2687    movzwl  2(rPC),%edx                         # %edx<- 0000CCCC
2688    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
2689    movzbl  rINSTbl,%ecx                        # ecx<- BA
2690    sarl    $4,%ecx                            # ecx<- B
2691    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2692    andb    $0xf,rINSTbl                       # rINST<- A
2693    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2694    movl    (%eax,%edx,4),%eax                  # resolved entry
2695    testl   %eax,%eax                           # is resolved entry null?
2696    jne     .LOP_IPUT_SHORT_finish                  # no, already resolved
2697    movl    %edx,OUT_ARG1(%esp)
2698    movl    rGLUE,%edx
2699    jmp     .LOP_IPUT_SHORT_resolve
2700
2701
2702/* ------------------------------ */
2703    .balign 64
2704.L_OP_SGET: /* 0x60 */
2705/* File: x86/OP_SGET.S */
2706    /*
2707     * General 32-bit SGET handler.
2708     *
2709     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2710     */
2711    /* op vAA, field@BBBB */
2712    movl      rGLUE,%ecx
2713    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2714    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2715    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2716    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2717    testl     %eax,%eax                          # resolved entry null?
2718    je        .LOP_SGET_resolve                # if not, make it so
2719.LOP_SGET_finish:     # field ptr in eax
2720    movl      offStaticField_value(%eax),%eax
2721    FETCH_INST_OPCODE 2 %edx
2722    ADVANCE_PC 2
2723    SET_VREG %eax rINST
2724    GOTO_NEXT_R %edx
2725
2726/* ------------------------------ */
2727    .balign 64
2728.L_OP_SGET_WIDE: /* 0x61 */
2729/* File: x86/OP_SGET_WIDE.S */
2730    /*
2731     * 64-bit SGET handler.
2732     *
2733     */
2734    /* sget-wide vAA, field@BBBB */
2735    movl      rGLUE,%ecx
2736    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2737    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2738    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2739    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2740    testl     %eax,%eax                          # resolved entry null?
2741    je        .LOP_SGET_WIDE_resolve                # if not, make it so
2742.LOP_SGET_WIDE_finish:     # field ptr in eax
2743    movl      offStaticField_value(%eax),%ecx    # ecx<- lsw
2744    movl      4+offStaticField_value(%eax),%eax  # eax<- msw
2745    FETCH_INST_OPCODE 2 %edx
2746    ADVANCE_PC 2
2747    SET_VREG_WORD %ecx rINST 0
2748    SET_VREG_WORD %eax rINST 1
2749    GOTO_NEXT_R %edx
2750
2751/* ------------------------------ */
2752    .balign 64
2753.L_OP_SGET_OBJECT: /* 0x62 */
2754/* File: x86/OP_SGET_OBJECT.S */
2755/* File: x86/OP_SGET.S */
2756    /*
2757     * General 32-bit SGET handler.
2758     *
2759     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2760     */
2761    /* op vAA, field@BBBB */
2762    movl      rGLUE,%ecx
2763    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2764    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2765    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2766    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2767    testl     %eax,%eax                          # resolved entry null?
2768    je        .LOP_SGET_OBJECT_resolve                # if not, make it so
2769.LOP_SGET_OBJECT_finish:     # field ptr in eax
2770    movl      offStaticField_value(%eax),%eax
2771    FETCH_INST_OPCODE 2 %edx
2772    ADVANCE_PC 2
2773    SET_VREG %eax rINST
2774    GOTO_NEXT_R %edx
2775
2776
2777/* ------------------------------ */
2778    .balign 64
2779.L_OP_SGET_BOOLEAN: /* 0x63 */
2780/* File: x86/OP_SGET_BOOLEAN.S */
2781/* File: x86/OP_SGET.S */
2782    /*
2783     * General 32-bit SGET handler.
2784     *
2785     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2786     */
2787    /* op vAA, field@BBBB */
2788    movl      rGLUE,%ecx
2789    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2790    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2791    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2792    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2793    testl     %eax,%eax                          # resolved entry null?
2794    je        .LOP_SGET_BOOLEAN_resolve                # if not, make it so
2795.LOP_SGET_BOOLEAN_finish:     # field ptr in eax
2796    movl      offStaticField_value(%eax),%eax
2797    FETCH_INST_OPCODE 2 %edx
2798    ADVANCE_PC 2
2799    SET_VREG %eax rINST
2800    GOTO_NEXT_R %edx
2801
2802
2803/* ------------------------------ */
2804    .balign 64
2805.L_OP_SGET_BYTE: /* 0x64 */
2806/* File: x86/OP_SGET_BYTE.S */
2807/* File: x86/OP_SGET.S */
2808    /*
2809     * General 32-bit SGET handler.
2810     *
2811     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2812     */
2813    /* op vAA, field@BBBB */
2814    movl      rGLUE,%ecx
2815    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2816    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2817    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2818    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2819    testl     %eax,%eax                          # resolved entry null?
2820    je        .LOP_SGET_BYTE_resolve                # if not, make it so
2821.LOP_SGET_BYTE_finish:     # field ptr in eax
2822    movl      offStaticField_value(%eax),%eax
2823    FETCH_INST_OPCODE 2 %edx
2824    ADVANCE_PC 2
2825    SET_VREG %eax rINST
2826    GOTO_NEXT_R %edx
2827
2828
2829/* ------------------------------ */
2830    .balign 64
2831.L_OP_SGET_CHAR: /* 0x65 */
2832/* File: x86/OP_SGET_CHAR.S */
2833/* File: x86/OP_SGET.S */
2834    /*
2835     * General 32-bit SGET handler.
2836     *
2837     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2838     */
2839    /* op vAA, field@BBBB */
2840    movl      rGLUE,%ecx
2841    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2842    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2843    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2844    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2845    testl     %eax,%eax                          # resolved entry null?
2846    je        .LOP_SGET_CHAR_resolve                # if not, make it so
2847.LOP_SGET_CHAR_finish:     # field ptr in eax
2848    movl      offStaticField_value(%eax),%eax
2849    FETCH_INST_OPCODE 2 %edx
2850    ADVANCE_PC 2
2851    SET_VREG %eax rINST
2852    GOTO_NEXT_R %edx
2853
2854
2855/* ------------------------------ */
2856    .balign 64
2857.L_OP_SGET_SHORT: /* 0x66 */
2858/* File: x86/OP_SGET_SHORT.S */
2859/* File: x86/OP_SGET.S */
2860    /*
2861     * General 32-bit SGET handler.
2862     *
2863     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2864     */
2865    /* op vAA, field@BBBB */
2866    movl      rGLUE,%ecx
2867    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2868    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2869    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2870    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2871    testl     %eax,%eax                          # resolved entry null?
2872    je        .LOP_SGET_SHORT_resolve                # if not, make it so
2873.LOP_SGET_SHORT_finish:     # field ptr in eax
2874    movl      offStaticField_value(%eax),%eax
2875    FETCH_INST_OPCODE 2 %edx
2876    ADVANCE_PC 2
2877    SET_VREG %eax rINST
2878    GOTO_NEXT_R %edx
2879
2880
2881/* ------------------------------ */
2882    .balign 64
2883.L_OP_SPUT: /* 0x67 */
2884/* File: x86/OP_SPUT.S */
2885    /*
2886     * General 32-bit SPUT handler.
2887     *
2888     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2889     */
2890    /* op vAA, field@BBBB */
2891    movl      rGLUE,%ecx
2892    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2893    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2894    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2895    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2896    testl     %eax,%eax                          # resolved entry null?
2897    je        .LOP_SPUT_resolve                # if not, make it so
2898.LOP_SPUT_finish:     # field ptr in eax
2899    GET_VREG_R  %ecx rINST
2900    FETCH_INST_OPCODE 2 %edx
2901    ADVANCE_PC 2
2902    movl      %ecx,offStaticField_value(%eax)
2903    GOTO_NEXT_R %edx
2904
2905/* ------------------------------ */
2906    .balign 64
2907.L_OP_SPUT_WIDE: /* 0x68 */
2908/* File: x86/OP_SPUT_WIDE.S */
2909    /*
2910     * General 32-bit SPUT handler.
2911     *
2912     * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
2913     */
2914    /* op vAA, field@BBBB */
2915    movl      rGLUE,%ecx
2916    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2917    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2918    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2919    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2920    testl     %eax,%eax                          # resolved entry null?
2921    je        .LOP_SPUT_WIDE_resolve                # if not, make it so
2922.LOP_SPUT_WIDE_finish:     # field ptr in eax
2923    GET_VREG_WORD %ecx rINST 0                  # rINST<- lsw
2924    GET_VREG_WORD rINST rINST 1                 # ecx<- msw
2925    FETCH_INST_OPCODE 2 %edx
2926    ADVANCE_PC 2
2927    movl      %ecx,offStaticField_value(%eax)
2928    movl      rINST,4+offStaticField_value(%eax)
2929    GOTO_NEXT_R %edx
2930
2931/* ------------------------------ */
2932    .balign 64
2933.L_OP_SPUT_OBJECT: /* 0x69 */
2934/* File: x86/OP_SPUT_OBJECT.S */
2935    /*
2936     * SPUT object handler.
2937     */
2938    /* op vAA, field@BBBB */
2939    movl      rGLUE,%ecx
2940    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2941    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2942    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2943    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField
2944    testl     %eax,%eax                          # resolved entry null?
2945    je        .LOP_SPUT_OBJECT_resolve                # if not, make it so
2946.LOP_SPUT_OBJECT_finish:                              # field ptr in eax
2947    movzbl    rINSTbl,%ecx                       # ecx<- AA
2948    GET_VREG_R  %ecx %ecx
2949    jmp       .LOP_SPUT_OBJECT_continue
2950
2951/* ------------------------------ */
2952    .balign 64
2953.L_OP_SPUT_BOOLEAN: /* 0x6a */
2954/* File: x86/OP_SPUT_BOOLEAN.S */
2955/* File: x86/OP_SPUT.S */
2956    /*
2957     * General 32-bit SPUT handler.
2958     *
2959     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2960     */
2961    /* op vAA, field@BBBB */
2962    movl      rGLUE,%ecx
2963    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2964    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2965    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2966    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2967    testl     %eax,%eax                          # resolved entry null?
2968    je        .LOP_SPUT_BOOLEAN_resolve                # if not, make it so
2969.LOP_SPUT_BOOLEAN_finish:     # field ptr in eax
2970    GET_VREG_R  %ecx rINST
2971    FETCH_INST_OPCODE 2 %edx
2972    ADVANCE_PC 2
2973    movl      %ecx,offStaticField_value(%eax)
2974    GOTO_NEXT_R %edx
2975
2976
2977/* ------------------------------ */
2978    .balign 64
2979.L_OP_SPUT_BYTE: /* 0x6b */
2980/* File: x86/OP_SPUT_BYTE.S */
2981/* File: x86/OP_SPUT.S */
2982    /*
2983     * General 32-bit SPUT handler.
2984     *
2985     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2986     */
2987    /* op vAA, field@BBBB */
2988    movl      rGLUE,%ecx
2989    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2990    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2991    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2992    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2993    testl     %eax,%eax                          # resolved entry null?
2994    je        .LOP_SPUT_BYTE_resolve                # if not, make it so
2995.LOP_SPUT_BYTE_finish:     # field ptr in eax
2996    GET_VREG_R  %ecx rINST
2997    FETCH_INST_OPCODE 2 %edx
2998    ADVANCE_PC 2
2999    movl      %ecx,offStaticField_value(%eax)
3000    GOTO_NEXT_R %edx
3001
3002
3003/* ------------------------------ */
3004    .balign 64
3005.L_OP_SPUT_CHAR: /* 0x6c */
3006/* File: x86/OP_SPUT_CHAR.S */
3007/* File: x86/OP_SPUT.S */
3008    /*
3009     * General 32-bit SPUT handler.
3010     *
3011     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3012     */
3013    /* op vAA, field@BBBB */
3014    movl      rGLUE,%ecx
3015    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3016    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3017    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3018    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3019    testl     %eax,%eax                          # resolved entry null?
3020    je        .LOP_SPUT_CHAR_resolve                # if not, make it so
3021.LOP_SPUT_CHAR_finish:     # field ptr in eax
3022    GET_VREG_R  %ecx rINST
3023    FETCH_INST_OPCODE 2 %edx
3024    ADVANCE_PC 2
3025    movl      %ecx,offStaticField_value(%eax)
3026    GOTO_NEXT_R %edx
3027
3028
3029/* ------------------------------ */
3030    .balign 64
3031.L_OP_SPUT_SHORT: /* 0x6d */
3032/* File: x86/OP_SPUT_SHORT.S */
3033/* File: x86/OP_SPUT.S */
3034    /*
3035     * General 32-bit SPUT handler.
3036     *
3037     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3038     */
3039    /* op vAA, field@BBBB */
3040    movl      rGLUE,%ecx
3041    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3042    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3043    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3044    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3045    testl     %eax,%eax                          # resolved entry null?
3046    je        .LOP_SPUT_SHORT_resolve                # if not, make it so
3047.LOP_SPUT_SHORT_finish:     # field ptr in eax
3048    GET_VREG_R  %ecx rINST
3049    FETCH_INST_OPCODE 2 %edx
3050    ADVANCE_PC 2
3051    movl      %ecx,offStaticField_value(%eax)
3052    GOTO_NEXT_R %edx
3053
3054
3055/* ------------------------------ */
3056    .balign 64
3057.L_OP_INVOKE_VIRTUAL: /* 0x6e */
3058/* File: x86/OP_INVOKE_VIRTUAL.S */
3059
3060    /*
3061     * Handle a virtual method call.
3062     *
3063     * for: invoke-virtual, invoke-virtual/range
3064     */
3065    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3066    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3067    movl      rGLUE,%eax
3068    movzwl    2(rPC),%ecx                 # ecx<- BBBB
3069    movl      offGlue_methodClassDex(%eax),%eax  # eax<- pDvmDex
3070    EXPORT_PC
3071    movl      offDvmDex_pResMethods(%eax),%eax   # eax<- pDvmDex->pResMethods
3072    movl      (%eax,%ecx,4),%eax          # eax<- resolved baseMethod
3073    testl     %eax,%eax                   # already resolved?
3074    jne       .LOP_INVOKE_VIRTUAL_continue        # yes, continue
3075    movl      rGLUE,%eax
3076    movl      %ecx,OUT_ARG1(%esp)         # arg1<- ref
3077    movl      offGlue_method(%eax),%eax   # eax<- glue->method
3078    jmp       .LOP_INVOKE_VIRTUAL_more
3079
3080/* ------------------------------ */
3081    .balign 64
3082.L_OP_INVOKE_SUPER: /* 0x6f */
3083/* File: x86/OP_INVOKE_SUPER.S */
3084    /*
3085     * Handle a "super" method call.
3086     *
3087     * for: invoke-super, invoke-super/range
3088     */
3089    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3090    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3091    movl      rGLUE,rINST
3092    movzwl    2(rPC),%eax               # eax<- BBBB
3093    movl      offGlue_methodClassDex(rINST),%ecx # ecx<- pDvmDex
3094    EXPORT_PC
3095    movl      offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods
3096    movl      (%ecx,%eax,4),%ecx        # ecx<- resolved baseMethod
3097    movl      offGlue_method(rINST),%eax # eax<- method
3098    movzwl    4(rPC),rINST              # rINST<- GFED or CCCC
3099    .if       (!0)
3100    andl      $0xf,rINST               # rINST<- D (or stays CCCC)
3101    .endif
3102    GET_VREG_R  rINST rINST             # rINST<- "this" ptr
3103    testl     rINST,rINST               # null "this"?
3104    je        common_errNullObject      # yes, throw
3105    movl      offMethod_clazz(%eax),%eax # eax<- method->clazz
3106    testl     %ecx,%ecx                 # already resolved?
3107    jne       .LOP_INVOKE_SUPER_continue      # yes - go on
3108    jmp       .LOP_INVOKE_SUPER_resolve
3109
3110/* ------------------------------ */
3111    .balign 64
3112.L_OP_INVOKE_DIRECT: /* 0x70 */
3113/* File: x86/OP_INVOKE_DIRECT.S */
3114    /*
3115     * Handle a direct method call.
3116     *
3117     * (We could defer the "is 'this' pointer null" test to the common
3118     * method invocation code, and use a flag to indicate that static
3119     * calls don't count.  If we do this as part of copying the arguments
3120     * out we could avoiding loading the first arg twice.)
3121     *
3122     * for: invoke-direct, invoke-direct/range
3123     */
3124    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3125    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3126    movl      rGLUE,%ecx
3127    movzwl    2(rPC),%eax              # eax<- BBBB
3128    movl      offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
3129    EXPORT_PC
3130    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
3131    movzwl    4(rPC),%edx              # edx<- GFED or CCCC
3132    movl      (%ecx,%eax,4),%eax       # eax<- resolved methodToCall
3133    .if       (!0)
3134    andl      $0xf,%edx               # edx<- D (or stays CCCC)
3135    .endif
3136    testl     %eax,%eax                # already resolved?
3137    GET_VREG_R  %ecx %edx              # ecx<- "this" ptr
3138    je        .LOP_INVOKE_DIRECT_resolve      # not resolved, do it now
3139.LOP_INVOKE_DIRECT_finish:
3140    testl     %ecx,%ecx                # null "this"?
3141    jne       common_invokeMethodNoRange  # no, continue on
3142    jmp       common_errNullObject
3143
3144/* ------------------------------ */
3145    .balign 64
3146.L_OP_INVOKE_STATIC: /* 0x71 */
3147/* File: x86/OP_INVOKE_STATIC.S */
3148    /*
3149     * Handle a static method call.
3150     *
3151     * for: invoke-static, invoke-static/range
3152     */
3153    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3154    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3155    movl      rGLUE,%ecx
3156    movzwl    2(rPC),%eax               # eax<- BBBB
3157    movl      offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
3158    EXPORT_PC
3159    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
3160    movl      (%ecx,%eax,4),%eax        # eax<- resolved methodToCall
3161    testl     %eax,%eax
3162    jne       common_invokeMethodNoRange
3163    movl      rGLUE,%ecx
3164    movl      offGlue_method(%ecx),%ecx # ecx<- glue->method
3165    movzwl    2(rPC),%eax
3166    movl      offMethod_clazz(%ecx),%ecx# ecx<- method->clazz
3167    movl      %eax,OUT_ARG1(%esp)       # arg1<- BBBB
3168    movl      %ecx,OUT_ARG0(%esp)       # arg0<- clazz
3169    jmp       .LOP_INVOKE_STATIC_continue
3170
3171/* ------------------------------ */
3172    .balign 64
3173.L_OP_INVOKE_INTERFACE: /* 0x72 */
3174/* File: x86/OP_INVOKE_INTERFACE.S */
3175    /*
3176     * Handle an interface method call.
3177     *
3178     * for: invoke-interface, invoke-interface/range
3179     */
3180    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3181    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3182    movzwl     4(rPC),%eax              # eax<- FEDC or CCCC
3183    movl       rGLUE,%ecx
3184    .if        (!0)
3185    andl       $0xf,%eax               # eax<- C (or stays CCCC)
3186    .endif
3187    GET_VREG_R   %eax %eax              # eax<- "this"
3188    EXPORT_PC
3189    testl      %eax,%eax                # null this?
3190    je         common_errNullObject     # yes, fail
3191    movl       offObject_clazz(%eax),%eax# eax<- thisPtr->clazz
3192    movl       %eax,OUT_ARG0(%esp)                 # arg0<- class
3193    movl       offGlue_methodClassDex(%ecx),%eax   # eax<- methodClassDex
3194    movl       offGlue_method(%ecx),%ecx           # ecx<- method
3195    movl       %eax,OUT_ARG3(%esp)                 # arg3<- dex
3196    movzwl     2(rPC),%eax                         # eax<- BBBB
3197    movl       %ecx,OUT_ARG2(%esp)                 # arg2<- method
3198    movl       %eax,OUT_ARG1(%esp)                 # arg1<- BBBB
3199    jmp        .LOP_INVOKE_INTERFACE_continue
3200
3201/* ------------------------------ */
3202    .balign 64
3203.L_OP_UNUSED_73: /* 0x73 */
3204/* File: x86/OP_UNUSED_73.S */
3205/* File: x86/unused.S */
3206    jmp     common_abort
3207
3208
3209/* ------------------------------ */
3210    .balign 64
3211.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
3212/* File: x86/OP_INVOKE_VIRTUAL_RANGE.S */
3213/* File: x86/OP_INVOKE_VIRTUAL.S */
3214
3215    /*
3216     * Handle a virtual method call.
3217     *
3218     * for: invoke-virtual, invoke-virtual/range
3219     */
3220    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3221    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3222    movl      rGLUE,%eax
3223    movzwl    2(rPC),%ecx                 # ecx<- BBBB
3224    movl      offGlue_methodClassDex(%eax),%eax  # eax<- pDvmDex
3225    EXPORT_PC
3226    movl      offDvmDex_pResMethods(%eax),%eax   # eax<- pDvmDex->pResMethods
3227    movl      (%eax,%ecx,4),%eax          # eax<- resolved baseMethod
3228    testl     %eax,%eax                   # already resolved?
3229    jne       .LOP_INVOKE_VIRTUAL_RANGE_continue        # yes, continue
3230    movl      rGLUE,%eax
3231    movl      %ecx,OUT_ARG1(%esp)         # arg1<- ref
3232    movl      offGlue_method(%eax),%eax   # eax<- glue->method
3233    jmp       .LOP_INVOKE_VIRTUAL_RANGE_more
3234
3235
3236/* ------------------------------ */
3237    .balign 64
3238.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */
3239/* File: x86/OP_INVOKE_SUPER_RANGE.S */
3240/* File: x86/OP_INVOKE_SUPER.S */
3241    /*
3242     * Handle a "super" method call.
3243     *
3244     * for: invoke-super, invoke-super/range
3245     */
3246    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3247    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3248    movl      rGLUE,rINST
3249    movzwl    2(rPC),%eax               # eax<- BBBB
3250    movl      offGlue_methodClassDex(rINST),%ecx # ecx<- pDvmDex
3251    EXPORT_PC
3252    movl      offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods
3253    movl      (%ecx,%eax,4),%ecx        # ecx<- resolved baseMethod
3254    movl      offGlue_method(rINST),%eax # eax<- method
3255    movzwl    4(rPC),rINST              # rINST<- GFED or CCCC
3256    .if       (!1)
3257    andl      $0xf,rINST               # rINST<- D (or stays CCCC)
3258    .endif
3259    GET_VREG_R  rINST rINST             # rINST<- "this" ptr
3260    testl     rINST,rINST               # null "this"?
3261    je        common_errNullObject      # yes, throw
3262    movl      offMethod_clazz(%eax),%eax # eax<- method->clazz
3263    testl     %ecx,%ecx                 # already resolved?
3264    jne       .LOP_INVOKE_SUPER_RANGE_continue      # yes - go on
3265    jmp       .LOP_INVOKE_SUPER_RANGE_resolve
3266
3267
3268/* ------------------------------ */
3269    .balign 64
3270.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
3271/* File: x86/OP_INVOKE_DIRECT_RANGE.S */
3272/* File: x86/OP_INVOKE_DIRECT.S */
3273    /*
3274     * Handle a direct method call.
3275     *
3276     * (We could defer the "is 'this' pointer null" test to the common
3277     * method invocation code, and use a flag to indicate that static
3278     * calls don't count.  If we do this as part of copying the arguments
3279     * out we could avoiding loading the first arg twice.)
3280     *
3281     * for: invoke-direct, invoke-direct/range
3282     */
3283    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3284    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3285    movl      rGLUE,%ecx
3286    movzwl    2(rPC),%eax              # eax<- BBBB
3287    movl      offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
3288    EXPORT_PC
3289    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
3290    movzwl    4(rPC),%edx              # edx<- GFED or CCCC
3291    movl      (%ecx,%eax,4),%eax       # eax<- resolved methodToCall
3292    .if       (!1)
3293    andl      $0xf,%edx               # edx<- D (or stays CCCC)
3294    .endif
3295    testl     %eax,%eax                # already resolved?
3296    GET_VREG_R  %ecx %edx              # ecx<- "this" ptr
3297    je        .LOP_INVOKE_DIRECT_RANGE_resolve      # not resolved, do it now
3298.LOP_INVOKE_DIRECT_RANGE_finish:
3299    testl     %ecx,%ecx                # null "this"?
3300    jne       common_invokeMethodRange  # no, continue on
3301    jmp       common_errNullObject
3302
3303
3304/* ------------------------------ */
3305    .balign 64
3306.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */
3307/* File: x86/OP_INVOKE_STATIC_RANGE.S */
3308/* File: x86/OP_INVOKE_STATIC.S */
3309    /*
3310     * Handle a static method call.
3311     *
3312     * for: invoke-static, invoke-static/range
3313     */
3314    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3315    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3316    movl      rGLUE,%ecx
3317    movzwl    2(rPC),%eax               # eax<- BBBB
3318    movl      offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
3319    EXPORT_PC
3320    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
3321    movl      (%ecx,%eax,4),%eax        # eax<- resolved methodToCall
3322    testl     %eax,%eax
3323    jne       common_invokeMethodRange
3324    movl      rGLUE,%ecx
3325    movl      offGlue_method(%ecx),%ecx # ecx<- glue->method
3326    movzwl    2(rPC),%eax
3327    movl      offMethod_clazz(%ecx),%ecx# ecx<- method->clazz
3328    movl      %eax,OUT_ARG1(%esp)       # arg1<- BBBB
3329    movl      %ecx,OUT_ARG0(%esp)       # arg0<- clazz
3330    jmp       .LOP_INVOKE_STATIC_RANGE_continue
3331
3332
3333/* ------------------------------ */
3334    .balign 64
3335.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
3336/* File: x86/OP_INVOKE_INTERFACE_RANGE.S */
3337/* File: x86/OP_INVOKE_INTERFACE.S */
3338    /*
3339     * Handle an interface method call.
3340     *
3341     * for: invoke-interface, invoke-interface/range
3342     */
3343    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3344    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3345    movzwl     4(rPC),%eax              # eax<- FEDC or CCCC
3346    movl       rGLUE,%ecx
3347    .if        (!1)
3348    andl       $0xf,%eax               # eax<- C (or stays CCCC)
3349    .endif
3350    GET_VREG_R   %eax %eax              # eax<- "this"
3351    EXPORT_PC
3352    testl      %eax,%eax                # null this?
3353    je         common_errNullObject     # yes, fail
3354    movl       offObject_clazz(%eax),%eax# eax<- thisPtr->clazz
3355    movl       %eax,OUT_ARG0(%esp)                 # arg0<- class
3356    movl       offGlue_methodClassDex(%ecx),%eax   # eax<- methodClassDex
3357    movl       offGlue_method(%ecx),%ecx           # ecx<- method
3358    movl       %eax,OUT_ARG3(%esp)                 # arg3<- dex
3359    movzwl     2(rPC),%eax                         # eax<- BBBB
3360    movl       %ecx,OUT_ARG2(%esp)                 # arg2<- method
3361    movl       %eax,OUT_ARG1(%esp)                 # arg1<- BBBB
3362    jmp        .LOP_INVOKE_INTERFACE_RANGE_continue
3363
3364
3365/* ------------------------------ */
3366    .balign 64
3367.L_OP_UNUSED_79: /* 0x79 */
3368/* File: x86/OP_UNUSED_79.S */
3369/* File: x86/unused.S */
3370    jmp     common_abort
3371
3372
3373/* ------------------------------ */
3374    .balign 64
3375.L_OP_UNUSED_7A: /* 0x7a */
3376/* File: x86/OP_UNUSED_7A.S */
3377/* File: x86/unused.S */
3378    jmp     common_abort
3379
3380
3381/* ------------------------------ */
3382    .balign 64
3383.L_OP_NEG_INT: /* 0x7b */
3384/* File: x86/OP_NEG_INT.S */
3385/* File: x86/unop.S */
3386    /*
3387     * Generic 32-bit unary operation.  Provide an "instr" line that
3388     * specifies an instruction that performs "result = op eax".
3389     */
3390    /* unop vA, vB */
3391    movzbl   rINSTbl,%ecx           # ecx<- A+
3392    sarl     $4,rINST             # rINST<- B
3393    GET_VREG_R %eax rINST           # eax<- vB
3394    andb     $0xf,%cl              # ecx<- A
3395    FETCH_INST_OPCODE 1 %edx
3396    ADVANCE_PC 1
3397
3398
3399    negl %eax
3400    SET_VREG %eax %ecx
3401    GOTO_NEXT_R %edx
3402
3403
3404/* ------------------------------ */
3405    .balign 64
3406.L_OP_NOT_INT: /* 0x7c */
3407/* File: x86/OP_NOT_INT.S */
3408/* File: x86/unop.S */
3409    /*
3410     * Generic 32-bit unary operation.  Provide an "instr" line that
3411     * specifies an instruction that performs "result = op eax".
3412     */
3413    /* unop vA, vB */
3414    movzbl   rINSTbl,%ecx           # ecx<- A+
3415    sarl     $4,rINST             # rINST<- B
3416    GET_VREG_R %eax rINST           # eax<- vB
3417    andb     $0xf,%cl              # ecx<- A
3418    FETCH_INST_OPCODE 1 %edx
3419    ADVANCE_PC 1
3420
3421
3422    notl %eax
3423    SET_VREG %eax %ecx
3424    GOTO_NEXT_R %edx
3425
3426
3427/* ------------------------------ */
3428    .balign 64
3429.L_OP_NEG_LONG: /* 0x7d */
3430/* File: x86/OP_NEG_LONG.S */
3431    /* unop vA, vB */
3432    movzbl    rINSTbl,%ecx        # ecx<- BA
3433    sarl      $4,%ecx            # ecx<- B
3434    andb      $0xf,rINSTbl       # rINST<- A
3435    GET_VREG_WORD %eax %ecx 0     # eax<- v[B+0]
3436    GET_VREG_WORD %ecx %ecx 1     # ecx<- v[B+1]
3437    negl      %eax
3438    adcl      $0,%ecx
3439    negl      %ecx
3440    FETCH_INST_OPCODE 1 %edx
3441    SET_VREG_WORD %eax rINST 0    # v[A+0]<- eax
3442    SET_VREG_WORD %ecx rINST 1    # v[A+1]<- ecx
3443    ADVANCE_PC 1
3444    GOTO_NEXT_R %edx
3445
3446/* ------------------------------ */
3447    .balign 64
3448.L_OP_NOT_LONG: /* 0x7e */
3449/* File: x86/OP_NOT_LONG.S */
3450    /* unop vA, vB */
3451    movzbl    rINSTbl,%ecx       # ecx<- BA
3452    sarl      $4,%ecx           # ecx<- B
3453    andb      $0xf,rINSTbl      # rINST<- A
3454    GET_VREG_WORD %eax %ecx 0    # eax<- v[B+0]
3455    GET_VREG_WORD %ecx %ecx 1    # ecx<- v[B+1]
3456    FETCH_INST_OPCODE 1 %edx
3457    notl      %eax
3458    notl      %ecx
3459    SET_VREG_WORD %eax rINST 0   # v[A+0]<- eax
3460    SET_VREG_WORD %ecx rINST 1   # v[A+1]<- ecx
3461    ADVANCE_PC 1
3462    GOTO_NEXT_R %edx
3463
3464/* ------------------------------ */
3465    .balign 64
3466.L_OP_NEG_FLOAT: /* 0x7f */
3467/* File: x86/OP_NEG_FLOAT.S */
3468/* File: x86/fpcvt.S */
3469    /*
3470     * Generic 32-bit FP conversion operation.
3471     */
3472    /* unop vA, vB */
3473    movzbl   rINSTbl,%ecx       # ecx<- A+
3474    sarl     $4,rINST         # rINST<- B
3475    flds    (rFP,rINST,4)      # %st0<- vB
3476    andb     $0xf,%cl          # ecx<- A
3477    FETCH_INST_OPCODE 1 %edx
3478    ADVANCE_PC 1
3479    fchs
3480    fstps  (rFP,%ecx,4)        # vA<- %st0
3481    GOTO_NEXT_R %edx
3482
3483
3484/* ------------------------------ */
3485    .balign 64
3486.L_OP_NEG_DOUBLE: /* 0x80 */
3487/* File: x86/OP_NEG_DOUBLE.S */
3488/* File: x86/fpcvt.S */
3489    /*
3490     * Generic 32-bit FP conversion operation.
3491     */
3492    /* unop vA, vB */
3493    movzbl   rINSTbl,%ecx       # ecx<- A+
3494    sarl     $4,rINST         # rINST<- B
3495    fldl    (rFP,rINST,4)      # %st0<- vB
3496    andb     $0xf,%cl          # ecx<- A
3497    FETCH_INST_OPCODE 1 %edx
3498    ADVANCE_PC 1
3499    fchs
3500    fstpl  (rFP,%ecx,4)        # vA<- %st0
3501    GOTO_NEXT_R %edx
3502
3503
3504/* ------------------------------ */
3505    .balign 64
3506.L_OP_INT_TO_LONG: /* 0x81 */
3507/* File: x86/OP_INT_TO_LONG.S */
3508    /* int to long vA, vB */
3509    movzbl  rINSTbl,%eax                # eax<- +A
3510    sarl    $4,%eax                    # eax<- B
3511    GET_VREG_R %eax %eax                # eax<- vB
3512    andb    $0xf,rINSTbl               # rINST<- A
3513    cltd                                # edx:eax<- sssssssBBBBBBBB
3514    SET_VREG_WORD %edx rINST 1          # v[A+1]<- edx/rPC
3515    FETCH_INST_OPCODE 1 %edx
3516    SET_VREG_WORD %eax rINST 0          # v[A+0]<- %eax
3517    ADVANCE_PC 1
3518    GOTO_NEXT_R %edx
3519
3520/* ------------------------------ */
3521    .balign 64
3522.L_OP_INT_TO_FLOAT: /* 0x82 */
3523/* File: x86/OP_INT_TO_FLOAT.S */
3524/* File: x86/fpcvt.S */
3525    /*
3526     * Generic 32-bit FP conversion operation.
3527     */
3528    /* unop vA, vB */
3529    movzbl   rINSTbl,%ecx       # ecx<- A+
3530    sarl     $4,rINST         # rINST<- B
3531    fildl    (rFP,rINST,4)      # %st0<- vB
3532    andb     $0xf,%cl          # ecx<- A
3533    FETCH_INST_OPCODE 1 %edx
3534    ADVANCE_PC 1
3535
3536    fstps  (rFP,%ecx,4)        # vA<- %st0
3537    GOTO_NEXT_R %edx
3538
3539
3540/* ------------------------------ */
3541    .balign 64
3542.L_OP_INT_TO_DOUBLE: /* 0x83 */
3543/* File: x86/OP_INT_TO_DOUBLE.S */
3544/* File: x86/fpcvt.S */
3545    /*
3546     * Generic 32-bit FP conversion operation.
3547     */
3548    /* unop vA, vB */
3549    movzbl   rINSTbl,%ecx       # ecx<- A+
3550    sarl     $4,rINST         # rINST<- B
3551    fildl    (rFP,rINST,4)      # %st0<- vB
3552    andb     $0xf,%cl          # ecx<- A
3553    FETCH_INST_OPCODE 1 %edx
3554    ADVANCE_PC 1
3555
3556    fstpl  (rFP,%ecx,4)        # vA<- %st0
3557    GOTO_NEXT_R %edx
3558
3559
3560/* ------------------------------ */
3561    .balign 64
3562.L_OP_LONG_TO_INT: /* 0x84 */
3563/* File: x86/OP_LONG_TO_INT.S */
3564/* we ignore the high word, making this equivalent to a 32-bit reg move */
3565/* File: x86/OP_MOVE.S */
3566    /* for move, move-object, long-to-int */
3567    /* op vA, vB */
3568    movzbl rINSTbl,%eax          # eax<- BA
3569    andb   $0xf,%al             # eax<- A
3570    shrl   $4,rINST            # rINST<- B
3571    GET_VREG_R %ecx rINST
3572    FETCH_INST_OPCODE 1 %edx
3573    ADVANCE_PC 1
3574    SET_VREG %ecx %eax           # fp[A]<-fp[B]
3575    GOTO_NEXT_R %edx
3576
3577
3578/* ------------------------------ */
3579    .balign 64
3580.L_OP_LONG_TO_FLOAT: /* 0x85 */
3581/* File: x86/OP_LONG_TO_FLOAT.S */
3582/* File: x86/fpcvt.S */
3583    /*
3584     * Generic 32-bit FP conversion operation.
3585     */
3586    /* unop vA, vB */
3587    movzbl   rINSTbl,%ecx       # ecx<- A+
3588    sarl     $4,rINST         # rINST<- B
3589    fildll    (rFP,rINST,4)      # %st0<- vB
3590    andb     $0xf,%cl          # ecx<- A
3591    FETCH_INST_OPCODE 1 %edx
3592    ADVANCE_PC 1
3593
3594    fstps  (rFP,%ecx,4)        # vA<- %st0
3595    GOTO_NEXT_R %edx
3596
3597
3598/* ------------------------------ */
3599    .balign 64
3600.L_OP_LONG_TO_DOUBLE: /* 0x86 */
3601/* File: x86/OP_LONG_TO_DOUBLE.S */
3602/* File: x86/fpcvt.S */
3603    /*
3604     * Generic 32-bit FP conversion operation.
3605     */
3606    /* unop vA, vB */
3607    movzbl   rINSTbl,%ecx       # ecx<- A+
3608    sarl     $4,rINST         # rINST<- B
3609    fildll    (rFP,rINST,4)      # %st0<- vB
3610    andb     $0xf,%cl          # ecx<- A
3611    FETCH_INST_OPCODE 1 %edx
3612    ADVANCE_PC 1
3613
3614    fstpl  (rFP,%ecx,4)        # vA<- %st0
3615    GOTO_NEXT_R %edx
3616
3617
3618/* ------------------------------ */
3619    .balign 64
3620.L_OP_FLOAT_TO_INT: /* 0x87 */
3621/* File: x86/OP_FLOAT_TO_INT.S */
3622/* File: x86/cvtfp_int.S */
3623/* On fp to int conversions, Java requires that
3624 * if the result > maxint, it should be clamped to maxint.  If it is less
3625 * than minint, it should be clamped to minint.  If it is a nan, the result
3626 * should be zero.  Further, the rounding mode is to truncate.  This model
3627 * differs from what is delivered normally via the x86 fpu, so we have
3628 * to play some games.
3629 */
3630    /* float/double to int/long vA, vB */
3631    movzbl    rINSTbl,%ecx       # ecx<- A+
3632    sarl      $4,rINST         # rINST<- B
3633    .if 0
3634    fldl     (rFP,rINST,4)       # %st0<- vB
3635    .else
3636    flds     (rFP,rINST,4)       # %st0<- vB
3637    .endif
3638    ftst
3639    fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
3640    movzwl   LOCAL0_OFFSET(%ebp),%eax
3641    movb     $0xc,%ah
3642    movw     %ax,LOCAL0_OFFSET+2(%ebp)
3643    fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
3644    FETCH_INST_OPCODE 1 %edx
3645    andb     $0xf,%cl                # ecx<- A
3646    .if 0
3647    fistpll  (rFP,%ecx,4)             # convert and store
3648    .else
3649    fistpl   (rFP,%ecx,4)             # convert and store
3650    .endif
3651    fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
3652    jmp      .LOP_FLOAT_TO_INT_continue
3653
3654
3655/* ------------------------------ */
3656    .balign 64
3657.L_OP_FLOAT_TO_LONG: /* 0x88 */
3658/* File: x86/OP_FLOAT_TO_LONG.S */
3659/* File: x86/cvtfp_int.S */
3660/* On fp to int conversions, Java requires that
3661 * if the result > maxint, it should be clamped to maxint.  If it is less
3662 * than minint, it should be clamped to minint.  If it is a nan, the result
3663 * should be zero.  Further, the rounding mode is to truncate.  This model
3664 * differs from what is delivered normally via the x86 fpu, so we have
3665 * to play some games.
3666 */
3667    /* float/double to int/long vA, vB */
3668    movzbl    rINSTbl,%ecx       # ecx<- A+
3669    sarl      $4,rINST         # rINST<- B
3670    .if 0
3671    fldl     (rFP,rINST,4)       # %st0<- vB
3672    .else
3673    flds     (rFP,rINST,4)       # %st0<- vB
3674    .endif
3675    ftst
3676    fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
3677    movzwl   LOCAL0_OFFSET(%ebp),%eax
3678    movb     $0xc,%ah
3679    movw     %ax,LOCAL0_OFFSET+2(%ebp)
3680    fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
3681    FETCH_INST_OPCODE 1 %edx
3682    andb     $0xf,%cl                # ecx<- A
3683    .if 1
3684    fistpll  (rFP,%ecx,4)             # convert and store
3685    .else
3686    fistpl   (rFP,%ecx,4)             # convert and store
3687    .endif
3688    fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
3689    jmp      .LOP_FLOAT_TO_LONG_continue
3690
3691
3692/* ------------------------------ */
3693    .balign 64
3694.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */
3695/* File: x86/OP_FLOAT_TO_DOUBLE.S */
3696/* File: x86/fpcvt.S */
3697    /*
3698     * Generic 32-bit FP conversion operation.
3699     */
3700    /* unop vA, vB */
3701    movzbl   rINSTbl,%ecx       # ecx<- A+
3702    sarl     $4,rINST         # rINST<- B
3703    flds    (rFP,rINST,4)      # %st0<- vB
3704    andb     $0xf,%cl          # ecx<- A
3705    FETCH_INST_OPCODE 1 %edx
3706    ADVANCE_PC 1
3707
3708    fstpl  (rFP,%ecx,4)        # vA<- %st0
3709    GOTO_NEXT_R %edx
3710
3711
3712/* ------------------------------ */
3713    .balign 64
3714.L_OP_DOUBLE_TO_INT: /* 0x8a */
3715/* File: x86/OP_DOUBLE_TO_INT.S */
3716/* File: x86/cvtfp_int.S */
3717/* On fp to int conversions, Java requires that
3718 * if the result > maxint, it should be clamped to maxint.  If it is less
3719 * than minint, it should be clamped to minint.  If it is a nan, the result
3720 * should be zero.  Further, the rounding mode is to truncate.  This model
3721 * differs from what is delivered normally via the x86 fpu, so we have
3722 * to play some games.
3723 */
3724    /* float/double to int/long vA, vB */
3725    movzbl    rINSTbl,%ecx       # ecx<- A+
3726    sarl      $4,rINST         # rINST<- B
3727    .if 1
3728    fldl     (rFP,rINST,4)       # %st0<- vB
3729    .else
3730    flds     (rFP,rINST,4)       # %st0<- vB
3731    .endif
3732    ftst
3733    fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
3734    movzwl   LOCAL0_OFFSET(%ebp),%eax
3735    movb     $0xc,%ah
3736    movw     %ax,LOCAL0_OFFSET+2(%ebp)
3737    fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
3738    FETCH_INST_OPCODE 1 %edx
3739    andb     $0xf,%cl                # ecx<- A
3740    .if 0
3741    fistpll  (rFP,%ecx,4)             # convert and store
3742    .else
3743    fistpl   (rFP,%ecx,4)             # convert and store
3744    .endif
3745    fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
3746    jmp      .LOP_DOUBLE_TO_INT_continue
3747
3748
3749/* ------------------------------ */
3750    .balign 64
3751.L_OP_DOUBLE_TO_LONG: /* 0x8b */
3752/* File: x86/OP_DOUBLE_TO_LONG.S */
3753/* File: x86/cvtfp_int.S */
3754/* On fp to int conversions, Java requires that
3755 * if the result > maxint, it should be clamped to maxint.  If it is less
3756 * than minint, it should be clamped to minint.  If it is a nan, the result
3757 * should be zero.  Further, the rounding mode is to truncate.  This model
3758 * differs from what is delivered normally via the x86 fpu, so we have
3759 * to play some games.
3760 */
3761    /* float/double to int/long vA, vB */
3762    movzbl    rINSTbl,%ecx       # ecx<- A+
3763    sarl      $4,rINST         # rINST<- B
3764    .if 1
3765    fldl     (rFP,rINST,4)       # %st0<- vB
3766    .else
3767    flds     (rFP,rINST,4)       # %st0<- vB
3768    .endif
3769    ftst
3770    fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
3771    movzwl   LOCAL0_OFFSET(%ebp),%eax
3772    movb     $0xc,%ah
3773    movw     %ax,LOCAL0_OFFSET+2(%ebp)
3774    fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
3775    FETCH_INST_OPCODE 1 %edx
3776    andb     $0xf,%cl                # ecx<- A
3777    .if 1
3778    fistpll  (rFP,%ecx,4)             # convert and store
3779    .else
3780    fistpl   (rFP,%ecx,4)             # convert and store
3781    .endif
3782    fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
3783    jmp      .LOP_DOUBLE_TO_LONG_continue
3784
3785
3786/* ------------------------------ */
3787    .balign 64
3788.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */
3789/* File: x86/OP_DOUBLE_TO_FLOAT.S */
3790/* File: x86/fpcvt.S */
3791    /*
3792     * Generic 32-bit FP conversion operation.
3793     */
3794    /* unop vA, vB */
3795    movzbl   rINSTbl,%ecx       # ecx<- A+
3796    sarl     $4,rINST         # rINST<- B
3797    fldl    (rFP,rINST,4)      # %st0<- vB
3798    andb     $0xf,%cl          # ecx<- A
3799    FETCH_INST_OPCODE 1 %edx
3800    ADVANCE_PC 1
3801
3802    fstps  (rFP,%ecx,4)        # vA<- %st0
3803    GOTO_NEXT_R %edx
3804
3805
3806/* ------------------------------ */
3807    .balign 64
3808.L_OP_INT_TO_BYTE: /* 0x8d */
3809/* File: x86/OP_INT_TO_BYTE.S */
3810/* File: x86/unop.S */
3811    /*
3812     * Generic 32-bit unary operation.  Provide an "instr" line that
3813     * specifies an instruction that performs "result = op eax".
3814     */
3815    /* unop vA, vB */
3816    movzbl   rINSTbl,%ecx           # ecx<- A+
3817    sarl     $4,rINST             # rINST<- B
3818    GET_VREG_R %eax rINST           # eax<- vB
3819    andb     $0xf,%cl              # ecx<- A
3820    FETCH_INST_OPCODE 1 %edx
3821    ADVANCE_PC 1
3822
3823
3824    movsbl %al,%eax
3825    SET_VREG %eax %ecx
3826    GOTO_NEXT_R %edx
3827
3828
3829/* ------------------------------ */
3830    .balign 64
3831.L_OP_INT_TO_CHAR: /* 0x8e */
3832/* File: x86/OP_INT_TO_CHAR.S */
3833/* File: x86/unop.S */
3834    /*
3835     * Generic 32-bit unary operation.  Provide an "instr" line that
3836     * specifies an instruction that performs "result = op eax".
3837     */
3838    /* unop vA, vB */
3839    movzbl   rINSTbl,%ecx           # ecx<- A+
3840    sarl     $4,rINST             # rINST<- B
3841    GET_VREG_R %eax rINST           # eax<- vB
3842    andb     $0xf,%cl              # ecx<- A
3843    FETCH_INST_OPCODE 1 %edx
3844    ADVANCE_PC 1
3845
3846
3847    movzwl %ax,%eax
3848    SET_VREG %eax %ecx
3849    GOTO_NEXT_R %edx
3850
3851
3852/* ------------------------------ */
3853    .balign 64
3854.L_OP_INT_TO_SHORT: /* 0x8f */
3855/* File: x86/OP_INT_TO_SHORT.S */
3856/* File: x86/unop.S */
3857    /*
3858     * Generic 32-bit unary operation.  Provide an "instr" line that
3859     * specifies an instruction that performs "result = op eax".
3860     */
3861    /* unop vA, vB */
3862    movzbl   rINSTbl,%ecx           # ecx<- A+
3863    sarl     $4,rINST             # rINST<- B
3864    GET_VREG_R %eax rINST           # eax<- vB
3865    andb     $0xf,%cl              # ecx<- A
3866    FETCH_INST_OPCODE 1 %edx
3867    ADVANCE_PC 1
3868
3869
3870    movswl %ax,%eax
3871    SET_VREG %eax %ecx
3872    GOTO_NEXT_R %edx
3873
3874
3875/* ------------------------------ */
3876    .balign 64
3877.L_OP_ADD_INT: /* 0x90 */
3878/* File: x86/OP_ADD_INT.S */
3879/* File: x86/binop.S */
3880    /*
3881     * Generic 32-bit binary operation.  Provide an "instr" line that
3882     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
3883     * This could be an x86 instruction or a function call.  (If the result
3884     * comes back in a register other than eax, you can override "result".)
3885     *
3886     * For: add-int, sub-int, and-int, or-int,
3887     *      xor-int, shl-int, shr-int, ushr-int
3888     */
3889    /* binop vAA, vBB, vCC */
3890    movzbl   2(rPC),%eax   # eax<- BB
3891    movzbl   3(rPC),%ecx   # ecx<- CC
3892    GET_VREG_R %eax %eax   # eax<- vBB
3893    addl (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
3894    FETCH_INST_OPCODE 2 %edx
3895    ADVANCE_PC 2
3896    SET_VREG %eax rINST
3897    GOTO_NEXT_R %edx
3898
3899
3900/* ------------------------------ */
3901    .balign 64
3902.L_OP_SUB_INT: /* 0x91 */
3903/* File: x86/OP_SUB_INT.S */
3904/* File: x86/binop.S */
3905    /*
3906     * Generic 32-bit binary operation.  Provide an "instr" line that
3907     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
3908     * This could be an x86 instruction or a function call.  (If the result
3909     * comes back in a register other than eax, you can override "result".)
3910     *
3911     * For: add-int, sub-int, and-int, or-int,
3912     *      xor-int, shl-int, shr-int, ushr-int
3913     */
3914    /* binop vAA, vBB, vCC */
3915    movzbl   2(rPC),%eax   # eax<- BB
3916    movzbl   3(rPC),%ecx   # ecx<- CC
3917    GET_VREG_R %eax %eax   # eax<- vBB
3918    subl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
3919    FETCH_INST_OPCODE 2 %edx
3920    ADVANCE_PC 2
3921    SET_VREG %eax rINST
3922    GOTO_NEXT_R %edx
3923
3924
3925/* ------------------------------ */
3926    .balign 64
3927.L_OP_MUL_INT: /* 0x92 */
3928/* File: x86/OP_MUL_INT.S */
3929    /*
3930     * 32-bit binary multiplication.
3931     */
3932    /* mul vAA, vBB, vCC */
3933    movzbl   2(rPC),%eax            # eax<- BB
3934    movzbl   3(rPC),%ecx            # ecx<- CC
3935    GET_VREG_R %eax %eax            # eax<- vBB
3936    imull    (rFP,%ecx,4),%eax      # trashes edx
3937    FETCH_INST_OPCODE 2 %edx
3938    ADVANCE_PC 2
3939    SET_VREG %eax rINST
3940    GOTO_NEXT_R %edx
3941
3942/* ------------------------------ */
3943    .balign 64
3944.L_OP_DIV_INT: /* 0x93 */
3945/* File: x86/OP_DIV_INT.S */
3946/* File: x86/bindiv.S */
3947
3948    /*
3949     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
3950     * op1=-1.
3951     */
3952    /* binop vAA, vBB, vCC */
3953    movzbl   2(rPC),%eax            # eax<- BB
3954    movzbl   3(rPC),%ecx            # ecx<- CC
3955    GET_VREG_R %eax %eax            # eax<- vBB
3956    GET_VREG_R %ecx %ecx            # eax<- vBB
3957    cmpl     $0,%ecx
3958    je       common_errDivideByZero
3959    cmpl     $-1,%ecx
3960    jne      .LOP_DIV_INT_continue_div
3961    cmpl     $0x80000000,%eax
3962    jne      .LOP_DIV_INT_continue_div
3963    movl     $0x80000000,%eax
3964    jmp      .LOP_DIV_INT_finish_div
3965
3966
3967
3968/* ------------------------------ */
3969    .balign 64
3970.L_OP_REM_INT: /* 0x94 */
3971/* File: x86/OP_REM_INT.S */
3972/* File: x86/bindiv.S */
3973
3974    /*
3975     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
3976     * op1=-1.
3977     */
3978    /* binop vAA, vBB, vCC */
3979    movzbl   2(rPC),%eax            # eax<- BB
3980    movzbl   3(rPC),%ecx            # ecx<- CC
3981    GET_VREG_R %eax %eax            # eax<- vBB
3982    GET_VREG_R %ecx %ecx            # eax<- vBB
3983    cmpl     $0,%ecx
3984    je       common_errDivideByZero
3985    cmpl     $-1,%ecx
3986    jne      .LOP_REM_INT_continue_div
3987    cmpl     $0x80000000,%eax
3988    jne      .LOP_REM_INT_continue_div
3989    movl     $0,%edx
3990    jmp      .LOP_REM_INT_finish_div
3991
3992
3993
3994/* ------------------------------ */
3995    .balign 64
3996.L_OP_AND_INT: /* 0x95 */
3997/* File: x86/OP_AND_INT.S */
3998/* File: x86/binop.S */
3999    /*
4000     * Generic 32-bit binary operation.  Provide an "instr" line that
4001     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
4002     * This could be an x86 instruction or a function call.  (If the result
4003     * comes back in a register other than eax, you can override "result".)
4004     *
4005     * For: add-int, sub-int, and-int, or-int,
4006     *      xor-int, shl-int, shr-int, ushr-int
4007     */
4008    /* binop vAA, vBB, vCC */
4009    movzbl   2(rPC),%eax   # eax<- BB
4010    movzbl   3(rPC),%ecx   # ecx<- CC
4011    GET_VREG_R %eax %eax   # eax<- vBB
4012    andl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
4013    FETCH_INST_OPCODE 2 %edx
4014    ADVANCE_PC 2
4015    SET_VREG %eax rINST
4016    GOTO_NEXT_R %edx
4017
4018
4019/* ------------------------------ */
4020    .balign 64
4021.L_OP_OR_INT: /* 0x96 */
4022/* File: x86/OP_OR_INT.S */
4023/* File: x86/binop.S */
4024    /*
4025     * Generic 32-bit binary operation.  Provide an "instr" line that
4026     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
4027     * This could be an x86 instruction or a function call.  (If the result
4028     * comes back in a register other than eax, you can override "result".)
4029     *
4030     * For: add-int, sub-int, and-int, or-int,
4031     *      xor-int, shl-int, shr-int, ushr-int
4032     */
4033    /* binop vAA, vBB, vCC */
4034    movzbl   2(rPC),%eax   # eax<- BB
4035    movzbl   3(rPC),%ecx   # ecx<- CC
4036    GET_VREG_R %eax %eax   # eax<- vBB
4037    orl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
4038    FETCH_INST_OPCODE 2 %edx
4039    ADVANCE_PC 2
4040    SET_VREG %eax rINST
4041    GOTO_NEXT_R %edx
4042
4043
4044/* ------------------------------ */
4045    .balign 64
4046.L_OP_XOR_INT: /* 0x97 */
4047/* File: x86/OP_XOR_INT.S */
4048/* File: x86/binop.S */
4049    /*
4050     * Generic 32-bit binary operation.  Provide an "instr" line that
4051     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
4052     * This could be an x86 instruction or a function call.  (If the result
4053     * comes back in a register other than eax, you can override "result".)
4054     *
4055     * For: add-int, sub-int, and-int, or-int,
4056     *      xor-int, shl-int, shr-int, ushr-int
4057     */
4058    /* binop vAA, vBB, vCC */
4059    movzbl   2(rPC),%eax   # eax<- BB
4060    movzbl   3(rPC),%ecx   # ecx<- CC
4061    GET_VREG_R %eax %eax   # eax<- vBB
4062    xorl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
4063    FETCH_INST_OPCODE 2 %edx
4064    ADVANCE_PC 2
4065    SET_VREG %eax rINST
4066    GOTO_NEXT_R %edx
4067
4068
4069/* ------------------------------ */
4070    .balign 64
4071.L_OP_SHL_INT: /* 0x98 */
4072/* File: x86/OP_SHL_INT.S */
4073/* File: x86/binop1.S */
4074    /*
4075     * Generic 32-bit binary operation in which both operands loaded to
4076     * registers (op0 in eax, op1 in ecx).
4077     */
4078    /* binop vAA, vBB, vCC */
4079    movzbl   2(rPC),%eax            # eax<- BB
4080    movzbl   3(rPC),%ecx            # ecx<- CC
4081    GET_VREG_R %eax %eax            # eax<- vBB
4082    GET_VREG_R %ecx %ecx            # eax<- vBB
4083    sall    %cl,%eax                          # ex: addl    %ecx,%eax
4084    FETCH_INST_OPCODE 2 %edx
4085    ADVANCE_PC 2
4086    SET_VREG %eax rINST
4087    GOTO_NEXT_R %edx
4088
4089
4090/* ------------------------------ */
4091    .balign 64
4092.L_OP_SHR_INT: /* 0x99 */
4093/* File: x86/OP_SHR_INT.S */
4094/* File: x86/binop1.S */
4095    /*
4096     * Generic 32-bit binary operation in which both operands loaded to
4097     * registers (op0 in eax, op1 in ecx).
4098     */
4099    /* binop vAA, vBB, vCC */
4100    movzbl   2(rPC),%eax            # eax<- BB
4101    movzbl   3(rPC),%ecx            # ecx<- CC
4102    GET_VREG_R %eax %eax            # eax<- vBB
4103    GET_VREG_R %ecx %ecx            # eax<- vBB
4104    sarl    %cl,%eax                          # ex: addl    %ecx,%eax
4105    FETCH_INST_OPCODE 2 %edx
4106    ADVANCE_PC 2
4107    SET_VREG %eax rINST
4108    GOTO_NEXT_R %edx
4109
4110
4111/* ------------------------------ */
4112    .balign 64
4113.L_OP_USHR_INT: /* 0x9a */
4114/* File: x86/OP_USHR_INT.S */
4115/* File: x86/binop1.S */
4116    /*
4117     * Generic 32-bit binary operation in which both operands loaded to
4118     * registers (op0 in eax, op1 in ecx).
4119     */
4120    /* binop vAA, vBB, vCC */
4121    movzbl   2(rPC),%eax            # eax<- BB
4122    movzbl   3(rPC),%ecx            # ecx<- CC
4123    GET_VREG_R %eax %eax            # eax<- vBB
4124    GET_VREG_R %ecx %ecx            # eax<- vBB
4125    shrl    %cl,%eax                          # ex: addl    %ecx,%eax
4126    FETCH_INST_OPCODE 2 %edx
4127    ADVANCE_PC 2
4128    SET_VREG %eax rINST
4129    GOTO_NEXT_R %edx
4130
4131
4132/* ------------------------------ */
4133    .balign 64
4134.L_OP_ADD_LONG: /* 0x9b */
4135/* File: x86/OP_ADD_LONG.S */
4136/* File: x86/binopWide.S */
4137    /*
4138     * Generic 64-bit binary operation.
4139     */
4140    /* binop vAA, vBB, vCC */
4141
4142    movzbl    2(rPC),%eax               # eax<- BB
4143    movzbl    3(rPC),%ecx               # ecx<- CC
4144    GET_VREG_WORD %edx %eax 0           # edx<- v[BB+0]
4145    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
4146    addl (rFP,%ecx,4),%edx         # ex: addl   (rFP,%ecx,4),%edx
4147    adcl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
4148    SET_VREG_WORD %edx rINST 0          # v[AA+0] <- edx
4149    FETCH_INST_OPCODE 2 %edx
4150    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
4151    ADVANCE_PC 2
4152    GOTO_NEXT_R %edx
4153
4154
4155/* ------------------------------ */
4156    .balign 64
4157.L_OP_SUB_LONG: /* 0x9c */
4158/* File: x86/OP_SUB_LONG.S */
4159/* File: x86/binopWide.S */
4160    /*
4161     * Generic 64-bit binary operation.
4162     */
4163    /* binop vAA, vBB, vCC */
4164
4165    movzbl    2(rPC),%eax               # eax<- BB
4166    movzbl    3(rPC),%ecx               # ecx<- CC
4167    GET_VREG_WORD %edx %eax 0           # edx<- v[BB+0]
4168    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
4169    subl (rFP,%ecx,4),%edx         # ex: addl   (rFP,%ecx,4),%edx
4170    sbbl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
4171    SET_VREG_WORD %edx rINST 0          # v[AA+0] <- edx
4172    FETCH_INST_OPCODE 2 %edx
4173    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
4174    ADVANCE_PC 2
4175    GOTO_NEXT_R %edx
4176
4177
4178/* ------------------------------ */
4179    .balign 64
4180.L_OP_MUL_LONG: /* 0x9d */
4181/* File: x86/OP_MUL_LONG.S */
4182    /*
4183     * Signed 64-bit integer multiply.
4184     *
4185     * We could definately use more free registers for
4186     * this code.   We spill rINSTw (ebx),
4187     * giving us eax, ebc, ecx and edx as computational
4188     * temps.  On top of that, we'll spill edi (rFP)
4189     * for use as the vB pointer and esi (rPC) for use
4190     * as the vC pointer.  Yuck.
4191     */
4192    /* mul-long vAA, vBB, vCC */
4193    movzbl    2(rPC),%eax              # eax<- B
4194    movzbl    3(rPC),%ecx              # ecx<- C
4195    SPILL_TMP2(%esi)                   # save Dalvik PC
4196    SPILL(rFP)
4197    SPILL(rINST)
4198    leal      (rFP,%eax,4),%esi        # esi<- &v[B]
4199    leal      (rFP,%ecx,4),rFP         # rFP<- &v[C]
4200    movl      4(%esi),%ecx             # ecx<- Bmsw
4201    imull     (rFP),%ecx               # ecx<- (Bmsw*Clsw)
4202    movl      4(rFP),%eax              # eax<- Cmsw
4203    imull     (%esi),%eax              # eax<- (Cmsw*Blsw)
4204    addl      %eax,%ecx                # ecx<- (Bmsw*Clsw)+(Cmsw*Blsw)
4205    movl      (rFP),%eax               # eax<- Clsw
4206    mull      (%esi)                   # eax<- (Clsw*Alsw)
4207    UNSPILL(rINST)
4208    UNSPILL(rFP)
4209    jmp       .LOP_MUL_LONG_continue
4210
4211/* ------------------------------ */
4212    .balign 64
4213.L_OP_DIV_LONG: /* 0x9e */
4214/* File: x86/OP_DIV_LONG.S */
4215    /* div vAA, vBB, vCC */
4216    movzbl    3(rPC),%eax              # eax<- CC
4217    movzbl    2(rPC),%ecx              # ecx<- BB
4218    GET_VREG_WORD %edx %eax 0
4219    GET_VREG_WORD %eax %eax 1
4220    movl     %edx,OUT_ARG2(%esp)
4221    testl    %eax,%eax
4222    je       .LOP_DIV_LONG_check_zero
4223    cmpl     $-1,%eax
4224    je       .LOP_DIV_LONG_check_neg1
4225.LOP_DIV_LONG_notSpecial:
4226    GET_VREG_WORD %edx %ecx 0
4227    GET_VREG_WORD %ecx %ecx 1
4228.LOP_DIV_LONG_notSpecial1:
4229    movl     %eax,OUT_ARG3(%esp)
4230    movl     %edx,OUT_ARG0(%esp)
4231    movl     %ecx,OUT_ARG1(%esp)
4232    jmp      .LOP_DIV_LONG_continue
4233
4234/* ------------------------------ */
4235    .balign 64
4236.L_OP_REM_LONG: /* 0x9f */
4237/* File: x86/OP_REM_LONG.S */
4238/* File: x86/OP_DIV_LONG.S */
4239    /* div vAA, vBB, vCC */
4240    movzbl    3(rPC),%eax              # eax<- CC
4241    movzbl    2(rPC),%ecx              # ecx<- BB
4242    GET_VREG_WORD %edx %eax 0
4243    GET_VREG_WORD %eax %eax 1
4244    movl     %edx,OUT_ARG2(%esp)
4245    testl    %eax,%eax
4246    je       .LOP_REM_LONG_check_zero
4247    cmpl     $-1,%eax
4248    je       .LOP_REM_LONG_check_neg1
4249.LOP_REM_LONG_notSpecial:
4250    GET_VREG_WORD %edx %ecx 0
4251    GET_VREG_WORD %ecx %ecx 1
4252.LOP_REM_LONG_notSpecial1:
4253    movl     %eax,OUT_ARG3(%esp)
4254    movl     %edx,OUT_ARG0(%esp)
4255    movl     %ecx,OUT_ARG1(%esp)
4256    jmp      .LOP_REM_LONG_continue
4257
4258
4259/* ------------------------------ */
4260    .balign 64
4261.L_OP_AND_LONG: /* 0xa0 */
4262/* File: x86/OP_AND_LONG.S */
4263/* File: x86/binopWide.S */
4264    /*
4265     * Generic 64-bit binary operation.
4266     */
4267    /* binop vAA, vBB, vCC */
4268
4269    movzbl    2(rPC),%eax               # eax<- BB
4270    movzbl    3(rPC),%ecx               # ecx<- CC
4271    GET_VREG_WORD %edx %eax 0           # edx<- v[BB+0]
4272    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
4273    andl (rFP,%ecx,4),%edx         # ex: addl   (rFP,%ecx,4),%edx
4274    andl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
4275    SET_VREG_WORD %edx rINST 0          # v[AA+0] <- edx
4276    FETCH_INST_OPCODE 2 %edx
4277    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
4278    ADVANCE_PC 2
4279    GOTO_NEXT_R %edx
4280
4281
4282/* ------------------------------ */
4283    .balign 64
4284.L_OP_OR_LONG: /* 0xa1 */
4285/* File: x86/OP_OR_LONG.S */
4286/* File: x86/binopWide.S */
4287    /*
4288     * Generic 64-bit binary operation.
4289     */
4290    /* binop vAA, vBB, vCC */
4291
4292    movzbl    2(rPC),%eax               # eax<- BB
4293    movzbl    3(rPC),%ecx               # ecx<- CC
4294    GET_VREG_WORD %edx %eax 0           # edx<- v[BB+0]
4295    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
4296    orl (rFP,%ecx,4),%edx         # ex: addl   (rFP,%ecx,4),%edx
4297    orl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
4298    SET_VREG_WORD %edx rINST 0          # v[AA+0] <- edx
4299    FETCH_INST_OPCODE 2 %edx
4300    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
4301    ADVANCE_PC 2
4302    GOTO_NEXT_R %edx
4303
4304
4305/* ------------------------------ */
4306    .balign 64
4307.L_OP_XOR_LONG: /* 0xa2 */
4308/* File: x86/OP_XOR_LONG.S */
4309/* File: x86/binopWide.S */
4310    /*
4311     * Generic 64-bit binary operation.
4312     */
4313    /* binop vAA, vBB, vCC */
4314
4315    movzbl    2(rPC),%eax               # eax<- BB
4316    movzbl    3(rPC),%ecx               # ecx<- CC
4317    GET_VREG_WORD %edx %eax 0           # edx<- v[BB+0]
4318    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
4319    xorl (rFP,%ecx,4),%edx         # ex: addl   (rFP,%ecx,4),%edx
4320    xorl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
4321    SET_VREG_WORD %edx rINST 0          # v[AA+0] <- edx
4322    FETCH_INST_OPCODE 2 %edx
4323    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
4324    ADVANCE_PC 2
4325    GOTO_NEXT_R %edx
4326
4327
4328/* ------------------------------ */
4329    .balign 64
4330.L_OP_SHL_LONG: /* 0xa3 */
4331/* File: x86/OP_SHL_LONG.S */
4332    /*
4333     * Long integer shift.  This is different from the generic 32/64-bit
4334     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4335     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4336     * 6 bits of the shift distance.  x86 shifts automatically mask off
4337     * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
4338     * case specially.
4339     */
4340    /* shl-long vAA, vBB, vCC */
4341    /* ecx gets shift count */
4342    /* Need to spill edx */
4343    /* rINSTw gets AA */
4344    movzbl    2(rPC),%eax               # eax<- BB
4345    movzbl    3(rPC),%ecx               # ecx<- CC
4346    GET_VREG_WORD %edx %eax 1           # ecx<- v[BB+1]
4347    GET_VREG_R   %ecx %ecx              # ecx<- vCC
4348    GET_VREG_WORD %eax %eax 0           # eax<- v[BB+0]
4349    shldl     %eax,%edx
4350    sall      %cl,%eax
4351    testb     $32,%cl
4352    je        2f
4353    movl      %eax,%edx
4354    xorl      %eax,%eax
43552:
4356    SET_VREG_WORD %edx rINST 1          # v[AA+1]<- %edx
4357    FETCH_INST_OPCODE 2 %edx
4358    jmp       .LOP_SHL_LONG_finish
4359
4360/* ------------------------------ */
4361    .balign 64
4362.L_OP_SHR_LONG: /* 0xa4 */
4363/* File: x86/OP_SHR_LONG.S */
4364    /*
4365     * Long integer shift.  This is different from the generic 32/64-bit
4366     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4367     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4368     * 6 bits of the shift distance.  x86 shifts automatically mask off
4369     * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
4370     * case specially.
4371     */
4372    /* shr-long vAA, vBB, vCC */
4373    /* ecx gets shift count */
4374    /* Need to spill edx */
4375    /* rINSTw gets AA */
4376    movzbl    2(rPC),%eax               # eax<- BB
4377    movzbl    3(rPC),%ecx               # ecx<- CC
4378    GET_VREG_WORD %edx %eax 1           # edx<- v[BB+1]
4379    GET_VREG_R   %ecx %ecx              # ecx<- vCC
4380    GET_VREG_WORD %eax %eax 0           # eax<- v[BB+0]
4381    shrdl     %edx,%eax
4382    sarl      %cl,%edx
4383    testb     $32,%cl
4384    je        2f
4385    movl      %edx,%eax
4386    sarl      $31,%edx
43872:
4388    SET_VREG_WORD %edx rINST 1          # v[AA+1]<- edx
4389    FETCH_INST_OPCODE 2 %edx
4390    jmp       .LOP_SHR_LONG_finish
4391
4392/* ------------------------------ */
4393    .balign 64
4394.L_OP_USHR_LONG: /* 0xa5 */
4395/* File: x86/OP_USHR_LONG.S */
4396    /*
4397     * Long integer shift.  This is different from the generic 32/64-bit
4398     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4399     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4400     * 6 bits of the shift distance.  x86 shifts automatically mask off
4401     * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
4402     * case specially.
4403     */
4404    /* shr-long vAA, vBB, vCC */
4405    /* ecx gets shift count */
4406    /* Need to spill edx */
4407    /* rINSTw gets AA */
4408    movzbl    2(rPC),%eax               # eax<- BB
4409    movzbl    3(rPC),%ecx               # ecx<- CC
4410    GET_VREG_WORD %edx %eax 1           # edx<- v[BB+1]
4411    GET_VREG_R  %ecx %ecx               # ecx<- vCC
4412    GET_VREG_WORD %eax %eax 0           # eax<- v[BB+0]
4413    shrdl     %edx,%eax
4414    shrl      %cl,%edx
4415    testb     $32,%cl
4416    je        2f
4417    movl      %edx,%eax
4418    xorl      %edx,%edx
44192:
4420    SET_VREG_WORD %edx rINST 1          # v[AA+1]<- edx
4421    FETCH_INST_OPCODE 2 %edx
4422    jmp       .LOP_USHR_LONG_finish
4423
4424/* ------------------------------ */
4425    .balign 64
4426.L_OP_ADD_FLOAT: /* 0xa6 */
4427/* File: x86/OP_ADD_FLOAT.S */
4428/* File: x86/binflop.S */
4429    /*
4430     * Generic 32-bit binary float operation.
4431     *
4432     * For: add-fp, sub-fp, mul-fp, div-fp
4433     */
4434    /* binop vAA, vBB, vCC */
4435    movzbl   2(rPC),%eax          # eax<- CC
4436    movzbl   3(rPC),%ecx          # ecx<- BB
4437    flds    (rFP,%eax,4)         # vCC to fp stack
4438    fadds   (rFP,%ecx,4)         # ex: faddp
4439    FETCH_INST_OPCODE 2 %edx
4440    ADVANCE_PC 2
4441    fstps   (rFP,rINST,4)         # %st to vAA
4442    GOTO_NEXT_R %edx
4443
4444
4445/* ------------------------------ */
4446    .balign 64
4447.L_OP_SUB_FLOAT: /* 0xa7 */
4448/* File: x86/OP_SUB_FLOAT.S */
4449/* File: x86/binflop.S */
4450    /*
4451     * Generic 32-bit binary float operation.
4452     *
4453     * For: add-fp, sub-fp, mul-fp, div-fp
4454     */
4455    /* binop vAA, vBB, vCC */
4456    movzbl   2(rPC),%eax          # eax<- CC
4457    movzbl   3(rPC),%ecx          # ecx<- BB
4458    flds    (rFP,%eax,4)         # vCC to fp stack
4459    fsubs   (rFP,%ecx,4)         # ex: faddp
4460    FETCH_INST_OPCODE 2 %edx
4461    ADVANCE_PC 2
4462    fstps   (rFP,rINST,4)         # %st to vAA
4463    GOTO_NEXT_R %edx
4464
4465
4466/* ------------------------------ */
4467    .balign 64
4468.L_OP_MUL_FLOAT: /* 0xa8 */
4469/* File: x86/OP_MUL_FLOAT.S */
4470/* File: x86/binflop.S */
4471    /*
4472     * Generic 32-bit binary float operation.
4473     *
4474     * For: add-fp, sub-fp, mul-fp, div-fp
4475     */
4476    /* binop vAA, vBB, vCC */
4477    movzbl   2(rPC),%eax          # eax<- CC
4478    movzbl   3(rPC),%ecx          # ecx<- BB
4479    flds    (rFP,%eax,4)         # vCC to fp stack
4480    fmuls   (rFP,%ecx,4)         # ex: faddp
4481    FETCH_INST_OPCODE 2 %edx
4482    ADVANCE_PC 2
4483    fstps   (rFP,rINST,4)         # %st to vAA
4484    GOTO_NEXT_R %edx
4485
4486
4487/* ------------------------------ */
4488    .balign 64
4489.L_OP_DIV_FLOAT: /* 0xa9 */
4490/* File: x86/OP_DIV_FLOAT.S */
4491/* File: x86/binflop.S */
4492    /*
4493     * Generic 32-bit binary float operation.
4494     *
4495     * For: add-fp, sub-fp, mul-fp, div-fp
4496     */
4497    /* binop vAA, vBB, vCC */
4498    movzbl   2(rPC),%eax          # eax<- CC
4499    movzbl   3(rPC),%ecx          # ecx<- BB
4500    flds    (rFP,%eax,4)         # vCC to fp stack
4501    fdivs   (rFP,%ecx,4)         # ex: faddp
4502    FETCH_INST_OPCODE 2 %edx
4503    ADVANCE_PC 2
4504    fstps   (rFP,rINST,4)         # %st to vAA
4505    GOTO_NEXT_R %edx
4506
4507
4508/* ------------------------------ */
4509    .balign 64
4510.L_OP_REM_FLOAT: /* 0xaa */
4511/* File: x86/OP_REM_FLOAT.S */
4512    /* rem_float vAA, vBB, vCC */
4513    movzbl   3(rPC),%ecx            # ecx<- BB
4514    movzbl   2(rPC),%eax            # eax<- CC
4515    flds     (rFP,%ecx,4)           # vCC to fp stack
4516    flds     (rFP,%eax,4)           # vCC to fp stack
4517    movzbl   rINSTbl,%ecx           # ecx<- AA
4518    FETCH_INST_OPCODE 2 %edx
45191:
4520    fprem
4521    fstsw     %ax
4522    sahf
4523    jp        1b
4524    fstp      %st(1)
4525    ADVANCE_PC 2
4526    fstps    (rFP,%ecx,4)           # %st to vAA
4527    GOTO_NEXT_R %edx
4528
4529/* ------------------------------ */
4530    .balign 64
4531.L_OP_ADD_DOUBLE: /* 0xab */
4532/* File: x86/OP_ADD_DOUBLE.S */
4533/* File: x86/binflop.S */
4534    /*
4535     * Generic 32-bit binary float operation.
4536     *
4537     * For: add-fp, sub-fp, mul-fp, div-fp
4538     */
4539    /* binop vAA, vBB, vCC */
4540    movzbl   2(rPC),%eax          # eax<- CC
4541    movzbl   3(rPC),%ecx          # ecx<- BB
4542    fldl    (rFP,%eax,4)         # vCC to fp stack
4543    faddl   (rFP,%ecx,4)         # ex: faddp
4544    FETCH_INST_OPCODE 2 %edx
4545    ADVANCE_PC 2
4546    fstpl   (rFP,rINST,4)         # %st to vAA
4547    GOTO_NEXT_R %edx
4548
4549
4550/* ------------------------------ */
4551    .balign 64
4552.L_OP_SUB_DOUBLE: /* 0xac */
4553/* File: x86/OP_SUB_DOUBLE.S */
4554/* File: x86/binflop.S */
4555    /*
4556     * Generic 32-bit binary float operation.
4557     *
4558     * For: add-fp, sub-fp, mul-fp, div-fp
4559     */
4560    /* binop vAA, vBB, vCC */
4561    movzbl   2(rPC),%eax          # eax<- CC
4562    movzbl   3(rPC),%ecx          # ecx<- BB
4563    fldl    (rFP,%eax,4)         # vCC to fp stack
4564    fsubl   (rFP,%ecx,4)         # ex: faddp
4565    FETCH_INST_OPCODE 2 %edx
4566    ADVANCE_PC 2
4567    fstpl   (rFP,rINST,4)         # %st to vAA
4568    GOTO_NEXT_R %edx
4569
4570
4571/* ------------------------------ */
4572    .balign 64
4573.L_OP_MUL_DOUBLE: /* 0xad */
4574/* File: x86/OP_MUL_DOUBLE.S */
4575/* File: x86/binflop.S */
4576    /*
4577     * Generic 32-bit binary float operation.
4578     *
4579     * For: add-fp, sub-fp, mul-fp, div-fp
4580     */
4581    /* binop vAA, vBB, vCC */
4582    movzbl   2(rPC),%eax          # eax<- CC
4583    movzbl   3(rPC),%ecx          # ecx<- BB
4584    fldl    (rFP,%eax,4)         # vCC to fp stack
4585    fmull   (rFP,%ecx,4)         # ex: faddp
4586    FETCH_INST_OPCODE 2 %edx
4587    ADVANCE_PC 2
4588    fstpl   (rFP,rINST,4)         # %st to vAA
4589    GOTO_NEXT_R %edx
4590
4591
4592/* ------------------------------ */
4593    .balign 64
4594.L_OP_DIV_DOUBLE: /* 0xae */
4595/* File: x86/OP_DIV_DOUBLE.S */
4596/* File: x86/binflop.S */
4597    /*
4598     * Generic 32-bit binary float operation.
4599     *
4600     * For: add-fp, sub-fp, mul-fp, div-fp
4601     */
4602    /* binop vAA, vBB, vCC */
4603    movzbl   2(rPC),%eax          # eax<- CC
4604    movzbl   3(rPC),%ecx          # ecx<- BB
4605    fldl    (rFP,%eax,4)         # vCC to fp stack
4606    fdivl   (rFP,%ecx,4)         # ex: faddp
4607    FETCH_INST_OPCODE 2 %edx
4608    ADVANCE_PC 2
4609    fstpl   (rFP,rINST,4)         # %st to vAA
4610    GOTO_NEXT_R %edx
4611
4612
4613/* ------------------------------ */
4614    .balign 64
4615.L_OP_REM_DOUBLE: /* 0xaf */
4616/* File: x86/OP_REM_DOUBLE.S */
4617    /* rem_float vAA, vBB, vCC */
4618    movzbl   3(rPC),%ecx            # ecx<- BB
4619    movzbl   2(rPC),%eax            # eax<- CC
4620    fldl     (rFP,%ecx,4)           # vCC to fp stack
4621    fldl     (rFP,%eax,4)           # vCC to fp stack
4622    movzbl   rINSTbl,%ecx           # ecx<- AA
4623    FETCH_INST_OPCODE 2 %edx
46241:
4625    fprem
4626    fstsw     %ax
4627    sahf
4628    jp        1b
4629    fstp      %st(1)
4630    ADVANCE_PC 2
4631    fstpl    (rFP,%ecx,4)           # %st to vAA
4632    GOTO_NEXT_R %edx
4633
4634/* ------------------------------ */
4635    .balign 64
4636.L_OP_ADD_INT_2ADDR: /* 0xb0 */
4637/* File: x86/OP_ADD_INT_2ADDR.S */
4638/* File: x86/binop2addr.S */
4639    /*
4640     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
4641     * that specifies an instruction that performs "result = r0 op r1".
4642     * This could be an ARM instruction or a function call.  (If the result
4643     * comes back in a register other than r0, you can override "result".)
4644     *
4645     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4646     * vCC (r1).  Useful for integer division and modulus.
4647     *
4648     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
4649     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
4650     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
4651     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
4652     */
4653    /* binop/2addr vA, vB */
4654    movzx   rINSTbl,%ecx               # ecx<- A+
4655    sarl    $4,rINST                 # rINST<- B
4656    GET_VREG_R %eax rINST              # eax<- vB
4657    FETCH_INST_OPCODE 1 %edx
4658    andb    $0xf,%cl                  # ecx<- A
4659    addl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
4660    ADVANCE_PC 1
4661    GOTO_NEXT_R %edx
4662
4663
4664/* ------------------------------ */
4665    .balign 64
4666.L_OP_SUB_INT_2ADDR: /* 0xb1 */
4667/* File: x86/OP_SUB_INT_2ADDR.S */
4668/* File: x86/binop2addr.S */
4669    /*
4670     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
4671     * that specifies an instruction that performs "result = r0 op r1".
4672     * This could be an ARM instruction or a function call.  (If the result
4673     * comes back in a register other than r0, you can override "result".)
4674     *
4675     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4676     * vCC (r1).  Useful for integer division and modulus.
4677     *
4678     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
4679     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
4680     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
4681     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
4682     */
4683    /* binop/2addr vA, vB */
4684    movzx   rINSTbl,%ecx               # ecx<- A+
4685    sarl    $4,rINST                 # rINST<- B
4686    GET_VREG_R %eax rINST              # eax<- vB
4687    FETCH_INST_OPCODE 1 %edx
4688    andb    $0xf,%cl                  # ecx<- A
4689    subl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
4690    ADVANCE_PC 1
4691    GOTO_NEXT_R %edx
4692
4693
4694/* ------------------------------ */
4695    .balign 64
4696.L_OP_MUL_INT_2ADDR: /* 0xb2 */
4697/* File: x86/OP_MUL_INT_2ADDR.S */
4698    /* mul vA, vB */
4699    movzx   rINSTbl,%ecx               # ecx<- A+
4700    sarl    $4,rINST                 # rINST<- B
4701    GET_VREG_R %eax rINST              # eax<- vB
4702    andb    $0xf,%cl                  # ecx<- A
4703    imull   (rFP,%ecx,4),%eax
4704    FETCH_INST_OPCODE 1 %edx
4705    SET_VREG %eax %ecx
4706    ADVANCE_PC 1
4707    GOTO_NEXT_R %edx
4708
4709/* ------------------------------ */
4710    .balign 64
4711.L_OP_DIV_INT_2ADDR: /* 0xb3 */
4712/* File: x86/OP_DIV_INT_2ADDR.S */
4713/* File: x86/bindiv2addr.S */
4714    /*
4715     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
4716     * op1=-1.
4717     */
4718    /* div/rem/2addr vA, vB */
4719    movzx    rINSTbl,%ecx          # eax<- BA
4720    sarl     $4,%ecx              # ecx<- B
4721    GET_VREG_R %ecx %ecx           # eax<- vBB
4722    andb     $0xf,rINSTbl         # rINST<- A
4723    GET_VREG_R %eax rINST          # eax<- vBB
4724    cmpl     $0,%ecx
4725    je       common_errDivideByZero
4726    cmpl     $-1,%ecx
4727    jne      .LOP_DIV_INT_2ADDR_continue_div2addr
4728    cmpl     $0x80000000,%eax
4729    jne      .LOP_DIV_INT_2ADDR_continue_div2addr
4730    movl     $0x80000000,%eax
4731    jmp      .LOP_DIV_INT_2ADDR_finish_div2addr
4732
4733
4734
4735/* ------------------------------ */
4736    .balign 64
4737.L_OP_REM_INT_2ADDR: /* 0xb4 */
4738/* File: x86/OP_REM_INT_2ADDR.S */
4739/* File: x86/bindiv2addr.S */
4740    /*
4741     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
4742     * op1=-1.
4743     */
4744    /* div/rem/2addr vA, vB */
4745    movzx    rINSTbl,%ecx          # eax<- BA
4746    sarl     $4,%ecx              # ecx<- B
4747    GET_VREG_R %ecx %ecx           # eax<- vBB
4748    andb     $0xf,rINSTbl         # rINST<- A
4749    GET_VREG_R %eax rINST          # eax<- vBB
4750    cmpl     $0,%ecx
4751    je       common_errDivideByZero
4752    cmpl     $-1,%ecx
4753    jne      .LOP_REM_INT_2ADDR_continue_div2addr
4754    cmpl     $0x80000000,%eax
4755    jne      .LOP_REM_INT_2ADDR_continue_div2addr
4756    movl     $0,%edx
4757    jmp      .LOP_REM_INT_2ADDR_finish_div2addr
4758
4759
4760
4761/* ------------------------------ */
4762    .balign 64
4763.L_OP_AND_INT_2ADDR: /* 0xb5 */
4764/* File: x86/OP_AND_INT_2ADDR.S */
4765/* File: x86/binop2addr.S */
4766    /*
4767     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
4768     * that specifies an instruction that performs "result = r0 op r1".
4769     * This could be an ARM instruction or a function call.  (If the result
4770     * comes back in a register other than r0, you can override "result".)
4771     *
4772     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4773     * vCC (r1).  Useful for integer division and modulus.
4774     *
4775     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
4776     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
4777     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
4778     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
4779     */
4780    /* binop/2addr vA, vB */
4781    movzx   rINSTbl,%ecx               # ecx<- A+
4782    sarl    $4,rINST                 # rINST<- B
4783    GET_VREG_R %eax rINST              # eax<- vB
4784    FETCH_INST_OPCODE 1 %edx
4785    andb    $0xf,%cl                  # ecx<- A
4786    andl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
4787    ADVANCE_PC 1
4788    GOTO_NEXT_R %edx
4789
4790
4791/* ------------------------------ */
4792    .balign 64
4793.L_OP_OR_INT_2ADDR: /* 0xb6 */
4794/* File: x86/OP_OR_INT_2ADDR.S */
4795/* File: x86/binop2addr.S */
4796    /*
4797     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
4798     * that specifies an instruction that performs "result = r0 op r1".
4799     * This could be an ARM instruction or a function call.  (If the result
4800     * comes back in a register other than r0, you can override "result".)
4801     *
4802     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4803     * vCC (r1).  Useful for integer division and modulus.
4804     *
4805     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
4806     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
4807     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
4808     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
4809     */
4810    /* binop/2addr vA, vB */
4811    movzx   rINSTbl,%ecx               # ecx<- A+
4812    sarl    $4,rINST                 # rINST<- B
4813    GET_VREG_R %eax rINST              # eax<- vB
4814    FETCH_INST_OPCODE 1 %edx
4815    andb    $0xf,%cl                  # ecx<- A
4816    orl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
4817    ADVANCE_PC 1
4818    GOTO_NEXT_R %edx
4819
4820
4821/* ------------------------------ */
4822    .balign 64
4823.L_OP_XOR_INT_2ADDR: /* 0xb7 */
4824/* File: x86/OP_XOR_INT_2ADDR.S */
4825/* File: x86/binop2addr.S */
4826    /*
4827     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
4828     * that specifies an instruction that performs "result = r0 op r1".
4829     * This could be an ARM instruction or a function call.  (If the result
4830     * comes back in a register other than r0, you can override "result".)
4831     *
4832     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4833     * vCC (r1).  Useful for integer division and modulus.
4834     *
4835     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
4836     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
4837     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
4838     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
4839     */
4840    /* binop/2addr vA, vB */
4841    movzx   rINSTbl,%ecx               # ecx<- A+
4842    sarl    $4,rINST                 # rINST<- B
4843    GET_VREG_R %eax rINST              # eax<- vB
4844    FETCH_INST_OPCODE 1 %edx
4845    andb    $0xf,%cl                  # ecx<- A
4846    xorl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
4847    ADVANCE_PC 1
4848    GOTO_NEXT_R %edx
4849
4850
4851/* ------------------------------ */
4852    .balign 64
4853.L_OP_SHL_INT_2ADDR: /* 0xb8 */
4854/* File: x86/OP_SHL_INT_2ADDR.S */
4855/* File: x86/shop2addr.S */
4856    /*
4857     * Generic 32-bit "shift/2addr" operation.
4858     */
4859    /* shift/2addr vA, vB */
4860    movzx    rINSTbl,%ecx           # eax<- BA
4861    sarl     $4,%ecx               # ecx<- B
4862    GET_VREG_R %ecx %ecx            # eax<- vBB
4863    andb     $0xf,rINSTbl          # rINST<- A
4864    GET_VREG_R %eax rINST           # eax<- vAA
4865    sall    %cl,%eax                          # ex: sarl %cl,%eax
4866    FETCH_INST_OPCODE 1 %edx
4867    SET_VREG %eax rINST
4868    ADVANCE_PC 1
4869    GOTO_NEXT_R %edx
4870
4871
4872/* ------------------------------ */
4873    .balign 64
4874.L_OP_SHR_INT_2ADDR: /* 0xb9 */
4875/* File: x86/OP_SHR_INT_2ADDR.S */
4876/* File: x86/shop2addr.S */
4877    /*
4878     * Generic 32-bit "shift/2addr" operation.
4879     */
4880    /* shift/2addr vA, vB */
4881    movzx    rINSTbl,%ecx           # eax<- BA
4882    sarl     $4,%ecx               # ecx<- B
4883    GET_VREG_R %ecx %ecx            # eax<- vBB
4884    andb     $0xf,rINSTbl          # rINST<- A
4885    GET_VREG_R %eax rINST           # eax<- vAA
4886    sarl    %cl,%eax                          # ex: sarl %cl,%eax
4887    FETCH_INST_OPCODE 1 %edx
4888    SET_VREG %eax rINST
4889    ADVANCE_PC 1
4890    GOTO_NEXT_R %edx
4891
4892
4893/* ------------------------------ */
4894    .balign 64
4895.L_OP_USHR_INT_2ADDR: /* 0xba */
4896/* File: x86/OP_USHR_INT_2ADDR.S */
4897/* File: x86/shop2addr.S */
4898    /*
4899     * Generic 32-bit "shift/2addr" operation.
4900     */
4901    /* shift/2addr vA, vB */
4902    movzx    rINSTbl,%ecx           # eax<- BA
4903    sarl     $4,%ecx               # ecx<- B
4904    GET_VREG_R %ecx %ecx            # eax<- vBB
4905    andb     $0xf,rINSTbl          # rINST<- A
4906    GET_VREG_R %eax rINST           # eax<- vAA
4907    shrl    %cl,%eax                          # ex: sarl %cl,%eax
4908    FETCH_INST_OPCODE 1 %edx
4909    SET_VREG %eax rINST
4910    ADVANCE_PC 1
4911    GOTO_NEXT_R %edx
4912
4913
4914/* ------------------------------ */
4915    .balign 64
4916.L_OP_ADD_LONG_2ADDR: /* 0xbb */
4917/* File: x86/OP_ADD_LONG_2ADDR.S */
4918/* File: x86/binopWide2addr.S */
4919    /*
4920     * Generic 64-bit binary operation.
4921     */
4922    /* binop/2addr vA, vB */
4923    movzbl    rINSTbl,%ecx              # ecx<- BA
4924    sarl      $4,%ecx                  # ecx<- B
4925    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
4926    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
4927    andb      $0xF,rINSTbl             # rINST<- A
4928    addl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
4929    adcl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
4930    FETCH_INST_OPCODE 1 %edx
4931    ADVANCE_PC 1
4932    GOTO_NEXT_R %edx
4933
4934
4935/* ------------------------------ */
4936    .balign 64
4937.L_OP_SUB_LONG_2ADDR: /* 0xbc */
4938/* File: x86/OP_SUB_LONG_2ADDR.S */
4939/* File: x86/binopWide2addr.S */
4940    /*
4941     * Generic 64-bit binary operation.
4942     */
4943    /* binop/2addr vA, vB */
4944    movzbl    rINSTbl,%ecx              # ecx<- BA
4945    sarl      $4,%ecx                  # ecx<- B
4946    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
4947    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
4948    andb      $0xF,rINSTbl             # rINST<- A
4949    subl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
4950    sbbl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
4951    FETCH_INST_OPCODE 1 %edx
4952    ADVANCE_PC 1
4953    GOTO_NEXT_R %edx
4954
4955
4956/* ------------------------------ */
4957    .balign 64
4958.L_OP_MUL_LONG_2ADDR: /* 0xbd */
4959/* File: x86/OP_MUL_LONG_2ADDR.S */
4960    /*
4961     * Signed 64-bit integer multiply, 2-addr version
4962     *
4963     * We could definately use more free registers for
4964     * this code.  We must spill %edx (edx) because it
4965     * is used by imul.  We'll also spill rINST (ebx),
4966     * giving us eax, ebc, ecx and edx as computational
4967     * temps.  On top of that, we'll spill %esi (edi)
4968     * for use as the vA pointer and rFP (esi) for use
4969     * as the vB pointer.  Yuck.
4970     */
4971    /* mul-long/2addr vA, vB */
4972    movzbl    rINSTbl,%eax             # eax<- BA
4973    andb      $0xf,%al                # eax<- A
4974    sarl      $4,rINST                # rINST<- B
4975    SPILL_TMP2(%esi)
4976    SPILL(rFP)
4977    leal      (rFP,%eax,4),%esi        # %esi<- &v[A]
4978    leal      (rFP,rINST,4),rFP        # rFP<- &v[B]
4979    movl      4(%esi),%ecx             # ecx<- Amsw
4980    imull     (rFP),%ecx               # ecx<- (Amsw*Blsw)
4981    movl      4(rFP),%eax              # eax<- Bmsw
4982    imull     (%esi),%eax              # eax<- (Bmsw*Alsw)
4983    addl      %eax,%ecx                # ecx<- (Amsw*Blsw)+(Bmsw*Alsw)
4984    movl      (rFP),%eax               # eax<- Blsw
4985    mull      (%esi)                   # eax<- (Blsw*Alsw)
4986    jmp       .LOP_MUL_LONG_2ADDR_continue
4987
4988/* ------------------------------ */
4989    .balign 64
4990.L_OP_DIV_LONG_2ADDR: /* 0xbe */
4991/* File: x86/OP_DIV_LONG_2ADDR.S */
4992    /* div/2addr vA, vB */
4993    movzbl    rINSTbl,%eax
4994    shrl      $4,%eax                  # eax<- B
4995    andb      $0xf,rINSTbl             # rINST<- A
4996    GET_VREG_WORD %edx %eax 0
4997    GET_VREG_WORD %eax %eax 1
4998    movl     %edx,OUT_ARG2(%esp)
4999    testl    %eax,%eax
5000    je       .LOP_DIV_LONG_2ADDR_check_zero
5001    cmpl     $-1,%eax
5002    je       .LOP_DIV_LONG_2ADDR_check_neg1
5003.LOP_DIV_LONG_2ADDR_notSpecial:
5004    GET_VREG_WORD %edx rINST 0
5005    GET_VREG_WORD %ecx rINST 1
5006.LOP_DIV_LONG_2ADDR_notSpecial1:
5007    jmp      .LOP_DIV_LONG_2ADDR_continue
5008
5009/* ------------------------------ */
5010    .balign 64
5011.L_OP_REM_LONG_2ADDR: /* 0xbf */
5012/* File: x86/OP_REM_LONG_2ADDR.S */
5013/* File: x86/OP_DIV_LONG_2ADDR.S */
5014    /* div/2addr vA, vB */
5015    movzbl    rINSTbl,%eax
5016    shrl      $4,%eax                  # eax<- B
5017    andb      $0xf,rINSTbl             # rINST<- A
5018    GET_VREG_WORD %edx %eax 0
5019    GET_VREG_WORD %eax %eax 1
5020    movl     %edx,OUT_ARG2(%esp)
5021    testl    %eax,%eax
5022    je       .LOP_REM_LONG_2ADDR_check_zero
5023    cmpl     $-1,%eax
5024    je       .LOP_REM_LONG_2ADDR_check_neg1
5025.LOP_REM_LONG_2ADDR_notSpecial:
5026    GET_VREG_WORD %edx rINST 0
5027    GET_VREG_WORD %ecx rINST 1
5028.LOP_REM_LONG_2ADDR_notSpecial1:
5029    jmp      .LOP_REM_LONG_2ADDR_continue
5030
5031
5032/* ------------------------------ */
5033    .balign 64
5034.L_OP_AND_LONG_2ADDR: /* 0xc0 */
5035/* File: x86/OP_AND_LONG_2ADDR.S */
5036/* File: x86/binopWide2addr.S */
5037    /*
5038     * Generic 64-bit binary operation.
5039     */
5040    /* binop/2addr vA, vB */
5041    movzbl    rINSTbl,%ecx              # ecx<- BA
5042    sarl      $4,%ecx                  # ecx<- B
5043    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
5044    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
5045    andb      $0xF,rINSTbl             # rINST<- A
5046    andl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
5047    andl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
5048    FETCH_INST_OPCODE 1 %edx
5049    ADVANCE_PC 1
5050    GOTO_NEXT_R %edx
5051
5052
5053/* ------------------------------ */
5054    .balign 64
5055.L_OP_OR_LONG_2ADDR: /* 0xc1 */
5056/* File: x86/OP_OR_LONG_2ADDR.S */
5057/* File: x86/binopWide2addr.S */
5058    /*
5059     * Generic 64-bit binary operation.
5060     */
5061    /* binop/2addr vA, vB */
5062    movzbl    rINSTbl,%ecx              # ecx<- BA
5063    sarl      $4,%ecx                  # ecx<- B
5064    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
5065    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
5066    andb      $0xF,rINSTbl             # rINST<- A
5067    orl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
5068    orl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
5069    FETCH_INST_OPCODE 1 %edx
5070    ADVANCE_PC 1
5071    GOTO_NEXT_R %edx
5072
5073
5074/* ------------------------------ */
5075    .balign 64
5076.L_OP_XOR_LONG_2ADDR: /* 0xc2 */
5077/* File: x86/OP_XOR_LONG_2ADDR.S */
5078/* File: x86/binopWide2addr.S */
5079    /*
5080     * Generic 64-bit binary operation.
5081     */
5082    /* binop/2addr vA, vB */
5083    movzbl    rINSTbl,%ecx              # ecx<- BA
5084    sarl      $4,%ecx                  # ecx<- B
5085    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
5086    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
5087    andb      $0xF,rINSTbl             # rINST<- A
5088    xorl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
5089    xorl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
5090    FETCH_INST_OPCODE 1 %edx
5091    ADVANCE_PC 1
5092    GOTO_NEXT_R %edx
5093
5094
5095/* ------------------------------ */
5096    .balign 64
5097.L_OP_SHL_LONG_2ADDR: /* 0xc3 */
5098/* File: x86/OP_SHL_LONG_2ADDR.S */
5099    /*
5100     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
5101     * 32-bit shift distance.
5102     */
5103    /* shl-long/2addr vA, vB */
5104    /* ecx gets shift count */
5105    /* Need to spill edx */
5106    /* rINSTw gets AA */
5107    movzbl    rINSTbl,%ecx             # ecx<- BA
5108    andb      $0xf,rINSTbl            # rINST<- A
5109    GET_VREG_WORD %eax rINST 0         # eax<- v[AA+0]
5110    sarl      $4,%ecx                 # ecx<- B
5111    GET_VREG_WORD %edx rINST 1         # edx<- v[AA+1]
5112    GET_VREG_R  %ecx %ecx              # ecx<- vBB
5113    shldl     %eax,%edx
5114    sall      %cl,%eax
5115    testb     $32,%cl
5116    je        2f
5117    movl      %eax,%edx
5118    xorl      %eax,%eax
51192:
5120    SET_VREG_WORD %edx rINST 1         # v[AA+1]<- edx
5121    jmp       .LOP_SHL_LONG_2ADDR_finish
5122
5123/* ------------------------------ */
5124    .balign 64
5125.L_OP_SHR_LONG_2ADDR: /* 0xc4 */
5126/* File: x86/OP_SHR_LONG_2ADDR.S */
5127    /*
5128     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
5129     * 32-bit shift distance.
5130     */
5131    /* shl-long/2addr vA, vB */
5132    /* ecx gets shift count */
5133    /* Need to spill edx */
5134    /* rINSTw gets AA */
5135    movzbl    rINSTbl,%ecx         # ecx<- BA
5136    andb      $0xf,rINSTbl        # rINST<- A
5137    GET_VREG_WORD %eax rINST 0     # eax<- v[AA+0]
5138    sarl      $4,%ecx             # ecx<- B
5139    GET_VREG_WORD %edx rINST 1     # edx<- v[AA+1]
5140    GET_VREG_R %ecx %ecx           # ecx<- vBB
5141    shrdl     %edx,%eax
5142    sarl      %cl,%edx
5143    testb     $32,%cl
5144    je        2f
5145    movl      %edx,%eax
5146    sarl      $31,%edx
51472:
5148    SET_VREG_WORD %edx rINST 1     # v[AA+1]<- edx
5149    jmp       .LOP_SHR_LONG_2ADDR_finish
5150
5151/* ------------------------------ */
5152    .balign 64
5153.L_OP_USHR_LONG_2ADDR: /* 0xc5 */
5154/* File: x86/OP_USHR_LONG_2ADDR.S */
5155    /*
5156     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
5157     * 32-bit shift distance.
5158     */
5159    /* shl-long/2addr vA, vB */
5160    /* ecx gets shift count */
5161    /* Need to spill edx */
5162    /* rINSTw gets AA */
5163    movzbl    rINSTbl,%ecx             # ecx<- BA
5164    andb      $0xf,rINSTbl            # rINST<- A
5165    GET_VREG_WORD %eax rINST 0         # eax<- v[AA+0]
5166    sarl      $4,%ecx                 # ecx<- B
5167    GET_VREG_WORD %edx rINST 1         # edx<- v[AA+1]
5168    GET_VREG_R %ecx %ecx               # ecx<- vBB
5169    shrdl     %edx,%eax
5170    shrl      %cl,%edx
5171    testb     $32,%cl
5172    je        2f
5173    movl      %edx,%eax
5174    xorl      %edx,%edx
51752:
5176    SET_VREG_WORD %edx rINST 1         # v[AA+1]<- edx
5177    jmp       .LOP_USHR_LONG_2ADDR_finish
5178
5179/* ------------------------------ */
5180    .balign 64
5181.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
5182/* File: x86/OP_ADD_FLOAT_2ADDR.S */
5183/* File: x86/binflop2addr.S */
5184    /*
5185     * Generic 32-bit binary float operation.
5186     *
5187     * For: add-fp, sub-fp, mul-fp, div-fp
5188     */
5189
5190    /* binop/2addr vA, vB */
5191    movzx   rINSTbl,%ecx           # ecx<- A+
5192    andb    $0xf,%cl              # ecx<- A
5193    flds    (rFP,%ecx,4)          # vAA to fp stack
5194    sarl    $4,rINST             # rINST<- B
5195    fadds   (rFP,rINST,4)         # ex: faddp
5196    FETCH_INST_OPCODE 1 %edx
5197    ADVANCE_PC 1
5198    fstps    (rFP,%ecx,4)         # %st to vA
5199    GOTO_NEXT_R %edx
5200
5201
5202/* ------------------------------ */
5203    .balign 64
5204.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
5205/* File: x86/OP_SUB_FLOAT_2ADDR.S */
5206/* File: x86/binflop2addr.S */
5207    /*
5208     * Generic 32-bit binary float operation.
5209     *
5210     * For: add-fp, sub-fp, mul-fp, div-fp
5211     */
5212
5213    /* binop/2addr vA, vB */
5214    movzx   rINSTbl,%ecx           # ecx<- A+
5215    andb    $0xf,%cl              # ecx<- A
5216    flds    (rFP,%ecx,4)          # vAA to fp stack
5217    sarl    $4,rINST             # rINST<- B
5218    fsubs   (rFP,rINST,4)         # ex: faddp
5219    FETCH_INST_OPCODE 1 %edx
5220    ADVANCE_PC 1
5221    fstps    (rFP,%ecx,4)         # %st to vA
5222    GOTO_NEXT_R %edx
5223
5224
5225/* ------------------------------ */
5226    .balign 64
5227.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
5228/* File: x86/OP_MUL_FLOAT_2ADDR.S */
5229/* File: x86/binflop2addr.S */
5230    /*
5231     * Generic 32-bit binary float operation.
5232     *
5233     * For: add-fp, sub-fp, mul-fp, div-fp
5234     */
5235
5236    /* binop/2addr vA, vB */
5237    movzx   rINSTbl,%ecx           # ecx<- A+
5238    andb    $0xf,%cl              # ecx<- A
5239    flds    (rFP,%ecx,4)          # vAA to fp stack
5240    sarl    $4,rINST             # rINST<- B
5241    fmuls   (rFP,rINST,4)         # ex: faddp
5242    FETCH_INST_OPCODE 1 %edx
5243    ADVANCE_PC 1
5244    fstps    (rFP,%ecx,4)         # %st to vA
5245    GOTO_NEXT_R %edx
5246
5247
5248/* ------------------------------ */
5249    .balign 64
5250.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
5251/* File: x86/OP_DIV_FLOAT_2ADDR.S */
5252/* File: x86/binflop2addr.S */
5253    /*
5254     * Generic 32-bit binary float operation.
5255     *
5256     * For: add-fp, sub-fp, mul-fp, div-fp
5257     */
5258
5259    /* binop/2addr vA, vB */
5260    movzx   rINSTbl,%ecx           # ecx<- A+
5261    andb    $0xf,%cl              # ecx<- A
5262    flds    (rFP,%ecx,4)          # vAA to fp stack
5263    sarl    $4,rINST             # rINST<- B
5264    fdivs   (rFP,rINST,4)         # ex: faddp
5265    FETCH_INST_OPCODE 1 %edx
5266    ADVANCE_PC 1
5267    fstps    (rFP,%ecx,4)         # %st to vA
5268    GOTO_NEXT_R %edx
5269
5270
5271/* ------------------------------ */
5272    .balign 64
5273.L_OP_REM_FLOAT_2ADDR: /* 0xca */
5274/* File: x86/OP_REM_FLOAT_2ADDR.S */
5275    /* rem_float/2addr vA, vB */
5276    movzx   rINSTbl,%ecx                # ecx<- A+
5277    sarl    $4,rINST                  # rINST<- B
5278    flds     (rFP,rINST,4)              # vBB to fp stack
5279    andb    $0xf,%cl                   # ecx<- A
5280    flds     (rFP,%ecx,4)               # vAA to fp stack
5281    FETCH_INST_OPCODE 1 %edx
52821:
5283    fprem
5284    fstsw     %ax
5285    sahf
5286    jp        1b
5287    fstp      %st(1)
5288    ADVANCE_PC 1
5289    fstps    (rFP,%ecx,4)               # %st to vA
5290    GOTO_NEXT_R %edx
5291
5292/* ------------------------------ */
5293    .balign 64
5294.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
5295/* File: x86/OP_ADD_DOUBLE_2ADDR.S */
5296/* File: x86/binflop2addr.S */
5297    /*
5298     * Generic 32-bit binary float operation.
5299     *
5300     * For: add-fp, sub-fp, mul-fp, div-fp
5301     */
5302
5303    /* binop/2addr vA, vB */
5304    movzx   rINSTbl,%ecx           # ecx<- A+
5305    andb    $0xf,%cl              # ecx<- A
5306    fldl    (rFP,%ecx,4)          # vAA to fp stack
5307    sarl    $4,rINST             # rINST<- B
5308    faddl   (rFP,rINST,4)         # ex: faddp
5309    FETCH_INST_OPCODE 1 %edx
5310    ADVANCE_PC 1
5311    fstpl    (rFP,%ecx,4)         # %st to vA
5312    GOTO_NEXT_R %edx
5313
5314
5315/* ------------------------------ */
5316    .balign 64
5317.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
5318/* File: x86/OP_SUB_DOUBLE_2ADDR.S */
5319/* File: x86/binflop2addr.S */
5320    /*
5321     * Generic 32-bit binary float operation.
5322     *
5323     * For: add-fp, sub-fp, mul-fp, div-fp
5324     */
5325
5326    /* binop/2addr vA, vB */
5327    movzx   rINSTbl,%ecx           # ecx<- A+
5328    andb    $0xf,%cl              # ecx<- A
5329    fldl    (rFP,%ecx,4)          # vAA to fp stack
5330    sarl    $4,rINST             # rINST<- B
5331    fsubl   (rFP,rINST,4)         # ex: faddp
5332    FETCH_INST_OPCODE 1 %edx
5333    ADVANCE_PC 1
5334    fstpl    (rFP,%ecx,4)         # %st to vA
5335    GOTO_NEXT_R %edx
5336
5337
5338/* ------------------------------ */
5339    .balign 64
5340.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
5341/* File: x86/OP_MUL_DOUBLE_2ADDR.S */
5342/* File: x86/binflop2addr.S */
5343    /*
5344     * Generic 32-bit binary float operation.
5345     *
5346     * For: add-fp, sub-fp, mul-fp, div-fp
5347     */
5348
5349    /* binop/2addr vA, vB */
5350    movzx   rINSTbl,%ecx           # ecx<- A+
5351    andb    $0xf,%cl              # ecx<- A
5352    fldl    (rFP,%ecx,4)          # vAA to fp stack
5353    sarl    $4,rINST             # rINST<- B
5354    fmull   (rFP,rINST,4)         # ex: faddp
5355    FETCH_INST_OPCODE 1 %edx
5356    ADVANCE_PC 1
5357    fstpl    (rFP,%ecx,4)         # %st to vA
5358    GOTO_NEXT_R %edx
5359
5360
5361/* ------------------------------ */
5362    .balign 64
5363.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */
5364/* File: x86/OP_DIV_DOUBLE_2ADDR.S */
5365/* File: x86/binflop2addr.S */
5366    /*
5367     * Generic 32-bit binary float operation.
5368     *
5369     * For: add-fp, sub-fp, mul-fp, div-fp
5370     */
5371
5372    /* binop/2addr vA, vB */
5373    movzx   rINSTbl,%ecx           # ecx<- A+
5374    andb    $0xf,%cl              # ecx<- A
5375    fldl    (rFP,%ecx,4)          # vAA to fp stack
5376    sarl    $4,rINST             # rINST<- B
5377    fdivl   (rFP,rINST,4)         # ex: faddp
5378    FETCH_INST_OPCODE 1 %edx
5379    ADVANCE_PC 1
5380    fstpl    (rFP,%ecx,4)         # %st to vA
5381    GOTO_NEXT_R %edx
5382
5383
5384/* ------------------------------ */
5385    .balign 64
5386.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */
5387/* File: x86/OP_REM_DOUBLE_2ADDR.S */
5388    /* rem_float/2addr vA, vB */
5389    movzx   rINSTbl,%ecx                # ecx<- A+
5390    sarl    $4,rINST                  # rINST<- B
5391    fldl     (rFP,rINST,4)              # vBB to fp stack
5392    andb    $0xf,%cl                   # ecx<- A
5393    fldl     (rFP,%ecx,4)               # vAA to fp stack
5394    FETCH_INST_OPCODE 1 %edx
53951:
5396    fprem
5397    fstsw     %ax
5398    sahf
5399    jp        1b
5400    fstp      %st(1)
5401    ADVANCE_PC 1
5402    fstpl    (rFP,%ecx,4)               # %st to vA
5403    GOTO_NEXT_R %edx
5404
5405/* ------------------------------ */
5406    .balign 64
5407.L_OP_ADD_INT_LIT16: /* 0xd0 */
5408/* File: x86/OP_ADD_INT_LIT16.S */
5409/* File: x86/binopLit16.S */
5410    /*
5411     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
5412     * that specifies an instruction that performs "result = eax op ecx".
5413     * This could be an x86 instruction or a function call.  (If the result
5414     * comes back in a register other than eax, you can override "result".)
5415     *
5416     * For: add-int/lit16, rsub-int,
5417     *      and-int/lit16, or-int/lit16, xor-int/lit16
5418     */
5419    /* binop/lit16 vA, vB, #+CCCC */
5420    movzbl   rINSTbl,%eax               # eax<- 000000BA
5421    sarl     $4,%eax                   # eax<- B
5422    GET_VREG_R %eax %eax                # eax<- vB
5423    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
5424    andb     $0xf,rINSTbl              # rINST<- A
5425    addl %ecx,%eax                              # for example: addl %ecx, %eax
5426    SET_VREG %eax rINST
5427    FETCH_INST_OPCODE 2 %edx
5428    ADVANCE_PC 2
5429    GOTO_NEXT_R %edx
5430
5431
5432/* ------------------------------ */
5433    .balign 64
5434.L_OP_RSUB_INT: /* 0xd1 */
5435/* File: x86/OP_RSUB_INT.S */
5436/* File: x86/binopLit16.S */
5437    /*
5438     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
5439     * that specifies an instruction that performs "result = eax op ecx".
5440     * This could be an x86 instruction or a function call.  (If the result
5441     * comes back in a register other than eax, you can override "result".)
5442     *
5443     * For: add-int/lit16, rsub-int,
5444     *      and-int/lit16, or-int/lit16, xor-int/lit16
5445     */
5446    /* binop/lit16 vA, vB, #+CCCC */
5447    movzbl   rINSTbl,%eax               # eax<- 000000BA
5448    sarl     $4,%eax                   # eax<- B
5449    GET_VREG_R %eax %eax                # eax<- vB
5450    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
5451    andb     $0xf,rINSTbl              # rINST<- A
5452    subl %eax,%ecx                              # for example: addl %ecx, %eax
5453    SET_VREG %ecx rINST
5454    FETCH_INST_OPCODE 2 %edx
5455    ADVANCE_PC 2
5456    GOTO_NEXT_R %edx
5457
5458
5459/* ------------------------------ */
5460    .balign 64
5461.L_OP_MUL_INT_LIT16: /* 0xd2 */
5462/* File: x86/OP_MUL_INT_LIT16.S */
5463    /* mul/lit16 vA, vB, #+CCCC */
5464    /* Need A in rINST, ssssCCCC in ecx, vB in eax */
5465    movzbl   rINSTbl,%eax               # eax<- 000000BA
5466    sarl     $4,%eax                   # eax<- B
5467    GET_VREG_R %eax %eax                # eax<- vB
5468    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
5469    andb     $0xf,rINSTbl              # rINST<- A
5470    imull     %ecx,%eax                 # trashes edx
5471    FETCH_INST_OPCODE 2 %edx
5472    ADVANCE_PC 2
5473    SET_VREG %eax rINST
5474    GOTO_NEXT_R %edx
5475
5476/* ------------------------------ */
5477    .balign 64
5478.L_OP_DIV_INT_LIT16: /* 0xd3 */
5479/* File: x86/OP_DIV_INT_LIT16.S */
5480/* File: x86/bindivLit16.S */
5481    /*
5482     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
5483     * op1=-1.
5484     */
5485    /* div/rem/lit16 vA, vB, #+CCCC */
5486    /* Need A in rINST, ssssCCCC in ecx, vB in eax */
5487    movzbl   rINSTbl,%eax         # eax<- 000000BA
5488    sarl     $4,%eax             # eax<- B
5489    GET_VREG_R %eax %eax          # eax<- vB
5490    movswl   2(rPC),%ecx          # ecx<- ssssCCCC
5491    andb     $0xf,rINSTbl        # rINST<- A
5492    cmpl     $0,%ecx
5493    je       common_errDivideByZero
5494    cmpl     $-1,%ecx
5495    jne      .LOP_DIV_INT_LIT16_continue_div
5496    cmpl     $0x80000000,%eax
5497    jne      .LOP_DIV_INT_LIT16_continue_div
5498    movl     $0x80000000,%eax
5499    jmp      .LOP_DIV_INT_LIT16_finish_div
5500
5501
5502
5503/* ------------------------------ */
5504    .balign 64
5505.L_OP_REM_INT_LIT16: /* 0xd4 */
5506/* File: x86/OP_REM_INT_LIT16.S */
5507/* File: x86/bindivLit16.S */
5508    /*
5509     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
5510     * op1=-1.
5511     */
5512    /* div/rem/lit16 vA, vB, #+CCCC */
5513    /* Need A in rINST, ssssCCCC in ecx, vB in eax */
5514    movzbl   rINSTbl,%eax         # eax<- 000000BA
5515    sarl     $4,%eax             # eax<- B
5516    GET_VREG_R %eax %eax          # eax<- vB
5517    movswl   2(rPC),%ecx          # ecx<- ssssCCCC
5518    andb     $0xf,rINSTbl        # rINST<- A
5519    cmpl     $0,%ecx
5520    je       common_errDivideByZero
5521    cmpl     $-1,%ecx
5522    jne      .LOP_REM_INT_LIT16_continue_div
5523    cmpl     $0x80000000,%eax
5524    jne      .LOP_REM_INT_LIT16_continue_div
5525    movl     $0,%edx
5526    jmp      .LOP_REM_INT_LIT16_finish_div
5527
5528
5529
5530/* ------------------------------ */
5531    .balign 64
5532.L_OP_AND_INT_LIT16: /* 0xd5 */
5533/* File: x86/OP_AND_INT_LIT16.S */
5534/* File: x86/binopLit16.S */
5535    /*
5536     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
5537     * that specifies an instruction that performs "result = eax op ecx".
5538     * This could be an x86 instruction or a function call.  (If the result
5539     * comes back in a register other than eax, you can override "result".)
5540     *
5541     * For: add-int/lit16, rsub-int,
5542     *      and-int/lit16, or-int/lit16, xor-int/lit16
5543     */
5544    /* binop/lit16 vA, vB, #+CCCC */
5545    movzbl   rINSTbl,%eax               # eax<- 000000BA
5546    sarl     $4,%eax                   # eax<- B
5547    GET_VREG_R %eax %eax                # eax<- vB
5548    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
5549    andb     $0xf,rINSTbl              # rINST<- A
5550    andl %ecx,%eax                              # for example: addl %ecx, %eax
5551    SET_VREG %eax rINST
5552    FETCH_INST_OPCODE 2 %edx
5553    ADVANCE_PC 2
5554    GOTO_NEXT_R %edx
5555
5556
5557/* ------------------------------ */
5558    .balign 64
5559.L_OP_OR_INT_LIT16: /* 0xd6 */
5560/* File: x86/OP_OR_INT_LIT16.S */
5561/* File: x86/binopLit16.S */
5562    /*
5563     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
5564     * that specifies an instruction that performs "result = eax op ecx".
5565     * This could be an x86 instruction or a function call.  (If the result
5566     * comes back in a register other than eax, you can override "result".)
5567     *
5568     * For: add-int/lit16, rsub-int,
5569     *      and-int/lit16, or-int/lit16, xor-int/lit16
5570     */
5571    /* binop/lit16 vA, vB, #+CCCC */
5572    movzbl   rINSTbl,%eax               # eax<- 000000BA
5573    sarl     $4,%eax                   # eax<- B
5574    GET_VREG_R %eax %eax                # eax<- vB
5575    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
5576    andb     $0xf,rINSTbl              # rINST<- A
5577    orl     %ecx,%eax                              # for example: addl %ecx, %eax
5578    SET_VREG %eax rINST
5579    FETCH_INST_OPCODE 2 %edx
5580    ADVANCE_PC 2
5581    GOTO_NEXT_R %edx
5582
5583
5584/* ------------------------------ */
5585    .balign 64
5586.L_OP_XOR_INT_LIT16: /* 0xd7 */
5587/* File: x86/OP_XOR_INT_LIT16.S */
5588/* File: x86/binopLit16.S */
5589    /*
5590     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
5591     * that specifies an instruction that performs "result = eax op ecx".
5592     * This could be an x86 instruction or a function call.  (If the result
5593     * comes back in a register other than eax, you can override "result".)
5594     *
5595     * For: add-int/lit16, rsub-int,
5596     *      and-int/lit16, or-int/lit16, xor-int/lit16
5597     */
5598    /* binop/lit16 vA, vB, #+CCCC */
5599    movzbl   rINSTbl,%eax               # eax<- 000000BA
5600    sarl     $4,%eax                   # eax<- B
5601    GET_VREG_R %eax %eax                # eax<- vB
5602    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
5603    andb     $0xf,rINSTbl              # rINST<- A
5604    xor    %ecx,%eax                              # for example: addl %ecx, %eax
5605    SET_VREG %eax rINST
5606    FETCH_INST_OPCODE 2 %edx
5607    ADVANCE_PC 2
5608    GOTO_NEXT_R %edx
5609
5610
5611/* ------------------------------ */
5612    .balign 64
5613.L_OP_ADD_INT_LIT8: /* 0xd8 */
5614/* File: x86/OP_ADD_INT_LIT8.S */
5615/* File: x86/binopLit8.S */
5616    /*
5617     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
5618     * that specifies an instruction that performs "result = eax op ecx".
5619     * This could be an x86 instruction or a function call.  (If the result
5620     * comes back in a register other than r0, you can override "result".)
5621     *
5622     * For: add-int/lit8, rsub-int/lit8
5623     *      and-int/lit8, or-int/lit8, xor-int/lit8,
5624     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
5625     */
5626    /* binop/lit8 vAA, vBB, #+CC */
5627    movzbl    2(rPC),%eax              # eax<- BB
5628    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
5629    GET_VREG_R   %eax %eax             # eax<- rBB
5630    addl %ecx,%eax                             # ex: addl %ecx,%eax
5631    FETCH_INST_OPCODE 2 %edx
5632    SET_VREG   %eax rINST
5633    ADVANCE_PC 2
5634    GOTO_NEXT_R %edx
5635
5636
5637/* ------------------------------ */
5638    .balign 64
5639.L_OP_RSUB_INT_LIT8: /* 0xd9 */
5640/* File: x86/OP_RSUB_INT_LIT8.S */
5641/* File: x86/binopLit8.S */
5642    /*
5643     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
5644     * that specifies an instruction that performs "result = eax op ecx".
5645     * This could be an x86 instruction or a function call.  (If the result
5646     * comes back in a register other than r0, you can override "result".)
5647     *
5648     * For: add-int/lit8, rsub-int/lit8
5649     *      and-int/lit8, or-int/lit8, xor-int/lit8,
5650     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
5651     */
5652    /* binop/lit8 vAA, vBB, #+CC */
5653    movzbl    2(rPC),%eax              # eax<- BB
5654    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
5655    GET_VREG_R   %eax %eax             # eax<- rBB
5656    subl  %eax,%ecx                             # ex: addl %ecx,%eax
5657    FETCH_INST_OPCODE 2 %edx
5658    SET_VREG   %ecx rINST
5659    ADVANCE_PC 2
5660    GOTO_NEXT_R %edx
5661
5662
5663/* ------------------------------ */
5664    .balign 64
5665.L_OP_MUL_INT_LIT8: /* 0xda */
5666/* File: x86/OP_MUL_INT_LIT8.S */
5667    /* mul/lit8 vAA, vBB, #+CC */
5668    movzbl    2(rPC),%eax              # eax<- BB
5669    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
5670    GET_VREG_R   %eax %eax             # eax<- rBB
5671    imull     %ecx,%eax                # trashes edx
5672    FETCH_INST_OPCODE 2 %edx
5673    ADVANCE_PC 2
5674    SET_VREG  %eax rINST
5675    GOTO_NEXT_R %edx
5676
5677/* ------------------------------ */
5678    .balign 64
5679.L_OP_DIV_INT_LIT8: /* 0xdb */
5680/* File: x86/OP_DIV_INT_LIT8.S */
5681/* File: x86/bindivLit8.S */
5682    /*
5683     * 32-bit div/rem "lit8" binary operation.  Handles special case of
5684     * op0=minint & op1=-1
5685     */
5686    /* div/rem/lit8 vAA, vBB, #+CC */
5687    movzbl    2(rPC),%eax        # eax<- BB
5688    movsbl    3(rPC),%ecx        # ecx<- ssssssCC
5689    GET_VREG_R  %eax %eax        # eax<- rBB
5690    cmpl     $0,%ecx
5691    je       common_errDivideByZero
5692    cmpl     $0x80000000,%eax
5693    jne      .LOP_DIV_INT_LIT8_continue_div
5694    cmpl     $-1,%ecx
5695    jne      .LOP_DIV_INT_LIT8_continue_div
5696    movl     $0x80000000,%eax
5697    jmp      .LOP_DIV_INT_LIT8_finish_div
5698
5699
5700
5701/* ------------------------------ */
5702    .balign 64
5703.L_OP_REM_INT_LIT8: /* 0xdc */
5704/* File: x86/OP_REM_INT_LIT8.S */
5705/* File: x86/bindivLit8.S */
5706    /*
5707     * 32-bit div/rem "lit8" binary operation.  Handles special case of
5708     * op0=minint & op1=-1
5709     */
5710    /* div/rem/lit8 vAA, vBB, #+CC */
5711    movzbl    2(rPC),%eax        # eax<- BB
5712    movsbl    3(rPC),%ecx        # ecx<- ssssssCC
5713    GET_VREG_R  %eax %eax        # eax<- rBB
5714    cmpl     $0,%ecx
5715    je       common_errDivideByZero
5716    cmpl     $0x80000000,%eax
5717    jne      .LOP_REM_INT_LIT8_continue_div
5718    cmpl     $-1,%ecx
5719    jne      .LOP_REM_INT_LIT8_continue_div
5720    movl     $0,%edx
5721    jmp      .LOP_REM_INT_LIT8_finish_div
5722
5723
5724
5725/* ------------------------------ */
5726    .balign 64
5727.L_OP_AND_INT_LIT8: /* 0xdd */
5728/* File: x86/OP_AND_INT_LIT8.S */
5729/* File: x86/binopLit8.S */
5730    /*
5731     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
5732     * that specifies an instruction that performs "result = eax op ecx".
5733     * This could be an x86 instruction or a function call.  (If the result
5734     * comes back in a register other than r0, you can override "result".)
5735     *
5736     * For: add-int/lit8, rsub-int/lit8
5737     *      and-int/lit8, or-int/lit8, xor-int/lit8,
5738     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
5739     */
5740    /* binop/lit8 vAA, vBB, #+CC */
5741    movzbl    2(rPC),%eax              # eax<- BB
5742    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
5743    GET_VREG_R   %eax %eax             # eax<- rBB
5744    andl %ecx,%eax                             # ex: addl %ecx,%eax
5745    FETCH_INST_OPCODE 2 %edx
5746    SET_VREG   %eax rINST
5747    ADVANCE_PC 2
5748    GOTO_NEXT_R %edx
5749
5750
5751/* ------------------------------ */
5752    .balign 64
5753.L_OP_OR_INT_LIT8: /* 0xde */
5754/* File: x86/OP_OR_INT_LIT8.S */
5755/* File: x86/binopLit8.S */
5756    /*
5757     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
5758     * that specifies an instruction that performs "result = eax op ecx".
5759     * This could be an x86 instruction or a function call.  (If the result
5760     * comes back in a register other than r0, you can override "result".)
5761     *
5762     * For: add-int/lit8, rsub-int/lit8
5763     *      and-int/lit8, or-int/lit8, xor-int/lit8,
5764     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
5765     */
5766    /* binop/lit8 vAA, vBB, #+CC */
5767    movzbl    2(rPC),%eax              # eax<- BB
5768    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
5769    GET_VREG_R   %eax %eax             # eax<- rBB
5770    orl     %ecx,%eax                             # ex: addl %ecx,%eax
5771    FETCH_INST_OPCODE 2 %edx
5772    SET_VREG   %eax rINST
5773    ADVANCE_PC 2
5774    GOTO_NEXT_R %edx
5775
5776
5777/* ------------------------------ */
5778    .balign 64
5779.L_OP_XOR_INT_LIT8: /* 0xdf */
5780/* File: x86/OP_XOR_INT_LIT8.S */
5781/* File: x86/binopLit8.S */
5782    /*
5783     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
5784     * that specifies an instruction that performs "result = eax op ecx".
5785     * This could be an x86 instruction or a function call.  (If the result
5786     * comes back in a register other than r0, you can override "result".)
5787     *
5788     * For: add-int/lit8, rsub-int/lit8
5789     *      and-int/lit8, or-int/lit8, xor-int/lit8,
5790     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
5791     */
5792    /* binop/lit8 vAA, vBB, #+CC */
5793    movzbl    2(rPC),%eax              # eax<- BB
5794    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
5795    GET_VREG_R   %eax %eax             # eax<- rBB
5796    xor    %ecx,%eax                             # ex: addl %ecx,%eax
5797    FETCH_INST_OPCODE 2 %edx
5798    SET_VREG   %eax rINST
5799    ADVANCE_PC 2
5800    GOTO_NEXT_R %edx
5801
5802
5803/* ------------------------------ */
5804    .balign 64
5805.L_OP_SHL_INT_LIT8: /* 0xe0 */
5806/* File: x86/OP_SHL_INT_LIT8.S */
5807/* File: x86/binopLit8.S */
5808    /*
5809     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
5810     * that specifies an instruction that performs "result = eax op ecx".
5811     * This could be an x86 instruction or a function call.  (If the result
5812     * comes back in a register other than r0, you can override "result".)
5813     *
5814     * For: add-int/lit8, rsub-int/lit8
5815     *      and-int/lit8, or-int/lit8, xor-int/lit8,
5816     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
5817     */
5818    /* binop/lit8 vAA, vBB, #+CC */
5819    movzbl    2(rPC),%eax              # eax<- BB
5820    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
5821    GET_VREG_R   %eax %eax             # eax<- rBB
5822    sall  %cl,%eax                             # ex: addl %ecx,%eax
5823    FETCH_INST_OPCODE 2 %edx
5824    SET_VREG   %eax rINST
5825    ADVANCE_PC 2
5826    GOTO_NEXT_R %edx
5827
5828
5829/* ------------------------------ */
5830    .balign 64
5831.L_OP_SHR_INT_LIT8: /* 0xe1 */
5832/* File: x86/OP_SHR_INT_LIT8.S */
5833/* File: x86/binopLit8.S */
5834    /*
5835     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
5836     * that specifies an instruction that performs "result = eax op ecx".
5837     * This could be an x86 instruction or a function call.  (If the result
5838     * comes back in a register other than r0, you can override "result".)
5839     *
5840     * For: add-int/lit8, rsub-int/lit8
5841     *      and-int/lit8, or-int/lit8, xor-int/lit8,
5842     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
5843     */
5844    /* binop/lit8 vAA, vBB, #+CC */
5845    movzbl    2(rPC),%eax              # eax<- BB
5846    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
5847    GET_VREG_R   %eax %eax             # eax<- rBB
5848    sarl    %cl,%eax                             # ex: addl %ecx,%eax
5849    FETCH_INST_OPCODE 2 %edx
5850    SET_VREG   %eax rINST
5851    ADVANCE_PC 2
5852    GOTO_NEXT_R %edx
5853
5854
5855/* ------------------------------ */
5856    .balign 64
5857.L_OP_USHR_INT_LIT8: /* 0xe2 */
5858/* File: x86/OP_USHR_INT_LIT8.S */
5859/* File: x86/binopLit8.S */
5860    /*
5861     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
5862     * that specifies an instruction that performs "result = eax op ecx".
5863     * This could be an x86 instruction or a function call.  (If the result
5864     * comes back in a register other than r0, you can override "result".)
5865     *
5866     * For: add-int/lit8, rsub-int/lit8
5867     *      and-int/lit8, or-int/lit8, xor-int/lit8,
5868     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
5869     */
5870    /* binop/lit8 vAA, vBB, #+CC */
5871    movzbl    2(rPC),%eax              # eax<- BB
5872    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
5873    GET_VREG_R   %eax %eax             # eax<- rBB
5874    shrl     %cl,%eax                             # ex: addl %ecx,%eax
5875    FETCH_INST_OPCODE 2 %edx
5876    SET_VREG   %eax rINST
5877    ADVANCE_PC 2
5878    GOTO_NEXT_R %edx
5879
5880
5881/* ------------------------------ */
5882    .balign 64
5883.L_OP_IGET_VOLATILE: /* 0xe3 */
5884/* File: x86/OP_IGET_VOLATILE.S */
5885/* File: x86/OP_IGET.S */
5886    /*
5887     * General 32-bit instance field get.
5888     *
5889     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
5890     */
5891    /* op vA, vB, field@CCCC */
5892    movl    rGLUE,%ecx
5893    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
5894    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
5895    movzbl  rINSTbl,%ecx                        # ecx<- BA
5896    sarl    $4,%ecx                            # ecx<- B
5897    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
5898    andb    $0xf,rINSTbl                       # rINST<- A
5899    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
5900    movl    (%eax,%edx,4),%eax                  # resolved entry
5901    testl   %eax,%eax                           # is resolved entry null?
5902    jne     .LOP_IGET_VOLATILE_finish                  # no, already resolved
5903    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
5904    movl    rGLUE,%edx
5905    jmp     .LOP_IGET_VOLATILE_resolve
5906
5907
5908/* ------------------------------ */
5909    .balign 64
5910.L_OP_IPUT_VOLATILE: /* 0xe4 */
5911/* File: x86/OP_IPUT_VOLATILE.S */
5912/* File: x86/OP_IPUT.S */
5913
5914    /*
5915     * General 32-bit instance field put.
5916     *
5917     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
5918     */
5919    /* op vA, vB, field@CCCC */
5920    movl    rGLUE,%ecx
5921    movzwl  2(rPC),%edx                         # %edx<- 0000CCCC
5922    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
5923    movzbl  rINSTbl,%ecx                        # ecx<- BA
5924    sarl    $4,%ecx                            # ecx<- B
5925    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
5926    andb    $0xf,rINSTbl                       # rINST<- A
5927    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
5928    movl    (%eax,%edx,4),%eax                  # resolved entry
5929    testl   %eax,%eax                           # is resolved entry null?
5930    jne     .LOP_IPUT_VOLATILE_finish                  # no, already resolved
5931    movl    %edx,OUT_ARG1(%esp)
5932    movl    rGLUE,%edx
5933    jmp     .LOP_IPUT_VOLATILE_resolve
5934
5935
5936/* ------------------------------ */
5937    .balign 64
5938.L_OP_SGET_VOLATILE: /* 0xe5 */
5939/* File: x86/OP_SGET_VOLATILE.S */
5940/* File: x86/OP_SGET.S */
5941    /*
5942     * General 32-bit SGET handler.
5943     *
5944     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
5945     */
5946    /* op vAA, field@BBBB */
5947    movl      rGLUE,%ecx
5948    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
5949    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
5950    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
5951    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
5952    testl     %eax,%eax                          # resolved entry null?
5953    je        .LOP_SGET_VOLATILE_resolve                # if not, make it so
5954.LOP_SGET_VOLATILE_finish:     # field ptr in eax
5955    movl      offStaticField_value(%eax),%eax
5956    FETCH_INST_OPCODE 2 %edx
5957    ADVANCE_PC 2
5958    SET_VREG %eax rINST
5959    GOTO_NEXT_R %edx
5960
5961
5962/* ------------------------------ */
5963    .balign 64
5964.L_OP_SPUT_VOLATILE: /* 0xe6 */
5965/* File: x86/OP_SPUT_VOLATILE.S */
5966/* File: x86/OP_SPUT.S */
5967    /*
5968     * General 32-bit SPUT handler.
5969     *
5970     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
5971     */
5972    /* op vAA, field@BBBB */
5973    movl      rGLUE,%ecx
5974    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
5975    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
5976    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
5977    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
5978    testl     %eax,%eax                          # resolved entry null?
5979    je        .LOP_SPUT_VOLATILE_resolve                # if not, make it so
5980.LOP_SPUT_VOLATILE_finish:     # field ptr in eax
5981    GET_VREG_R  %ecx rINST
5982    FETCH_INST_OPCODE 2 %edx
5983    ADVANCE_PC 2
5984    movl      %ecx,offStaticField_value(%eax)
5985    GOTO_NEXT_R %edx
5986
5987
5988/* ------------------------------ */
5989    .balign 64
5990.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
5991/* File: x86/OP_IGET_OBJECT_VOLATILE.S */
5992/* File: x86/OP_IGET.S */
5993    /*
5994     * General 32-bit instance field get.
5995     *
5996     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
5997     */
5998    /* op vA, vB, field@CCCC */
5999    movl    rGLUE,%ecx
6000    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
6001    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
6002    movzbl  rINSTbl,%ecx                        # ecx<- BA
6003    sarl    $4,%ecx                            # ecx<- B
6004    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6005    andb    $0xf,rINSTbl                       # rINST<- A
6006    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
6007    movl    (%eax,%edx,4),%eax                  # resolved entry
6008    testl   %eax,%eax                           # is resolved entry null?
6009    jne     .LOP_IGET_OBJECT_VOLATILE_finish                  # no, already resolved
6010    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
6011    movl    rGLUE,%edx
6012    jmp     .LOP_IGET_OBJECT_VOLATILE_resolve
6013
6014
6015/* ------------------------------ */
6016    .balign 64
6017.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
6018    /* (stub) */
6019    SAVE_PC_FP_TO_GLUE %ecx          # leaves rGLUE in %ecx
6020    movl %ecx,OUT_ARG0(%esp)         # glue is first arg to function
6021    call      dvmMterp_OP_IGET_WIDE_VOLATILE     # do the real work
6022    mov       rGLUE,%ecx
6023    LOAD_PC_FP_FROM_GLUE             # retrieve updated values
6024    FETCH_INST
6025    GOTO_NEXT
6026/* ------------------------------ */
6027    .balign 64
6028.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
6029    /* (stub) */
6030    SAVE_PC_FP_TO_GLUE %ecx          # leaves rGLUE in %ecx
6031    movl %ecx,OUT_ARG0(%esp)         # glue is first arg to function
6032    call      dvmMterp_OP_IPUT_WIDE_VOLATILE     # do the real work
6033    mov       rGLUE,%ecx
6034    LOAD_PC_FP_FROM_GLUE             # retrieve updated values
6035    FETCH_INST
6036    GOTO_NEXT
6037/* ------------------------------ */
6038    .balign 64
6039.L_OP_SGET_WIDE_VOLATILE: /* 0xea */
6040    /* (stub) */
6041    SAVE_PC_FP_TO_GLUE %ecx          # leaves rGLUE in %ecx
6042    movl %ecx,OUT_ARG0(%esp)         # glue is first arg to function
6043    call      dvmMterp_OP_SGET_WIDE_VOLATILE     # do the real work
6044    mov       rGLUE,%ecx
6045    LOAD_PC_FP_FROM_GLUE             # retrieve updated values
6046    FETCH_INST
6047    GOTO_NEXT
6048/* ------------------------------ */
6049    .balign 64
6050.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
6051    /* (stub) */
6052    SAVE_PC_FP_TO_GLUE %ecx          # leaves rGLUE in %ecx
6053    movl %ecx,OUT_ARG0(%esp)         # glue is first arg to function
6054    call      dvmMterp_OP_SPUT_WIDE_VOLATILE     # do the real work
6055    mov       rGLUE,%ecx
6056    LOAD_PC_FP_FROM_GLUE             # retrieve updated values
6057    FETCH_INST
6058    GOTO_NEXT
6059/* ------------------------------ */
6060    .balign 64
6061.L_OP_BREAKPOINT: /* 0xec */
6062/* File: x86/OP_BREAKPOINT.S */
6063/* File: x86/unused.S */
6064    jmp     common_abort
6065
6066
6067/* ------------------------------ */
6068    .balign 64
6069.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */
6070/* File: x86/OP_THROW_VERIFICATION_ERROR.S */
6071    /*
6072     * Handle a throw-verification-error instruction.  This throws an
6073     * exception for an error discovered during verification.  The
6074     * exception is indicated by AA, with some detail provided by BBBB.
6075     */
6076    /* op AA, ref@BBBB */
6077    movl     rGLUE,%ecx
6078    movzwl   2(rPC),%eax                     # eax<- BBBB
6079    movl     offGlue_method(%ecx),%ecx       # ecx<- glue->method
6080    EXPORT_PC
6081    movl     %eax,OUT_ARG2(%esp)             # arg2<- BBBB
6082    movl     rINST,OUT_ARG1(%esp)            # arg1<- AA
6083    movl     %ecx,OUT_ARG0(%esp)             # arg0<- method
6084    call     dvmThrowVerificationError       # call(method, kind, ref)
6085    jmp      common_exceptionThrown          # handle exception
6086
6087/* ------------------------------ */
6088    .balign 64
6089.L_OP_EXECUTE_INLINE: /* 0xee */
6090/* File: x86/OP_EXECUTE_INLINE.S */
6091    /*
6092     * Execute a "native inline" instruction.
6093     *
6094     * We will be calling through a function table:
6095     *
6096     * (*gDvmInlineOpsTable[opIndex].func)(arg0, arg1, arg2, arg3, pResult)
6097     *
6098     * Ignores argument count - always loads 4.
6099     *
6100     */
6101    /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */
6102    movl      rGLUE,%ecx
6103    EXPORT_PC
6104    movzwl    2(rPC),%eax               # eax<- BBBB
6105    leal      offGlue_retval(%ecx),%ecx # ecx<- & glue->retval
6106    movl      %ecx,OUT_ARG4(%esp)
6107    call      .LOP_EXECUTE_INLINE_continue      # make call; will return after
6108    testl     %eax,%eax                 # successful?
6109    FETCH_INST_OPCODE 3 %edx
6110    je        common_exceptionThrown    # no, handle exception
6111    ADVANCE_PC 3
6112    GOTO_NEXT_R %edx
6113
6114/* ------------------------------ */
6115    .balign 64
6116.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */
6117    /* (stub) */
6118    SAVE_PC_FP_TO_GLUE %ecx          # leaves rGLUE in %ecx
6119    movl %ecx,OUT_ARG0(%esp)         # glue is first arg to function
6120    call      dvmMterp_OP_EXECUTE_INLINE_RANGE     # do the real work
6121    mov       rGLUE,%ecx
6122    LOAD_PC_FP_FROM_GLUE             # retrieve updated values
6123    FETCH_INST
6124    GOTO_NEXT
6125/* ------------------------------ */
6126    .balign 64
6127.L_OP_INVOKE_DIRECT_EMPTY: /* 0xf0 */
6128/* File: x86/OP_INVOKE_DIRECT_EMPTY.S */
6129    /*
6130     * invoke-direct-empty is a no-op in a "standard" interpreter.
6131     */
6132    FETCH_INST_WORD 3
6133    ADVANCE_PC 3
6134    GOTO_NEXT
6135
6136/* ------------------------------ */
6137    .balign 64
6138.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */
6139    /* (stub) */
6140    SAVE_PC_FP_TO_GLUE %ecx          # leaves rGLUE in %ecx
6141    movl %ecx,OUT_ARG0(%esp)         # glue is first arg to function
6142    call      dvmMterp_OP_RETURN_VOID_BARRIER     # do the real work
6143    mov       rGLUE,%ecx
6144    LOAD_PC_FP_FROM_GLUE             # retrieve updated values
6145    FETCH_INST
6146    GOTO_NEXT
6147/* ------------------------------ */
6148    .balign 64
6149.L_OP_IGET_QUICK: /* 0xf2 */
6150/* File: x86/OP_IGET_QUICK.S */
6151    /* For: iget-quick, iget-object-quick */
6152    /* op vA, vB, offset@CCCC */
6153    movzbl    rINSTbl,%ecx              # ecx<- BA
6154    sarl      $4,%ecx                  # ecx<- B
6155    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
6156    movzwl    2(rPC),%eax               # eax<- field byte offset
6157    cmpl      $0,%ecx                  # is object null?
6158    je        common_errNullObject
6159    movl      (%ecx,%eax,1),%eax
6160    FETCH_INST_OPCODE 2 %edx
6161    ADVANCE_PC 2
6162    andb      $0xf,rINSTbl             # rINST<- A
6163    SET_VREG  %eax rINST                # fp[A]<- result
6164    GOTO_NEXT_R %edx
6165
6166/* ------------------------------ */
6167    .balign 64
6168.L_OP_IGET_WIDE_QUICK: /* 0xf3 */
6169/* File: x86/OP_IGET_WIDE_QUICK.S */
6170    /* For: iget-wide-quick */
6171    /* op vA, vB, offset@CCCC */
6172    movzbl    rINSTbl,%ecx              # ecx<- BA
6173    sarl      $4,%ecx                  # ecx<- B
6174    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
6175    movzwl    2(rPC),%eax               # eax<- field byte offset
6176    cmpl      $0,%ecx                  # is object null?
6177    je        common_errNullObject
6178    leal      (%ecx,%eax,1),%eax        # eax<- address of 64-bit source
6179    movl      (%eax),%ecx               # ecx<- lsw
6180    movl      4(%eax),%eax              # eax<- msw
6181    andb      $0xf,rINSTbl             # rINST<- A
6182    FETCH_INST_OPCODE 2 %edx
6183    SET_VREG_WORD %ecx rINST 0          # v[A+0]<- lsw
6184    SET_VREG_WORD %eax rINST 1          # v[A+1]<- msw
6185    ADVANCE_PC 2
6186    GOTO_NEXT_R %edx
6187
6188/* ------------------------------ */
6189    .balign 64
6190.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */
6191/* File: x86/OP_IGET_OBJECT_QUICK.S */
6192/* File: x86/OP_IGET_QUICK.S */
6193    /* For: iget-quick, iget-object-quick */
6194    /* op vA, vB, offset@CCCC */
6195    movzbl    rINSTbl,%ecx              # ecx<- BA
6196    sarl      $4,%ecx                  # ecx<- B
6197    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
6198    movzwl    2(rPC),%eax               # eax<- field byte offset
6199    cmpl      $0,%ecx                  # is object null?
6200    je        common_errNullObject
6201    movl      (%ecx,%eax,1),%eax
6202    FETCH_INST_OPCODE 2 %edx
6203    ADVANCE_PC 2
6204    andb      $0xf,rINSTbl             # rINST<- A
6205    SET_VREG  %eax rINST                # fp[A]<- result
6206    GOTO_NEXT_R %edx
6207
6208
6209/* ------------------------------ */
6210    .balign 64
6211.L_OP_IPUT_QUICK: /* 0xf5 */
6212/* File: x86/OP_IPUT_QUICK.S */
6213    /* For: iput-quick */
6214    /* op vA, vB, offset@CCCC */
6215    movzbl    rINSTbl,%ecx              # ecx<- BA
6216    sarl      $4,%ecx                  # ecx<- B
6217    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
6218    andb      $0xf,rINSTbl             # rINST<- A
6219    GET_VREG_R  rINST,rINST             # rINST<- v[A]
6220    movzwl    2(rPC),%eax               # eax<- field byte offset
6221    testl     %ecx,%ecx                 # is object null?
6222    FETCH_INST_OPCODE 2 %edx
6223    je        common_errNullObject
6224    movl      rINST,(%ecx,%eax,1)
6225    ADVANCE_PC 2
6226    GOTO_NEXT_R %edx
6227
6228/* ------------------------------ */
6229    .balign 64
6230.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */
6231/* File: x86/OP_IPUT_WIDE_QUICK.S */
6232    /* For: iput-wide-quick */
6233    /* op vA, vB, offset@CCCC */
6234    movzbl    rINSTbl,%ecx              # ecx<- BA
6235    sarl      $4,%ecx                  # ecx<- B
6236    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
6237    movzwl    2(rPC),%eax               # eax<- field byte offset
6238    testl      %ecx,%ecx                # is object null?
6239    je        common_errNullObject
6240    leal      (%ecx,%eax,1),%ecx        # ecx<- Address of 64-bit target
6241    andb      $0xf,rINSTbl             # rINST<- A
6242    GET_VREG_WORD %eax rINST 0          # eax<- lsw
6243    GET_VREG_WORD rINST rINST 1         # rINST<- msw
6244    FETCH_INST_OPCODE 2 %edx
6245    movl      %eax,(%ecx)
6246    movl      rINST,4(%ecx)
6247    ADVANCE_PC 2
6248    GOTO_NEXT_R %edx
6249
6250/* ------------------------------ */
6251    .balign 64
6252.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
6253/* File: x86/OP_IPUT_OBJECT_QUICK.S */
6254    /* For: iput-object-quick */
6255    /* op vA, vB, offset@CCCC */
6256    movzbl    rINSTbl,%ecx              # ecx<- BA
6257    sarl      $4,%ecx                  # ecx<- B
6258    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
6259    andb      $0xf,rINSTbl             # rINST<- A
6260    GET_VREG_R  rINST rINST             # rINST<- v[A]
6261    movzwl    2(rPC),%eax               # eax<- field byte offset
6262    testl     %ecx,%ecx                 # is object null?
6263    je        common_errNullObject
6264    movl      rINST,(%ecx,%eax,1)
6265    movl      rGLUE,%eax
6266    jmp       .LOP_IPUT_OBJECT_QUICK_finish
6267
6268/* ------------------------------ */
6269    .balign 64
6270.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
6271/* File: x86/OP_INVOKE_VIRTUAL_QUICK.S */
6272    /*
6273     * Handle an optimized virtual method call.
6274     *
6275     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
6276     */
6277    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
6278    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
6279    movzwl    4(rPC),%eax               # eax<- FEDC or CCCC
6280    movzwl    2(rPC),%ecx               # ecx<- BBBB
6281    .if     (!0)
6282    andl      $0xf,%eax                # eax<- C (or stays CCCC)
6283    .endif
6284    GET_VREG_R  %eax %eax               # eax<- vC ("this" ptr)
6285    testl     %eax,%eax                 # null?
6286    je        common_errNullObject      # yep, throw exception
6287    movl      offObject_clazz(%eax),%eax # eax<- thisPtr->clazz
6288    movl      offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable
6289    EXPORT_PC                           # might throw later - get ready
6290    movl      (%eax,%ecx,4),%eax        # eax<- vtable[BBBB]
6291    jmp       common_invokeMethodNoRange
6292
6293/* ------------------------------ */
6294    .balign 64
6295.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
6296/* File: x86/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */
6297/* File: x86/OP_INVOKE_VIRTUAL_QUICK.S */
6298    /*
6299     * Handle an optimized virtual method call.
6300     *
6301     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
6302     */
6303    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
6304    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
6305    movzwl    4(rPC),%eax               # eax<- FEDC or CCCC
6306    movzwl    2(rPC),%ecx               # ecx<- BBBB
6307    .if     (!1)
6308    andl      $0xf,%eax                # eax<- C (or stays CCCC)
6309    .endif
6310    GET_VREG_R  %eax %eax               # eax<- vC ("this" ptr)
6311    testl     %eax,%eax                 # null?
6312    je        common_errNullObject      # yep, throw exception
6313    movl      offObject_clazz(%eax),%eax # eax<- thisPtr->clazz
6314    movl      offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable
6315    EXPORT_PC                           # might throw later - get ready
6316    movl      (%eax,%ecx,4),%eax        # eax<- vtable[BBBB]
6317    jmp       common_invokeMethodRange
6318
6319
6320/* ------------------------------ */
6321    .balign 64
6322.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */
6323/* File: x86/OP_INVOKE_SUPER_QUICK.S */
6324    /*
6325     * Handle an optimized "super" method call.
6326     *
6327     * for: [opt] invoke-super-quick, invoke-super-quick/range
6328     */
6329    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
6330    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
6331    movl      rGLUE,%ecx
6332    movzwl    4(rPC),%eax               # eax<- GFED or CCCC
6333    movl      offGlue_method(%ecx),%ecx # ecx<- current method
6334    .if       (!0)
6335    andl      $0xf,%eax                # eax<- D (or stays CCCC)
6336    .endif
6337    movl      offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
6338    GET_VREG_R  %eax %eax               # eax<- "this"
6339    movl      offClassObject_super(%ecx),%ecx # ecx<- method->clazz->super
6340    testl     %eax,%eax                 # null "this"?
6341    je        common_errNullObject      # "this" is null, throw exception
6342    movzwl    2(rPC),%eax               # eax<- BBBB
6343    movl      offClassObject_vtable(%ecx),%ecx # ecx<- vtable
6344    EXPORT_PC
6345    movl      (%ecx,%eax,4),%eax        # eax<- super->vtable[BBBB]
6346    jmp       common_invokeMethodNoRange
6347
6348/* ------------------------------ */
6349    .balign 64
6350.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
6351/* File: x86/OP_INVOKE_SUPER_QUICK_RANGE.S */
6352/* File: x86/OP_INVOKE_SUPER_QUICK.S */
6353    /*
6354     * Handle an optimized "super" method call.
6355     *
6356     * for: [opt] invoke-super-quick, invoke-super-quick/range
6357     */
6358    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
6359    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
6360    movl      rGLUE,%ecx
6361    movzwl    4(rPC),%eax               # eax<- GFED or CCCC
6362    movl      offGlue_method(%ecx),%ecx # ecx<- current method
6363    .if       (!1)
6364    andl      $0xf,%eax                # eax<- D (or stays CCCC)
6365    .endif
6366    movl      offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
6367    GET_VREG_R  %eax %eax               # eax<- "this"
6368    movl      offClassObject_super(%ecx),%ecx # ecx<- method->clazz->super
6369    testl     %eax,%eax                 # null "this"?
6370    je        common_errNullObject      # "this" is null, throw exception
6371    movzwl    2(rPC),%eax               # eax<- BBBB
6372    movl      offClassObject_vtable(%ecx),%ecx # ecx<- vtable
6373    EXPORT_PC
6374    movl      (%ecx,%eax,4),%eax        # eax<- super->vtable[BBBB]
6375    jmp       common_invokeMethodRange
6376
6377
6378/* ------------------------------ */
6379    .balign 64
6380.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
6381/* File: x86/OP_IPUT_OBJECT_VOLATILE.S */
6382/* File: x86/OP_IPUT_OBJECT.S */
6383    /*
6384     * Object field put.
6385     *
6386     * for: iput-object
6387     */
6388    /* op vA, vB, field@CCCC */
6389    movl    rGLUE,%ecx
6390    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
6391    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
6392    movzbl  rINSTbl,%ecx                        # ecx<- BA
6393    sarl    $4,%ecx                            # ecx<- B
6394    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6395    andb    $0xf,rINSTbl                       # rINST<- A
6396    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
6397    movl    (%eax,%edx,4),%eax                  # resolved entry
6398    testl   %eax,%eax                           # is resolved entry null?
6399    jne     .LOP_IPUT_OBJECT_VOLATILE_finish                  # no, already resolved
6400    movl    %edx,OUT_ARG1(%esp)
6401    movl    rGLUE,%edx
6402    jmp     .LOP_IPUT_OBJECT_VOLATILE_resolve
6403
6404
6405/* ------------------------------ */
6406    .balign 64
6407.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
6408/* File: x86/OP_SGET_OBJECT_VOLATILE.S */
6409/* File: x86/OP_SGET.S */
6410    /*
6411     * General 32-bit SGET handler.
6412     *
6413     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
6414     */
6415    /* op vAA, field@BBBB */
6416    movl      rGLUE,%ecx
6417    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
6418    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
6419    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
6420    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
6421    testl     %eax,%eax                          # resolved entry null?
6422    je        .LOP_SGET_OBJECT_VOLATILE_resolve                # if not, make it so
6423.LOP_SGET_OBJECT_VOLATILE_finish:     # field ptr in eax
6424    movl      offStaticField_value(%eax),%eax
6425    FETCH_INST_OPCODE 2 %edx
6426    ADVANCE_PC 2
6427    SET_VREG %eax rINST
6428    GOTO_NEXT_R %edx
6429
6430
6431/* ------------------------------ */
6432    .balign 64
6433.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
6434/* File: x86/OP_SPUT_OBJECT_VOLATILE.S */
6435/* File: x86/OP_SPUT_OBJECT.S */
6436    /*
6437     * SPUT object handler.
6438     */
6439    /* op vAA, field@BBBB */
6440    movl      rGLUE,%ecx
6441    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
6442    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
6443    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
6444    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField
6445    testl     %eax,%eax                          # resolved entry null?
6446    je        .LOP_SPUT_OBJECT_VOLATILE_resolve                # if not, make it so
6447.LOP_SPUT_OBJECT_VOLATILE_finish:                              # field ptr in eax
6448    movzbl    rINSTbl,%ecx                       # ecx<- AA
6449    GET_VREG_R  %ecx %ecx
6450    jmp       .LOP_SPUT_OBJECT_VOLATILE_continue
6451
6452
6453/* ------------------------------ */
6454    .balign 64
6455.L_OP_DISPATCH_FF: /* 0xff */
6456/* File: x86/OP_DISPATCH_FF.S */
6457    leal      256(rINST),%edx
6458    GOTO_NEXT_JUMBO_R %edx
6459
6460/* ------------------------------ */
6461    .balign 64
6462.L_OP_CONST_CLASS_JUMBO: /* 0x100 */
6463/* File: x86/OP_CONST_CLASS_JUMBO.S */
6464    /* const-class/jumbo vBBBB, Class@AAAAAAAA */
6465    movl      rGLUE,%ecx
6466    movl      2(rPC),%eax              # eax<- AAAAAAAA
6467    movl      offGlue_methodClassDex(%ecx),%ecx# ecx<- glue->methodClassDex
6468    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- dvmDex->pResClasses
6469    movl      (%ecx,%eax,4),%eax       # eax<- rResClasses[AAAAAAAA]
6470    FETCH_INST_OPCODE 4 %edx
6471    testl     %eax,%eax                # resolved yet?
6472    je        .LOP_CONST_CLASS_JUMBO_resolve
6473    SET_VREG  %eax rINST               # vBBBB<- rResClasses[AAAAAAAA]
6474    ADVANCE_PC 4
6475    GOTO_NEXT_R %edx
6476
6477/* ------------------------------ */
6478    .balign 64
6479.L_OP_CHECK_CAST_JUMBO: /* 0x101 */
6480/* File: x86/OP_CHECK_CAST_JUMBO.S */
6481    /*
6482     * Check to see if a cast from one class to another is allowed.
6483     */
6484    /* check-cast/jumbo vBBBB, class@AAAAAAAA */
6485    movl      rGLUE,%ecx
6486    GET_VREG_R  rINST,rINST             # rINST<- vBBBB (object)
6487    movl      2(rPC),%eax               # eax<- AAAAAAAA
6488    movl      offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
6489    testl     rINST,rINST               # is oject null?
6490    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
6491    je        .LOP_CHECK_CAST_JUMBO_okay          # null obj, cast always succeeds
6492    movl      (%ecx,%eax,4),%eax        # eax<- resolved class
6493    movl      offObject_clazz(rINST),%ecx # ecx<- obj->clazz
6494    testl     %eax,%eax                 # have we resolved this before?
6495    je        .LOP_CHECK_CAST_JUMBO_resolve       # no, go do it now
6496.LOP_CHECK_CAST_JUMBO_resolved:
6497    cmpl      %eax,%ecx                 # same class (trivial success)?
6498    jne       .LOP_CHECK_CAST_JUMBO_fullcheck     # no, do full check
6499.LOP_CHECK_CAST_JUMBO_okay:
6500    FETCH_INST_OPCODE 4 %edx
6501    ADVANCE_PC 4
6502    GOTO_NEXT_R %edx
6503
6504/* ------------------------------ */
6505    .balign 64
6506.L_OP_INSTANCE_OF_JUMBO: /* 0x102 */
6507/* File: x86/OP_INSTANCE_OF_JUMBO.S */
6508    /*
6509     * Check to see if an object reference is an instance of a class.
6510     *
6511     * Most common situation is a non-null object, being compared against
6512     * an already-resolved class.
6513     */
6514    /* instance-of/jumbo vBBBB, vCCCC, class@AAAAAAAA */
6515    movzwl  8(rPC),%eax                 # eax<- CCCC
6516    GET_VREG_R %eax %eax                # eax<- vCCCC (obj)
6517    movl    rGLUE,%ecx
6518    testl   %eax,%eax                   # object null?
6519    movl    offGlue_methodClassDex(%ecx),%ecx  # ecx<- pDvmDex
6520    je      .LOP_INSTANCE_OF_JUMBO_store           # null obj, not instance, store it
6521    movl    2(rPC),%edx                 # edx<- AAAAAAAA
6522    movl    offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
6523    movl    (%ecx,%edx,4),%ecx          # ecx<- resolved class
6524    movl    offObject_clazz(%eax),%eax  # eax<- obj->clazz
6525    testl   %ecx,%ecx                   # have we resolved this before?
6526    je      .LOP_INSTANCE_OF_JUMBO_resolve         # not resolved, do it now
6527.LOP_INSTANCE_OF_JUMBO_resolved:  # eax<- obj->clazz, ecx<- resolved class
6528    cmpl    %eax,%ecx                   # same class (trivial success)?
6529    je      .LOP_INSTANCE_OF_JUMBO_trivial         # yes, trivial finish
6530    jmp     .LOP_INSTANCE_OF_JUMBO_fullcheck       # no, do full check
6531
6532/* ------------------------------ */
6533    .balign 64
6534.L_OP_NEW_INSTANCE_JUMBO: /* 0x103 */
6535/* File: x86/OP_NEW_INSTANCE_JUMBO.S */
6536    /*
6537     * Create a new instance of a class.
6538     */
6539    /* new-instance/jumbo vBBBB, class@AAAAAAAA */
6540    movl      rGLUE,%ecx
6541    movl      2(rPC),%eax               # eax<- AAAAAAAA
6542    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- pDvmDex
6543    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
6544    EXPORT_PC
6545    movl      (%ecx,%eax,4),%ecx        # ecx<- resolved class
6546    testl     %ecx,%ecx                 # resolved?
6547    je        .LOP_NEW_INSTANCE_JUMBO_resolve       # no, go do it
6548.LOP_NEW_INSTANCE_JUMBO_resolved:  # on entry, ecx<- class
6549    cmpb      $CLASS_INITIALIZED,offClassObject_status(%ecx)
6550    je        .LOP_NEW_INSTANCE_JUMBO_initialized
6551    jmp       .LOP_NEW_INSTANCE_JUMBO_needinit
6552
6553/* ------------------------------ */
6554    .balign 64
6555.L_OP_NEW_ARRAY_JUMBO: /* 0x104 */
6556/* File: x86/OP_NEW_ARRAY_JUMBO.S */
6557    /*
6558     * Allocate an array of objects, specified with the array class
6559     * and a count.
6560     *
6561     * The verifier guarantees that this is an array class, so we don't
6562     * check for it here.
6563     */
6564    /* new-array/jumbo vBBBB, vCCCC, class@AAAAAAAA */
6565    movl    rGLUE,%ecx
6566    EXPORT_PC
6567    movl    offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
6568    movl    2(rPC),%eax                       # eax<- AAAAAAAA
6569    movl    offDvmDex_pResClasses(%ecx),%ecx  # ecx<- pDvmDex->pResClasses
6570    movl    (%ecx,%eax,4),%ecx                # ecx<- resolved class
6571    movzwl  8(rPC),%eax                       # eax<- CCCC
6572    GET_VREG_R %eax %eax                      # eax<- vCCCC (array length)
6573    testl   %eax,%eax
6574    js      common_errNegativeArraySize       # bail
6575    testl   %ecx,%ecx                         # already resolved?
6576    jne     .LOP_NEW_ARRAY_JUMBO_finish                # yes, fast path
6577    jmp     .LOP_NEW_ARRAY_JUMBO_resolve               # resolve now
6578
6579/* ------------------------------ */
6580    .balign 64
6581.L_OP_FILLED_NEW_ARRAY_JUMBO: /* 0x105 */
6582/* File: x86/OP_FILLED_NEW_ARRAY_JUMBO.S */
6583    /*
6584     * Create a new array with elements filled from registers.
6585     */
6586    /* filled-new-array/jumbo {vCCCC..v(CCCC+BBBB-1)}, type@AAAAAAAA */
6587    movl    rGLUE,%eax
6588    movl    offGlue_methodClassDex(%eax),%eax # eax<- pDvmDex
6589    movl    2(rPC),%ecx                       # ecx<- AAAAAAAA
6590    movl    offDvmDex_pResClasses(%eax),%eax  # eax<- pDvmDex->pResClasses
6591    movl    (%eax,%ecx,4),%eax                # eax<- resolved class
6592    EXPORT_PC
6593    testl   %eax,%eax                         # already resolved?
6594    jne     .LOP_FILLED_NEW_ARRAY_JUMBO_continue              # yes, continue
6595    # less frequent path, so we'll redo some work
6596    movl    rGLUE,%eax
6597    movl    $0,OUT_ARG2(%esp)                # arg2<- false
6598    movl    %ecx,OUT_ARG1(%esp)               # arg1<- AAAAAAAA
6599    movl    offGlue_method(%eax),%eax         # eax<- glue->method
6600    jmp     .LOP_FILLED_NEW_ARRAY_JUMBO_more
6601
6602/* ------------------------------ */
6603    .balign 64
6604.L_OP_IGET_JUMBO: /* 0x106 */
6605/* File: x86/OP_IGET_JUMBO.S */
6606    /*
6607     * Jumbo 32-bit instance field get.
6608     *
6609     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
6610     *      iget-char/jumbo, iget-short/jumbo
6611     */
6612    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6613    movl    rGLUE,%ecx
6614    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6615    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
6616    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6617    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6618    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6619    movl    (%eax,%edx,4),%eax                  # resolved entry
6620    testl   %eax,%eax                           # is resolved entry null?
6621    jne     .LOP_IGET_JUMBO_finish                  # no, already resolved
6622    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
6623    movl    rGLUE,%edx
6624    jmp     .LOP_IGET_JUMBO_resolve
6625
6626/* ------------------------------ */
6627    .balign 64
6628.L_OP_IGET_WIDE_JUMBO: /* 0x107 */
6629/* File: x86/OP_IGET_WIDE_JUMBO.S */
6630    /*
6631     * Jumbo 64-bit instance field get.
6632     */
6633    /* iget-wide/jumbo vBBBB, vCCCC, field@AAAA */
6634    movl    rGLUE,%ecx
6635    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6636    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
6637    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6638    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6639    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6640    movl    (%eax,%edx,4),%eax                  # resolved entry
6641    testl   %eax,%eax                           # is resolved entry null?
6642    jne     .LOP_IGET_WIDE_JUMBO_finish                  # no, already resolved
6643    movl    %edx,OUT_ARG1(%esp)                 # for dvmResolveInstField
6644    movl    rGLUE,%edx
6645    jmp     .LOP_IGET_WIDE_JUMBO_resolve
6646
6647/* ------------------------------ */
6648    .balign 64
6649.L_OP_IGET_OBJECT_JUMBO: /* 0x108 */
6650/* File: x86/OP_IGET_OBJECT_JUMBO.S */
6651/* File: x86/OP_IGET_JUMBO.S */
6652    /*
6653     * Jumbo 32-bit instance field get.
6654     *
6655     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
6656     *      iget-char/jumbo, iget-short/jumbo
6657     */
6658    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6659    movl    rGLUE,%ecx
6660    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6661    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
6662    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6663    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6664    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6665    movl    (%eax,%edx,4),%eax                  # resolved entry
6666    testl   %eax,%eax                           # is resolved entry null?
6667    jne     .LOP_IGET_OBJECT_JUMBO_finish                  # no, already resolved
6668    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
6669    movl    rGLUE,%edx
6670    jmp     .LOP_IGET_OBJECT_JUMBO_resolve
6671
6672
6673/* ------------------------------ */
6674    .balign 64
6675.L_OP_IGET_BOOLEAN_JUMBO: /* 0x109 */
6676/* File: x86/OP_IGET_BOOLEAN_JUMBO.S */
6677/* File: x86/OP_IGET_JUMBO.S */
6678    /*
6679     * Jumbo 32-bit instance field get.
6680     *
6681     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
6682     *      iget-char/jumbo, iget-short/jumbo
6683     */
6684    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6685    movl    rGLUE,%ecx
6686    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6687    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
6688    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6689    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6690    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6691    movl    (%eax,%edx,4),%eax                  # resolved entry
6692    testl   %eax,%eax                           # is resolved entry null?
6693    jne     .LOP_IGET_BOOLEAN_JUMBO_finish                  # no, already resolved
6694    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
6695    movl    rGLUE,%edx
6696    jmp     .LOP_IGET_BOOLEAN_JUMBO_resolve
6697
6698
6699/* ------------------------------ */
6700    .balign 64
6701.L_OP_IGET_BYTE_JUMBO: /* 0x10a */
6702/* File: x86/OP_IGET_BYTE_JUMBO.S */
6703/* File: x86/OP_IGET_JUMBO.S */
6704    /*
6705     * Jumbo 32-bit instance field get.
6706     *
6707     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
6708     *      iget-char/jumbo, iget-short/jumbo
6709     */
6710    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6711    movl    rGLUE,%ecx
6712    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6713    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
6714    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6715    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6716    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6717    movl    (%eax,%edx,4),%eax                  # resolved entry
6718    testl   %eax,%eax                           # is resolved entry null?
6719    jne     .LOP_IGET_BYTE_JUMBO_finish                  # no, already resolved
6720    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
6721    movl    rGLUE,%edx
6722    jmp     .LOP_IGET_BYTE_JUMBO_resolve
6723
6724
6725/* ------------------------------ */
6726    .balign 64
6727.L_OP_IGET_CHAR_JUMBO: /* 0x10b */
6728/* File: x86/OP_IGET_CHAR_JUMBO.S */
6729/* File: x86/OP_IGET_JUMBO.S */
6730    /*
6731     * Jumbo 32-bit instance field get.
6732     *
6733     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
6734     *      iget-char/jumbo, iget-short/jumbo
6735     */
6736    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6737    movl    rGLUE,%ecx
6738    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6739    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
6740    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6741    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6742    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6743    movl    (%eax,%edx,4),%eax                  # resolved entry
6744    testl   %eax,%eax                           # is resolved entry null?
6745    jne     .LOP_IGET_CHAR_JUMBO_finish                  # no, already resolved
6746    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
6747    movl    rGLUE,%edx
6748    jmp     .LOP_IGET_CHAR_JUMBO_resolve
6749
6750
6751/* ------------------------------ */
6752    .balign 64
6753.L_OP_IGET_SHORT_JUMBO: /* 0x10c */
6754/* File: x86/OP_IGET_SHORT_JUMBO.S */
6755/* File: x86/OP_IGET_JUMBO.S */
6756    /*
6757     * Jumbo 32-bit instance field get.
6758     *
6759     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
6760     *      iget-char/jumbo, iget-short/jumbo
6761     */
6762    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6763    movl    rGLUE,%ecx
6764    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6765    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
6766    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6767    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6768    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6769    movl    (%eax,%edx,4),%eax                  # resolved entry
6770    testl   %eax,%eax                           # is resolved entry null?
6771    jne     .LOP_IGET_SHORT_JUMBO_finish                  # no, already resolved
6772    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
6773    movl    rGLUE,%edx
6774    jmp     .LOP_IGET_SHORT_JUMBO_resolve
6775
6776
6777/* ------------------------------ */
6778    .balign 64
6779.L_OP_IPUT_JUMBO: /* 0x10d */
6780/* File: x86/OP_IPUT_JUMBO.S */
6781    /*
6782     * Jumbo 32-bit instance field put.
6783     *
6784     * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo,
6785            iput-char/jumbo, iput-short/jumbo
6786     */
6787    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6788    movl    rGLUE,%ecx
6789    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6790    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
6791    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6792    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6793    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6794    movl    (%eax,%edx,4),%eax                  # resolved entry
6795    testl   %eax,%eax                           # is resolved entry null?
6796    jne     .LOP_IPUT_JUMBO_finish                  # no, already resolved
6797    movl    %edx,OUT_ARG1(%esp)
6798    movl    rGLUE,%edx
6799    jmp     .LOP_IPUT_JUMBO_resolve
6800
6801/* ------------------------------ */
6802    .balign 64
6803.L_OP_IPUT_WIDE_JUMBO: /* 0x10e */
6804/* File: x86/OP_IPUT_WIDE_JUMBO.S */
6805    /*
6806     * Jumbo 64-bit instance field put.
6807     */
6808    /* iput-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */
6809    movl    rGLUE,%ecx
6810    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6811    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
6812    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6813    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6814    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6815    movl    (%eax,%edx,4),%eax                  # resolved entry
6816    testl   %eax,%eax                           # is resolved entry null?
6817    jne     .LOP_IPUT_WIDE_JUMBO_finish                  # no, already resolved
6818    movl    %edx,OUT_ARG1(%esp)
6819    movl    rGLUE,%edx
6820    jmp     .LOP_IPUT_WIDE_JUMBO_resolve
6821
6822/* ------------------------------ */
6823    .balign 64
6824.L_OP_IPUT_OBJECT_JUMBO: /* 0x10f */
6825/* File: x86/OP_IPUT_OBJECT_JUMBO.S */
6826    /*
6827     * Jumbo object field put.
6828     */
6829    /* iput-object/jumbo vBBBB, vCCCC, field@AAAAAAAA */
6830    movl    rGLUE,%ecx
6831    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6832    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
6833    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6834    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6835    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6836    movl    (%eax,%edx,4),%eax                  # resolved entry
6837    testl   %eax,%eax                           # is resolved entry null?
6838    jne     .LOP_IPUT_OBJECT_JUMBO_finish                  # no, already resolved
6839    movl    %edx,OUT_ARG1(%esp)
6840    movl    rGLUE,%edx
6841    jmp     .LOP_IPUT_OBJECT_JUMBO_resolve
6842
6843/* ------------------------------ */
6844    .balign 64
6845.L_OP_IPUT_BOOLEAN_JUMBO: /* 0x110 */
6846/* File: x86/OP_IPUT_BOOLEAN_JUMBO.S */
6847/* File: x86/OP_IPUT_JUMBO.S */
6848    /*
6849     * Jumbo 32-bit instance field put.
6850     *
6851     * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo,
6852            iput-char/jumbo, iput-short/jumbo
6853     */
6854    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6855    movl    rGLUE,%ecx
6856    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6857    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
6858    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6859    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6860    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6861    movl    (%eax,%edx,4),%eax                  # resolved entry
6862    testl   %eax,%eax                           # is resolved entry null?
6863    jne     .LOP_IPUT_BOOLEAN_JUMBO_finish                  # no, already resolved
6864    movl    %edx,OUT_ARG1(%esp)
6865    movl    rGLUE,%edx
6866    jmp     .LOP_IPUT_BOOLEAN_JUMBO_resolve
6867
6868
6869/* ------------------------------ */
6870    .balign 64
6871.L_OP_IPUT_BYTE_JUMBO: /* 0x111 */
6872/* File: x86/OP_IPUT_BYTE_JUMBO.S */
6873/* File: x86/OP_IPUT_JUMBO.S */
6874    /*
6875     * Jumbo 32-bit instance field put.
6876     *
6877     * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo,
6878            iput-char/jumbo, iput-short/jumbo
6879     */
6880    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6881    movl    rGLUE,%ecx
6882    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6883    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
6884    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6885    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6886    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6887    movl    (%eax,%edx,4),%eax                  # resolved entry
6888    testl   %eax,%eax                           # is resolved entry null?
6889    jne     .LOP_IPUT_BYTE_JUMBO_finish                  # no, already resolved
6890    movl    %edx,OUT_ARG1(%esp)
6891    movl    rGLUE,%edx
6892    jmp     .LOP_IPUT_BYTE_JUMBO_resolve
6893
6894
6895/* ------------------------------ */
6896    .balign 64
6897.L_OP_IPUT_CHAR_JUMBO: /* 0x112 */
6898/* File: x86/OP_IPUT_CHAR_JUMBO.S */
6899/* File: x86/OP_IPUT_JUMBO.S */
6900    /*
6901     * Jumbo 32-bit instance field put.
6902     *
6903     * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo,
6904            iput-char/jumbo, iput-short/jumbo
6905     */
6906    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6907    movl    rGLUE,%ecx
6908    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6909    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
6910    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6911    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6912    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6913    movl    (%eax,%edx,4),%eax                  # resolved entry
6914    testl   %eax,%eax                           # is resolved entry null?
6915    jne     .LOP_IPUT_CHAR_JUMBO_finish                  # no, already resolved
6916    movl    %edx,OUT_ARG1(%esp)
6917    movl    rGLUE,%edx
6918    jmp     .LOP_IPUT_CHAR_JUMBO_resolve
6919
6920
6921/* ------------------------------ */
6922    .balign 64
6923.L_OP_IPUT_SHORT_JUMBO: /* 0x113 */
6924/* File: x86/OP_IPUT_SHORT_JUMBO.S */
6925/* File: x86/OP_IPUT_JUMBO.S */
6926    /*
6927     * Jumbo 32-bit instance field put.
6928     *
6929     * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo,
6930            iput-char/jumbo, iput-short/jumbo
6931     */
6932    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6933    movl    rGLUE,%ecx
6934    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6935    movl    offGlue_methodClassDex(%ecx),%eax   # eax<- DvmDex
6936    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6937    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6938    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6939    movl    (%eax,%edx,4),%eax                  # resolved entry
6940    testl   %eax,%eax                           # is resolved entry null?
6941    jne     .LOP_IPUT_SHORT_JUMBO_finish                  # no, already resolved
6942    movl    %edx,OUT_ARG1(%esp)
6943    movl    rGLUE,%edx
6944    jmp     .LOP_IPUT_SHORT_JUMBO_resolve
6945
6946
6947/* ------------------------------ */
6948    .balign 64
6949.L_OP_SGET_JUMBO: /* 0x114 */
6950/* File: x86/OP_SGET_JUMBO.S */
6951    /*
6952     * Jumbo 32-bit SGET handler.
6953     *
6954     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
6955     *      sget-char/jumbo, sget-short/jumbo
6956     */
6957    /* exop vBBBB, field@AAAAAAAA */
6958    movl      rGLUE,%ecx
6959    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
6960    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
6961    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
6962    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
6963    testl     %eax,%eax                          # resolved entry null?
6964    je        .LOP_SGET_JUMBO_resolve                # if not, make it so
6965.LOP_SGET_JUMBO_finish:     # field ptr in eax
6966    movl      offStaticField_value(%eax),%eax
6967    FETCH_INST_OPCODE 4 %edx
6968    ADVANCE_PC 4
6969    SET_VREG %eax rINST
6970    GOTO_NEXT_R %edx
6971
6972/* ------------------------------ */
6973    .balign 64
6974.L_OP_SGET_WIDE_JUMBO: /* 0x115 */
6975/* File: x86/OP_SGET_WIDE_JUMBO.S */
6976    /*
6977     * Jumbo 64-bit SGET handler.
6978     *
6979     */
6980    /* sget-wide/jumbo vBBBB, field@AAAAAAAA */
6981    movl      rGLUE,%ecx
6982    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
6983    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
6984    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
6985    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
6986    testl     %eax,%eax                          # resolved entry null?
6987    je        .LOP_SGET_WIDE_JUMBO_resolve                # if not, make it so
6988.LOP_SGET_WIDE_JUMBO_finish:     # field ptr in eax
6989    movl      offStaticField_value(%eax),%ecx    # ecx<- lsw
6990    movl      4+offStaticField_value(%eax),%eax  # eax<- msw
6991    FETCH_INST_OPCODE 2 %edx
6992    ADVANCE_PC 2
6993    SET_VREG_WORD %ecx rINST 0
6994    SET_VREG_WORD %eax rINST 1
6995    GOTO_NEXT_R %edx
6996
6997/* ------------------------------ */
6998    .balign 64
6999.L_OP_SGET_OBJECT_JUMBO: /* 0x116 */
7000/* File: x86/OP_SGET_OBJECT_JUMBO.S */
7001/* File: x86/OP_SGET_JUMBO.S */
7002    /*
7003     * Jumbo 32-bit SGET handler.
7004     *
7005     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
7006     *      sget-char/jumbo, sget-short/jumbo
7007     */
7008    /* exop vBBBB, field@AAAAAAAA */
7009    movl      rGLUE,%ecx
7010    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7011    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7012    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7013    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7014    testl     %eax,%eax                          # resolved entry null?
7015    je        .LOP_SGET_OBJECT_JUMBO_resolve                # if not, make it so
7016.LOP_SGET_OBJECT_JUMBO_finish:     # field ptr in eax
7017    movl      offStaticField_value(%eax),%eax
7018    FETCH_INST_OPCODE 4 %edx
7019    ADVANCE_PC 4
7020    SET_VREG %eax rINST
7021    GOTO_NEXT_R %edx
7022
7023
7024/* ------------------------------ */
7025    .balign 64
7026.L_OP_SGET_BOOLEAN_JUMBO: /* 0x117 */
7027/* File: x86/OP_SGET_BOOLEAN_JUMBO.S */
7028/* File: x86/OP_SGET_JUMBO.S */
7029    /*
7030     * Jumbo 32-bit SGET handler.
7031     *
7032     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
7033     *      sget-char/jumbo, sget-short/jumbo
7034     */
7035    /* exop vBBBB, field@AAAAAAAA */
7036    movl      rGLUE,%ecx
7037    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7038    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7039    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7040    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7041    testl     %eax,%eax                          # resolved entry null?
7042    je        .LOP_SGET_BOOLEAN_JUMBO_resolve                # if not, make it so
7043.LOP_SGET_BOOLEAN_JUMBO_finish:     # field ptr in eax
7044    movl      offStaticField_value(%eax),%eax
7045    FETCH_INST_OPCODE 4 %edx
7046    ADVANCE_PC 4
7047    SET_VREG %eax rINST
7048    GOTO_NEXT_R %edx
7049
7050
7051/* ------------------------------ */
7052    .balign 64
7053.L_OP_SGET_BYTE_JUMBO: /* 0x118 */
7054/* File: x86/OP_SGET_BYTE_JUMBO.S */
7055/* File: x86/OP_SGET_JUMBO.S */
7056    /*
7057     * Jumbo 32-bit SGET handler.
7058     *
7059     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
7060     *      sget-char/jumbo, sget-short/jumbo
7061     */
7062    /* exop vBBBB, field@AAAAAAAA */
7063    movl      rGLUE,%ecx
7064    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7065    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7066    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7067    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7068    testl     %eax,%eax                          # resolved entry null?
7069    je        .LOP_SGET_BYTE_JUMBO_resolve                # if not, make it so
7070.LOP_SGET_BYTE_JUMBO_finish:     # field ptr in eax
7071    movl      offStaticField_value(%eax),%eax
7072    FETCH_INST_OPCODE 4 %edx
7073    ADVANCE_PC 4
7074    SET_VREG %eax rINST
7075    GOTO_NEXT_R %edx
7076
7077
7078/* ------------------------------ */
7079    .balign 64
7080.L_OP_SGET_CHAR_JUMBO: /* 0x119 */
7081/* File: x86/OP_SGET_CHAR_JUMBO.S */
7082/* File: x86/OP_SGET_JUMBO.S */
7083    /*
7084     * Jumbo 32-bit SGET handler.
7085     *
7086     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
7087     *      sget-char/jumbo, sget-short/jumbo
7088     */
7089    /* exop vBBBB, field@AAAAAAAA */
7090    movl      rGLUE,%ecx
7091    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7092    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7093    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7094    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7095    testl     %eax,%eax                          # resolved entry null?
7096    je        .LOP_SGET_CHAR_JUMBO_resolve                # if not, make it so
7097.LOP_SGET_CHAR_JUMBO_finish:     # field ptr in eax
7098    movl      offStaticField_value(%eax),%eax
7099    FETCH_INST_OPCODE 4 %edx
7100    ADVANCE_PC 4
7101    SET_VREG %eax rINST
7102    GOTO_NEXT_R %edx
7103
7104
7105/* ------------------------------ */
7106    .balign 64
7107.L_OP_SGET_SHORT_JUMBO: /* 0x11a */
7108/* File: x86/OP_SGET_SHORT_JUMBO.S */
7109/* File: x86/OP_SGET_JUMBO.S */
7110    /*
7111     * Jumbo 32-bit SGET handler.
7112     *
7113     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
7114     *      sget-char/jumbo, sget-short/jumbo
7115     */
7116    /* exop vBBBB, field@AAAAAAAA */
7117    movl      rGLUE,%ecx
7118    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7119    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7120    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7121    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7122    testl     %eax,%eax                          # resolved entry null?
7123    je        .LOP_SGET_SHORT_JUMBO_resolve                # if not, make it so
7124.LOP_SGET_SHORT_JUMBO_finish:     # field ptr in eax
7125    movl      offStaticField_value(%eax),%eax
7126    FETCH_INST_OPCODE 4 %edx
7127    ADVANCE_PC 4
7128    SET_VREG %eax rINST
7129    GOTO_NEXT_R %edx
7130
7131
7132/* ------------------------------ */
7133    .balign 64
7134.L_OP_SPUT_JUMBO: /* 0x11b */
7135/* File: x86/OP_SPUT_JUMBO.S */
7136    /*
7137     * Jumbo 32-bit SPUT handler.
7138     *
7139     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
7140     *      sput-short/jumbo
7141     */
7142    /* exop vBBBB, field@AAAAAAAA */
7143    movl      rGLUE,%ecx
7144    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7145    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7146    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7147    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7148    testl     %eax,%eax                          # resolved entry null?
7149    je        .LOP_SPUT_JUMBO_resolve                # if not, make it so
7150.LOP_SPUT_JUMBO_finish:     # field ptr in eax
7151    GET_VREG_R  %ecx rINST
7152    FETCH_INST_OPCODE 4 %edx
7153    ADVANCE_PC 4
7154    movl      %ecx,offStaticField_value(%eax)
7155    GOTO_NEXT_R %edx
7156
7157/* ------------------------------ */
7158    .balign 64
7159.L_OP_SPUT_WIDE_JUMBO: /* 0x11c */
7160/* File: x86/OP_SPUT_WIDE_JUMBO.S */
7161    /*
7162     * Jumbo 64-bit SPUT handler.
7163     */
7164    /* sput-wide/jumbo vBBBB, field@AAAAAAAA */
7165    movl      rGLUE,%ecx
7166    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7167    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7168    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7169    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7170    testl     %eax,%eax                          # resolved entry null?
7171    je        .LOP_SPUT_WIDE_JUMBO_resolve                # if not, make it so
7172.LOP_SPUT_WIDE_JUMBO_finish:     # field ptr in eax
7173    GET_VREG_WORD %ecx rINST 0                  # ecx<- lsw
7174    GET_VREG_WORD rINST rINST 1                 # rINST<- msw
7175    FETCH_INST_OPCODE 4 %edx
7176    ADVANCE_PC 4
7177    movl      %ecx,offStaticField_value(%eax)
7178    movl      rINST,4+offStaticField_value(%eax)
7179    GOTO_NEXT_R %edx
7180
7181/* ------------------------------ */
7182    .balign 64
7183.L_OP_SPUT_OBJECT_JUMBO: /* 0x11d */
7184/* File: x86/OP_SPUT_OBJECT_JUMBO.S */
7185    /*
7186     * Jumbo SPUT object handler.
7187     */
7188    /* sput-object/jumbo vBBBB, field@AAAAAAAA */
7189    movl      rGLUE,%ecx
7190    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7191    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7192    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7193    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField
7194    testl     %eax,%eax                          # resolved entry null?
7195    je        .LOP_SPUT_OBJECT_JUMBO_resolve                # if not, make it so
7196.LOP_SPUT_OBJECT_JUMBO_finish:                              # field ptr in eax
7197    GET_VREG_R  %ecx rINST
7198    jmp       .LOP_SPUT_OBJECT_JUMBO_continue
7199
7200/* ------------------------------ */
7201    .balign 64
7202.L_OP_SPUT_BOOLEAN_JUMBO: /* 0x11e */
7203/* File: x86/OP_SPUT_BOOLEAN_JUMBO.S */
7204/* File: x86/OP_SPUT_JUMBO.S */
7205    /*
7206     * Jumbo 32-bit SPUT handler.
7207     *
7208     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
7209     *      sput-short/jumbo
7210     */
7211    /* exop vBBBB, field@AAAAAAAA */
7212    movl      rGLUE,%ecx
7213    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7214    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7215    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7216    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7217    testl     %eax,%eax                          # resolved entry null?
7218    je        .LOP_SPUT_BOOLEAN_JUMBO_resolve                # if not, make it so
7219.LOP_SPUT_BOOLEAN_JUMBO_finish:     # field ptr in eax
7220    GET_VREG_R  %ecx rINST
7221    FETCH_INST_OPCODE 4 %edx
7222    ADVANCE_PC 4
7223    movl      %ecx,offStaticField_value(%eax)
7224    GOTO_NEXT_R %edx
7225
7226
7227/* ------------------------------ */
7228    .balign 64
7229.L_OP_SPUT_BYTE_JUMBO: /* 0x11f */
7230/* File: x86/OP_SPUT_BYTE_JUMBO.S */
7231/* File: x86/OP_SPUT_JUMBO.S */
7232    /*
7233     * Jumbo 32-bit SPUT handler.
7234     *
7235     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
7236     *      sput-short/jumbo
7237     */
7238    /* exop vBBBB, field@AAAAAAAA */
7239    movl      rGLUE,%ecx
7240    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7241    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7242    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7243    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7244    testl     %eax,%eax                          # resolved entry null?
7245    je        .LOP_SPUT_BYTE_JUMBO_resolve                # if not, make it so
7246.LOP_SPUT_BYTE_JUMBO_finish:     # field ptr in eax
7247    GET_VREG_R  %ecx rINST
7248    FETCH_INST_OPCODE 4 %edx
7249    ADVANCE_PC 4
7250    movl      %ecx,offStaticField_value(%eax)
7251    GOTO_NEXT_R %edx
7252
7253
7254/* ------------------------------ */
7255    .balign 64
7256.L_OP_SPUT_CHAR_JUMBO: /* 0x120 */
7257/* File: x86/OP_SPUT_CHAR_JUMBO.S */
7258/* File: x86/OP_SPUT_JUMBO.S */
7259    /*
7260     * Jumbo 32-bit SPUT handler.
7261     *
7262     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
7263     *      sput-short/jumbo
7264     */
7265    /* exop vBBBB, field@AAAAAAAA */
7266    movl      rGLUE,%ecx
7267    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7268    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7269    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7270    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7271    testl     %eax,%eax                          # resolved entry null?
7272    je        .LOP_SPUT_CHAR_JUMBO_resolve                # if not, make it so
7273.LOP_SPUT_CHAR_JUMBO_finish:     # field ptr in eax
7274    GET_VREG_R  %ecx rINST
7275    FETCH_INST_OPCODE 4 %edx
7276    ADVANCE_PC 4
7277    movl      %ecx,offStaticField_value(%eax)
7278    GOTO_NEXT_R %edx
7279
7280
7281/* ------------------------------ */
7282    .balign 64
7283.L_OP_SPUT_SHORT_JUMBO: /* 0x121 */
7284/* File: x86/OP_SPUT_SHORT_JUMBO.S */
7285/* File: x86/OP_SPUT_JUMBO.S */
7286    /*
7287     * Jumbo 32-bit SPUT handler.
7288     *
7289     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
7290     *      sput-short/jumbo
7291     */
7292    /* exop vBBBB, field@AAAAAAAA */
7293    movl      rGLUE,%ecx
7294    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7295    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7296    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7297    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7298    testl     %eax,%eax                          # resolved entry null?
7299    je        .LOP_SPUT_SHORT_JUMBO_resolve                # if not, make it so
7300.LOP_SPUT_SHORT_JUMBO_finish:     # field ptr in eax
7301    GET_VREG_R  %ecx rINST
7302    FETCH_INST_OPCODE 4 %edx
7303    ADVANCE_PC 4
7304    movl      %ecx,offStaticField_value(%eax)
7305    GOTO_NEXT_R %edx
7306
7307
7308/* ------------------------------ */
7309    .balign 64
7310.L_OP_INVOKE_VIRTUAL_JUMBO: /* 0x122 */
7311/* File: x86/OP_INVOKE_VIRTUAL_JUMBO.S */
7312    /*
7313     * Handle a jumbo virtual method call.
7314     */
7315    /* invoke-virtual/jumbo vBBBB, {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
7316    movl      rGLUE,%eax
7317    movl      2(rPC),%ecx                 # ecx<- AAAAAAAA
7318    movl      offGlue_methodClassDex(%eax),%eax  # eax<- pDvmDex
7319    EXPORT_PC
7320    movl      offDvmDex_pResMethods(%eax),%eax   # eax<- pDvmDex->pResMethods
7321    movl      (%eax,%ecx,4),%eax          # eax<- resolved baseMethod
7322    testl     %eax,%eax                   # already resolved?
7323    jne       .LOP_INVOKE_VIRTUAL_JUMBO_continue        # yes, continue
7324    movl      rGLUE,%eax
7325    movl      %ecx,OUT_ARG1(%esp)         # arg1<- ref
7326    movl      offGlue_method(%eax),%eax   # eax<- glue->method
7327    jmp       .LOP_INVOKE_VIRTUAL_JUMBO_more
7328
7329/* ------------------------------ */
7330    .balign 64
7331.L_OP_INVOKE_SUPER_JUMBO: /* 0x123 */
7332/* File: x86/OP_INVOKE_SUPER_JUMBO.S */
7333    /*
7334     * Handle a jumbo "super" method call.
7335     */
7336    /* invoke-super/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
7337    movl      rGLUE,rINST
7338    movl      2(rPC),%eax               # eax<- AAAAAAAA
7339    movl      offGlue_methodClassDex(rINST),%ecx # ecx<- pDvmDex
7340    EXPORT_PC
7341    movl      offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods
7342    movl      (%ecx,%eax,4),%ecx        # ecx<- resolved baseMethod
7343    movl      offGlue_method(rINST),%eax # eax<- method
7344    movzwl    8(rPC),rINST              # rINST<- CCCC
7345    GET_VREG_R  rINST rINST             # rINST<- "this" ptr
7346    testl     rINST,rINST               # null "this"?
7347    je        common_errNullObject      # yes, throw
7348    movl      offMethod_clazz(%eax),%eax # eax<- method->clazz
7349    testl     %ecx,%ecx                 # already resolved?
7350    jne       .LOP_INVOKE_SUPER_JUMBO_continue      # yes - go on
7351    jmp       .LOP_INVOKE_SUPER_JUMBO_resolve
7352
7353/* ------------------------------ */
7354    .balign 64
7355.L_OP_INVOKE_DIRECT_JUMBO: /* 0x124 */
7356/* File: x86/OP_INVOKE_DIRECT_JUMBO.S */
7357    /*
7358     * Handle a jumbo direct method call.
7359     *
7360     * (We could defer the "is 'this' pointer null" test to the common
7361     * method invocation code, and use a flag to indicate that static
7362     * calls don't count.  If we do this as part of copying the arguments
7363     * out we could avoiding loading the first arg twice.)
7364     */
7365    /* invoke-direct/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
7366    movl      rGLUE,%ecx
7367    movl      2(rPC),%eax              # eax<- AAAAAAAA
7368    movl      offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
7369    EXPORT_PC
7370    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
7371    movzwl    8(rPC),%edx              # edx<- CCCC
7372    movl      (%ecx,%eax,4),%eax       # eax<- resolved methodToCall
7373    testl     %eax,%eax                # already resolved?
7374    GET_VREG_R  %ecx %edx              # ecx<- "this" ptr
7375    je        .LOP_INVOKE_DIRECT_JUMBO_resolve      # not resolved, do it now
7376.LOP_INVOKE_DIRECT_JUMBO_finish:
7377    testl     %ecx,%ecx                # null "this"?
7378    jne       common_invokeMethodJumbo # no, continue on
7379    jmp       common_errNullObject
7380
7381/* ------------------------------ */
7382    .balign 64
7383.L_OP_INVOKE_STATIC_JUMBO: /* 0x125 */
7384/* File: x86/OP_INVOKE_STATIC_JUMBO.S */
7385    /*
7386     * Handle a jumbo static method call.
7387     */
7388    /* invoke-static/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
7389    movl      rGLUE,%ecx
7390    movl      2(rPC),%eax               # eax<- AAAAAAAA
7391    movl      offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
7392    EXPORT_PC
7393    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
7394    movl      (%ecx,%eax,4),%eax        # eax<- resolved methodToCall
7395    testl     %eax,%eax
7396    jne       common_invokeMethodJumbo
7397    movl      rGLUE,%ecx
7398    movl      offGlue_method(%ecx),%ecx # ecx<- glue->method
7399    movl      2(rPC),%eax               # eax<- AAAAAAAA
7400    movl      offMethod_clazz(%ecx),%ecx# ecx<- method->clazz
7401    movl      %eax,OUT_ARG1(%esp)       # arg1<- AAAAAAAA
7402    movl      %ecx,OUT_ARG0(%esp)       # arg0<- clazz
7403    jmp       .LOP_INVOKE_STATIC_JUMBO_continue
7404
7405/* ------------------------------ */
7406    .balign 64
7407.L_OP_INVOKE_INTERFACE_JUMBO: /* 0x126 */
7408/* File: x86/OP_INVOKE_INTERFACE_JUMBO.S */
7409    /*
7410     * Handle a jumbo interface method call.
7411     */
7412    /* invoke-interface/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
7413    movzwl     8(rPC),%eax              # eax<- CCCC
7414    movl       rGLUE,%ecx
7415    GET_VREG_R   %eax %eax              # eax<- "this"
7416    EXPORT_PC
7417    testl      %eax,%eax                # null this?
7418    je         common_errNullObject     # yes, fail
7419    movl       offObject_clazz(%eax),%eax# eax<- thisPtr->clazz
7420    movl       %eax,OUT_ARG0(%esp)                 # arg0<- class
7421    movl       offGlue_methodClassDex(%ecx),%eax   # eax<- methodClassDex
7422    movl       offGlue_method(%ecx),%ecx           # ecx<- method
7423    movl       %eax,OUT_ARG3(%esp)                 # arg3<- dex
7424    movl       2(rPC),%eax                         # eax<- AAAAAAAA
7425    movl       %ecx,OUT_ARG2(%esp)                 # arg2<- method
7426    movl       %eax,OUT_ARG1(%esp)                 # arg1<- AAAAAAAA
7427    jmp        .LOP_INVOKE_INTERFACE_JUMBO_continue
7428
7429/* ------------------------------ */
7430    .balign 64
7431.L_OP_UNUSED_27FF: /* 0x127 */
7432/* File: x86/OP_UNUSED_27FF.S */
7433/* File: x86/unused.S */
7434    jmp     common_abort
7435
7436
7437/* ------------------------------ */
7438    .balign 64
7439.L_OP_UNUSED_28FF: /* 0x128 */
7440/* File: x86/OP_UNUSED_28FF.S */
7441/* File: x86/unused.S */
7442    jmp     common_abort
7443
7444
7445/* ------------------------------ */
7446    .balign 64
7447.L_OP_UNUSED_29FF: /* 0x129 */
7448/* File: x86/OP_UNUSED_29FF.S */
7449/* File: x86/unused.S */
7450    jmp     common_abort
7451
7452
7453/* ------------------------------ */
7454    .balign 64
7455.L_OP_UNUSED_2AFF: /* 0x12a */
7456/* File: x86/OP_UNUSED_2AFF.S */
7457/* File: x86/unused.S */
7458    jmp     common_abort
7459
7460
7461/* ------------------------------ */
7462    .balign 64
7463.L_OP_UNUSED_2BFF: /* 0x12b */
7464/* File: x86/OP_UNUSED_2BFF.S */
7465/* File: x86/unused.S */
7466    jmp     common_abort
7467
7468
7469/* ------------------------------ */
7470    .balign 64
7471.L_OP_UNUSED_2CFF: /* 0x12c */
7472/* File: x86/OP_UNUSED_2CFF.S */
7473/* File: x86/unused.S */
7474    jmp     common_abort
7475
7476
7477/* ------------------------------ */
7478    .balign 64
7479.L_OP_UNUSED_2DFF: /* 0x12d */
7480/* File: x86/OP_UNUSED_2DFF.S */
7481/* File: x86/unused.S */
7482    jmp     common_abort
7483
7484
7485/* ------------------------------ */
7486    .balign 64
7487.L_OP_UNUSED_2EFF: /* 0x12e */
7488/* File: x86/OP_UNUSED_2EFF.S */
7489/* File: x86/unused.S */
7490    jmp     common_abort
7491
7492
7493/* ------------------------------ */
7494    .balign 64
7495.L_OP_UNUSED_2FFF: /* 0x12f */
7496/* File: x86/OP_UNUSED_2FFF.S */
7497/* File: x86/unused.S */
7498    jmp     common_abort
7499
7500
7501/* ------------------------------ */
7502    .balign 64
7503.L_OP_UNUSED_30FF: /* 0x130 */
7504/* File: x86/OP_UNUSED_30FF.S */
7505/* File: x86/unused.S */
7506    jmp     common_abort
7507
7508
7509/* ------------------------------ */
7510    .balign 64
7511.L_OP_UNUSED_31FF: /* 0x131 */
7512/* File: x86/OP_UNUSED_31FF.S */
7513/* File: x86/unused.S */
7514    jmp     common_abort
7515
7516
7517/* ------------------------------ */
7518    .balign 64
7519.L_OP_UNUSED_32FF: /* 0x132 */
7520/* File: x86/OP_UNUSED_32FF.S */
7521/* File: x86/unused.S */
7522    jmp     common_abort
7523
7524
7525/* ------------------------------ */
7526    .balign 64
7527.L_OP_UNUSED_33FF: /* 0x133 */
7528/* File: x86/OP_UNUSED_33FF.S */
7529/* File: x86/unused.S */
7530    jmp     common_abort
7531
7532
7533/* ------------------------------ */
7534    .balign 64
7535.L_OP_UNUSED_34FF: /* 0x134 */
7536/* File: x86/OP_UNUSED_34FF.S */
7537/* File: x86/unused.S */
7538    jmp     common_abort
7539
7540
7541/* ------------------------------ */
7542    .balign 64
7543.L_OP_UNUSED_35FF: /* 0x135 */
7544/* File: x86/OP_UNUSED_35FF.S */
7545/* File: x86/unused.S */
7546    jmp     common_abort
7547
7548
7549/* ------------------------------ */
7550    .balign 64
7551.L_OP_UNUSED_36FF: /* 0x136 */
7552/* File: x86/OP_UNUSED_36FF.S */
7553/* File: x86/unused.S */
7554    jmp     common_abort
7555
7556
7557/* ------------------------------ */
7558    .balign 64
7559.L_OP_UNUSED_37FF: /* 0x137 */
7560/* File: x86/OP_UNUSED_37FF.S */
7561/* File: x86/unused.S */
7562    jmp     common_abort
7563
7564
7565/* ------------------------------ */
7566    .balign 64
7567.L_OP_UNUSED_38FF: /* 0x138 */
7568/* File: x86/OP_UNUSED_38FF.S */
7569/* File: x86/unused.S */
7570    jmp     common_abort
7571
7572
7573/* ------------------------------ */
7574    .balign 64
7575.L_OP_UNUSED_39FF: /* 0x139 */
7576/* File: x86/OP_UNUSED_39FF.S */
7577/* File: x86/unused.S */
7578    jmp     common_abort
7579
7580
7581/* ------------------------------ */
7582    .balign 64
7583.L_OP_UNUSED_3AFF: /* 0x13a */
7584/* File: x86/OP_UNUSED_3AFF.S */
7585/* File: x86/unused.S */
7586    jmp     common_abort
7587
7588
7589/* ------------------------------ */
7590    .balign 64
7591.L_OP_UNUSED_3BFF: /* 0x13b */
7592/* File: x86/OP_UNUSED_3BFF.S */
7593/* File: x86/unused.S */
7594    jmp     common_abort
7595
7596
7597/* ------------------------------ */
7598    .balign 64
7599.L_OP_UNUSED_3CFF: /* 0x13c */
7600/* File: x86/OP_UNUSED_3CFF.S */
7601/* File: x86/unused.S */
7602    jmp     common_abort
7603
7604
7605/* ------------------------------ */
7606    .balign 64
7607.L_OP_UNUSED_3DFF: /* 0x13d */
7608/* File: x86/OP_UNUSED_3DFF.S */
7609/* File: x86/unused.S */
7610    jmp     common_abort
7611
7612
7613/* ------------------------------ */
7614    .balign 64
7615.L_OP_UNUSED_3EFF: /* 0x13e */
7616/* File: x86/OP_UNUSED_3EFF.S */
7617/* File: x86/unused.S */
7618    jmp     common_abort
7619
7620
7621/* ------------------------------ */
7622    .balign 64
7623.L_OP_UNUSED_3FFF: /* 0x13f */
7624/* File: x86/OP_UNUSED_3FFF.S */
7625/* File: x86/unused.S */
7626    jmp     common_abort
7627
7628
7629/* ------------------------------ */
7630    .balign 64
7631.L_OP_UNUSED_40FF: /* 0x140 */
7632/* File: x86/OP_UNUSED_40FF.S */
7633/* File: x86/unused.S */
7634    jmp     common_abort
7635
7636
7637/* ------------------------------ */
7638    .balign 64
7639.L_OP_UNUSED_41FF: /* 0x141 */
7640/* File: x86/OP_UNUSED_41FF.S */
7641/* File: x86/unused.S */
7642    jmp     common_abort
7643
7644
7645/* ------------------------------ */
7646    .balign 64
7647.L_OP_UNUSED_42FF: /* 0x142 */
7648/* File: x86/OP_UNUSED_42FF.S */
7649/* File: x86/unused.S */
7650    jmp     common_abort
7651
7652
7653/* ------------------------------ */
7654    .balign 64
7655.L_OP_UNUSED_43FF: /* 0x143 */
7656/* File: x86/OP_UNUSED_43FF.S */
7657/* File: x86/unused.S */
7658    jmp     common_abort
7659
7660
7661/* ------------------------------ */
7662    .balign 64
7663.L_OP_UNUSED_44FF: /* 0x144 */
7664/* File: x86/OP_UNUSED_44FF.S */
7665/* File: x86/unused.S */
7666    jmp     common_abort
7667
7668
7669/* ------------------------------ */
7670    .balign 64
7671.L_OP_UNUSED_45FF: /* 0x145 */
7672/* File: x86/OP_UNUSED_45FF.S */
7673/* File: x86/unused.S */
7674    jmp     common_abort
7675
7676
7677/* ------------------------------ */
7678    .balign 64
7679.L_OP_UNUSED_46FF: /* 0x146 */
7680/* File: x86/OP_UNUSED_46FF.S */
7681/* File: x86/unused.S */
7682    jmp     common_abort
7683
7684
7685/* ------------------------------ */
7686    .balign 64
7687.L_OP_UNUSED_47FF: /* 0x147 */
7688/* File: x86/OP_UNUSED_47FF.S */
7689/* File: x86/unused.S */
7690    jmp     common_abort
7691
7692
7693/* ------------------------------ */
7694    .balign 64
7695.L_OP_UNUSED_48FF: /* 0x148 */
7696/* File: x86/OP_UNUSED_48FF.S */
7697/* File: x86/unused.S */
7698    jmp     common_abort
7699
7700
7701/* ------------------------------ */
7702    .balign 64
7703.L_OP_UNUSED_49FF: /* 0x149 */
7704/* File: x86/OP_UNUSED_49FF.S */
7705/* File: x86/unused.S */
7706    jmp     common_abort
7707
7708
7709/* ------------------------------ */
7710    .balign 64
7711.L_OP_UNUSED_4AFF: /* 0x14a */
7712/* File: x86/OP_UNUSED_4AFF.S */
7713/* File: x86/unused.S */
7714    jmp     common_abort
7715
7716
7717/* ------------------------------ */
7718    .balign 64
7719.L_OP_UNUSED_4BFF: /* 0x14b */
7720/* File: x86/OP_UNUSED_4BFF.S */
7721/* File: x86/unused.S */
7722    jmp     common_abort
7723
7724
7725/* ------------------------------ */
7726    .balign 64
7727.L_OP_UNUSED_4CFF: /* 0x14c */
7728/* File: x86/OP_UNUSED_4CFF.S */
7729/* File: x86/unused.S */
7730    jmp     common_abort
7731
7732
7733/* ------------------------------ */
7734    .balign 64
7735.L_OP_UNUSED_4DFF: /* 0x14d */
7736/* File: x86/OP_UNUSED_4DFF.S */
7737/* File: x86/unused.S */
7738    jmp     common_abort
7739
7740
7741/* ------------------------------ */
7742    .balign 64
7743.L_OP_UNUSED_4EFF: /* 0x14e */
7744/* File: x86/OP_UNUSED_4EFF.S */
7745/* File: x86/unused.S */
7746    jmp     common_abort
7747
7748
7749/* ------------------------------ */
7750    .balign 64
7751.L_OP_UNUSED_4FFF: /* 0x14f */
7752/* File: x86/OP_UNUSED_4FFF.S */
7753/* File: x86/unused.S */
7754    jmp     common_abort
7755
7756
7757/* ------------------------------ */
7758    .balign 64
7759.L_OP_UNUSED_50FF: /* 0x150 */
7760/* File: x86/OP_UNUSED_50FF.S */
7761/* File: x86/unused.S */
7762    jmp     common_abort
7763
7764
7765/* ------------------------------ */
7766    .balign 64
7767.L_OP_UNUSED_51FF: /* 0x151 */
7768/* File: x86/OP_UNUSED_51FF.S */
7769/* File: x86/unused.S */
7770    jmp     common_abort
7771
7772
7773/* ------------------------------ */
7774    .balign 64
7775.L_OP_UNUSED_52FF: /* 0x152 */
7776/* File: x86/OP_UNUSED_52FF.S */
7777/* File: x86/unused.S */
7778    jmp     common_abort
7779
7780
7781/* ------------------------------ */
7782    .balign 64
7783.L_OP_UNUSED_53FF: /* 0x153 */
7784/* File: x86/OP_UNUSED_53FF.S */
7785/* File: x86/unused.S */
7786    jmp     common_abort
7787
7788
7789/* ------------------------------ */
7790    .balign 64
7791.L_OP_UNUSED_54FF: /* 0x154 */
7792/* File: x86/OP_UNUSED_54FF.S */
7793/* File: x86/unused.S */
7794    jmp     common_abort
7795
7796
7797/* ------------------------------ */
7798    .balign 64
7799.L_OP_UNUSED_55FF: /* 0x155 */
7800/* File: x86/OP_UNUSED_55FF.S */
7801/* File: x86/unused.S */
7802    jmp     common_abort
7803
7804
7805/* ------------------------------ */
7806    .balign 64
7807.L_OP_UNUSED_56FF: /* 0x156 */
7808/* File: x86/OP_UNUSED_56FF.S */
7809/* File: x86/unused.S */
7810    jmp     common_abort
7811
7812
7813/* ------------------------------ */
7814    .balign 64
7815.L_OP_UNUSED_57FF: /* 0x157 */
7816/* File: x86/OP_UNUSED_57FF.S */
7817/* File: x86/unused.S */
7818    jmp     common_abort
7819
7820
7821/* ------------------------------ */
7822    .balign 64
7823.L_OP_UNUSED_58FF: /* 0x158 */
7824/* File: x86/OP_UNUSED_58FF.S */
7825/* File: x86/unused.S */
7826    jmp     common_abort
7827
7828
7829/* ------------------------------ */
7830    .balign 64
7831.L_OP_UNUSED_59FF: /* 0x159 */
7832/* File: x86/OP_UNUSED_59FF.S */
7833/* File: x86/unused.S */
7834    jmp     common_abort
7835
7836
7837/* ------------------------------ */
7838    .balign 64
7839.L_OP_UNUSED_5AFF: /* 0x15a */
7840/* File: x86/OP_UNUSED_5AFF.S */
7841/* File: x86/unused.S */
7842    jmp     common_abort
7843
7844
7845/* ------------------------------ */
7846    .balign 64
7847.L_OP_UNUSED_5BFF: /* 0x15b */
7848/* File: x86/OP_UNUSED_5BFF.S */
7849/* File: x86/unused.S */
7850    jmp     common_abort
7851
7852
7853/* ------------------------------ */
7854    .balign 64
7855.L_OP_UNUSED_5CFF: /* 0x15c */
7856/* File: x86/OP_UNUSED_5CFF.S */
7857/* File: x86/unused.S */
7858    jmp     common_abort
7859
7860
7861/* ------------------------------ */
7862    .balign 64
7863.L_OP_UNUSED_5DFF: /* 0x15d */
7864/* File: x86/OP_UNUSED_5DFF.S */
7865/* File: x86/unused.S */
7866    jmp     common_abort
7867
7868
7869/* ------------------------------ */
7870    .balign 64
7871.L_OP_UNUSED_5EFF: /* 0x15e */
7872/* File: x86/OP_UNUSED_5EFF.S */
7873/* File: x86/unused.S */
7874    jmp     common_abort
7875
7876
7877/* ------------------------------ */
7878    .balign 64
7879.L_OP_UNUSED_5FFF: /* 0x15f */
7880/* File: x86/OP_UNUSED_5FFF.S */
7881/* File: x86/unused.S */
7882    jmp     common_abort
7883
7884
7885/* ------------------------------ */
7886    .balign 64
7887.L_OP_UNUSED_60FF: /* 0x160 */
7888/* File: x86/OP_UNUSED_60FF.S */
7889/* File: x86/unused.S */
7890    jmp     common_abort
7891
7892
7893/* ------------------------------ */
7894    .balign 64
7895.L_OP_UNUSED_61FF: /* 0x161 */
7896/* File: x86/OP_UNUSED_61FF.S */
7897/* File: x86/unused.S */
7898    jmp     common_abort
7899
7900
7901/* ------------------------------ */
7902    .balign 64
7903.L_OP_UNUSED_62FF: /* 0x162 */
7904/* File: x86/OP_UNUSED_62FF.S */
7905/* File: x86/unused.S */
7906    jmp     common_abort
7907
7908
7909/* ------------------------------ */
7910    .balign 64
7911.L_OP_UNUSED_63FF: /* 0x163 */
7912/* File: x86/OP_UNUSED_63FF.S */
7913/* File: x86/unused.S */
7914    jmp     common_abort
7915
7916
7917/* ------------------------------ */
7918    .balign 64
7919.L_OP_UNUSED_64FF: /* 0x164 */
7920/* File: x86/OP_UNUSED_64FF.S */
7921/* File: x86/unused.S */
7922    jmp     common_abort
7923
7924
7925/* ------------------------------ */
7926    .balign 64
7927.L_OP_UNUSED_65FF: /* 0x165 */
7928/* File: x86/OP_UNUSED_65FF.S */
7929/* File: x86/unused.S */
7930    jmp     common_abort
7931
7932
7933/* ------------------------------ */
7934    .balign 64
7935.L_OP_UNUSED_66FF: /* 0x166 */
7936/* File: x86/OP_UNUSED_66FF.S */
7937/* File: x86/unused.S */
7938    jmp     common_abort
7939
7940
7941/* ------------------------------ */
7942    .balign 64
7943.L_OP_UNUSED_67FF: /* 0x167 */
7944/* File: x86/OP_UNUSED_67FF.S */
7945/* File: x86/unused.S */
7946    jmp     common_abort
7947
7948
7949/* ------------------------------ */
7950    .balign 64
7951.L_OP_UNUSED_68FF: /* 0x168 */
7952/* File: x86/OP_UNUSED_68FF.S */
7953/* File: x86/unused.S */
7954    jmp     common_abort
7955
7956
7957/* ------------------------------ */
7958    .balign 64
7959.L_OP_UNUSED_69FF: /* 0x169 */
7960/* File: x86/OP_UNUSED_69FF.S */
7961/* File: x86/unused.S */
7962    jmp     common_abort
7963
7964
7965/* ------------------------------ */
7966    .balign 64
7967.L_OP_UNUSED_6AFF: /* 0x16a */
7968/* File: x86/OP_UNUSED_6AFF.S */
7969/* File: x86/unused.S */
7970    jmp     common_abort
7971
7972
7973/* ------------------------------ */
7974    .balign 64
7975.L_OP_UNUSED_6BFF: /* 0x16b */
7976/* File: x86/OP_UNUSED_6BFF.S */
7977/* File: x86/unused.S */
7978    jmp     common_abort
7979
7980
7981/* ------------------------------ */
7982    .balign 64
7983.L_OP_UNUSED_6CFF: /* 0x16c */
7984/* File: x86/OP_UNUSED_6CFF.S */
7985/* File: x86/unused.S */
7986    jmp     common_abort
7987
7988
7989/* ------------------------------ */
7990    .balign 64
7991.L_OP_UNUSED_6DFF: /* 0x16d */
7992/* File: x86/OP_UNUSED_6DFF.S */
7993/* File: x86/unused.S */
7994    jmp     common_abort
7995
7996
7997/* ------------------------------ */
7998    .balign 64
7999.L_OP_UNUSED_6EFF: /* 0x16e */
8000/* File: x86/OP_UNUSED_6EFF.S */
8001/* File: x86/unused.S */
8002    jmp     common_abort
8003
8004
8005/* ------------------------------ */
8006    .balign 64
8007.L_OP_UNUSED_6FFF: /* 0x16f */
8008/* File: x86/OP_UNUSED_6FFF.S */
8009/* File: x86/unused.S */
8010    jmp     common_abort
8011
8012
8013/* ------------------------------ */
8014    .balign 64
8015.L_OP_UNUSED_70FF: /* 0x170 */
8016/* File: x86/OP_UNUSED_70FF.S */
8017/* File: x86/unused.S */
8018    jmp     common_abort
8019
8020
8021/* ------------------------------ */
8022    .balign 64
8023.L_OP_UNUSED_71FF: /* 0x171 */
8024/* File: x86/OP_UNUSED_71FF.S */
8025/* File: x86/unused.S */
8026    jmp     common_abort
8027
8028
8029/* ------------------------------ */
8030    .balign 64
8031.L_OP_UNUSED_72FF: /* 0x172 */
8032/* File: x86/OP_UNUSED_72FF.S */
8033/* File: x86/unused.S */
8034    jmp     common_abort
8035
8036
8037/* ------------------------------ */
8038    .balign 64
8039.L_OP_UNUSED_73FF: /* 0x173 */
8040/* File: x86/OP_UNUSED_73FF.S */
8041/* File: x86/unused.S */
8042    jmp     common_abort
8043
8044
8045/* ------------------------------ */
8046    .balign 64
8047.L_OP_UNUSED_74FF: /* 0x174 */
8048/* File: x86/OP_UNUSED_74FF.S */
8049/* File: x86/unused.S */
8050    jmp     common_abort
8051
8052
8053/* ------------------------------ */
8054    .balign 64
8055.L_OP_UNUSED_75FF: /* 0x175 */
8056/* File: x86/OP_UNUSED_75FF.S */
8057/* File: x86/unused.S */
8058    jmp     common_abort
8059
8060
8061/* ------------------------------ */
8062    .balign 64
8063.L_OP_UNUSED_76FF: /* 0x176 */
8064/* File: x86/OP_UNUSED_76FF.S */
8065/* File: x86/unused.S */
8066    jmp     common_abort
8067
8068
8069/* ------------------------------ */
8070    .balign 64
8071.L_OP_UNUSED_77FF: /* 0x177 */
8072/* File: x86/OP_UNUSED_77FF.S */
8073/* File: x86/unused.S */
8074    jmp     common_abort
8075
8076
8077/* ------------------------------ */
8078    .balign 64
8079.L_OP_UNUSED_78FF: /* 0x178 */
8080/* File: x86/OP_UNUSED_78FF.S */
8081/* File: x86/unused.S */
8082    jmp     common_abort
8083
8084
8085/* ------------------------------ */
8086    .balign 64
8087.L_OP_UNUSED_79FF: /* 0x179 */
8088/* File: x86/OP_UNUSED_79FF.S */
8089/* File: x86/unused.S */
8090    jmp     common_abort
8091
8092
8093/* ------------------------------ */
8094    .balign 64
8095.L_OP_UNUSED_7AFF: /* 0x17a */
8096/* File: x86/OP_UNUSED_7AFF.S */
8097/* File: x86/unused.S */
8098    jmp     common_abort
8099
8100
8101/* ------------------------------ */
8102    .balign 64
8103.L_OP_UNUSED_7BFF: /* 0x17b */
8104/* File: x86/OP_UNUSED_7BFF.S */
8105/* File: x86/unused.S */
8106    jmp     common_abort
8107
8108
8109/* ------------------------------ */
8110    .balign 64
8111.L_OP_UNUSED_7CFF: /* 0x17c */
8112/* File: x86/OP_UNUSED_7CFF.S */
8113/* File: x86/unused.S */
8114    jmp     common_abort
8115
8116
8117/* ------------------------------ */
8118    .balign 64
8119.L_OP_UNUSED_7DFF: /* 0x17d */
8120/* File: x86/OP_UNUSED_7DFF.S */
8121/* File: x86/unused.S */
8122    jmp     common_abort
8123
8124
8125/* ------------------------------ */
8126    .balign 64
8127.L_OP_UNUSED_7EFF: /* 0x17e */
8128/* File: x86/OP_UNUSED_7EFF.S */
8129/* File: x86/unused.S */
8130    jmp     common_abort
8131
8132
8133/* ------------------------------ */
8134    .balign 64
8135.L_OP_UNUSED_7FFF: /* 0x17f */
8136/* File: x86/OP_UNUSED_7FFF.S */
8137/* File: x86/unused.S */
8138    jmp     common_abort
8139
8140
8141/* ------------------------------ */
8142    .balign 64
8143.L_OP_UNUSED_80FF: /* 0x180 */
8144/* File: x86/OP_UNUSED_80FF.S */
8145/* File: x86/unused.S */
8146    jmp     common_abort
8147
8148
8149/* ------------------------------ */
8150    .balign 64
8151.L_OP_UNUSED_81FF: /* 0x181 */
8152/* File: x86/OP_UNUSED_81FF.S */
8153/* File: x86/unused.S */
8154    jmp     common_abort
8155
8156
8157/* ------------------------------ */
8158    .balign 64
8159.L_OP_UNUSED_82FF: /* 0x182 */
8160/* File: x86/OP_UNUSED_82FF.S */
8161/* File: x86/unused.S */
8162    jmp     common_abort
8163
8164
8165/* ------------------------------ */
8166    .balign 64
8167.L_OP_UNUSED_83FF: /* 0x183 */
8168/* File: x86/OP_UNUSED_83FF.S */
8169/* File: x86/unused.S */
8170    jmp     common_abort
8171
8172
8173/* ------------------------------ */
8174    .balign 64
8175.L_OP_UNUSED_84FF: /* 0x184 */
8176/* File: x86/OP_UNUSED_84FF.S */
8177/* File: x86/unused.S */
8178    jmp     common_abort
8179
8180
8181/* ------------------------------ */
8182    .balign 64
8183.L_OP_UNUSED_85FF: /* 0x185 */
8184/* File: x86/OP_UNUSED_85FF.S */
8185/* File: x86/unused.S */
8186    jmp     common_abort
8187
8188
8189/* ------------------------------ */
8190    .balign 64
8191.L_OP_UNUSED_86FF: /* 0x186 */
8192/* File: x86/OP_UNUSED_86FF.S */
8193/* File: x86/unused.S */
8194    jmp     common_abort
8195
8196
8197/* ------------------------------ */
8198    .balign 64
8199.L_OP_UNUSED_87FF: /* 0x187 */
8200/* File: x86/OP_UNUSED_87FF.S */
8201/* File: x86/unused.S */
8202    jmp     common_abort
8203
8204
8205/* ------------------------------ */
8206    .balign 64
8207.L_OP_UNUSED_88FF: /* 0x188 */
8208/* File: x86/OP_UNUSED_88FF.S */
8209/* File: x86/unused.S */
8210    jmp     common_abort
8211
8212
8213/* ------------------------------ */
8214    .balign 64
8215.L_OP_UNUSED_89FF: /* 0x189 */
8216/* File: x86/OP_UNUSED_89FF.S */
8217/* File: x86/unused.S */
8218    jmp     common_abort
8219
8220
8221/* ------------------------------ */
8222    .balign 64
8223.L_OP_UNUSED_8AFF: /* 0x18a */
8224/* File: x86/OP_UNUSED_8AFF.S */
8225/* File: x86/unused.S */
8226    jmp     common_abort
8227
8228
8229/* ------------------------------ */
8230    .balign 64
8231.L_OP_UNUSED_8BFF: /* 0x18b */
8232/* File: x86/OP_UNUSED_8BFF.S */
8233/* File: x86/unused.S */
8234    jmp     common_abort
8235
8236
8237/* ------------------------------ */
8238    .balign 64
8239.L_OP_UNUSED_8CFF: /* 0x18c */
8240/* File: x86/OP_UNUSED_8CFF.S */
8241/* File: x86/unused.S */
8242    jmp     common_abort
8243
8244
8245/* ------------------------------ */
8246    .balign 64
8247.L_OP_UNUSED_8DFF: /* 0x18d */
8248/* File: x86/OP_UNUSED_8DFF.S */
8249/* File: x86/unused.S */
8250    jmp     common_abort
8251
8252
8253/* ------------------------------ */
8254    .balign 64
8255.L_OP_UNUSED_8EFF: /* 0x18e */
8256/* File: x86/OP_UNUSED_8EFF.S */
8257/* File: x86/unused.S */
8258    jmp     common_abort
8259
8260
8261/* ------------------------------ */
8262    .balign 64
8263.L_OP_UNUSED_8FFF: /* 0x18f */
8264/* File: x86/OP_UNUSED_8FFF.S */
8265/* File: x86/unused.S */
8266    jmp     common_abort
8267
8268
8269/* ------------------------------ */
8270    .balign 64
8271.L_OP_UNUSED_90FF: /* 0x190 */
8272/* File: x86/OP_UNUSED_90FF.S */
8273/* File: x86/unused.S */
8274    jmp     common_abort
8275
8276
8277/* ------------------------------ */
8278    .balign 64
8279.L_OP_UNUSED_91FF: /* 0x191 */
8280/* File: x86/OP_UNUSED_91FF.S */
8281/* File: x86/unused.S */
8282    jmp     common_abort
8283
8284
8285/* ------------------------------ */
8286    .balign 64
8287.L_OP_UNUSED_92FF: /* 0x192 */
8288/* File: x86/OP_UNUSED_92FF.S */
8289/* File: x86/unused.S */
8290    jmp     common_abort
8291
8292
8293/* ------------------------------ */
8294    .balign 64
8295.L_OP_UNUSED_93FF: /* 0x193 */
8296/* File: x86/OP_UNUSED_93FF.S */
8297/* File: x86/unused.S */
8298    jmp     common_abort
8299
8300
8301/* ------------------------------ */
8302    .balign 64
8303.L_OP_UNUSED_94FF: /* 0x194 */
8304/* File: x86/OP_UNUSED_94FF.S */
8305/* File: x86/unused.S */
8306    jmp     common_abort
8307
8308
8309/* ------------------------------ */
8310    .balign 64
8311.L_OP_UNUSED_95FF: /* 0x195 */
8312/* File: x86/OP_UNUSED_95FF.S */
8313/* File: x86/unused.S */
8314    jmp     common_abort
8315
8316
8317/* ------------------------------ */
8318    .balign 64
8319.L_OP_UNUSED_96FF: /* 0x196 */
8320/* File: x86/OP_UNUSED_96FF.S */
8321/* File: x86/unused.S */
8322    jmp     common_abort
8323
8324
8325/* ------------------------------ */
8326    .balign 64
8327.L_OP_UNUSED_97FF: /* 0x197 */
8328/* File: x86/OP_UNUSED_97FF.S */
8329/* File: x86/unused.S */
8330    jmp     common_abort
8331
8332
8333/* ------------------------------ */
8334    .balign 64
8335.L_OP_UNUSED_98FF: /* 0x198 */
8336/* File: x86/OP_UNUSED_98FF.S */
8337/* File: x86/unused.S */
8338    jmp     common_abort
8339
8340
8341/* ------------------------------ */
8342    .balign 64
8343.L_OP_UNUSED_99FF: /* 0x199 */
8344/* File: x86/OP_UNUSED_99FF.S */
8345/* File: x86/unused.S */
8346    jmp     common_abort
8347
8348
8349/* ------------------------------ */
8350    .balign 64
8351.L_OP_UNUSED_9AFF: /* 0x19a */
8352/* File: x86/OP_UNUSED_9AFF.S */
8353/* File: x86/unused.S */
8354    jmp     common_abort
8355
8356
8357/* ------------------------------ */
8358    .balign 64
8359.L_OP_UNUSED_9BFF: /* 0x19b */
8360/* File: x86/OP_UNUSED_9BFF.S */
8361/* File: x86/unused.S */
8362    jmp     common_abort
8363
8364
8365/* ------------------------------ */
8366    .balign 64
8367.L_OP_UNUSED_9CFF: /* 0x19c */
8368/* File: x86/OP_UNUSED_9CFF.S */
8369/* File: x86/unused.S */
8370    jmp     common_abort
8371
8372
8373/* ------------------------------ */
8374    .balign 64
8375.L_OP_UNUSED_9DFF: /* 0x19d */
8376/* File: x86/OP_UNUSED_9DFF.S */
8377/* File: x86/unused.S */
8378    jmp     common_abort
8379
8380
8381/* ------------------------------ */
8382    .balign 64
8383.L_OP_UNUSED_9EFF: /* 0x19e */
8384/* File: x86/OP_UNUSED_9EFF.S */
8385/* File: x86/unused.S */
8386    jmp     common_abort
8387
8388
8389/* ------------------------------ */
8390    .balign 64
8391.L_OP_UNUSED_9FFF: /* 0x19f */
8392/* File: x86/OP_UNUSED_9FFF.S */
8393/* File: x86/unused.S */
8394    jmp     common_abort
8395
8396
8397/* ------------------------------ */
8398    .balign 64
8399.L_OP_UNUSED_A0FF: /* 0x1a0 */
8400/* File: x86/OP_UNUSED_A0FF.S */
8401/* File: x86/unused.S */
8402    jmp     common_abort
8403
8404
8405/* ------------------------------ */
8406    .balign 64
8407.L_OP_UNUSED_A1FF: /* 0x1a1 */
8408/* File: x86/OP_UNUSED_A1FF.S */
8409/* File: x86/unused.S */
8410    jmp     common_abort
8411
8412
8413/* ------------------------------ */
8414    .balign 64
8415.L_OP_UNUSED_A2FF: /* 0x1a2 */
8416/* File: x86/OP_UNUSED_A2FF.S */
8417/* File: x86/unused.S */
8418    jmp     common_abort
8419
8420
8421/* ------------------------------ */
8422    .balign 64
8423.L_OP_UNUSED_A3FF: /* 0x1a3 */
8424/* File: x86/OP_UNUSED_A3FF.S */
8425/* File: x86/unused.S */
8426    jmp     common_abort
8427
8428
8429/* ------------------------------ */
8430    .balign 64
8431.L_OP_UNUSED_A4FF: /* 0x1a4 */
8432/* File: x86/OP_UNUSED_A4FF.S */
8433/* File: x86/unused.S */
8434    jmp     common_abort
8435
8436
8437/* ------------------------------ */
8438    .balign 64
8439.L_OP_UNUSED_A5FF: /* 0x1a5 */
8440/* File: x86/OP_UNUSED_A5FF.S */
8441/* File: x86/unused.S */
8442    jmp     common_abort
8443
8444
8445/* ------------------------------ */
8446    .balign 64
8447.L_OP_UNUSED_A6FF: /* 0x1a6 */
8448/* File: x86/OP_UNUSED_A6FF.S */
8449/* File: x86/unused.S */
8450    jmp     common_abort
8451
8452
8453/* ------------------------------ */
8454    .balign 64
8455.L_OP_UNUSED_A7FF: /* 0x1a7 */
8456/* File: x86/OP_UNUSED_A7FF.S */
8457/* File: x86/unused.S */
8458    jmp     common_abort
8459
8460
8461/* ------------------------------ */
8462    .balign 64
8463.L_OP_UNUSED_A8FF: /* 0x1a8 */
8464/* File: x86/OP_UNUSED_A8FF.S */
8465/* File: x86/unused.S */
8466    jmp     common_abort
8467
8468
8469/* ------------------------------ */
8470    .balign 64
8471.L_OP_UNUSED_A9FF: /* 0x1a9 */
8472/* File: x86/OP_UNUSED_A9FF.S */
8473/* File: x86/unused.S */
8474    jmp     common_abort
8475
8476
8477/* ------------------------------ */
8478    .balign 64
8479.L_OP_UNUSED_AAFF: /* 0x1aa */
8480/* File: x86/OP_UNUSED_AAFF.S */
8481/* File: x86/unused.S */
8482    jmp     common_abort
8483
8484
8485/* ------------------------------ */
8486    .balign 64
8487.L_OP_UNUSED_ABFF: /* 0x1ab */
8488/* File: x86/OP_UNUSED_ABFF.S */
8489/* File: x86/unused.S */
8490    jmp     common_abort
8491
8492
8493/* ------------------------------ */
8494    .balign 64
8495.L_OP_UNUSED_ACFF: /* 0x1ac */
8496/* File: x86/OP_UNUSED_ACFF.S */
8497/* File: x86/unused.S */
8498    jmp     common_abort
8499
8500
8501/* ------------------------------ */
8502    .balign 64
8503.L_OP_UNUSED_ADFF: /* 0x1ad */
8504/* File: x86/OP_UNUSED_ADFF.S */
8505/* File: x86/unused.S */
8506    jmp     common_abort
8507
8508
8509/* ------------------------------ */
8510    .balign 64
8511.L_OP_UNUSED_AEFF: /* 0x1ae */
8512/* File: x86/OP_UNUSED_AEFF.S */
8513/* File: x86/unused.S */
8514    jmp     common_abort
8515
8516
8517/* ------------------------------ */
8518    .balign 64
8519.L_OP_UNUSED_AFFF: /* 0x1af */
8520/* File: x86/OP_UNUSED_AFFF.S */
8521/* File: x86/unused.S */
8522    jmp     common_abort
8523
8524
8525/* ------------------------------ */
8526    .balign 64
8527.L_OP_UNUSED_B0FF: /* 0x1b0 */
8528/* File: x86/OP_UNUSED_B0FF.S */
8529/* File: x86/unused.S */
8530    jmp     common_abort
8531
8532
8533/* ------------------------------ */
8534    .balign 64
8535.L_OP_UNUSED_B1FF: /* 0x1b1 */
8536/* File: x86/OP_UNUSED_B1FF.S */
8537/* File: x86/unused.S */
8538    jmp     common_abort
8539
8540
8541/* ------------------------------ */
8542    .balign 64
8543.L_OP_UNUSED_B2FF: /* 0x1b2 */
8544/* File: x86/OP_UNUSED_B2FF.S */
8545/* File: x86/unused.S */
8546    jmp     common_abort
8547
8548
8549/* ------------------------------ */
8550    .balign 64
8551.L_OP_UNUSED_B3FF: /* 0x1b3 */
8552/* File: x86/OP_UNUSED_B3FF.S */
8553/* File: x86/unused.S */
8554    jmp     common_abort
8555
8556
8557/* ------------------------------ */
8558    .balign 64
8559.L_OP_UNUSED_B4FF: /* 0x1b4 */
8560/* File: x86/OP_UNUSED_B4FF.S */
8561/* File: x86/unused.S */
8562    jmp     common_abort
8563
8564
8565/* ------------------------------ */
8566    .balign 64
8567.L_OP_UNUSED_B5FF: /* 0x1b5 */
8568/* File: x86/OP_UNUSED_B5FF.S */
8569/* File: x86/unused.S */
8570    jmp     common_abort
8571
8572
8573/* ------------------------------ */
8574    .balign 64
8575.L_OP_UNUSED_B6FF: /* 0x1b6 */
8576/* File: x86/OP_UNUSED_B6FF.S */
8577/* File: x86/unused.S */
8578    jmp     common_abort
8579
8580
8581/* ------------------------------ */
8582    .balign 64
8583.L_OP_UNUSED_B7FF: /* 0x1b7 */
8584/* File: x86/OP_UNUSED_B7FF.S */
8585/* File: x86/unused.S */
8586    jmp     common_abort
8587
8588
8589/* ------------------------------ */
8590    .balign 64
8591.L_OP_UNUSED_B8FF: /* 0x1b8 */
8592/* File: x86/OP_UNUSED_B8FF.S */
8593/* File: x86/unused.S */
8594    jmp     common_abort
8595
8596
8597/* ------------------------------ */
8598    .balign 64
8599.L_OP_UNUSED_B9FF: /* 0x1b9 */
8600/* File: x86/OP_UNUSED_B9FF.S */
8601/* File: x86/unused.S */
8602    jmp     common_abort
8603
8604
8605/* ------------------------------ */
8606    .balign 64
8607.L_OP_UNUSED_BAFF: /* 0x1ba */
8608/* File: x86/OP_UNUSED_BAFF.S */
8609/* File: x86/unused.S */
8610    jmp     common_abort
8611
8612
8613/* ------------------------------ */
8614    .balign 64
8615.L_OP_UNUSED_BBFF: /* 0x1bb */
8616/* File: x86/OP_UNUSED_BBFF.S */
8617/* File: x86/unused.S */
8618    jmp     common_abort
8619
8620
8621/* ------------------------------ */
8622    .balign 64
8623.L_OP_UNUSED_BCFF: /* 0x1bc */
8624/* File: x86/OP_UNUSED_BCFF.S */
8625/* File: x86/unused.S */
8626    jmp     common_abort
8627
8628
8629/* ------------------------------ */
8630    .balign 64
8631.L_OP_UNUSED_BDFF: /* 0x1bd */
8632/* File: x86/OP_UNUSED_BDFF.S */
8633/* File: x86/unused.S */
8634    jmp     common_abort
8635
8636
8637/* ------------------------------ */
8638    .balign 64
8639.L_OP_UNUSED_BEFF: /* 0x1be */
8640/* File: x86/OP_UNUSED_BEFF.S */
8641/* File: x86/unused.S */
8642    jmp     common_abort
8643
8644
8645/* ------------------------------ */
8646    .balign 64
8647.L_OP_UNUSED_BFFF: /* 0x1bf */
8648/* File: x86/OP_UNUSED_BFFF.S */
8649/* File: x86/unused.S */
8650    jmp     common_abort
8651
8652
8653/* ------------------------------ */
8654    .balign 64
8655.L_OP_UNUSED_C0FF: /* 0x1c0 */
8656/* File: x86/OP_UNUSED_C0FF.S */
8657/* File: x86/unused.S */
8658    jmp     common_abort
8659
8660
8661/* ------------------------------ */
8662    .balign 64
8663.L_OP_UNUSED_C1FF: /* 0x1c1 */
8664/* File: x86/OP_UNUSED_C1FF.S */
8665/* File: x86/unused.S */
8666    jmp     common_abort
8667
8668
8669/* ------------------------------ */
8670    .balign 64
8671.L_OP_UNUSED_C2FF: /* 0x1c2 */
8672/* File: x86/OP_UNUSED_C2FF.S */
8673/* File: x86/unused.S */
8674    jmp     common_abort
8675
8676
8677/* ------------------------------ */
8678    .balign 64
8679.L_OP_UNUSED_C3FF: /* 0x1c3 */
8680/* File: x86/OP_UNUSED_C3FF.S */
8681/* File: x86/unused.S */
8682    jmp     common_abort
8683
8684
8685/* ------------------------------ */
8686    .balign 64
8687.L_OP_UNUSED_C4FF: /* 0x1c4 */
8688/* File: x86/OP_UNUSED_C4FF.S */
8689/* File: x86/unused.S */
8690    jmp     common_abort
8691
8692
8693/* ------------------------------ */
8694    .balign 64
8695.L_OP_UNUSED_C5FF: /* 0x1c5 */
8696/* File: x86/OP_UNUSED_C5FF.S */
8697/* File: x86/unused.S */
8698    jmp     common_abort
8699
8700
8701/* ------------------------------ */
8702    .balign 64
8703.L_OP_UNUSED_C6FF: /* 0x1c6 */
8704/* File: x86/OP_UNUSED_C6FF.S */
8705/* File: x86/unused.S */
8706    jmp     common_abort
8707
8708
8709/* ------------------------------ */
8710    .balign 64
8711.L_OP_UNUSED_C7FF: /* 0x1c7 */
8712/* File: x86/OP_UNUSED_C7FF.S */
8713/* File: x86/unused.S */
8714    jmp     common_abort
8715
8716
8717/* ------------------------------ */
8718    .balign 64
8719.L_OP_UNUSED_C8FF: /* 0x1c8 */
8720/* File: x86/OP_UNUSED_C8FF.S */
8721/* File: x86/unused.S */
8722    jmp     common_abort
8723
8724
8725/* ------------------------------ */
8726    .balign 64
8727.L_OP_UNUSED_C9FF: /* 0x1c9 */
8728/* File: x86/OP_UNUSED_C9FF.S */
8729/* File: x86/unused.S */
8730    jmp     common_abort
8731
8732
8733/* ------------------------------ */
8734    .balign 64
8735.L_OP_UNUSED_CAFF: /* 0x1ca */
8736/* File: x86/OP_UNUSED_CAFF.S */
8737/* File: x86/unused.S */
8738    jmp     common_abort
8739
8740
8741/* ------------------------------ */
8742    .balign 64
8743.L_OP_UNUSED_CBFF: /* 0x1cb */
8744/* File: x86/OP_UNUSED_CBFF.S */
8745/* File: x86/unused.S */
8746    jmp     common_abort
8747
8748
8749/* ------------------------------ */
8750    .balign 64
8751.L_OP_UNUSED_CCFF: /* 0x1cc */
8752/* File: x86/OP_UNUSED_CCFF.S */
8753/* File: x86/unused.S */
8754    jmp     common_abort
8755
8756
8757/* ------------------------------ */
8758    .balign 64
8759.L_OP_UNUSED_CDFF: /* 0x1cd */
8760/* File: x86/OP_UNUSED_CDFF.S */
8761/* File: x86/unused.S */
8762    jmp     common_abort
8763
8764
8765/* ------------------------------ */
8766    .balign 64
8767.L_OP_UNUSED_CEFF: /* 0x1ce */
8768/* File: x86/OP_UNUSED_CEFF.S */
8769/* File: x86/unused.S */
8770    jmp     common_abort
8771
8772
8773/* ------------------------------ */
8774    .balign 64
8775.L_OP_UNUSED_CFFF: /* 0x1cf */
8776/* File: x86/OP_UNUSED_CFFF.S */
8777/* File: x86/unused.S */
8778    jmp     common_abort
8779
8780
8781/* ------------------------------ */
8782    .balign 64
8783.L_OP_UNUSED_D0FF: /* 0x1d0 */
8784/* File: x86/OP_UNUSED_D0FF.S */
8785/* File: x86/unused.S */
8786    jmp     common_abort
8787
8788
8789/* ------------------------------ */
8790    .balign 64
8791.L_OP_UNUSED_D1FF: /* 0x1d1 */
8792/* File: x86/OP_UNUSED_D1FF.S */
8793/* File: x86/unused.S */
8794    jmp     common_abort
8795
8796
8797/* ------------------------------ */
8798    .balign 64
8799.L_OP_UNUSED_D2FF: /* 0x1d2 */
8800/* File: x86/OP_UNUSED_D2FF.S */
8801/* File: x86/unused.S */
8802    jmp     common_abort
8803
8804
8805/* ------------------------------ */
8806    .balign 64
8807.L_OP_UNUSED_D3FF: /* 0x1d3 */
8808/* File: x86/OP_UNUSED_D3FF.S */
8809/* File: x86/unused.S */
8810    jmp     common_abort
8811
8812
8813/* ------------------------------ */
8814    .balign 64
8815.L_OP_UNUSED_D4FF: /* 0x1d4 */
8816/* File: x86/OP_UNUSED_D4FF.S */
8817/* File: x86/unused.S */
8818    jmp     common_abort
8819
8820
8821/* ------------------------------ */
8822    .balign 64
8823.L_OP_UNUSED_D5FF: /* 0x1d5 */
8824/* File: x86/OP_UNUSED_D5FF.S */
8825/* File: x86/unused.S */
8826    jmp     common_abort
8827
8828
8829/* ------------------------------ */
8830    .balign 64
8831.L_OP_UNUSED_D6FF: /* 0x1d6 */
8832/* File: x86/OP_UNUSED_D6FF.S */
8833/* File: x86/unused.S */
8834    jmp     common_abort
8835
8836
8837/* ------------------------------ */
8838    .balign 64
8839.L_OP_UNUSED_D7FF: /* 0x1d7 */
8840/* File: x86/OP_UNUSED_D7FF.S */
8841/* File: x86/unused.S */
8842    jmp     common_abort
8843
8844
8845/* ------------------------------ */
8846    .balign 64
8847.L_OP_UNUSED_D8FF: /* 0x1d8 */
8848/* File: x86/OP_UNUSED_D8FF.S */
8849/* File: x86/unused.S */
8850    jmp     common_abort
8851
8852
8853/* ------------------------------ */
8854    .balign 64
8855.L_OP_UNUSED_D9FF: /* 0x1d9 */
8856/* File: x86/OP_UNUSED_D9FF.S */
8857/* File: x86/unused.S */
8858    jmp     common_abort
8859
8860
8861/* ------------------------------ */
8862    .balign 64
8863.L_OP_UNUSED_DAFF: /* 0x1da */
8864/* File: x86/OP_UNUSED_DAFF.S */
8865/* File: x86/unused.S */
8866    jmp     common_abort
8867
8868
8869/* ------------------------------ */
8870    .balign 64
8871.L_OP_UNUSED_DBFF: /* 0x1db */
8872/* File: x86/OP_UNUSED_DBFF.S */
8873/* File: x86/unused.S */
8874    jmp     common_abort
8875
8876
8877/* ------------------------------ */
8878    .balign 64
8879.L_OP_UNUSED_DCFF: /* 0x1dc */
8880/* File: x86/OP_UNUSED_DCFF.S */
8881/* File: x86/unused.S */
8882    jmp     common_abort
8883
8884
8885/* ------------------------------ */
8886    .balign 64
8887.L_OP_UNUSED_DDFF: /* 0x1dd */
8888/* File: x86/OP_UNUSED_DDFF.S */
8889/* File: x86/unused.S */
8890    jmp     common_abort
8891
8892
8893/* ------------------------------ */
8894    .balign 64
8895.L_OP_UNUSED_DEFF: /* 0x1de */
8896/* File: x86/OP_UNUSED_DEFF.S */
8897/* File: x86/unused.S */
8898    jmp     common_abort
8899
8900
8901/* ------------------------------ */
8902    .balign 64
8903.L_OP_UNUSED_DFFF: /* 0x1df */
8904/* File: x86/OP_UNUSED_DFFF.S */
8905/* File: x86/unused.S */
8906    jmp     common_abort
8907
8908
8909/* ------------------------------ */
8910    .balign 64
8911.L_OP_UNUSED_E0FF: /* 0x1e0 */
8912/* File: x86/OP_UNUSED_E0FF.S */
8913/* File: x86/unused.S */
8914    jmp     common_abort
8915
8916
8917/* ------------------------------ */
8918    .balign 64
8919.L_OP_UNUSED_E1FF: /* 0x1e1 */
8920/* File: x86/OP_UNUSED_E1FF.S */
8921/* File: x86/unused.S */
8922    jmp     common_abort
8923
8924
8925/* ------------------------------ */
8926    .balign 64
8927.L_OP_UNUSED_E2FF: /* 0x1e2 */
8928/* File: x86/OP_UNUSED_E2FF.S */
8929/* File: x86/unused.S */
8930    jmp     common_abort
8931
8932
8933/* ------------------------------ */
8934    .balign 64
8935.L_OP_UNUSED_E3FF: /* 0x1e3 */
8936/* File: x86/OP_UNUSED_E3FF.S */
8937/* File: x86/unused.S */
8938    jmp     common_abort
8939
8940
8941/* ------------------------------ */
8942    .balign 64
8943.L_OP_UNUSED_E4FF: /* 0x1e4 */
8944/* File: x86/OP_UNUSED_E4FF.S */
8945/* File: x86/unused.S */
8946    jmp     common_abort
8947
8948
8949/* ------------------------------ */
8950    .balign 64
8951.L_OP_UNUSED_E5FF: /* 0x1e5 */
8952/* File: x86/OP_UNUSED_E5FF.S */
8953/* File: x86/unused.S */
8954    jmp     common_abort
8955
8956
8957/* ------------------------------ */
8958    .balign 64
8959.L_OP_UNUSED_E6FF: /* 0x1e6 */
8960/* File: x86/OP_UNUSED_E6FF.S */
8961/* File: x86/unused.S */
8962    jmp     common_abort
8963
8964
8965/* ------------------------------ */
8966    .balign 64
8967.L_OP_UNUSED_E7FF: /* 0x1e7 */
8968/* File: x86/OP_UNUSED_E7FF.S */
8969/* File: x86/unused.S */
8970    jmp     common_abort
8971
8972
8973/* ------------------------------ */
8974    .balign 64
8975.L_OP_UNUSED_E8FF: /* 0x1e8 */
8976/* File: x86/OP_UNUSED_E8FF.S */
8977/* File: x86/unused.S */
8978    jmp     common_abort
8979
8980
8981/* ------------------------------ */
8982    .balign 64
8983.L_OP_UNUSED_E9FF: /* 0x1e9 */
8984/* File: x86/OP_UNUSED_E9FF.S */
8985/* File: x86/unused.S */
8986    jmp     common_abort
8987
8988
8989/* ------------------------------ */
8990    .balign 64
8991.L_OP_UNUSED_EAFF: /* 0x1ea */
8992/* File: x86/OP_UNUSED_EAFF.S */
8993/* File: x86/unused.S */
8994    jmp     common_abort
8995
8996
8997/* ------------------------------ */
8998    .balign 64
8999.L_OP_UNUSED_EBFF: /* 0x1eb */
9000/* File: x86/OP_UNUSED_EBFF.S */
9001/* File: x86/unused.S */
9002    jmp     common_abort
9003
9004
9005/* ------------------------------ */
9006    .balign 64
9007.L_OP_UNUSED_ECFF: /* 0x1ec */
9008/* File: x86/OP_UNUSED_ECFF.S */
9009/* File: x86/unused.S */
9010    jmp     common_abort
9011
9012
9013/* ------------------------------ */
9014    .balign 64
9015.L_OP_UNUSED_EDFF: /* 0x1ed */
9016/* File: x86/OP_UNUSED_EDFF.S */
9017/* File: x86/unused.S */
9018    jmp     common_abort
9019
9020
9021/* ------------------------------ */
9022    .balign 64
9023.L_OP_UNUSED_EEFF: /* 0x1ee */
9024/* File: x86/OP_UNUSED_EEFF.S */
9025/* File: x86/unused.S */
9026    jmp     common_abort
9027
9028
9029/* ------------------------------ */
9030    .balign 64
9031.L_OP_UNUSED_EFFF: /* 0x1ef */
9032/* File: x86/OP_UNUSED_EFFF.S */
9033/* File: x86/unused.S */
9034    jmp     common_abort
9035
9036
9037/* ------------------------------ */
9038    .balign 64
9039.L_OP_UNUSED_F0FF: /* 0x1f0 */
9040/* File: x86/OP_UNUSED_F0FF.S */
9041/* File: x86/unused.S */
9042    jmp     common_abort
9043
9044
9045/* ------------------------------ */
9046    .balign 64
9047.L_OP_UNUSED_F1FF: /* 0x1f1 */
9048/* File: x86/OP_UNUSED_F1FF.S */
9049/* File: x86/unused.S */
9050    jmp     common_abort
9051
9052
9053/* ------------------------------ */
9054    .balign 64
9055.L_OP_UNUSED_F2FF: /* 0x1f2 */
9056/* File: x86/OP_UNUSED_F2FF.S */
9057/* File: x86/unused.S */
9058    jmp     common_abort
9059
9060
9061/* ------------------------------ */
9062    .balign 64
9063.L_OP_UNUSED_F3FF: /* 0x1f3 */
9064/* File: x86/OP_UNUSED_F3FF.S */
9065/* File: x86/unused.S */
9066    jmp     common_abort
9067
9068
9069/* ------------------------------ */
9070    .balign 64
9071.L_OP_UNUSED_F4FF: /* 0x1f4 */
9072/* File: x86/OP_UNUSED_F4FF.S */
9073/* File: x86/unused.S */
9074    jmp     common_abort
9075
9076
9077/* ------------------------------ */
9078    .balign 64
9079.L_OP_UNUSED_F5FF: /* 0x1f5 */
9080/* File: x86/OP_UNUSED_F5FF.S */
9081/* File: x86/unused.S */
9082    jmp     common_abort
9083
9084
9085/* ------------------------------ */
9086    .balign 64
9087.L_OP_UNUSED_F6FF: /* 0x1f6 */
9088/* File: x86/OP_UNUSED_F6FF.S */
9089/* File: x86/unused.S */
9090    jmp     common_abort
9091
9092
9093/* ------------------------------ */
9094    .balign 64
9095.L_OP_UNUSED_F7FF: /* 0x1f7 */
9096/* File: x86/OP_UNUSED_F7FF.S */
9097/* File: x86/unused.S */
9098    jmp     common_abort
9099
9100
9101/* ------------------------------ */
9102    .balign 64
9103.L_OP_UNUSED_F8FF: /* 0x1f8 */
9104/* File: x86/OP_UNUSED_F8FF.S */
9105/* File: x86/unused.S */
9106    jmp     common_abort
9107
9108
9109/* ------------------------------ */
9110    .balign 64
9111.L_OP_UNUSED_F9FF: /* 0x1f9 */
9112/* File: x86/OP_UNUSED_F9FF.S */
9113/* File: x86/unused.S */
9114    jmp     common_abort
9115
9116
9117/* ------------------------------ */
9118    .balign 64
9119.L_OP_UNUSED_FAFF: /* 0x1fa */
9120/* File: x86/OP_UNUSED_FAFF.S */
9121/* File: x86/unused.S */
9122    jmp     common_abort
9123
9124
9125/* ------------------------------ */
9126    .balign 64
9127.L_OP_UNUSED_FBFF: /* 0x1fb */
9128/* File: x86/OP_UNUSED_FBFF.S */
9129/* File: x86/unused.S */
9130    jmp     common_abort
9131
9132
9133/* ------------------------------ */
9134    .balign 64
9135.L_OP_UNUSED_FCFF: /* 0x1fc */
9136/* File: x86/OP_UNUSED_FCFF.S */
9137/* File: x86/unused.S */
9138    jmp     common_abort
9139
9140
9141/* ------------------------------ */
9142    .balign 64
9143.L_OP_UNUSED_FDFF: /* 0x1fd */
9144/* File: x86/OP_UNUSED_FDFF.S */
9145/* File: x86/unused.S */
9146    jmp     common_abort
9147
9148
9149/* ------------------------------ */
9150    .balign 64
9151.L_OP_UNUSED_FEFF: /* 0x1fe */
9152/* File: x86/OP_UNUSED_FEFF.S */
9153/* File: x86/unused.S */
9154    jmp     common_abort
9155
9156
9157/* ------------------------------ */
9158    .balign 64
9159.L_OP_THROW_VERIFICATION_ERROR_JUMBO: /* 0x1ff */
9160/* File: x86/OP_THROW_VERIFICATION_ERROR_JUMBO.S */
9161    /*
9162     * Handle a jumbo throw-verification-error instruction.  This throws an
9163     * exception for an error discovered during verification.  The
9164     * exception is indicated by BBBB, with some detail provided by AAAAAAAA.
9165     */
9166    /* exop BBBB, ref@AAAAAAAA */
9167    movl     rGLUE,%ecx
9168    movl     2(rPC),%eax                     # eax<- AAAAAAAA
9169    movl     offGlue_method(%ecx),%ecx       # ecx<- glue->method
9170    EXPORT_PC
9171    movl     %eax,OUT_ARG2(%esp)             # arg2<- AAAAAAAA
9172    movl     rINST,OUT_ARG1(%esp)            # arg1<- BBBB
9173    movl     %ecx,OUT_ARG0(%esp)             # arg0<- method
9174    call     dvmThrowVerificationError       # call(method, kind, ref)
9175    jmp      common_exceptionThrown          # handle exception
9176
9177
9178    .balign 64
9179    .size   dvmAsmInstructionStart, .-dvmAsmInstructionStart
9180    .global dvmAsmInstructionEnd
9181dvmAsmInstructionEnd:
9182
9183/*
9184 * ===========================================================================
9185 *  Sister implementations
9186 * ===========================================================================
9187 */
9188    .global dvmAsmSisterStart
9189    .type   dvmAsmSisterStart, %function
9190    .text
9191    .balign 4
9192dvmAsmSisterStart:
9193
9194/* continuation for OP_CONST_STRING */
9195
9196/* This is the less common path, so we'll redo some work
9197   here rather than force spills on the common path */
9198.LOP_CONST_STRING_resolve:
9199    movl     rGLUE,%eax
9200    movl     %ecx,rINST                # rINST<- AA
9201    EXPORT_PC
9202    movl     offGlue_method(%eax),%eax # eax<- glue->method
9203    movzwl   2(rPC),%ecx               # ecx<- BBBB
9204    movl     offMethod_clazz(%eax),%eax
9205    movl     %ecx,OUT_ARG1(%esp)
9206    movl     %eax,OUT_ARG0(%esp)
9207    call     dvmResolveString          # go resolve
9208    testl    %eax,%eax                 # failed?
9209    je       common_exceptionThrown
9210    SET_VREG %eax rINST
9211    FETCH_INST_OPCODE 2 %edx
9212    ADVANCE_PC 2
9213    GOTO_NEXT_R %edx
9214
9215/* continuation for OP_CONST_STRING_JUMBO */
9216
9217/* This is the less common path, so we'll redo some work
9218   here rather than force spills on the common path */
9219.LOP_CONST_STRING_JUMBO_resolve:
9220    movl     rGLUE,%eax
9221    movl     %ecx,rINST                # rINST<- AA
9222    EXPORT_PC
9223    movl     offGlue_method(%eax),%eax # eax<- glue->method
9224    movl     2(rPC),%ecx               # ecx<- BBBBBBBB
9225    movl     offMethod_clazz(%eax),%eax
9226    movl     %ecx,OUT_ARG1(%esp)
9227    movl     %eax,OUT_ARG0(%esp)
9228    call     dvmResolveString          # go resolve
9229    testl    %eax,%eax                 # failed?
9230    je       common_exceptionThrown
9231    SET_VREG %eax rINST
9232    FETCH_INST_OPCODE 3 %edx
9233    ADVANCE_PC 3
9234    GOTO_NEXT_R %edx
9235
9236/* continuation for OP_CONST_CLASS */
9237
9238/* This is the less common path, so we'll redo some work
9239   here rather than force spills on the common path */
9240.LOP_CONST_CLASS_resolve:
9241    movl     rGLUE,%eax
9242    movl     %ecx,rINST                # rINST<- AA
9243    EXPORT_PC
9244    movl     offGlue_method(%eax),%eax # eax<- glue->method
9245    movl     $1,OUT_ARG2(%esp)        # true
9246    movzwl   2(rPC),%ecx               # ecx<- BBBB
9247    movl     offMethod_clazz(%eax),%eax
9248    movl     %ecx,OUT_ARG1(%esp)
9249    movl     %eax,OUT_ARG0(%esp)
9250    call     dvmResolveClass           # go resolve
9251    testl    %eax,%eax                 # failed?
9252    je       common_exceptionThrown
9253    SET_VREG %eax rINST
9254    FETCH_INST_OPCODE 2 %edx
9255    ADVANCE_PC 2
9256    GOTO_NEXT_R %edx
9257
9258/* continuation for OP_MONITOR_ENTER */
9259
9260.LOP_MONITOR_ENTER_continue:
9261    movl    %ecx,OUT_ARG0(%esp)
9262    movl    %eax,OUT_ARG1(%esp)
9263    call    dvmLockObject               # dvmLockObject(self,object)
9264#ifdef WITH_DEADLOCK_PREDICTION
9265    movl    rGLUE,%ecx
9266    movl    offGlueSelf(%ecx),%ecx      # ecx<- glue->self
9267    movl    offThread_exception(%ecx),%eax
9268    testl   %eax,%eax
9269    jne     common_exceptionThrown
9270#endif
9271    ADVANCE_PC 1
9272    GOTO_NEXT
9273
9274/* continuation for OP_MONITOR_EXIT */
9275
9276.LOP_MONITOR_EXIT_continue:
9277    call    dvmUnlockObject             # unlock(self,obj)
9278    FETCH_INST_OPCODE 1 %edx
9279    testl   %eax,%eax                   # success?
9280    ADVANCE_PC 1
9281    je      common_exceptionThrown      # no, exception pending
9282    GOTO_NEXT_R %edx
9283.LOP_MONITOR_EXIT_errNullObject:
9284    ADVANCE_PC 1                        # advance before throw
9285    jmp     common_errNullObject
9286
9287/* continuation for OP_CHECK_CAST */
9288
9289    /*
9290     * Trivial test failed, need to perform full check.  This is common.
9291     *  ecx holds obj->clazz
9292     *  eax holds class resolved from BBBB
9293     *  rINST holds object
9294     */
9295.LOP_CHECK_CAST_fullcheck:
9296    movl    %eax,sReg0                 # we'll need the desired class on failure
9297    movl    %eax,OUT_ARG1(%esp)
9298    movl    %ecx,OUT_ARG0(%esp)
9299    call    dvmInstanceofNonTrivial    # eax<- boolean result
9300    testl   %eax,%eax                  # failed?
9301    jne     .LOP_CHECK_CAST_okay           # no, success
9302
9303    # A cast has failed.  We need to throw a ClassCastException.
9304    EXPORT_PC
9305    movl    offObject_clazz(rINST),%eax
9306    movl    %eax,OUT_ARG0(%esp)                 # arg0<- obj->clazz
9307    movl    sReg0,%ecx
9308    movl    %ecx,OUT_ARG1(%esp)                 # arg1<- desired class
9309    call    dvmThrowClassCastException
9310    jmp     common_exceptionThrown
9311
9312    /*
9313     * Resolution required.  This is the least-likely path, and we're
9314     * going to have to recreate some data.
9315     *
9316     *  rINST holds object
9317     */
9318.LOP_CHECK_CAST_resolve:
9319    movl    rGLUE,%ecx
9320    EXPORT_PC
9321    movzwl  2(rPC),%eax                # eax<- BBBB
9322    movl    offGlue_method(%ecx),%ecx  # ecx<- glue->method
9323    movl    %eax,OUT_ARG1(%esp)        # arg1<- BBBB
9324    movl    offMethod_clazz(%ecx),%ecx # ecx<- metho->clazz
9325    movl    $0,OUT_ARG2(%esp)         # arg2<- false
9326    movl    %ecx,OUT_ARG0(%esp)        # arg0<- method->clazz
9327    call    dvmResolveClass            # eax<- resolved ClassObject ptr
9328    testl   %eax,%eax                  # got null?
9329    je      common_exceptionThrown     # yes, handle exception
9330    movl    offObject_clazz(rINST),%ecx  # ecx<- obj->clazz
9331    jmp     .LOP_CHECK_CAST_resolved       # pick up where we left off
9332
9333/* continuation for OP_INSTANCE_OF */
9334
9335    /*
9336     * Trivial test failed, need to perform full check.  This is common.
9337     *  eax holds obj->clazz
9338     *  ecx holds class resolved from BBBB
9339     *  rINST has BA
9340     */
9341.LOP_INSTANCE_OF_fullcheck:
9342    movl    %eax,OUT_ARG0(%esp)
9343    movl    %ecx,OUT_ARG1(%esp)
9344    call    dvmInstanceofNonTrivial     # eax<- boolean result
9345    # fall through to OP_INSTANCE_OF_store
9346
9347    /*
9348     * eax holds boolean result
9349     * rINST holds BA
9350     */
9351.LOP_INSTANCE_OF_store:
9352    FETCH_INST_OPCODE 2 %edx
9353    andb    $0xf,rINSTbl               # <- A
9354    ADVANCE_PC 2
9355    SET_VREG %eax rINST                 # vA<- eax
9356    GOTO_NEXT_R %edx
9357
9358    /*
9359     * Trivial test succeeded, save and bail.
9360     *  r9 holds A
9361     */
9362.LOP_INSTANCE_OF_trivial:
9363    FETCH_INST_OPCODE 2 %edx
9364    andb    $0xf,rINSTbl               # <- A
9365    ADVANCE_PC 2
9366    movl    $1,%eax
9367    SET_VREG %eax rINST                 # vA<- true
9368    GOTO_NEXT_R %edx
9369
9370    /*
9371     * Resolution required.  This is the least-likely path.
9372     *
9373     *  edx holds BBBB
9374     *  rINST holds BA
9375     */
9376.LOP_INSTANCE_OF_resolve:
9377    movl    %edx,OUT_ARG1(%esp)         # arg1<- BBBB
9378    movl    rGLUE,%ecx
9379    movl    offGlue_method(%ecx),%ecx
9380    movl    $1,OUT_ARG2(%esp)          # arg2<- true
9381    movl    offMethod_clazz(%ecx),%ecx  # ecx<- method->clazz
9382    EXPORT_PC
9383    movl    %ecx,OUT_ARG0(%esp)         # arg0<- method->clazz
9384    call    dvmResolveClass             # eax<- resolved ClassObject ptr
9385    testl   %eax,%eax                   # success?
9386    je      common_exceptionThrown      # no, handle exception
9387/* Now, we need to sync up with fast path.  We need eax to
9388 * hold the obj->clazz, and ecx to hold the resolved class
9389 */
9390    movl    %eax,%ecx                   # ecx<- resolved class
9391    movl    rINST,%eax                # eax<- BA
9392    sarl    $4,%eax                    # eax<- B
9393    GET_VREG_R %eax %eax                # eax<- vB (obj)
9394    movl    offObject_clazz(%eax),%eax  # eax<- obj->clazz
9395    jmp     .LOP_INSTANCE_OF_resolved
9396
9397/* continuation for OP_NEW_INSTANCE */
9398
9399.LOP_NEW_INSTANCE_initialized:  # on entry, ecx<- class
9400    /* TODO: remove test for interface/abstract, now done in verifier */
9401    testl     $(ACC_INTERFACE|ACC_ABSTRACT),offClassObject_accessFlags(%ecx)
9402    movl      $ALLOC_DONT_TRACK,OUT_ARG1(%esp)
9403    jne       .LOP_NEW_INSTANCE_abstract
9404.LOP_NEW_INSTANCE_finish: # ecx=class
9405    movl     %ecx,OUT_ARG0(%esp)
9406    call     dvmAllocObject             # eax<- new object
9407    FETCH_INST_OPCODE 2 %edx
9408    testl    %eax,%eax                  # success?
9409    je       common_exceptionThrown     # no, bail out
9410    SET_VREG %eax rINST
9411    ADVANCE_PC 2
9412    GOTO_NEXT_R %edx
9413
9414    /*
9415     * Class initialization required.
9416     *
9417     *  ecx holds class object
9418     */
9419.LOP_NEW_INSTANCE_needinit:
9420    SPILL_TMP1(%ecx)                    # save object
9421    movl    %ecx,OUT_ARG0(%esp)
9422    call    dvmInitClass                # initialize class
9423    UNSPILL_TMP1(%ecx)                  # restore object
9424    testl   %eax,%eax                   # success?
9425    jne     .LOP_NEW_INSTANCE_initialized     # success, continue
9426    jmp     common_exceptionThrown      # go deal with init exception
9427
9428    /*
9429     * Resolution required.  This is the least-likely path.
9430     *
9431     */
9432.LOP_NEW_INSTANCE_resolve:
9433    movl    rGLUE,%ecx
9434    movzwl  2(rPC),%eax
9435    movl    offGlue_method(%ecx),%ecx   # ecx<- glue->method
9436    movl    %eax,OUT_ARG1(%esp)
9437    movl    offMethod_clazz(%ecx),%ecx  # ecx<- method->clazz
9438    movl    $0,OUT_ARG2(%esp)
9439    movl    %ecx,OUT_ARG0(%esp)
9440    call    dvmResolveClass             # call(clazz,off,flags)
9441    movl    %eax,%ecx                   # ecx<- resolved ClassObject ptr
9442    testl   %ecx,%ecx                   # success?
9443    jne     .LOP_NEW_INSTANCE_resolved        # good to go
9444    jmp     common_exceptionThrown      # no, handle exception
9445
9446    /*
9447     * TODO: remove this
9448     * We can't instantiate an abstract class or interface, so throw an
9449     * InstantiationError with the class descriptor as the message.
9450     *
9451     *  ecx holds class object
9452     */
9453.LOP_NEW_INSTANCE_abstract:
9454    movl    offClassObject_descriptor(%ecx),%eax
9455    movl    $.LstrInstantiationError,OUT_ARG0(%esp)
9456    movl    %eax,OUT_ARG1(%esp)
9457    call    dvmThrowExceptionWithClassMessage
9458    jmp     common_exceptionThrown
9459
9460/* continuation for OP_NEW_ARRAY */
9461
9462    /*
9463     * Resolve class.  (This is an uncommon case.)
9464     *  ecx holds class (null here)
9465     *  eax holds array length (vB)
9466     */
9467.LOP_NEW_ARRAY_resolve:
9468    movl    rGLUE,%ecx
9469    SPILL_TMP1(%eax)                   # save array length
9470    movl    offGlue_method(%ecx),%ecx  # ecx<- glue->method
9471    movzwl  2(rPC),%eax                # eax<- CCCC
9472    movl    offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
9473    movl    %eax,OUT_ARG1(%esp)
9474    movl    $0,OUT_ARG2(%esp)
9475    movl    %ecx,OUT_ARG0(%esp)
9476    call    dvmResolveClass            # eax<- call(clazz,ref,flag)
9477    movl    %eax,%ecx
9478    UNSPILL_TMP1(%eax)
9479    testl   %ecx,%ecx                  # successful resolution?
9480    je      common_exceptionThrown     # no, bail.
9481# fall through to OP_NEW_ARRAY_finish
9482
9483    /*
9484     * Finish allocation
9485     *
9486     * ecx holds class
9487     * eax holds array length (vB)
9488     */
9489.LOP_NEW_ARRAY_finish:
9490    movl    %ecx,OUT_ARG0(%esp)
9491    movl    %eax,OUT_ARG1(%esp)
9492    movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)
9493    call    dvmAllocArrayByClass    # eax<- call(clazz,length,flags)
9494    FETCH_INST_OPCODE 2 %edx
9495    testl   %eax,%eax               # failed?
9496    je      common_exceptionThrown  # yup - go handle
9497    SET_VREG %eax rINST
9498    ADVANCE_PC 2
9499    GOTO_NEXT_R %edx
9500
9501/* continuation for OP_FILLED_NEW_ARRAY */
9502
9503.LOP_FILLED_NEW_ARRAY_more:
9504    movl    offMethod_clazz(%eax),%eax        # eax<- method->clazz
9505    movl    %eax,OUT_ARG0(%esp)               # arg0<- clazz
9506    call    dvmResolveClass                   # eax<- call(clazz,ref,flag)
9507    testl   %eax,%eax                         # null?
9508    je      common_exceptionThrown            # yes, handle it
9509
9510       # note: fall through to .LOP_FILLED_NEW_ARRAY_continue
9511
9512    /*
9513     * On entry:
9514     *    eax holds array class [r0]
9515     *    rINST holds AA or BB [r10]
9516     *    ecx is scratch
9517     */
9518.LOP_FILLED_NEW_ARRAY_continue:
9519    movl    offClassObject_descriptor(%eax),%ecx  # ecx<- arrayClass->descriptor
9520    movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)     # arg2<- flags
9521    movzbl  1(%ecx),%ecx                          # ecx<- descriptor[1]
9522    movl    %eax,OUT_ARG0(%esp)                   # arg0<- arrayClass
9523    movl    rGLUE,%eax
9524    cmpb    $'I',%cl                             # supported?
9525    je      1f
9526    cmpb    $'L',%cl
9527    je      1f
9528    cmpb    $'[',%cl
9529    jne      .LOP_FILLED_NEW_ARRAY_notimpl                  # no, not handled yet
95301:
9531    movl    %ecx,offGlue_retval+4(%eax)           # save type
9532    .if      (!0)
9533    SPILL_TMP1(rINST)                              # save copy, need "B" later
9534    sarl    $4,rINST
9535    .endif
9536    movl    rINST,OUT_ARG1(%esp)                  # arg1<- A or AA (length)
9537    call    dvmAllocArrayByClass     # eax<- call(arrayClass, length, flags)
9538    movl    rGLUE,%ecx
9539    testl   %eax,%eax                             # alloc successful?
9540    je      common_exceptionThrown                # no, handle exception
9541    movl    %eax,offGlue_retval(%ecx)             # retval.l<- new array
9542    movzwl  4(rPC),%ecx                           # ecx<- FEDC or CCCC
9543    leal    offArrayObject_contents(%eax),%eax    # eax<- newArray->contents
9544
9545/* at this point:
9546 *     eax is pointer to tgt
9547 *     rINST is length
9548 *     ecx is FEDC or CCCC
9549 *     TMP_SPILL1 is BA
9550 *  We now need to copy values from registers into the array
9551 */
9552
9553    .if 0
9554    # set up src pointer
9555    SPILL_TMP2(%esi)
9556    SPILL_TMP3(%edi)
9557    leal    (rFP,%ecx,4),%esi # set up src ptr
9558    movl    %eax,%edi         # set up dst ptr
9559    movl    rINST,%ecx        # load count register
9560    rep
9561    movsd
9562    UNSPILL_TMP2(%esi)
9563    UNSPILL_TMP3(%edi)
9564    movl    rGLUE,%ecx
9565    movl    offGlue_retval+4(%ecx),%eax      # eax<- type
9566    FETCH_INST_OPCODE 3 %edx
9567    .else
9568    testl  rINST,rINST
9569    je     4f
9570    UNSPILL_TMP1(%edx)        # restore "BA"
9571    andl   $0x0f,%edx        # edx<- 0000000A
9572    sall   $16,%edx          # edx<- 000A0000
9573    orl    %ecx,%edx          # edx<- 000AFEDC
95743:
9575    movl   $0xf,%ecx
9576    andl   %edx,%ecx          # ecx<- next reg to load
9577    GET_VREG_R %ecx %ecx
9578    shrl   $4,%edx
9579    leal   4(%eax),%eax
9580    movl   %ecx,-4(%eax)
9581    sub    $1,rINST
9582    jne    3b
95834:
9584    movl   rGLUE,%ecx
9585    movl    offGlue_retval+4(%ecx),%eax      # eax<- type
9586    FETCH_INST_OPCODE 3 %edx
9587    .endif
9588
9589    cmpb    $'I',%al                        # Int array?
9590    je      5f                               # skip card mark if so
9591    movl    offGlue_retval(%ecx),%eax        # eax<- object head
9592    movl    offGlue_cardTable(%ecx),%ecx     # card table base
9593    shrl    $GC_CARD_SHIFT,%eax             # convert to card num
9594    movb    %cl,(%ecx,%eax)                  # mark card based on object head
95955:
9596    ADVANCE_PC 3
9597    GOTO_NEXT_R %edx
9598
9599
9600    /*
9601     * Throw an exception indicating that we have not implemented this
9602     * mode of filled-new-array.
9603     */
9604.LOP_FILLED_NEW_ARRAY_notimpl:
9605    movl    $.LstrInternalErrorA,%eax
9606    movl    %eax,OUT_ARG0(%esp)
9607    movl    $.LstrFilledNewArrayNotImplA,%eax
9608    movl    %eax,OUT_ARG1(%esp)
9609    call    dvmThrowException
9610    jmp     common_exceptionThrown
9611
9612/* continuation for OP_FILLED_NEW_ARRAY_RANGE */
9613
9614.LOP_FILLED_NEW_ARRAY_RANGE_more:
9615    movl    offMethod_clazz(%eax),%eax        # eax<- method->clazz
9616    movl    %eax,OUT_ARG0(%esp)               # arg0<- clazz
9617    call    dvmResolveClass                   # eax<- call(clazz,ref,flag)
9618    testl   %eax,%eax                         # null?
9619    je      common_exceptionThrown            # yes, handle it
9620
9621       # note: fall through to .LOP_FILLED_NEW_ARRAY_RANGE_continue
9622
9623    /*
9624     * On entry:
9625     *    eax holds array class [r0]
9626     *    rINST holds AA or BB [r10]
9627     *    ecx is scratch
9628     */
9629.LOP_FILLED_NEW_ARRAY_RANGE_continue:
9630    movl    offClassObject_descriptor(%eax),%ecx  # ecx<- arrayClass->descriptor
9631    movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)     # arg2<- flags
9632    movzbl  1(%ecx),%ecx                          # ecx<- descriptor[1]
9633    movl    %eax,OUT_ARG0(%esp)                   # arg0<- arrayClass
9634    movl    rGLUE,%eax
9635    cmpb    $'I',%cl                             # supported?
9636    je      1f
9637    cmpb    $'L',%cl
9638    je      1f
9639    cmpb    $'[',%cl
9640    jne      .LOP_FILLED_NEW_ARRAY_RANGE_notimpl                  # no, not handled yet
96411:
9642    movl    %ecx,offGlue_retval+4(%eax)           # save type
9643    .if      (!1)
9644    SPILL_TMP1(rINST)                              # save copy, need "B" later
9645    sarl    $4,rINST
9646    .endif
9647    movl    rINST,OUT_ARG1(%esp)                  # arg1<- A or AA (length)
9648    call    dvmAllocArrayByClass     # eax<- call(arrayClass, length, flags)
9649    movl    rGLUE,%ecx
9650    testl   %eax,%eax                             # alloc successful?
9651    je      common_exceptionThrown                # no, handle exception
9652    movl    %eax,offGlue_retval(%ecx)             # retval.l<- new array
9653    movzwl  4(rPC),%ecx                           # ecx<- FEDC or CCCC
9654    leal    offArrayObject_contents(%eax),%eax    # eax<- newArray->contents
9655
9656/* at this point:
9657 *     eax is pointer to tgt
9658 *     rINST is length
9659 *     ecx is FEDC or CCCC
9660 *     TMP_SPILL1 is BA
9661 *  We now need to copy values from registers into the array
9662 */
9663
9664    .if 1
9665    # set up src pointer
9666    SPILL_TMP2(%esi)
9667    SPILL_TMP3(%edi)
9668    leal    (rFP,%ecx,4),%esi # set up src ptr
9669    movl    %eax,%edi         # set up dst ptr
9670    movl    rINST,%ecx        # load count register
9671    rep
9672    movsd
9673    UNSPILL_TMP2(%esi)
9674    UNSPILL_TMP3(%edi)
9675    movl    rGLUE,%ecx
9676    movl    offGlue_retval+4(%ecx),%eax      # eax<- type
9677    FETCH_INST_OPCODE 3 %edx
9678    .else
9679    testl  rINST,rINST
9680    je     4f
9681    UNSPILL_TMP1(%edx)        # restore "BA"
9682    andl   $0x0f,%edx        # edx<- 0000000A
9683    sall   $16,%edx          # edx<- 000A0000
9684    orl    %ecx,%edx          # edx<- 000AFEDC
96853:
9686    movl   $0xf,%ecx
9687    andl   %edx,%ecx          # ecx<- next reg to load
9688    GET_VREG_R %ecx %ecx
9689    shrl   $4,%edx
9690    leal   4(%eax),%eax
9691    movl   %ecx,-4(%eax)
9692    sub    $1,rINST
9693    jne    3b
96944:
9695    movl   rGLUE,%ecx
9696    movl    offGlue_retval+4(%ecx),%eax      # eax<- type
9697    FETCH_INST_OPCODE 3 %edx
9698    .endif
9699
9700    cmpb    $'I',%al                        # Int array?
9701    je      5f                               # skip card mark if so
9702    movl    offGlue_retval(%ecx),%eax        # eax<- object head
9703    movl    offGlue_cardTable(%ecx),%ecx     # card table base
9704    shrl    $GC_CARD_SHIFT,%eax             # convert to card num
9705    movb    %cl,(%ecx,%eax)                  # mark card based on object head
97065:
9707    ADVANCE_PC 3
9708    GOTO_NEXT_R %edx
9709
9710
9711    /*
9712     * Throw an exception indicating that we have not implemented this
9713     * mode of filled-new-array.
9714     */
9715.LOP_FILLED_NEW_ARRAY_RANGE_notimpl:
9716    movl    $.LstrInternalErrorA,%eax
9717    movl    %eax,OUT_ARG0(%esp)
9718    movl    $.LstrFilledNewArrayNotImplA,%eax
9719    movl    %eax,OUT_ARG1(%esp)
9720    call    dvmThrowException
9721    jmp     common_exceptionThrown
9722
9723/* continuation for OP_CMPL_FLOAT */
9724
9725.LOP_CMPL_FLOAT_isNaN:
9726    movl      $-1,%ecx
9727    jmp       .LOP_CMPL_FLOAT_finish
9728
9729/* continuation for OP_CMPG_FLOAT */
9730
9731.LOP_CMPG_FLOAT_isNaN:
9732    movl      $1,%ecx
9733    jmp       .LOP_CMPG_FLOAT_finish
9734
9735/* continuation for OP_CMPL_DOUBLE */
9736
9737.LOP_CMPL_DOUBLE_isNaN:
9738    movl      $-1,%ecx
9739    jmp       .LOP_CMPL_DOUBLE_finish
9740
9741/* continuation for OP_CMPG_DOUBLE */
9742
9743.LOP_CMPG_DOUBLE_isNaN:
9744    movl      $1,%ecx
9745    jmp       .LOP_CMPG_DOUBLE_finish
9746
9747/* continuation for OP_CMP_LONG */
9748
9749.LOP_CMP_LONG_bigger:
9750    movl      $1,%ecx
9751    jmp       .LOP_CMP_LONG_finish
9752.LOP_CMP_LONG_smaller:
9753    movl      $-1,%ecx
9754.LOP_CMP_LONG_finish:
9755    SET_VREG %ecx rINST
9756    FETCH_INST_OPCODE 2 %edx
9757    ADVANCE_PC 2
9758    GOTO_NEXT_R %edx
9759
9760/* continuation for OP_AGET_WIDE */
9761
9762.LOP_AGET_WIDE_finish:
9763    leal      offArrayObject_contents(%eax,%ecx,8),%eax
9764    movl      (%eax),%ecx
9765    movl      4(%eax),%eax
9766    SET_VREG_WORD %ecx rINST 0
9767    SET_VREG_WORD %eax rINST 1
9768    FETCH_INST_OPCODE 2 %edx
9769    ADVANCE_PC 2
9770    GOTO_NEXT_R %edx
9771
9772/* continuation for OP_APUT_WIDE */
9773
9774.LOP_APUT_WIDE_finish:
9775    leal      offArrayObject_contents(%eax,%ecx,8),%eax
9776    GET_VREG_WORD %ecx rINST 0
9777    GET_VREG_WORD rINST rINST 1
9778    movl      rINST,4(%eax)
9779    FETCH_INST_OPCODE 2 %edx
9780    movl      %ecx,(%eax)
9781    ADVANCE_PC 2
9782    GOTO_NEXT_R %edx
9783
9784/* continuation for OP_APUT_OBJECT */
9785
9786    /* On entry:
9787     *   eax<- array object
9788     *   ecx<- index
9789     *   rINST<- vAA
9790     */
9791.LOP_APUT_OBJECT_continue:
9792    leal      offArrayObject_contents(%eax,%ecx,4),%ecx
9793    testl     rINST,rINST                    # storing null reference?
9794    je        .LOP_APUT_OBJECT_skip_check
9795    SPILL_TMP1(%ecx)                         # save target address
9796    SPILL_TMP2(%eax)                         # save object head
9797    movl      offObject_clazz(%eax),%eax     # eax<- arrayObj->clazz
9798    movl      offObject_clazz(rINST),%ecx    # ecx<- obj->clazz
9799    movl      %eax,OUT_ARG1(%esp)
9800    movl      %ecx,OUT_ARG0(%esp)
9801    movl      %ecx,sReg0                     # store the two classes for later
9802    movl      %eax,sReg1
9803    call      dvmCanPutArrayElement          # test object type vs. array type
9804    UNSPILL_TMP1(%ecx)                       # recover target address
9805    testl     %eax,%eax
9806    movl      rGLUE,%eax
9807    jne       .LOP_APUT_OBJECT_types_okay
9808
9809    # The types don't match.  We need to throw an ArrayStoreException.
9810    EXPORT_PC
9811    movl      sReg0,%eax                     # restore the two classes...
9812    movl      %eax,OUT_ARG0(%esp)
9813    movl      sReg1,%ecx
9814    movl      %ecx,OUT_ARG1(%esp)
9815    call      dvmThrowArrayStoreException    # ...and throw
9816    jmp       common_exceptionThrown
9817
9818.LOP_APUT_OBJECT_types_okay:
9819    movl      offGlue_cardTable(%eax),%eax   # get card table base
9820    movl      rINST,(%ecx)                   # store into array
9821    UNSPILL_TMP2(%ecx)                       # recover object head
9822    FETCH_INST_OPCODE 2 %edx
9823    shrl      $GC_CARD_SHIFT,%ecx           # object head to card number
9824    movb      %al,(%eax,%ecx)                # mark card using object head
9825    ADVANCE_PC 2
9826    GOTO_NEXT_R %edx
9827
9828.LOP_APUT_OBJECT_skip_check:
9829    movl      rINST,(%ecx)
9830    FETCH_INST_OPCODE 2 %edx
9831    ADVANCE_PC 2
9832    GOTO_NEXT_R %edx
9833
9834/* continuation for OP_IGET */
9835
9836
9837.LOP_IGET_resolve:
9838    EXPORT_PC
9839    movl    offGlue_method(%edx),%edx           # edx<- current method
9840    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
9841    SPILL_TMP1(%ecx)                            # save obj pointer across call
9842    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
9843    call    dvmResolveInstField                 #  ... to dvmResolveInstField
9844    UNSPILL_TMP1(%ecx)
9845    testl   %eax,%eax                           #  returns InstrField ptr
9846    jne     .LOP_IGET_finish
9847    jmp     common_exceptionThrown
9848
9849.LOP_IGET_finish:
9850    /*
9851     * Currently:
9852     *   eax holds resolved field
9853     *   ecx holds object
9854     *   rINST holds A
9855     */
9856    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
9857    testl   %ecx,%ecx                           # object null?
9858    je      common_errNullObject                # object was null
9859    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
9860    movl    rINST,%eax                          # eax<- A
9861    FETCH_INST_OPCODE 2 %edx
9862    SET_VREG %ecx %eax
9863    ADVANCE_PC 2
9864    GOTO_NEXT_R %edx
9865
9866/* continuation for OP_IGET_WIDE */
9867
9868
9869.LOP_IGET_WIDE_resolve:
9870    EXPORT_PC
9871    movl    offGlue_method(%edx),%edx           # edx<- current method
9872    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
9873    SPILL_TMP1(%ecx)                            # save objpointer across call
9874    movl    rPC,OUT_ARG0(%esp)                  # pass in method->clazz
9875    call    dvmResolveInstField                 #  ... to dvmResolveInstField
9876    UNSPILL_TMP1(%ecx)
9877    testl   %eax,%eax                           # returns InstrField ptr
9878    jne     .LOP_IGET_WIDE_finish
9879    jmp     common_exceptionThrown
9880
9881.LOP_IGET_WIDE_finish:
9882    /*
9883     * Currently:
9884     *   eax holds resolved field
9885     *   ecx holds object
9886     *   rINST holds A
9887     */
9888    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
9889    testl   %ecx,%ecx                           # object null?
9890    je      common_errNullObject                # object was null
9891    leal    (%ecx,%eax,1),%eax                  # eax<- address of field
9892    movl    (%eax),%ecx                         # ecx<- lsw
9893    movl    4(%eax),%eax                        # eax<- msw
9894    FETCH_INST_OPCODE 2 %edx
9895    SET_VREG_WORD %ecx rINST 0
9896    SET_VREG_WORD %eax rINST 1
9897    ADVANCE_PC 2
9898    GOTO_NEXT_R %edx
9899
9900/* continuation for OP_IGET_OBJECT */
9901
9902
9903.LOP_IGET_OBJECT_resolve:
9904    EXPORT_PC
9905    movl    offGlue_method(%edx),%edx           # edx<- current method
9906    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
9907    SPILL_TMP1(%ecx)                            # save obj pointer across call
9908    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
9909    call    dvmResolveInstField                 #  ... to dvmResolveInstField
9910    UNSPILL_TMP1(%ecx)
9911    testl   %eax,%eax                           #  returns InstrField ptr
9912    jne     .LOP_IGET_OBJECT_finish
9913    jmp     common_exceptionThrown
9914
9915.LOP_IGET_OBJECT_finish:
9916    /*
9917     * Currently:
9918     *   eax holds resolved field
9919     *   ecx holds object
9920     *   rINST holds A
9921     */
9922    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
9923    testl   %ecx,%ecx                           # object null?
9924    je      common_errNullObject                # object was null
9925    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
9926    movl    rINST,%eax                          # eax<- A
9927    FETCH_INST_OPCODE 2 %edx
9928    SET_VREG %ecx %eax
9929    ADVANCE_PC 2
9930    GOTO_NEXT_R %edx
9931
9932/* continuation for OP_IGET_BOOLEAN */
9933
9934
9935.LOP_IGET_BOOLEAN_resolve:
9936    EXPORT_PC
9937    movl    offGlue_method(%edx),%edx           # edx<- current method
9938    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
9939    SPILL_TMP1(%ecx)                            # save obj pointer across call
9940    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
9941    call    dvmResolveInstField                 #  ... to dvmResolveInstField
9942    UNSPILL_TMP1(%ecx)
9943    testl   %eax,%eax                           #  returns InstrField ptr
9944    jne     .LOP_IGET_BOOLEAN_finish
9945    jmp     common_exceptionThrown
9946
9947.LOP_IGET_BOOLEAN_finish:
9948    /*
9949     * Currently:
9950     *   eax holds resolved field
9951     *   ecx holds object
9952     *   rINST holds A
9953     */
9954    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
9955    testl   %ecx,%ecx                           # object null?
9956    je      common_errNullObject                # object was null
9957    movzbl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
9958    movl    rINST,%eax                          # eax<- A
9959    FETCH_INST_OPCODE 2 %edx
9960    SET_VREG %ecx %eax
9961    ADVANCE_PC 2
9962    GOTO_NEXT_R %edx
9963
9964/* continuation for OP_IGET_BYTE */
9965
9966
9967.LOP_IGET_BYTE_resolve:
9968    EXPORT_PC
9969    movl    offGlue_method(%edx),%edx           # edx<- current method
9970    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
9971    SPILL_TMP1(%ecx)                            # save obj pointer across call
9972    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
9973    call    dvmResolveInstField                 #  ... to dvmResolveInstField
9974    UNSPILL_TMP1(%ecx)
9975    testl   %eax,%eax                           #  returns InstrField ptr
9976    jne     .LOP_IGET_BYTE_finish
9977    jmp     common_exceptionThrown
9978
9979.LOP_IGET_BYTE_finish:
9980    /*
9981     * Currently:
9982     *   eax holds resolved field
9983     *   ecx holds object
9984     *   rINST holds A
9985     */
9986    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
9987    testl   %ecx,%ecx                           # object null?
9988    je      common_errNullObject                # object was null
9989    movsbl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
9990    movl    rINST,%eax                          # eax<- A
9991    FETCH_INST_OPCODE 2 %edx
9992    SET_VREG %ecx %eax
9993    ADVANCE_PC 2
9994    GOTO_NEXT_R %edx
9995
9996/* continuation for OP_IGET_CHAR */
9997
9998
9999.LOP_IGET_CHAR_resolve:
10000    EXPORT_PC
10001    movl    offGlue_method(%edx),%edx           # edx<- current method
10002    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
10003    SPILL_TMP1(%ecx)                            # save obj pointer across call
10004    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
10005    call    dvmResolveInstField                 #  ... to dvmResolveInstField
10006    UNSPILL_TMP1(%ecx)
10007    testl   %eax,%eax                           #  returns InstrField ptr
10008    jne     .LOP_IGET_CHAR_finish
10009    jmp     common_exceptionThrown
10010
10011.LOP_IGET_CHAR_finish:
10012    /*
10013     * Currently:
10014     *   eax holds resolved field
10015     *   ecx holds object
10016     *   rINST holds A
10017     */
10018    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
10019    testl   %ecx,%ecx                           # object null?
10020    je      common_errNullObject                # object was null
10021    movzwl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
10022    movl    rINST,%eax                          # eax<- A
10023    FETCH_INST_OPCODE 2 %edx
10024    SET_VREG %ecx %eax
10025    ADVANCE_PC 2
10026    GOTO_NEXT_R %edx
10027
10028/* continuation for OP_IGET_SHORT */
10029
10030
10031.LOP_IGET_SHORT_resolve:
10032    EXPORT_PC
10033    movl    offGlue_method(%edx),%edx           # edx<- current method
10034    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
10035    SPILL_TMP1(%ecx)                            # save obj pointer across call
10036    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
10037    call    dvmResolveInstField                 #  ... to dvmResolveInstField
10038    UNSPILL_TMP1(%ecx)
10039    testl   %eax,%eax                           #  returns InstrField ptr
10040    jne     .LOP_IGET_SHORT_finish
10041    jmp     common_exceptionThrown
10042
10043.LOP_IGET_SHORT_finish:
10044    /*
10045     * Currently:
10046     *   eax holds resolved field
10047     *   ecx holds object
10048     *   rINST holds A
10049     */
10050    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
10051    testl   %ecx,%ecx                           # object null?
10052    je      common_errNullObject                # object was null
10053    movswl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
10054    movl    rINST,%eax                          # eax<- A
10055    FETCH_INST_OPCODE 2 %edx
10056    SET_VREG %ecx %eax
10057    ADVANCE_PC 2
10058    GOTO_NEXT_R %edx
10059
10060/* continuation for OP_IPUT */
10061
10062
10063.LOP_IPUT_resolve:
10064    EXPORT_PC
10065    movl    offGlue_method(%edx),%edx           # edx<- current method
10066    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
10067    SPILL_TMP1(%ecx)                            # save obj pointer across call
10068    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
10069    call    dvmResolveInstField                 #  ... to dvmResolveInstField
10070    UNSPILL_TMP1(%ecx)
10071    testl   %eax,%eax                           # returns InstrField ptr
10072    jne     .LOP_IPUT_finish
10073    jmp     common_exceptionThrown
10074
10075.LOP_IPUT_finish:
10076    /*
10077     * Currently:
10078     *   eax holds resolved field
10079     *   ecx holds object
10080     *   rINST holds A
10081     */
10082    GET_VREG_R rINST rINST                       # rINST<- v[A]
10083    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
10084    testl   %ecx,%ecx                            # object null?
10085    je      common_errNullObject                 # object was null
10086    FETCH_INST_OPCODE 2 %edx
10087    movl   rINST,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
10088    ADVANCE_PC 2
10089    GOTO_NEXT_R %edx
10090
10091/* continuation for OP_IPUT_WIDE */
10092
10093
10094.LOP_IPUT_WIDE_resolve:
10095    EXPORT_PC
10096    movl    offGlue_method(%edx),%edx           # edx<- current method
10097    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
10098    SPILL_TMP1(%ecx)                            # save obj pointer across call
10099    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
10100    call    dvmResolveInstField                 #  ... to dvmResolveInstField
10101    UNSPILL_TMP1(%ecx)
10102    testl   %eax,%eax                           #  ... which returns InstrField ptr
10103    jne     .LOP_IPUT_WIDE_finish
10104    jmp     common_exceptionThrown
10105
10106.LOP_IPUT_WIDE_finish:
10107    /*
10108     * Currently:
10109     *   eax holds resolved field
10110     *   ecx holds object
10111     *   %edx is scratch, but needs to be unspilled
10112     *   rINST holds A
10113     */
10114    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
10115    testl   %ecx,%ecx                           # object null?
10116    je      common_errNullObject                # object was null
10117    leal    (%ecx,%eax,1),%eax                  # eax<- address of field
10118    GET_VREG_WORD %ecx rINST 0                  # ecx<- lsw
10119    GET_VREG_WORD rINST rINST 1                 # rINST<- msw
10120    FETCH_INST_OPCODE 2 %edx
10121    movl    rINST,4(%eax)
10122    movl    %ecx,(%eax)
10123    ADVANCE_PC 2
10124    GOTO_NEXT_R %edx
10125
10126/* continuation for OP_IPUT_OBJECT */
10127
10128
10129.LOP_IPUT_OBJECT_resolve:
10130    EXPORT_PC
10131    movl    offGlue_method(%edx),%edx           # edx<- current method
10132    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
10133    SPILL_TMP1(%ecx)                            # save obj pointer across call
10134    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
10135    call    dvmResolveInstField                 #  ... to dvmResolveInstField
10136    UNSPILL_TMP1(%ecx)
10137    testl   %eax,%eax                           # returns InstrField ptr
10138    jne     .LOP_IPUT_OBJECT_finish
10139    jmp     common_exceptionThrown
10140
10141.LOP_IPUT_OBJECT_finish:
10142    /*
10143     * Currently:
10144     *   eax holds resolved field
10145     *   ecx holds object
10146     *   %edx is scratch, but needs to be unspilled
10147     *   rINST holds A
10148     */
10149    GET_VREG_R rINST rINST                      # rINST<- v[A]
10150    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
10151    testl   %ecx,%ecx                           # object null?
10152    je      common_errNullObject                # object was null
10153    movl    rINST,(%ecx,%eax)      # obj.field <- v[A](8/16/32 bits)
10154    movl    rGLUE,%eax
10155    testl   rINST,rINST                         # stored a NULL?
10156    movl    offGlue_cardTable(%eax),%eax        # get card table base
10157    FETCH_INST_OPCODE 2 %edx
10158    je      1f                                  # skip card mark if null store
10159    shrl    $GC_CARD_SHIFT,%ecx                # object head to card number
10160    movb    %al,(%eax,%ecx)                     # mark card using object head
101611:
10162    ADVANCE_PC 2
10163    GOTO_NEXT_R %edx
10164
10165/* continuation for OP_IPUT_BOOLEAN */
10166
10167
10168.LOP_IPUT_BOOLEAN_resolve:
10169    EXPORT_PC
10170    movl    offGlue_method(%edx),%edx           # edx<- current method
10171    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
10172    SPILL_TMP1(%ecx)                            # save obj pointer across call
10173    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
10174    call    dvmResolveInstField                 #  ... to dvmResolveInstField
10175    UNSPILL_TMP1(%ecx)
10176    testl   %eax,%eax                           # returns InstrField ptr
10177    jne     .LOP_IPUT_BOOLEAN_finish
10178    jmp     common_exceptionThrown
10179
10180.LOP_IPUT_BOOLEAN_finish:
10181    /*
10182     * Currently:
10183     *   eax holds resolved field
10184     *   ecx holds object
10185     *   rINST holds A
10186     */
10187    GET_VREG_R rINST rINST                       # rINST<- v[A]
10188    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
10189    testl   %ecx,%ecx                            # object null?
10190    je      common_errNullObject                 # object was null
10191    FETCH_INST_OPCODE 2 %edx
10192    movb   rINSTbl,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
10193    ADVANCE_PC 2
10194    GOTO_NEXT_R %edx
10195
10196/* continuation for OP_IPUT_BYTE */
10197
10198
10199.LOP_IPUT_BYTE_resolve:
10200    EXPORT_PC
10201    movl    offGlue_method(%edx),%edx           # edx<- current method
10202    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
10203    SPILL_TMP1(%ecx)                            # save obj pointer across call
10204    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
10205    call    dvmResolveInstField                 #  ... to dvmResolveInstField
10206    UNSPILL_TMP1(%ecx)
10207    testl   %eax,%eax                           # returns InstrField ptr
10208    jne     .LOP_IPUT_BYTE_finish
10209    jmp     common_exceptionThrown
10210
10211.LOP_IPUT_BYTE_finish:
10212    /*
10213     * Currently:
10214     *   eax holds resolved field
10215     *   ecx holds object
10216     *   rINST holds A
10217     */
10218    GET_VREG_R rINST rINST                       # rINST<- v[A]
10219    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
10220    testl   %ecx,%ecx                            # object null?
10221    je      common_errNullObject                 # object was null
10222    FETCH_INST_OPCODE 2 %edx
10223    movb   rINSTbl,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
10224    ADVANCE_PC 2
10225    GOTO_NEXT_R %edx
10226
10227/* continuation for OP_IPUT_CHAR */
10228
10229
10230.LOP_IPUT_CHAR_resolve:
10231    EXPORT_PC
10232    movl    offGlue_method(%edx),%edx           # edx<- current method
10233    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
10234    SPILL_TMP1(%ecx)                            # save obj pointer across call
10235    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
10236    call    dvmResolveInstField                 #  ... to dvmResolveInstField
10237    UNSPILL_TMP1(%ecx)
10238    testl   %eax,%eax                           # returns InstrField ptr
10239    jne     .LOP_IPUT_CHAR_finish
10240    jmp     common_exceptionThrown
10241
10242.LOP_IPUT_CHAR_finish:
10243    /*
10244     * Currently:
10245     *   eax holds resolved field
10246     *   ecx holds object
10247     *   rINST holds A
10248     */
10249    GET_VREG_R rINST rINST                       # rINST<- v[A]
10250    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
10251    testl   %ecx,%ecx                            # object null?
10252    je      common_errNullObject                 # object was null
10253    FETCH_INST_OPCODE 2 %edx
10254    movw   rINSTw,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
10255    ADVANCE_PC 2
10256    GOTO_NEXT_R %edx
10257
10258/* continuation for OP_IPUT_SHORT */
10259
10260
10261.LOP_IPUT_SHORT_resolve:
10262    EXPORT_PC
10263    movl    offGlue_method(%edx),%edx           # edx<- current method
10264    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
10265    SPILL_TMP1(%ecx)                            # save obj pointer across call
10266    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
10267    call    dvmResolveInstField                 #  ... to dvmResolveInstField
10268    UNSPILL_TMP1(%ecx)
10269    testl   %eax,%eax                           # returns InstrField ptr
10270    jne     .LOP_IPUT_SHORT_finish
10271    jmp     common_exceptionThrown
10272
10273.LOP_IPUT_SHORT_finish:
10274    /*
10275     * Currently:
10276     *   eax holds resolved field
10277     *   ecx holds object
10278     *   rINST holds A
10279     */
10280    GET_VREG_R rINST rINST                       # rINST<- v[A]
10281    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
10282    testl   %ecx,%ecx                            # object null?
10283    je      common_errNullObject                 # object was null
10284    FETCH_INST_OPCODE 2 %edx
10285    movw   rINSTw,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
10286    ADVANCE_PC 2
10287    GOTO_NEXT_R %edx
10288
10289/* continuation for OP_SGET */
10290
10291    /*
10292     * Go resolve the field
10293     */
10294.LOP_SGET_resolve:
10295    movl     rGLUE,%ecx
10296    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10297    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
10298    EXPORT_PC                                   # could throw, need to export
10299    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10300    movl     %eax,OUT_ARG1(%esp)
10301    movl     %ecx,OUT_ARG0(%esp)
10302    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10303    testl    %eax,%eax
10304    jne      .LOP_SGET_finish                 # success, continue
10305    jmp      common_exceptionThrown             # no, handle exception
10306
10307/* continuation for OP_SGET_WIDE */
10308
10309    /*
10310     * Go resolve the field
10311     */
10312.LOP_SGET_WIDE_resolve:
10313    movl     rGLUE,%ecx
10314    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10315    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
10316    EXPORT_PC                                   # could throw, need to export
10317    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10318    movl     %eax,OUT_ARG1(%esp)
10319    movl     %ecx,OUT_ARG0(%esp)
10320    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10321    testl    %eax,%eax
10322    jne      .LOP_SGET_WIDE_finish                 # success, continue
10323    jmp      common_exceptionThrown             # no, handle exception
10324
10325/* continuation for OP_SGET_OBJECT */
10326
10327    /*
10328     * Go resolve the field
10329     */
10330.LOP_SGET_OBJECT_resolve:
10331    movl     rGLUE,%ecx
10332    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10333    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
10334    EXPORT_PC                                   # could throw, need to export
10335    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10336    movl     %eax,OUT_ARG1(%esp)
10337    movl     %ecx,OUT_ARG0(%esp)
10338    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10339    testl    %eax,%eax
10340    jne      .LOP_SGET_OBJECT_finish                 # success, continue
10341    jmp      common_exceptionThrown             # no, handle exception
10342
10343/* continuation for OP_SGET_BOOLEAN */
10344
10345    /*
10346     * Go resolve the field
10347     */
10348.LOP_SGET_BOOLEAN_resolve:
10349    movl     rGLUE,%ecx
10350    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10351    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
10352    EXPORT_PC                                   # could throw, need to export
10353    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10354    movl     %eax,OUT_ARG1(%esp)
10355    movl     %ecx,OUT_ARG0(%esp)
10356    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10357    testl    %eax,%eax
10358    jne      .LOP_SGET_BOOLEAN_finish                 # success, continue
10359    jmp      common_exceptionThrown             # no, handle exception
10360
10361/* continuation for OP_SGET_BYTE */
10362
10363    /*
10364     * Go resolve the field
10365     */
10366.LOP_SGET_BYTE_resolve:
10367    movl     rGLUE,%ecx
10368    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10369    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
10370    EXPORT_PC                                   # could throw, need to export
10371    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10372    movl     %eax,OUT_ARG1(%esp)
10373    movl     %ecx,OUT_ARG0(%esp)
10374    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10375    testl    %eax,%eax
10376    jne      .LOP_SGET_BYTE_finish                 # success, continue
10377    jmp      common_exceptionThrown             # no, handle exception
10378
10379/* continuation for OP_SGET_CHAR */
10380
10381    /*
10382     * Go resolve the field
10383     */
10384.LOP_SGET_CHAR_resolve:
10385    movl     rGLUE,%ecx
10386    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10387    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
10388    EXPORT_PC                                   # could throw, need to export
10389    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10390    movl     %eax,OUT_ARG1(%esp)
10391    movl     %ecx,OUT_ARG0(%esp)
10392    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10393    testl    %eax,%eax
10394    jne      .LOP_SGET_CHAR_finish                 # success, continue
10395    jmp      common_exceptionThrown             # no, handle exception
10396
10397/* continuation for OP_SGET_SHORT */
10398
10399    /*
10400     * Go resolve the field
10401     */
10402.LOP_SGET_SHORT_resolve:
10403    movl     rGLUE,%ecx
10404    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10405    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
10406    EXPORT_PC                                   # could throw, need to export
10407    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10408    movl     %eax,OUT_ARG1(%esp)
10409    movl     %ecx,OUT_ARG0(%esp)
10410    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10411    testl    %eax,%eax
10412    jne      .LOP_SGET_SHORT_finish                 # success, continue
10413    jmp      common_exceptionThrown             # no, handle exception
10414
10415/* continuation for OP_SPUT */
10416
10417    /*
10418     * Go resolve the field
10419     */
10420.LOP_SPUT_resolve:
10421    movl     rGLUE,%ecx
10422    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10423    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
10424    EXPORT_PC                                   # could throw, need to export
10425    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10426    movl     %eax,OUT_ARG1(%esp)
10427    movl     %ecx,OUT_ARG0(%esp)
10428    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10429    testl    %eax,%eax
10430    jne      .LOP_SPUT_finish                 # success, continue
10431    jmp      common_exceptionThrown             # no, handle exception
10432
10433/* continuation for OP_SPUT_WIDE */
10434
10435    /*
10436     * Go resolve the field
10437     */
10438.LOP_SPUT_WIDE_resolve:
10439    movl     rGLUE,%ecx
10440    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10441    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
10442    EXPORT_PC                                   # could throw, need to export
10443    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10444    movl     %eax,OUT_ARG1(%esp)
10445    movl     %ecx,OUT_ARG0(%esp)
10446    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10447    testl    %eax,%eax
10448    jne      .LOP_SPUT_WIDE_finish                 # success, continue
10449    jmp      common_exceptionThrown             # no, handle exception
10450
10451/* continuation for OP_SPUT_OBJECT */
10452
10453
10454.LOP_SPUT_OBJECT_continue:
10455    movl      %ecx,offStaticField_value(%eax)    # do the store
10456    testl     %ecx,%ecx                          # stored null object ptr?
10457    FETCH_INST_OPCODE 2 %edx
10458    je        1f                                 # skip card mark if null
10459    movl      rGLUE,%ecx
10460    movl      offField_clazz(%eax),%eax          # eax<- method->clazz
10461    movl      offGlue_cardTable(%ecx),%ecx       # get card table base
10462    shrl      $GC_CARD_SHIFT,%eax               # head to card number
10463    movb      %cl,(%ecx,%eax)                    # mark card
104641:
10465    ADVANCE_PC 2
10466    GOTO_NEXT_R %edx
10467
10468.LOP_SPUT_OBJECT_resolve:
10469    movl     rGLUE,%ecx
10470    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10471    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
10472    EXPORT_PC                                   # could throw, need to export
10473    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10474    movl     %eax,OUT_ARG1(%esp)
10475    movl     %ecx,OUT_ARG0(%esp)
10476    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10477    testl    %eax,%eax
10478    jne      .LOP_SPUT_OBJECT_finish                 # success, continue
10479    jmp      common_exceptionThrown             # no, handle exception
10480
10481/* continuation for OP_SPUT_BOOLEAN */
10482
10483    /*
10484     * Go resolve the field
10485     */
10486.LOP_SPUT_BOOLEAN_resolve:
10487    movl     rGLUE,%ecx
10488    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10489    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
10490    EXPORT_PC                                   # could throw, need to export
10491    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10492    movl     %eax,OUT_ARG1(%esp)
10493    movl     %ecx,OUT_ARG0(%esp)
10494    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10495    testl    %eax,%eax
10496    jne      .LOP_SPUT_BOOLEAN_finish                 # success, continue
10497    jmp      common_exceptionThrown             # no, handle exception
10498
10499/* continuation for OP_SPUT_BYTE */
10500
10501    /*
10502     * Go resolve the field
10503     */
10504.LOP_SPUT_BYTE_resolve:
10505    movl     rGLUE,%ecx
10506    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10507    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
10508    EXPORT_PC                                   # could throw, need to export
10509    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10510    movl     %eax,OUT_ARG1(%esp)
10511    movl     %ecx,OUT_ARG0(%esp)
10512    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10513    testl    %eax,%eax
10514    jne      .LOP_SPUT_BYTE_finish                 # success, continue
10515    jmp      common_exceptionThrown             # no, handle exception
10516
10517/* continuation for OP_SPUT_CHAR */
10518
10519    /*
10520     * Go resolve the field
10521     */
10522.LOP_SPUT_CHAR_resolve:
10523    movl     rGLUE,%ecx
10524    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10525    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
10526    EXPORT_PC                                   # could throw, need to export
10527    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10528    movl     %eax,OUT_ARG1(%esp)
10529    movl     %ecx,OUT_ARG0(%esp)
10530    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10531    testl    %eax,%eax
10532    jne      .LOP_SPUT_CHAR_finish                 # success, continue
10533    jmp      common_exceptionThrown             # no, handle exception
10534
10535/* continuation for OP_SPUT_SHORT */
10536
10537    /*
10538     * Go resolve the field
10539     */
10540.LOP_SPUT_SHORT_resolve:
10541    movl     rGLUE,%ecx
10542    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10543    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
10544    EXPORT_PC                                   # could throw, need to export
10545    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10546    movl     %eax,OUT_ARG1(%esp)
10547    movl     %ecx,OUT_ARG0(%esp)
10548    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10549    testl    %eax,%eax
10550    jne      .LOP_SPUT_SHORT_finish                 # success, continue
10551    jmp      common_exceptionThrown             # no, handle exception
10552
10553/* continuation for OP_INVOKE_VIRTUAL */
10554
10555
10556.LOP_INVOKE_VIRTUAL_more:
10557    movl      offMethod_clazz(%eax),%eax  # ecx<- method->clazz
10558    movl      %eax,OUT_ARG0(%esp)         # arg0<- clazz
10559    movl      $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags
10560    call      dvmResolveMethod            # eax<- call(clazz, ref, flags)
10561    testl     %eax,%eax                   # got null?
10562    jne       .LOP_INVOKE_VIRTUAL_continue        # no, continue
10563    jmp       common_exceptionThrown      # yes, handle exception
10564
10565    /* At this point:
10566     *   eax = resolved base method
10567     *   ecx = scratch
10568     */
10569.LOP_INVOKE_VIRTUAL_continue:
10570    movzwl    4(rPC),%ecx               # ecx<- GFED or CCCC
10571    .if       (!0)
10572    andl      $0xf,%ecx                # ecx<- D (or stays CCCC)
10573    .endif
10574    GET_VREG_R  %ecx %ecx               # ecx<- "this"
10575    movzwl    offMethod_methodIndex(%eax),%eax  # eax<- baseMethod->methodIndex
10576    testl     %ecx,%ecx                 # null this?
10577    je        common_errNullObject      # go if so
10578    movl      offObject_clazz(%ecx),%ecx  # ecx<- thisPtr->clazz
10579    movl      offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable
10580    movl      (%ecx,%eax,4),%eax        # eax<- vtable[methodIndex]
10581    jmp       common_invokeMethodNoRange
10582
10583/* continuation for OP_INVOKE_SUPER */
10584
10585    /*
10586     * At this point:
10587     *  ecx = resolved base method [r0]
10588     *  eax = method->clazz [r9]
10589     */
10590.LOP_INVOKE_SUPER_continue:
10591    movl    offClassObject_super(%eax),%eax   # eax<- method->clazz->super
10592    movzwl  offMethod_methodIndex(%ecx),%ecx  # ecx<- baseMthod->methodIndex
10593    cmpl    offClassObject_vtableCount(%eax),%ecx # compare(methodIndex,vtableCount)
10594    jae     .LOP_INVOKE_SUPER_nsm           # method not present in superclass
10595    movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
10596    movl    (%eax,%ecx,4),%eax        # eax<- vtable[methodIndex]
10597    jmp     common_invokeMethodNoRange
10598
10599
10600    /* At this point:
10601     * ecx = null (needs to be resolved base method)
10602     * eax = method->clazz
10603    */
10604.LOP_INVOKE_SUPER_resolve:
10605    SPILL_TMP1(%eax)                    # method->clazz
10606    movl    %eax,OUT_ARG0(%esp)         # arg0<- method->clazz
10607    movzwl  2(rPC),%ecx                 # ecx<- BBBB
10608    movl    $METHOD_VIRTUAL,OUT_ARG2(%esp)  # arg2<- resolver method type
10609    movl    %ecx,OUT_ARG1(%esp)         # arg1<- ref
10610    call    dvmResolveMethod            # eax<- call(clazz, ref, flags)
10611    testl   %eax,%eax                   # got null?
10612    movl    %eax,%ecx                   # ecx<- resolved base method
10613    UNSPILL_TMP1(%eax)                  # restore method->clazz
10614    jne     .LOP_INVOKE_SUPER_continue        # good to go - continue
10615    jmp     common_exceptionThrown      # handle exception
10616
10617    /*
10618     * Throw a NoSuchMethodError with the method name as the message.
10619     *  ecx = resolved base method
10620     */
10621.LOP_INVOKE_SUPER_nsm:
10622    movl    offMethod_name(%ecx),%eax
10623    mov     %eax,OUT_ARG1(%esp)
10624    jmp     common_errNoSuchMethod
10625
10626/* continuation for OP_INVOKE_DIRECT */
10627
10628    /*
10629     * On entry:
10630     *   TMP_SPILL  <- "this" register
10631     * Things a bit ugly on this path, but it's the less
10632     * frequent one.  We'll have to do some reloading.
10633     */
10634.LOP_INVOKE_DIRECT_resolve:
10635     SPILL_TMP1(%ecx)
10636     movl     rGLUE,%ecx
10637     movl     offGlue_method(%ecx),%ecx  # ecx<- glue->method
10638     movzwl   2(rPC),%eax      # reference (BBBB or CCCC)
10639     movl     offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
10640     movl     $METHOD_DIRECT,OUT_ARG2(%esp)
10641     movl     %eax,OUT_ARG1(%esp)
10642     movl     %ecx,OUT_ARG0(%esp)
10643     call     dvmResolveMethod # eax<- call(clazz, ref, flags)
10644     UNSPILL_TMP1(%ecx)
10645     testl    %eax,%eax
10646     jne      .LOP_INVOKE_DIRECT_finish
10647     jmp      common_exceptionThrown
10648
10649/* continuation for OP_INVOKE_STATIC */
10650
10651.LOP_INVOKE_STATIC_continue:
10652    movl      $METHOD_STATIC,%eax
10653    movl      %eax,OUT_ARG2(%esp)       # arg2<- flags
10654    call      dvmResolveMethod          # call(clazz,ref,flags)
10655    testl     %eax,%eax                 # got null?
10656    jne       common_invokeMethodNoRange
10657    jmp       common_exceptionThrown
10658
10659/* continuation for OP_INVOKE_INTERFACE */
10660
10661.LOP_INVOKE_INTERFACE_continue:
10662    call       dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex)
10663    testl      %eax,%eax
10664    je         common_exceptionThrown
10665    jmp        common_invokeMethodNoRange
10666
10667/* continuation for OP_INVOKE_VIRTUAL_RANGE */
10668
10669
10670.LOP_INVOKE_VIRTUAL_RANGE_more:
10671    movl      offMethod_clazz(%eax),%eax  # ecx<- method->clazz
10672    movl      %eax,OUT_ARG0(%esp)         # arg0<- clazz
10673    movl      $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags
10674    call      dvmResolveMethod            # eax<- call(clazz, ref, flags)
10675    testl     %eax,%eax                   # got null?
10676    jne       .LOP_INVOKE_VIRTUAL_RANGE_continue        # no, continue
10677    jmp       common_exceptionThrown      # yes, handle exception
10678
10679    /* At this point:
10680     *   eax = resolved base method
10681     *   ecx = scratch
10682     */
10683.LOP_INVOKE_VIRTUAL_RANGE_continue:
10684    movzwl    4(rPC),%ecx               # ecx<- GFED or CCCC
10685    .if       (!1)
10686    andl      $0xf,%ecx                # ecx<- D (or stays CCCC)
10687    .endif
10688    GET_VREG_R  %ecx %ecx               # ecx<- "this"
10689    movzwl    offMethod_methodIndex(%eax),%eax  # eax<- baseMethod->methodIndex
10690    testl     %ecx,%ecx                 # null this?
10691    je        common_errNullObject      # go if so
10692    movl      offObject_clazz(%ecx),%ecx  # ecx<- thisPtr->clazz
10693    movl      offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable
10694    movl      (%ecx,%eax,4),%eax        # eax<- vtable[methodIndex]
10695    jmp       common_invokeMethodRange
10696
10697/* continuation for OP_INVOKE_SUPER_RANGE */
10698
10699    /*
10700     * At this point:
10701     *  ecx = resolved base method [r0]
10702     *  eax = method->clazz [r9]
10703     */
10704.LOP_INVOKE_SUPER_RANGE_continue:
10705    movl    offClassObject_super(%eax),%eax   # eax<- method->clazz->super
10706    movzwl  offMethod_methodIndex(%ecx),%ecx  # ecx<- baseMthod->methodIndex
10707    cmpl    offClassObject_vtableCount(%eax),%ecx # compare(methodIndex,vtableCount)
10708    jae     .LOP_INVOKE_SUPER_RANGE_nsm           # method not present in superclass
10709    movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
10710    movl    (%eax,%ecx,4),%eax        # eax<- vtable[methodIndex]
10711    jmp     common_invokeMethodRange
10712
10713
10714    /* At this point:
10715     * ecx = null (needs to be resolved base method)
10716     * eax = method->clazz
10717    */
10718.LOP_INVOKE_SUPER_RANGE_resolve:
10719    SPILL_TMP1(%eax)                    # method->clazz
10720    movl    %eax,OUT_ARG0(%esp)         # arg0<- method->clazz
10721    movzwl  2(rPC),%ecx                 # ecx<- BBBB
10722    movl    $METHOD_VIRTUAL,OUT_ARG2(%esp)  # arg2<- resolver method type
10723    movl    %ecx,OUT_ARG1(%esp)         # arg1<- ref
10724    call    dvmResolveMethod            # eax<- call(clazz, ref, flags)
10725    testl   %eax,%eax                   # got null?
10726    movl    %eax,%ecx                   # ecx<- resolved base method
10727    UNSPILL_TMP1(%eax)                  # restore method->clazz
10728    jne     .LOP_INVOKE_SUPER_RANGE_continue        # good to go - continue
10729    jmp     common_exceptionThrown      # handle exception
10730
10731    /*
10732     * Throw a NoSuchMethodError with the method name as the message.
10733     *  ecx = resolved base method
10734     */
10735.LOP_INVOKE_SUPER_RANGE_nsm:
10736    movl    offMethod_name(%ecx),%eax
10737    mov     %eax,OUT_ARG1(%esp)
10738    jmp     common_errNoSuchMethod
10739
10740/* continuation for OP_INVOKE_DIRECT_RANGE */
10741
10742    /*
10743     * On entry:
10744     *   TMP_SPILL  <- "this" register
10745     * Things a bit ugly on this path, but it's the less
10746     * frequent one.  We'll have to do some reloading.
10747     */
10748.LOP_INVOKE_DIRECT_RANGE_resolve:
10749     SPILL_TMP1(%ecx)
10750     movl     rGLUE,%ecx
10751     movl     offGlue_method(%ecx),%ecx  # ecx<- glue->method
10752     movzwl   2(rPC),%eax      # reference (BBBB or CCCC)
10753     movl     offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
10754     movl     $METHOD_DIRECT,OUT_ARG2(%esp)
10755     movl     %eax,OUT_ARG1(%esp)
10756     movl     %ecx,OUT_ARG0(%esp)
10757     call     dvmResolveMethod # eax<- call(clazz, ref, flags)
10758     UNSPILL_TMP1(%ecx)
10759     testl    %eax,%eax
10760     jne      .LOP_INVOKE_DIRECT_RANGE_finish
10761     jmp      common_exceptionThrown
10762
10763/* continuation for OP_INVOKE_STATIC_RANGE */
10764
10765.LOP_INVOKE_STATIC_RANGE_continue:
10766    movl      $METHOD_STATIC,%eax
10767    movl      %eax,OUT_ARG2(%esp)       # arg2<- flags
10768    call      dvmResolveMethod          # call(clazz,ref,flags)
10769    testl     %eax,%eax                 # got null?
10770    jne       common_invokeMethodRange
10771    jmp       common_exceptionThrown
10772
10773/* continuation for OP_INVOKE_INTERFACE_RANGE */
10774
10775.LOP_INVOKE_INTERFACE_RANGE_continue:
10776    call       dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex)
10777    testl      %eax,%eax
10778    je         common_exceptionThrown
10779    jmp        common_invokeMethodRange
10780
10781/* continuation for OP_FLOAT_TO_INT */
10782
10783
10784.LOP_FLOAT_TO_INT_continue:
10785    .if 0
10786    movl     $0x80000000,%eax
10787    xorl     4(rFP,%ecx,4),%eax
10788    orl      (rFP,%ecx,4),%eax
10789    .else
10790    cmpl     $0x80000000,(rFP,%ecx,4)
10791    .endif
10792    je       .LOP_FLOAT_TO_INT_special_case # fix up result
10793
10794.LOP_FLOAT_TO_INT_finish:
10795    ADVANCE_PC 1
10796    GOTO_NEXT_R %edx
10797
10798.LOP_FLOAT_TO_INT_special_case:
10799    fnstsw   %ax
10800    sahf
10801    jp       .LOP_FLOAT_TO_INT_isNaN
10802    adcl     $-1,(rFP,%ecx,4)
10803    .if 0
10804    adcl     $-1,4(rFP,%ecx,4)
10805    .endif
10806   jmp       .LOP_FLOAT_TO_INT_finish
10807.LOP_FLOAT_TO_INT_isNaN:
10808    movl      $0,(rFP,%ecx,4)
10809    .if 0
10810    movl      $0,4(rFP,%ecx,4)
10811    .endif
10812    jmp       .LOP_FLOAT_TO_INT_finish
10813
10814/* continuation for OP_FLOAT_TO_LONG */
10815
10816
10817.LOP_FLOAT_TO_LONG_continue:
10818    .if 1
10819    movl     $0x80000000,%eax
10820    xorl     4(rFP,%ecx,4),%eax
10821    orl      (rFP,%ecx,4),%eax
10822    .else
10823    cmpl     $0x80000000,(rFP,%ecx,4)
10824    .endif
10825    je       .LOP_FLOAT_TO_LONG_special_case # fix up result
10826
10827.LOP_FLOAT_TO_LONG_finish:
10828    ADVANCE_PC 1
10829    GOTO_NEXT_R %edx
10830
10831.LOP_FLOAT_TO_LONG_special_case:
10832    fnstsw   %ax
10833    sahf
10834    jp       .LOP_FLOAT_TO_LONG_isNaN
10835    adcl     $-1,(rFP,%ecx,4)
10836    .if 1
10837    adcl     $-1,4(rFP,%ecx,4)
10838    .endif
10839   jmp       .LOP_FLOAT_TO_LONG_finish
10840.LOP_FLOAT_TO_LONG_isNaN:
10841    movl      $0,(rFP,%ecx,4)
10842    .if 1
10843    movl      $0,4(rFP,%ecx,4)
10844    .endif
10845    jmp       .LOP_FLOAT_TO_LONG_finish
10846
10847/* continuation for OP_DOUBLE_TO_INT */
10848
10849
10850.LOP_DOUBLE_TO_INT_continue:
10851    .if 0
10852    movl     $0x80000000,%eax
10853    xorl     4(rFP,%ecx,4),%eax
10854    orl      (rFP,%ecx,4),%eax
10855    .else
10856    cmpl     $0x80000000,(rFP,%ecx,4)
10857    .endif
10858    je       .LOP_DOUBLE_TO_INT_special_case # fix up result
10859
10860.LOP_DOUBLE_TO_INT_finish:
10861    ADVANCE_PC 1
10862    GOTO_NEXT_R %edx
10863
10864.LOP_DOUBLE_TO_INT_special_case:
10865    fnstsw   %ax
10866    sahf
10867    jp       .LOP_DOUBLE_TO_INT_isNaN
10868    adcl     $-1,(rFP,%ecx,4)
10869    .if 0
10870    adcl     $-1,4(rFP,%ecx,4)
10871    .endif
10872   jmp       .LOP_DOUBLE_TO_INT_finish
10873.LOP_DOUBLE_TO_INT_isNaN:
10874    movl      $0,(rFP,%ecx,4)
10875    .if 0
10876    movl      $0,4(rFP,%ecx,4)
10877    .endif
10878    jmp       .LOP_DOUBLE_TO_INT_finish
10879
10880/* continuation for OP_DOUBLE_TO_LONG */
10881
10882
10883.LOP_DOUBLE_TO_LONG_continue:
10884    .if 1
10885    movl     $0x80000000,%eax
10886    xorl     4(rFP,%ecx,4),%eax
10887    orl      (rFP,%ecx,4),%eax
10888    .else
10889    cmpl     $0x80000000,(rFP,%ecx,4)
10890    .endif
10891    je       .LOP_DOUBLE_TO_LONG_special_case # fix up result
10892
10893.LOP_DOUBLE_TO_LONG_finish:
10894    ADVANCE_PC 1
10895    GOTO_NEXT_R %edx
10896
10897.LOP_DOUBLE_TO_LONG_special_case:
10898    fnstsw   %ax
10899    sahf
10900    jp       .LOP_DOUBLE_TO_LONG_isNaN
10901    adcl     $-1,(rFP,%ecx,4)
10902    .if 1
10903    adcl     $-1,4(rFP,%ecx,4)
10904    .endif
10905   jmp       .LOP_DOUBLE_TO_LONG_finish
10906.LOP_DOUBLE_TO_LONG_isNaN:
10907    movl      $0,(rFP,%ecx,4)
10908    .if 1
10909    movl      $0,4(rFP,%ecx,4)
10910    .endif
10911    jmp       .LOP_DOUBLE_TO_LONG_finish
10912
10913/* continuation for OP_DIV_INT */
10914.LOP_DIV_INT_continue_div:
10915    cltd
10916    idivl   %ecx
10917.LOP_DIV_INT_finish_div:
10918    SET_VREG %eax rINST
10919    FETCH_INST_OPCODE 2 %edx
10920    ADVANCE_PC 2
10921    GOTO_NEXT_R %edx
10922
10923/* continuation for OP_REM_INT */
10924.LOP_REM_INT_continue_div:
10925    cltd
10926    idivl   %ecx
10927.LOP_REM_INT_finish_div:
10928    SET_VREG %edx rINST
10929    FETCH_INST_OPCODE 2 %edx
10930    ADVANCE_PC 2
10931    GOTO_NEXT_R %edx
10932
10933/* continuation for OP_MUL_LONG */
10934
10935.LOP_MUL_LONG_continue:
10936    leal      (%ecx,%edx),%edx     # full result now in %edx:%eax
10937    UNSPILL_TMP2(%esi)             # Restore Dalvik PC
10938    FETCH_INST_OPCODE 2 %ecx       # Fetch next instruction
10939    movl      %edx,4(rFP,rINST,4)  # v[B+1]<- %edx
10940    movl      %eax,(rFP,rINST,4)   # v[B]<- %eax
10941    ADVANCE_PC 2
10942    GOTO_NEXT_R %ecx
10943
10944/* continuation for OP_DIV_LONG */
10945
10946.LOP_DIV_LONG_continue:
10947    call     __divdi3
10948.LOP_DIV_LONG_finish:
10949    SET_VREG_WORD %edx rINST 1
10950    SET_VREG_WORD %eax rINST 0
10951    FETCH_INST_OPCODE 2 %edx
10952    ADVANCE_PC 2
10953    GOTO_NEXT_R %edx
10954
10955.LOP_DIV_LONG_check_zero:
10956    testl   %edx,%edx
10957    jne     .LOP_DIV_LONG_notSpecial
10958    jmp     common_errDivideByZero
10959.LOP_DIV_LONG_check_neg1:
10960    testl   %edx,%eax
10961    jne     .LOP_DIV_LONG_notSpecial
10962    GET_VREG_WORD %edx %ecx 0
10963    GET_VREG_WORD %ecx %ecx 1
10964    testl    %edx,%edx
10965    jne      .LOP_DIV_LONG_notSpecial1
10966    cmpl     $0x80000000,%ecx
10967    jne      .LOP_DIV_LONG_notSpecial1
10968    /* minint / -1, return minint on div, 0 on rem */
10969    xorl     %eax,%eax
10970    movl     $0x80000000,%edx
10971    jmp      .LOP_DIV_LONG_finish
10972
10973/* continuation for OP_REM_LONG */
10974
10975.LOP_REM_LONG_continue:
10976    call     __moddi3
10977.LOP_REM_LONG_finish:
10978    SET_VREG_WORD %edx rINST 1
10979    SET_VREG_WORD %eax rINST 0
10980    FETCH_INST_OPCODE 2 %edx
10981    ADVANCE_PC 2
10982    GOTO_NEXT_R %edx
10983
10984.LOP_REM_LONG_check_zero:
10985    testl   %edx,%edx
10986    jne     .LOP_REM_LONG_notSpecial
10987    jmp     common_errDivideByZero
10988.LOP_REM_LONG_check_neg1:
10989    testl   %edx,%eax
10990    jne     .LOP_REM_LONG_notSpecial
10991    GET_VREG_WORD %edx %ecx 0
10992    GET_VREG_WORD %ecx %ecx 1
10993    testl    %edx,%edx
10994    jne      .LOP_REM_LONG_notSpecial1
10995    cmpl     $0x80000000,%ecx
10996    jne      .LOP_REM_LONG_notSpecial1
10997    /* minint / -1, return minint on div, 0 on rem */
10998    xorl     %eax,%eax
10999    movl     $0,%edx
11000    jmp      .LOP_REM_LONG_finish
11001
11002/* continuation for OP_SHL_LONG */
11003
11004.LOP_SHL_LONG_finish:
11005    SET_VREG_WORD %eax rINST 0          # v[AA+0]<- %eax
11006    ADVANCE_PC 2
11007    GOTO_NEXT_R %edx
11008
11009/* continuation for OP_SHR_LONG */
11010
11011
11012.LOP_SHR_LONG_finish:
11013    SET_VREG_WORD %eax rINST 0          # v[AA+0]<- eax
11014    ADVANCE_PC 2
11015    GOTO_NEXT_R %edx
11016
11017/* continuation for OP_USHR_LONG */
11018
11019
11020.LOP_USHR_LONG_finish:
11021    SET_VREG_WORD %eax rINST 0         # v[BB+0]<- eax
11022    ADVANCE_PC 2
11023    GOTO_NEXT_R %edx
11024
11025/* continuation for OP_DIV_INT_2ADDR */
11026.LOP_DIV_INT_2ADDR_continue_div2addr:
11027    cltd
11028    idivl   %ecx
11029.LOP_DIV_INT_2ADDR_finish_div2addr:
11030    SET_VREG %eax rINST
11031    FETCH_INST_OPCODE 1 %edx
11032    ADVANCE_PC 1
11033    GOTO_NEXT_R %edx
11034
11035/* continuation for OP_REM_INT_2ADDR */
11036.LOP_REM_INT_2ADDR_continue_div2addr:
11037    cltd
11038    idivl   %ecx
11039.LOP_REM_INT_2ADDR_finish_div2addr:
11040    SET_VREG %edx rINST
11041    FETCH_INST_OPCODE 1 %edx
11042    ADVANCE_PC 1
11043    GOTO_NEXT_R %edx
11044
11045/* continuation for OP_MUL_LONG_2ADDR */
11046
11047.LOP_MUL_LONG_2ADDR_continue:
11048    leal      (%ecx,%edx),%edx         # full result now in %edx:%eax
11049    movl      %edx,4(%esi)             # v[A+1]<- %edx
11050    movl      %eax,(%esi)              # v[A]<- %eax
11051    UNSPILL_TMP2(%esi)
11052    FETCH_INST_OPCODE 1 %ecx
11053    UNSPILL(rFP)
11054    ADVANCE_PC 1
11055    GOTO_NEXT_R %ecx
11056
11057/* continuation for OP_DIV_LONG_2ADDR */
11058
11059.LOP_DIV_LONG_2ADDR_continue:
11060    movl     %eax,OUT_ARG3(%esp)
11061    movl     %edx,OUT_ARG0(%esp)
11062    movl     %ecx,OUT_ARG1(%esp)
11063    call     __divdi3
11064.LOP_DIV_LONG_2ADDR_finish:
11065    SET_VREG_WORD %edx rINST 1
11066    SET_VREG_WORD %eax rINST 0
11067    FETCH_INST_OPCODE 1 %edx
11068    ADVANCE_PC 1
11069    GOTO_NEXT_R %edx
11070
11071.LOP_DIV_LONG_2ADDR_check_zero:
11072    testl   %edx,%edx
11073    jne     .LOP_DIV_LONG_2ADDR_notSpecial
11074    jmp     common_errDivideByZero
11075.LOP_DIV_LONG_2ADDR_check_neg1:
11076    testl   %edx,%eax
11077    jne     .LOP_DIV_LONG_2ADDR_notSpecial
11078    GET_VREG_WORD %edx rINST 0
11079    GET_VREG_WORD %ecx rINST 1
11080    testl    %edx,%edx
11081    jne      .LOP_DIV_LONG_2ADDR_notSpecial1
11082    cmpl     $0x80000000,%ecx
11083    jne      .LOP_DIV_LONG_2ADDR_notSpecial1
11084    /* minint / -1, return minint on div, 0 on rem */
11085    xorl     %eax,%eax
11086    movl     $0x80000000,%edx
11087    jmp      .LOP_DIV_LONG_2ADDR_finish
11088
11089/* continuation for OP_REM_LONG_2ADDR */
11090
11091.LOP_REM_LONG_2ADDR_continue:
11092    movl     %eax,OUT_ARG3(%esp)
11093    movl     %edx,OUT_ARG0(%esp)
11094    movl     %ecx,OUT_ARG1(%esp)
11095    call     __moddi3
11096.LOP_REM_LONG_2ADDR_finish:
11097    SET_VREG_WORD %edx rINST 1
11098    SET_VREG_WORD %eax rINST 0
11099    FETCH_INST_OPCODE 1 %edx
11100    ADVANCE_PC 1
11101    GOTO_NEXT_R %edx
11102
11103.LOP_REM_LONG_2ADDR_check_zero:
11104    testl   %edx,%edx
11105    jne     .LOP_REM_LONG_2ADDR_notSpecial
11106    jmp     common_errDivideByZero
11107.LOP_REM_LONG_2ADDR_check_neg1:
11108    testl   %edx,%eax
11109    jne     .LOP_REM_LONG_2ADDR_notSpecial
11110    GET_VREG_WORD %edx rINST 0
11111    GET_VREG_WORD %ecx rINST 1
11112    testl    %edx,%edx
11113    jne      .LOP_REM_LONG_2ADDR_notSpecial1
11114    cmpl     $0x80000000,%ecx
11115    jne      .LOP_REM_LONG_2ADDR_notSpecial1
11116    /* minint / -1, return minint on div, 0 on rem */
11117    xorl     %eax,%eax
11118    movl     $0,%edx
11119    jmp      .LOP_REM_LONG_2ADDR_finish
11120
11121/* continuation for OP_SHL_LONG_2ADDR */
11122
11123
11124.LOP_SHL_LONG_2ADDR_finish:
11125    FETCH_INST_OPCODE 1 %edx
11126    SET_VREG_WORD %eax rINST 0         # v[AA+0]<- eax
11127    ADVANCE_PC 1
11128    GOTO_NEXT_R %edx
11129
11130/* continuation for OP_SHR_LONG_2ADDR */
11131
11132
11133.LOP_SHR_LONG_2ADDR_finish:
11134    FETCH_INST_OPCODE 1 %edx
11135    SET_VREG_WORD %eax rINST 0    # v[AA+0]<- eax
11136    ADVANCE_PC 1
11137    GOTO_NEXT_R %edx
11138
11139/* continuation for OP_USHR_LONG_2ADDR */
11140
11141
11142.LOP_USHR_LONG_2ADDR_finish:
11143    FETCH_INST_OPCODE 1 %edx
11144    SET_VREG_WORD %eax rINST 0         # v[AA+0]<- eax
11145    ADVANCE_PC 1
11146    GOTO_NEXT_R %edx
11147
11148/* continuation for OP_DIV_INT_LIT16 */
11149.LOP_DIV_INT_LIT16_continue_div:
11150    cltd
11151    idivl   %ecx
11152.LOP_DIV_INT_LIT16_finish_div:
11153    SET_VREG %eax rINST
11154    FETCH_INST_OPCODE 2 %edx
11155    ADVANCE_PC 2
11156    GOTO_NEXT_R %edx
11157
11158/* continuation for OP_REM_INT_LIT16 */
11159.LOP_REM_INT_LIT16_continue_div:
11160    cltd
11161    idivl   %ecx
11162.LOP_REM_INT_LIT16_finish_div:
11163    SET_VREG %edx rINST
11164    FETCH_INST_OPCODE 2 %edx
11165    ADVANCE_PC 2
11166    GOTO_NEXT_R %edx
11167
11168/* continuation for OP_DIV_INT_LIT8 */
11169.LOP_DIV_INT_LIT8_continue_div:
11170    cltd
11171    idivl   %ecx
11172.LOP_DIV_INT_LIT8_finish_div:
11173    SET_VREG %eax rINST
11174    FETCH_INST_OPCODE 2 %edx
11175    ADVANCE_PC 2
11176    GOTO_NEXT_R %edx
11177
11178/* continuation for OP_REM_INT_LIT8 */
11179.LOP_REM_INT_LIT8_continue_div:
11180    cltd
11181    idivl   %ecx
11182.LOP_REM_INT_LIT8_finish_div:
11183    SET_VREG %edx rINST
11184    FETCH_INST_OPCODE 2 %edx
11185    ADVANCE_PC 2
11186    GOTO_NEXT_R %edx
11187
11188/* continuation for OP_IGET_VOLATILE */
11189
11190
11191.LOP_IGET_VOLATILE_resolve:
11192    EXPORT_PC
11193    movl    offGlue_method(%edx),%edx           # edx<- current method
11194    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11195    SPILL_TMP1(%ecx)                            # save obj pointer across call
11196    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
11197    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11198    UNSPILL_TMP1(%ecx)
11199    testl   %eax,%eax                           #  returns InstrField ptr
11200    jne     .LOP_IGET_VOLATILE_finish
11201    jmp     common_exceptionThrown
11202
11203.LOP_IGET_VOLATILE_finish:
11204    /*
11205     * Currently:
11206     *   eax holds resolved field
11207     *   ecx holds object
11208     *   rINST holds A
11209     */
11210    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11211    testl   %ecx,%ecx                           # object null?
11212    je      common_errNullObject                # object was null
11213    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
11214    movl    rINST,%eax                          # eax<- A
11215    FETCH_INST_OPCODE 2 %edx
11216    SET_VREG %ecx %eax
11217    ADVANCE_PC 2
11218    GOTO_NEXT_R %edx
11219
11220/* continuation for OP_IPUT_VOLATILE */
11221
11222
11223.LOP_IPUT_VOLATILE_resolve:
11224    EXPORT_PC
11225    movl    offGlue_method(%edx),%edx           # edx<- current method
11226    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11227    SPILL_TMP1(%ecx)                            # save obj pointer across call
11228    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
11229    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11230    UNSPILL_TMP1(%ecx)
11231    testl   %eax,%eax                           # returns InstrField ptr
11232    jne     .LOP_IPUT_VOLATILE_finish
11233    jmp     common_exceptionThrown
11234
11235.LOP_IPUT_VOLATILE_finish:
11236    /*
11237     * Currently:
11238     *   eax holds resolved field
11239     *   ecx holds object
11240     *   rINST holds A
11241     */
11242    GET_VREG_R rINST rINST                       # rINST<- v[A]
11243    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
11244    testl   %ecx,%ecx                            # object null?
11245    je      common_errNullObject                 # object was null
11246    FETCH_INST_OPCODE 2 %edx
11247    movl   rINST,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
11248    ADVANCE_PC 2
11249    GOTO_NEXT_R %edx
11250
11251/* continuation for OP_SGET_VOLATILE */
11252
11253    /*
11254     * Go resolve the field
11255     */
11256.LOP_SGET_VOLATILE_resolve:
11257    movl     rGLUE,%ecx
11258    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
11259    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
11260    EXPORT_PC                                   # could throw, need to export
11261    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
11262    movl     %eax,OUT_ARG1(%esp)
11263    movl     %ecx,OUT_ARG0(%esp)
11264    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
11265    testl    %eax,%eax
11266    jne      .LOP_SGET_VOLATILE_finish                 # success, continue
11267    jmp      common_exceptionThrown             # no, handle exception
11268
11269/* continuation for OP_SPUT_VOLATILE */
11270
11271    /*
11272     * Go resolve the field
11273     */
11274.LOP_SPUT_VOLATILE_resolve:
11275    movl     rGLUE,%ecx
11276    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
11277    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
11278    EXPORT_PC                                   # could throw, need to export
11279    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
11280    movl     %eax,OUT_ARG1(%esp)
11281    movl     %ecx,OUT_ARG0(%esp)
11282    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
11283    testl    %eax,%eax
11284    jne      .LOP_SPUT_VOLATILE_finish                 # success, continue
11285    jmp      common_exceptionThrown             # no, handle exception
11286
11287/* continuation for OP_IGET_OBJECT_VOLATILE */
11288
11289
11290.LOP_IGET_OBJECT_VOLATILE_resolve:
11291    EXPORT_PC
11292    movl    offGlue_method(%edx),%edx           # edx<- current method
11293    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11294    SPILL_TMP1(%ecx)                            # save obj pointer across call
11295    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
11296    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11297    UNSPILL_TMP1(%ecx)
11298    testl   %eax,%eax                           #  returns InstrField ptr
11299    jne     .LOP_IGET_OBJECT_VOLATILE_finish
11300    jmp     common_exceptionThrown
11301
11302.LOP_IGET_OBJECT_VOLATILE_finish:
11303    /*
11304     * Currently:
11305     *   eax holds resolved field
11306     *   ecx holds object
11307     *   rINST holds A
11308     */
11309    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11310    testl   %ecx,%ecx                           # object null?
11311    je      common_errNullObject                # object was null
11312    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
11313    movl    rINST,%eax                          # eax<- A
11314    FETCH_INST_OPCODE 2 %edx
11315    SET_VREG %ecx %eax
11316    ADVANCE_PC 2
11317    GOTO_NEXT_R %edx
11318
11319/* continuation for OP_EXECUTE_INLINE */
11320
11321.LOP_EXECUTE_INLINE_continue:
11322    /*
11323     * Extract args, call function.
11324     *  ecx = #of args (0-4)
11325     *  eax = call index
11326     *  @esp = return addr
11327     *  esp is -4 from normal
11328     *
11329     *  Go ahead and load all 4 args, even if not used.
11330     */
11331    movzwl    4(rPC),%edx
11332
11333    movl      $0xf,%ecx
11334    andl      %edx,%ecx
11335    GET_VREG_R  %ecx %ecx
11336    sarl      $4,%edx
11337    movl      %ecx,4+OUT_ARG0(%esp)
11338
11339    movl      $0xf,%ecx
11340    andl      %edx,%ecx
11341    GET_VREG_R  %ecx %ecx
11342    sarl      $4,%edx
11343    movl      %ecx,4+OUT_ARG1(%esp)
11344
11345    movl      $0xf,%ecx
11346    andl      %edx,%ecx
11347    GET_VREG_R  %ecx %ecx
11348    sarl      $4,%edx
11349    movl      %ecx,4+OUT_ARG2(%esp)
11350
11351    movl      $0xf,%ecx
11352    andl      %edx,%ecx
11353    GET_VREG_R  %ecx %ecx
11354    sarl      $4,%edx
11355    movl      %ecx,4+OUT_ARG3(%esp)
11356
11357    sall      $4,%eax      # index *= sizeof(table entry)
11358    jmp       *gDvmInlineOpsTable(%eax)
11359    # will return to caller of .LOP_EXECUTE_INLINE_continue
11360
11361/* continuation for OP_IPUT_OBJECT_QUICK */
11362
11363.LOP_IPUT_OBJECT_QUICK_finish:
11364    testl     rINST,rINST               # did we store null?
11365    FETCH_INST_OPCODE 2 %edx
11366    movl      offGlue_cardTable(%eax),%eax  # get card table base
11367    je        1f                            # skip card mark if null store
11368    shrl      $GC_CARD_SHIFT,%ecx          # object head to card number
11369    movb      %al,(%eax,%ecx)               # mark card based on object head
113701:
11371    ADVANCE_PC 2
11372    GOTO_NEXT_R %edx
11373
11374/* continuation for OP_IPUT_OBJECT_VOLATILE */
11375
11376
11377.LOP_IPUT_OBJECT_VOLATILE_resolve:
11378    EXPORT_PC
11379    movl    offGlue_method(%edx),%edx           # edx<- current method
11380    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11381    SPILL_TMP1(%ecx)                            # save obj pointer across call
11382    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
11383    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11384    UNSPILL_TMP1(%ecx)
11385    testl   %eax,%eax                           # returns InstrField ptr
11386    jne     .LOP_IPUT_OBJECT_VOLATILE_finish
11387    jmp     common_exceptionThrown
11388
11389.LOP_IPUT_OBJECT_VOLATILE_finish:
11390    /*
11391     * Currently:
11392     *   eax holds resolved field
11393     *   ecx holds object
11394     *   %edx is scratch, but needs to be unspilled
11395     *   rINST holds A
11396     */
11397    GET_VREG_R rINST rINST                      # rINST<- v[A]
11398    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11399    testl   %ecx,%ecx                           # object null?
11400    je      common_errNullObject                # object was null
11401    movl    rINST,(%ecx,%eax)      # obj.field <- v[A](8/16/32 bits)
11402    movl    rGLUE,%eax
11403    testl   rINST,rINST                         # stored a NULL?
11404    movl    offGlue_cardTable(%eax),%eax        # get card table base
11405    FETCH_INST_OPCODE 2 %edx
11406    je      1f                                  # skip card mark if null store
11407    shrl    $GC_CARD_SHIFT,%ecx                # object head to card number
11408    movb    %al,(%eax,%ecx)                     # mark card using object head
114091:
11410    ADVANCE_PC 2
11411    GOTO_NEXT_R %edx
11412
11413/* continuation for OP_SGET_OBJECT_VOLATILE */
11414
11415    /*
11416     * Go resolve the field
11417     */
11418.LOP_SGET_OBJECT_VOLATILE_resolve:
11419    movl     rGLUE,%ecx
11420    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
11421    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
11422    EXPORT_PC                                   # could throw, need to export
11423    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
11424    movl     %eax,OUT_ARG1(%esp)
11425    movl     %ecx,OUT_ARG0(%esp)
11426    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
11427    testl    %eax,%eax
11428    jne      .LOP_SGET_OBJECT_VOLATILE_finish                 # success, continue
11429    jmp      common_exceptionThrown             # no, handle exception
11430
11431/* continuation for OP_SPUT_OBJECT_VOLATILE */
11432
11433
11434.LOP_SPUT_OBJECT_VOLATILE_continue:
11435    movl      %ecx,offStaticField_value(%eax)    # do the store
11436    testl     %ecx,%ecx                          # stored null object ptr?
11437    FETCH_INST_OPCODE 2 %edx
11438    je        1f                                 # skip card mark if null
11439    movl      rGLUE,%ecx
11440    movl      offField_clazz(%eax),%eax          # eax<- method->clazz
11441    movl      offGlue_cardTable(%ecx),%ecx       # get card table base
11442    shrl      $GC_CARD_SHIFT,%eax               # head to card number
11443    movb      %cl,(%ecx,%eax)                    # mark card
114441:
11445    ADVANCE_PC 2
11446    GOTO_NEXT_R %edx
11447
11448.LOP_SPUT_OBJECT_VOLATILE_resolve:
11449    movl     rGLUE,%ecx
11450    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
11451    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
11452    EXPORT_PC                                   # could throw, need to export
11453    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
11454    movl     %eax,OUT_ARG1(%esp)
11455    movl     %ecx,OUT_ARG0(%esp)
11456    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
11457    testl    %eax,%eax
11458    jne      .LOP_SPUT_OBJECT_VOLATILE_finish                 # success, continue
11459    jmp      common_exceptionThrown             # no, handle exception
11460
11461/* continuation for OP_CONST_CLASS_JUMBO */
11462
11463/* This is the less common path, so we'll redo some work
11464   here rather than force spills on the common path */
11465.LOP_CONST_CLASS_JUMBO_resolve:
11466    movl     rGLUE,%eax
11467    EXPORT_PC
11468    movl     offGlue_method(%eax),%eax # eax<- glue->method
11469    movl     $1,OUT_ARG2(%esp)        # true
11470    movl     2(rPC),%ecx               # ecx<- AAAAAAAA
11471    movl     offMethod_clazz(%eax),%eax
11472    movl     %ecx,OUT_ARG1(%esp)
11473    movl     %eax,OUT_ARG0(%esp)
11474    call     dvmResolveClass           # go resolve
11475    testl    %eax,%eax                 # failed?
11476    je       common_exceptionThrown
11477    SET_VREG %eax rINST
11478    FETCH_INST_OPCODE 4 %edx
11479    ADVANCE_PC 4
11480    GOTO_NEXT_R %edx
11481
11482/* continuation for OP_CHECK_CAST_JUMBO */
11483
11484    /*
11485     * Trivial test failed, need to perform full check.  This is common.
11486     *  ecx holds obj->clazz
11487     *  eax holds class resolved from AAAAAAAA
11488     *  rINST holds object
11489     */
11490.LOP_CHECK_CAST_JUMBO_fullcheck:
11491    movl    %eax,sReg0                 # we'll need the desired class on failure
11492    movl    %eax,OUT_ARG1(%esp)
11493    movl    %ecx,OUT_ARG0(%esp)
11494    call    dvmInstanceofNonTrivial    # eax<- boolean result
11495    testl   %eax,%eax                  # failed?
11496    jne     .LOP_CHECK_CAST_JUMBO_okay           # no, success
11497
11498    # A cast has failed.  We need to throw a ClassCastException.
11499    EXPORT_PC
11500    movl    offObject_clazz(rINST),%eax
11501    movl    %eax,OUT_ARG0(%esp)                 # arg0<- obj->clazz
11502    movl    sReg0,%ecx
11503    movl    %ecx,OUT_ARG1(%esp)                 # arg1<- desired class
11504    call    dvmThrowClassCastException
11505    jmp     common_exceptionThrown
11506
11507    /*
11508     * Resolution required.  This is the least-likely path, and we're
11509     * going to have to recreate some data.
11510     *
11511     *  rINST holds object
11512     */
11513.LOP_CHECK_CAST_JUMBO_resolve:
11514    movl    rGLUE,%ecx
11515    EXPORT_PC
11516    movl    2(rPC),%eax                # eax<- AAAAAAAA
11517    movl    offGlue_method(%ecx),%ecx  # ecx<- glue->method
11518    movl    %eax,OUT_ARG1(%esp)        # arg1<- AAAAAAAA
11519    movl    offMethod_clazz(%ecx),%ecx # ecx<- metho->clazz
11520    movl    $0,OUT_ARG2(%esp)         # arg2<- false
11521    movl    %ecx,OUT_ARG0(%esp)        # arg0<- method->clazz
11522    call    dvmResolveClass            # eax<- resolved ClassObject ptr
11523    testl   %eax,%eax                  # got null?
11524    je      common_exceptionThrown     # yes, handle exception
11525    movl    offObject_clazz(rINST),%ecx  # ecx<- obj->clazz
11526    jmp     .LOP_CHECK_CAST_JUMBO_resolved       # pick up where we left off
11527
11528/* continuation for OP_INSTANCE_OF_JUMBO */
11529
11530    /*
11531     * Trivial test failed, need to perform full check.  This is common.
11532     *  eax holds obj->clazz
11533     *  ecx holds class resolved from BBBB
11534     *  rINST has BA
11535     */
11536.LOP_INSTANCE_OF_JUMBO_fullcheck:
11537    movl    %eax,OUT_ARG0(%esp)
11538    movl    %ecx,OUT_ARG1(%esp)
11539    call    dvmInstanceofNonTrivial     # eax<- boolean result
11540    # fall through to OP_INSTANCE_OF_JUMBO_store
11541
11542    /*
11543     * eax holds boolean result
11544     * rINST holds BBBB
11545     */
11546.LOP_INSTANCE_OF_JUMBO_store:
11547    FETCH_INST_OPCODE 5 %edx
11548    ADVANCE_PC 5
11549    SET_VREG %eax rINST                 # vBBBB<- eax
11550    GOTO_NEXT_R %edx
11551
11552    /*
11553     * Trivial test succeeded, save and bail.
11554     *  r9 holds BBBB
11555     */
11556.LOP_INSTANCE_OF_JUMBO_trivial:
11557    FETCH_INST_OPCODE 5 %edx
11558    ADVANCE_PC 5
11559    movl    $1,%eax
11560    SET_VREG %eax rINST                 # vBBBB<- true
11561    GOTO_NEXT_R %edx
11562
11563    /*
11564     * Resolution required.  This is the least-likely path.
11565     *
11566     *  edx holds AAAAAAAA
11567     */
11568.LOP_INSTANCE_OF_JUMBO_resolve:
11569    movl    %edx,OUT_ARG1(%esp)         # arg1<- AAAAAAAA
11570    movl    rGLUE,%ecx
11571    movl    offGlue_method(%ecx),%ecx
11572    movl    $1,OUT_ARG2(%esp)          # arg2<- true
11573    movl    offMethod_clazz(%ecx),%ecx  # ecx<- method->clazz
11574    EXPORT_PC
11575    movl    %ecx,OUT_ARG0(%esp)         # arg0<- method->clazz
11576    call    dvmResolveClass             # eax<- resolved ClassObject ptr
11577    testl   %eax,%eax                   # success?
11578    je      common_exceptionThrown      # no, handle exception
11579/* Now, we need to sync up with fast path.  We need eax to
11580 * hold the obj->clazz, and ecx to hold the resolved class
11581 */
11582    movl    %eax,%ecx                   # ecx<- resolved class
11583    movzwl  8(rPC),%eax                 # eax<- CCCC
11584    GET_VREG_R %eax %eax                # eax<- vCCCC (obj)
11585    movl    offObject_clazz(%eax),%eax  # eax<- obj->clazz
11586    jmp     .LOP_INSTANCE_OF_JUMBO_resolved
11587
11588/* continuation for OP_NEW_INSTANCE_JUMBO */
11589
11590.LOP_NEW_INSTANCE_JUMBO_initialized:  # on entry, ecx<- class
11591    /* TODO: remove test for interface/abstract, now done in verifier */
11592    testl     $(ACC_INTERFACE|ACC_ABSTRACT),offClassObject_accessFlags(%ecx)
11593    movl      $ALLOC_DONT_TRACK,OUT_ARG1(%esp)
11594    jne       .LOP_NEW_INSTANCE_JUMBO_abstract
11595.LOP_NEW_INSTANCE_JUMBO_finish: # ecx=class
11596    movl     %ecx,OUT_ARG0(%esp)
11597    call     dvmAllocObject             # eax<- new object
11598    FETCH_INST_OPCODE 4 %edx
11599    testl    %eax,%eax                  # success?
11600    je       common_exceptionThrown     # no, bail out
11601    SET_VREG %eax rINST
11602    ADVANCE_PC 4
11603    GOTO_NEXT_R %edx
11604
11605    /*
11606     * Class initialization required.
11607     *
11608     *  ecx holds class object
11609     */
11610.LOP_NEW_INSTANCE_JUMBO_needinit:
11611    SPILL_TMP1(%ecx)                    # save object
11612    movl    %ecx,OUT_ARG0(%esp)
11613    call    dvmInitClass                # initialize class
11614    UNSPILL_TMP1(%ecx)                  # restore object
11615    testl   %eax,%eax                   # success?
11616    jne     .LOP_NEW_INSTANCE_JUMBO_initialized     # success, continue
11617    jmp     common_exceptionThrown      # go deal with init exception
11618
11619    /*
11620     * Resolution required.  This is the least-likely path.
11621     *
11622     */
11623.LOP_NEW_INSTANCE_JUMBO_resolve:
11624    movl    rGLUE,%ecx
11625    movl    2(rPC),%eax                 # eax<- AAAAAAAA
11626    movl    offGlue_method(%ecx),%ecx   # ecx<- glue->method
11627    movl    %eax,OUT_ARG1(%esp)
11628    movl    offMethod_clazz(%ecx),%ecx  # ecx<- method->clazz
11629    movl    $0,OUT_ARG2(%esp)
11630    movl    %ecx,OUT_ARG0(%esp)
11631    call    dvmResolveClass             # call(clazz,off,flags)
11632    movl    %eax,%ecx                   # ecx<- resolved ClassObject ptr
11633    testl   %ecx,%ecx                   # success?
11634    jne     .LOP_NEW_INSTANCE_JUMBO_resolved        # good to go
11635    jmp     common_exceptionThrown      # no, handle exception
11636
11637    /*
11638     * TODO: remove this
11639     * We can't instantiate an abstract class or interface, so throw an
11640     * InstantiationError with the class descriptor as the message.
11641     *
11642     *  ecx holds class object
11643     */
11644.LOP_NEW_INSTANCE_JUMBO_abstract:
11645    movl    offClassObject_descriptor(%ecx),%eax
11646    movl    $.LstrInstantiationError,OUT_ARG0(%esp)
11647    movl    %eax,OUT_ARG1(%esp)
11648    call    dvmThrowExceptionWithClassMessage
11649    jmp     common_exceptionThrown
11650
11651/* continuation for OP_NEW_ARRAY_JUMBO */
11652
11653    /*
11654     * Resolve class.  (This is an uncommon case.)
11655     *  ecx holds class (null here)
11656     *  eax holds array length (vCCCC)
11657     */
11658.LOP_NEW_ARRAY_JUMBO_resolve:
11659    movl    rGLUE,%ecx
11660    SPILL_TMP1(%eax)                   # save array length
11661    movl    offGlue_method(%ecx),%ecx  # ecx<- glue->method
11662    movl    2(rPC),%eax                # eax<- AAAAAAAA
11663    movl    offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
11664    movl    %eax,OUT_ARG1(%esp)
11665    movl    $0,OUT_ARG2(%esp)
11666    movl    %ecx,OUT_ARG0(%esp)
11667    call    dvmResolveClass            # eax<- call(clazz,ref,flag)
11668    movl    %eax,%ecx
11669    UNSPILL_TMP1(%eax)
11670    testl   %ecx,%ecx                  # successful resolution?
11671    je      common_exceptionThrown     # no, bail.
11672# fall through to OP_NEW_ARRAY_JUMBO_finish
11673
11674    /*
11675     * Finish allocation
11676     *
11677     * ecx holds class
11678     * eax holds array length (vCCCC)
11679     */
11680.LOP_NEW_ARRAY_JUMBO_finish:
11681    movl    %ecx,OUT_ARG0(%esp)
11682    movl    %eax,OUT_ARG1(%esp)
11683    movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)
11684    call    dvmAllocArrayByClass    # eax<- call(clazz,length,flags)
11685    FETCH_INST_OPCODE 5 %edx
11686    testl   %eax,%eax               # failed?
11687    je      common_exceptionThrown  # yup - go handle
11688    SET_VREG %eax rINST
11689    ADVANCE_PC 5
11690    GOTO_NEXT_R %edx
11691
11692/* continuation for OP_FILLED_NEW_ARRAY_JUMBO */
11693
11694.LOP_FILLED_NEW_ARRAY_JUMBO_more:
11695    movl    offMethod_clazz(%eax),%eax        # eax<- method->clazz
11696    movl    %eax,OUT_ARG0(%esp)               # arg0<- clazz
11697    call    dvmResolveClass                   # eax<- call(clazz,ref,flag)
11698    testl   %eax,%eax                         # null?
11699    je      common_exceptionThrown            # yes, handle it
11700
11701       # note: fall through to .LOP_FILLED_NEW_ARRAY_JUMBO_continue
11702
11703    /*
11704     * On entry:
11705     *    eax holds array class [r0]
11706     *    ecx is scratch
11707     */
11708.LOP_FILLED_NEW_ARRAY_JUMBO_continue:
11709    movl    offClassObject_descriptor(%eax),%ecx  # ecx<- arrayClass->descriptor
11710    movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)     # arg2<- flags
11711    movzbl  1(%ecx),%ecx                          # ecx<- descriptor[1]
11712    movl    %eax,OUT_ARG0(%esp)                   # arg0<- arrayClass
11713    movl    rGLUE,%eax
11714    cmpb    $'I',%cl                             # supported?
11715    je      1f
11716    cmpb    $'L',%cl
11717    je      1f
11718    cmpb    $'[',%cl
11719    jne      .LOP_FILLED_NEW_ARRAY_JUMBO_notimpl                  # no, not handled yet
117201:
11721    movl    %ecx,offGlue_retval+4(%eax)           # save type
11722    movl    rINST,OUT_ARG1(%esp)                  # arg1<- BBBB (length)
11723    call    dvmAllocArrayByClass     # eax<- call(arrayClass, length, flags)
11724    movl    rGLUE,%ecx
11725    testl   %eax,%eax                             # alloc successful?
11726    je      common_exceptionThrown                # no, handle exception
11727    movl    %eax,offGlue_retval(%ecx)             # retval.l<- new array
11728    movzwl  8(rPC),%ecx                           # ecx<- CCCC
11729    leal    offArrayObject_contents(%eax),%eax    # eax<- newArray->contents
11730
11731/* at this point:
11732 *     eax is pointer to tgt
11733 *     rINST is length
11734 *     ecx is CCCC
11735 *  We now need to copy values from registers into the array
11736 */
11737
11738    # set up src pointer
11739    SPILL_TMP2(%esi)
11740    SPILL_TMP3(%edi)
11741    leal    (rFP,%ecx,4),%esi # set up src ptr
11742    movl    %eax,%edi         # set up dst ptr
11743    movl    rINST,%ecx        # load count register
11744    rep
11745    movsd
11746    UNSPILL_TMP2(%esi)
11747    UNSPILL_TMP3(%edi)
11748    movl    rGLUE,%ecx
11749    movl    offGlue_retval+4(%ecx),%eax      # eax<- type
11750    FETCH_INST_OPCODE 5 %edx
11751
11752    cmpb    $'I',%al                        # Int array?
11753    je      5f                               # skip card mark if so
11754    movl    offGlue_retval(%ecx),%eax        # eax<- object head
11755    movl    offGlue_cardTable(%ecx),%ecx     # card table base
11756    shrl    $GC_CARD_SHIFT,%eax             # convert to card num
11757    movb    %cl,(%ecx,%eax)                  # mark card based on object head
117585:
11759    ADVANCE_PC 5
11760    GOTO_NEXT_R %edx
11761
11762
11763    /*
11764     * Throw an exception indicating that we have not implemented this
11765     * mode of filled-new-array.
11766     */
11767.LOP_FILLED_NEW_ARRAY_JUMBO_notimpl:
11768    movl    $.LstrInternalErrorA,%eax
11769    movl    %eax,OUT_ARG0(%esp)
11770    movl    $.LstrFilledNewArrayNotImplA,%eax
11771    movl    %eax,OUT_ARG1(%esp)
11772    call    dvmThrowException
11773    jmp     common_exceptionThrown
11774
11775/* continuation for OP_IGET_JUMBO */
11776
11777
11778.LOP_IGET_JUMBO_resolve:
11779    EXPORT_PC
11780    movl    offGlue_method(%edx),%edx           # edx<- current method
11781    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11782    SPILL_TMP1(%ecx)                            # save obj pointer across call
11783    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
11784    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11785    UNSPILL_TMP1(%ecx)
11786    testl   %eax,%eax                           #  returns InstrField ptr
11787    jne     .LOP_IGET_JUMBO_finish
11788    jmp     common_exceptionThrown
11789
11790.LOP_IGET_JUMBO_finish:
11791    /*
11792     * Currently:
11793     *   eax holds resolved field
11794     *   ecx holds object
11795     *   rINST holds BBBB
11796     */
11797    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11798    testl   %ecx,%ecx                           # object null?
11799    je      common_errNullObject                # object was null
11800    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
11801    movl    rINST,%eax                          # eax<- BBBB
11802    FETCH_INST_OPCODE 5 %edx
11803    SET_VREG %ecx %eax
11804    ADVANCE_PC 5
11805    GOTO_NEXT_R %edx
11806
11807/* continuation for OP_IGET_WIDE_JUMBO */
11808
11809
11810.LOP_IGET_WIDE_JUMBO_resolve:
11811    EXPORT_PC
11812    movl    offGlue_method(%edx),%edx           # edx<- current method
11813    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11814    SPILL_TMP1(%ecx)                            # save objpointer across call
11815    movl    rPC,OUT_ARG0(%esp)                  # pass in method->clazz
11816    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11817    UNSPILL_TMP1(%ecx)
11818    testl   %eax,%eax                           # returns InstrField ptr
11819    jne     .LOP_IGET_WIDE_JUMBO_finish
11820    jmp     common_exceptionThrown
11821
11822.LOP_IGET_WIDE_JUMBO_finish:
11823    /*
11824     * Currently:
11825     *   eax holds resolved field
11826     *   ecx holds object
11827     *   rINST holds BBBB
11828     */
11829    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11830    testl   %ecx,%ecx                           # object null?
11831    je      common_errNullObject                # object was null
11832    leal    (%ecx,%eax,1),%eax                  # eax<- address of field
11833    movl    (%eax),%ecx                         # ecx<- lsw
11834    movl    4(%eax),%eax                        # eax<- msw
11835    FETCH_INST_OPCODE 5 %edx
11836    SET_VREG_WORD %ecx rINST 0
11837    SET_VREG_WORD %eax rINST 1
11838    ADVANCE_PC 5
11839    GOTO_NEXT_R %edx
11840
11841/* continuation for OP_IGET_OBJECT_JUMBO */
11842
11843
11844.LOP_IGET_OBJECT_JUMBO_resolve:
11845    EXPORT_PC
11846    movl    offGlue_method(%edx),%edx           # edx<- current method
11847    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11848    SPILL_TMP1(%ecx)                            # save obj pointer across call
11849    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
11850    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11851    UNSPILL_TMP1(%ecx)
11852    testl   %eax,%eax                           #  returns InstrField ptr
11853    jne     .LOP_IGET_OBJECT_JUMBO_finish
11854    jmp     common_exceptionThrown
11855
11856.LOP_IGET_OBJECT_JUMBO_finish:
11857    /*
11858     * Currently:
11859     *   eax holds resolved field
11860     *   ecx holds object
11861     *   rINST holds BBBB
11862     */
11863    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11864    testl   %ecx,%ecx                           # object null?
11865    je      common_errNullObject                # object was null
11866    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
11867    movl    rINST,%eax                          # eax<- BBBB
11868    FETCH_INST_OPCODE 5 %edx
11869    SET_VREG %ecx %eax
11870    ADVANCE_PC 5
11871    GOTO_NEXT_R %edx
11872
11873/* continuation for OP_IGET_BOOLEAN_JUMBO */
11874
11875
11876.LOP_IGET_BOOLEAN_JUMBO_resolve:
11877    EXPORT_PC
11878    movl    offGlue_method(%edx),%edx           # edx<- current method
11879    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11880    SPILL_TMP1(%ecx)                            # save obj pointer across call
11881    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
11882    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11883    UNSPILL_TMP1(%ecx)
11884    testl   %eax,%eax                           #  returns InstrField ptr
11885    jne     .LOP_IGET_BOOLEAN_JUMBO_finish
11886    jmp     common_exceptionThrown
11887
11888.LOP_IGET_BOOLEAN_JUMBO_finish:
11889    /*
11890     * Currently:
11891     *   eax holds resolved field
11892     *   ecx holds object
11893     *   rINST holds BBBB
11894     */
11895    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11896    testl   %ecx,%ecx                           # object null?
11897    je      common_errNullObject                # object was null
11898    movzbl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
11899    movl    rINST,%eax                          # eax<- BBBB
11900    FETCH_INST_OPCODE 5 %edx
11901    SET_VREG %ecx %eax
11902    ADVANCE_PC 5
11903    GOTO_NEXT_R %edx
11904
11905/* continuation for OP_IGET_BYTE_JUMBO */
11906
11907
11908.LOP_IGET_BYTE_JUMBO_resolve:
11909    EXPORT_PC
11910    movl    offGlue_method(%edx),%edx           # edx<- current method
11911    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11912    SPILL_TMP1(%ecx)                            # save obj pointer across call
11913    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
11914    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11915    UNSPILL_TMP1(%ecx)
11916    testl   %eax,%eax                           #  returns InstrField ptr
11917    jne     .LOP_IGET_BYTE_JUMBO_finish
11918    jmp     common_exceptionThrown
11919
11920.LOP_IGET_BYTE_JUMBO_finish:
11921    /*
11922     * Currently:
11923     *   eax holds resolved field
11924     *   ecx holds object
11925     *   rINST holds BBBB
11926     */
11927    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11928    testl   %ecx,%ecx                           # object null?
11929    je      common_errNullObject                # object was null
11930    movsbl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
11931    movl    rINST,%eax                          # eax<- BBBB
11932    FETCH_INST_OPCODE 5 %edx
11933    SET_VREG %ecx %eax
11934    ADVANCE_PC 5
11935    GOTO_NEXT_R %edx
11936
11937/* continuation for OP_IGET_CHAR_JUMBO */
11938
11939
11940.LOP_IGET_CHAR_JUMBO_resolve:
11941    EXPORT_PC
11942    movl    offGlue_method(%edx),%edx           # edx<- current method
11943    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11944    SPILL_TMP1(%ecx)                            # save obj pointer across call
11945    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
11946    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11947    UNSPILL_TMP1(%ecx)
11948    testl   %eax,%eax                           #  returns InstrField ptr
11949    jne     .LOP_IGET_CHAR_JUMBO_finish
11950    jmp     common_exceptionThrown
11951
11952.LOP_IGET_CHAR_JUMBO_finish:
11953    /*
11954     * Currently:
11955     *   eax holds resolved field
11956     *   ecx holds object
11957     *   rINST holds BBBB
11958     */
11959    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11960    testl   %ecx,%ecx                           # object null?
11961    je      common_errNullObject                # object was null
11962    movzwl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
11963    movl    rINST,%eax                          # eax<- BBBB
11964    FETCH_INST_OPCODE 5 %edx
11965    SET_VREG %ecx %eax
11966    ADVANCE_PC 5
11967    GOTO_NEXT_R %edx
11968
11969/* continuation for OP_IGET_SHORT_JUMBO */
11970
11971
11972.LOP_IGET_SHORT_JUMBO_resolve:
11973    EXPORT_PC
11974    movl    offGlue_method(%edx),%edx           # edx<- current method
11975    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11976    SPILL_TMP1(%ecx)                            # save obj pointer across call
11977    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
11978    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11979    UNSPILL_TMP1(%ecx)
11980    testl   %eax,%eax                           #  returns InstrField ptr
11981    jne     .LOP_IGET_SHORT_JUMBO_finish
11982    jmp     common_exceptionThrown
11983
11984.LOP_IGET_SHORT_JUMBO_finish:
11985    /*
11986     * Currently:
11987     *   eax holds resolved field
11988     *   ecx holds object
11989     *   rINST holds BBBB
11990     */
11991    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11992    testl   %ecx,%ecx                           # object null?
11993    je      common_errNullObject                # object was null
11994    movswl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
11995    movl    rINST,%eax                          # eax<- BBBB
11996    FETCH_INST_OPCODE 5 %edx
11997    SET_VREG %ecx %eax
11998    ADVANCE_PC 5
11999    GOTO_NEXT_R %edx
12000
12001/* continuation for OP_IPUT_JUMBO */
12002
12003
12004.LOP_IPUT_JUMBO_resolve:
12005    EXPORT_PC
12006    movl    offGlue_method(%edx),%edx           # edx<- current method
12007    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
12008    SPILL_TMP1(%ecx)                            # save obj pointer across call
12009    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
12010    call    dvmResolveInstField                 #  ... to dvmResolveInstField
12011    UNSPILL_TMP1(%ecx)
12012    testl   %eax,%eax                           # returns InstrField ptr
12013    jne     .LOP_IPUT_JUMBO_finish
12014    jmp     common_exceptionThrown
12015
12016.LOP_IPUT_JUMBO_finish:
12017    /*
12018     * Currently:
12019     *   eax holds resolved field
12020     *   ecx holds object
12021     *   rINST holds BBBB
12022     */
12023    GET_VREG_R rINST rINST                       # rINST<- v[BBBB]
12024    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
12025    testl   %ecx,%ecx                            # object null?
12026    je      common_errNullObject                 # object was null
12027    FETCH_INST_OPCODE 5 %edx
12028    movl   rINST,(%ecx,%eax,1)            # obj.field <- v[BBBB](8/16/32 bits)
12029    ADVANCE_PC 5
12030    GOTO_NEXT_R %edx
12031
12032/* continuation for OP_IPUT_WIDE_JUMBO */
12033
12034
12035.LOP_IPUT_WIDE_JUMBO_resolve:
12036    EXPORT_PC
12037    movl    offGlue_method(%edx),%edx           # edx<- current method
12038    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
12039    SPILL_TMP1(%ecx)                            # save obj pointer across call
12040    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
12041    call    dvmResolveInstField                 #  ... to dvmResolveInstField
12042    UNSPILL_TMP1(%ecx)
12043    testl   %eax,%eax                           #  ... which returns InstrField ptr
12044    jne     .LOP_IPUT_WIDE_JUMBO_finish
12045    jmp     common_exceptionThrown
12046
12047.LOP_IPUT_WIDE_JUMBO_finish:
12048    /*
12049     * Currently:
12050     *   eax holds resolved field
12051     *   ecx holds object
12052     *   %edx is scratch, but needs to be unspilled
12053     *   rINST holds BBBB
12054     */
12055    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
12056    testl   %ecx,%ecx                           # object null?
12057    je      common_errNullObject                # object was null
12058    leal    (%ecx,%eax,1),%eax                  # eax<- address of field
12059    GET_VREG_WORD %ecx rINST 0                  # ecx<- lsw
12060    GET_VREG_WORD rINST rINST 1                 # rINST<- msw
12061    FETCH_INST_OPCODE 5 %edx
12062    movl    rINST,4(%eax)
12063    movl    %ecx,(%eax)
12064    ADVANCE_PC 5
12065    GOTO_NEXT_R %edx
12066
12067/* continuation for OP_IPUT_OBJECT_JUMBO */
12068
12069
12070.LOP_IPUT_OBJECT_JUMBO_resolve:
12071    EXPORT_PC
12072    movl    offGlue_method(%edx),%edx           # edx<- current method
12073    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
12074    SPILL_TMP1(%ecx)                            # save obj pointer across call
12075    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
12076    call    dvmResolveInstField                 #  ... to dvmResolveInstField
12077    UNSPILL_TMP1(%ecx)
12078    testl   %eax,%eax                           # returns InstrField ptr
12079    jne     .LOP_IPUT_OBJECT_JUMBO_finish
12080    jmp     common_exceptionThrown
12081
12082.LOP_IPUT_OBJECT_JUMBO_finish:
12083    /*
12084     * Currently:
12085     *   eax holds resolved field
12086     *   ecx holds object
12087     *   %edx is scratch, but needs to be unspilled
12088     *   rINST holds BBBB
12089     */
12090    GET_VREG_R rINST rINST                      # rINST<- v[BBBB]
12091    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
12092    testl   %ecx,%ecx                           # object null?
12093    je      common_errNullObject                # object was null
12094    movl    rINST,(%ecx,%eax)      # obj.field <- v[BBBB](8/16/32 bits)
12095    movl    rGLUE,%eax
12096    testl   rINST,rINST                         # stored a NULL?
12097    movl    offGlue_cardTable(%eax),%eax        # get card table base
12098    FETCH_INST_OPCODE 5 %edx
12099    je      1f                                  # skip card mark if null store
12100    shrl    $GC_CARD_SHIFT,%ecx                # object head to card number
12101    movb    %al,(%eax,%ecx)                     # mark card using object head
121021:
12103    ADVANCE_PC 5
12104    GOTO_NEXT_R %edx
12105
12106/* continuation for OP_IPUT_BOOLEAN_JUMBO */
12107
12108
12109.LOP_IPUT_BOOLEAN_JUMBO_resolve:
12110    EXPORT_PC
12111    movl    offGlue_method(%edx),%edx           # edx<- current method
12112    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
12113    SPILL_TMP1(%ecx)                            # save obj pointer across call
12114    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
12115    call    dvmResolveInstField                 #  ... to dvmResolveInstField
12116    UNSPILL_TMP1(%ecx)
12117    testl   %eax,%eax                           # returns InstrField ptr
12118    jne     .LOP_IPUT_BOOLEAN_JUMBO_finish
12119    jmp     common_exceptionThrown
12120
12121.LOP_IPUT_BOOLEAN_JUMBO_finish:
12122    /*
12123     * Currently:
12124     *   eax holds resolved field
12125     *   ecx holds object
12126     *   rINST holds BBBB
12127     */
12128    GET_VREG_R rINST rINST                       # rINST<- v[BBBB]
12129    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
12130    testl   %ecx,%ecx                            # object null?
12131    je      common_errNullObject                 # object was null
12132    FETCH_INST_OPCODE 5 %edx
12133    movb   rINSTbl,(%ecx,%eax,1)            # obj.field <- v[BBBB](8/16/32 bits)
12134    ADVANCE_PC 5
12135    GOTO_NEXT_R %edx
12136
12137/* continuation for OP_IPUT_BYTE_JUMBO */
12138
12139
12140.LOP_IPUT_BYTE_JUMBO_resolve:
12141    EXPORT_PC
12142    movl    offGlue_method(%edx),%edx           # edx<- current method
12143    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
12144    SPILL_TMP1(%ecx)                            # save obj pointer across call
12145    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
12146    call    dvmResolveInstField                 #  ... to dvmResolveInstField
12147    UNSPILL_TMP1(%ecx)
12148    testl   %eax,%eax                           # returns InstrField ptr
12149    jne     .LOP_IPUT_BYTE_JUMBO_finish
12150    jmp     common_exceptionThrown
12151
12152.LOP_IPUT_BYTE_JUMBO_finish:
12153    /*
12154     * Currently:
12155     *   eax holds resolved field
12156     *   ecx holds object
12157     *   rINST holds BBBB
12158     */
12159    GET_VREG_R rINST rINST                       # rINST<- v[BBBB]
12160    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
12161    testl   %ecx,%ecx                            # object null?
12162    je      common_errNullObject                 # object was null
12163    FETCH_INST_OPCODE 5 %edx
12164    movb   rINSTbl,(%ecx,%eax,1)            # obj.field <- v[BBBB](8/16/32 bits)
12165    ADVANCE_PC 5
12166    GOTO_NEXT_R %edx
12167
12168/* continuation for OP_IPUT_CHAR_JUMBO */
12169
12170
12171.LOP_IPUT_CHAR_JUMBO_resolve:
12172    EXPORT_PC
12173    movl    offGlue_method(%edx),%edx           # edx<- current method
12174    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
12175    SPILL_TMP1(%ecx)                            # save obj pointer across call
12176    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
12177    call    dvmResolveInstField                 #  ... to dvmResolveInstField
12178    UNSPILL_TMP1(%ecx)
12179    testl   %eax,%eax                           # returns InstrField ptr
12180    jne     .LOP_IPUT_CHAR_JUMBO_finish
12181    jmp     common_exceptionThrown
12182
12183.LOP_IPUT_CHAR_JUMBO_finish:
12184    /*
12185     * Currently:
12186     *   eax holds resolved field
12187     *   ecx holds object
12188     *   rINST holds BBBB
12189     */
12190    GET_VREG_R rINST rINST                       # rINST<- v[BBBB]
12191    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
12192    testl   %ecx,%ecx                            # object null?
12193    je      common_errNullObject                 # object was null
12194    FETCH_INST_OPCODE 5 %edx
12195    movw   rINSTw,(%ecx,%eax,1)            # obj.field <- v[BBBB](8/16/32 bits)
12196    ADVANCE_PC 5
12197    GOTO_NEXT_R %edx
12198
12199/* continuation for OP_IPUT_SHORT_JUMBO */
12200
12201
12202.LOP_IPUT_SHORT_JUMBO_resolve:
12203    EXPORT_PC
12204    movl    offGlue_method(%edx),%edx           # edx<- current method
12205    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
12206    SPILL_TMP1(%ecx)                            # save obj pointer across call
12207    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
12208    call    dvmResolveInstField                 #  ... to dvmResolveInstField
12209    UNSPILL_TMP1(%ecx)
12210    testl   %eax,%eax                           # returns InstrField ptr
12211    jne     .LOP_IPUT_SHORT_JUMBO_finish
12212    jmp     common_exceptionThrown
12213
12214.LOP_IPUT_SHORT_JUMBO_finish:
12215    /*
12216     * Currently:
12217     *   eax holds resolved field
12218     *   ecx holds object
12219     *   rINST holds BBBB
12220     */
12221    GET_VREG_R rINST rINST                       # rINST<- v[BBBB]
12222    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
12223    testl   %ecx,%ecx                            # object null?
12224    je      common_errNullObject                 # object was null
12225    FETCH_INST_OPCODE 5 %edx
12226    movw   rINSTw,(%ecx,%eax,1)            # obj.field <- v[BBBB](8/16/32 bits)
12227    ADVANCE_PC 5
12228    GOTO_NEXT_R %edx
12229
12230/* continuation for OP_SGET_JUMBO */
12231
12232    /*
12233     * Go resolve the field
12234     */
12235.LOP_SGET_JUMBO_resolve:
12236    movl     rGLUE,%ecx
12237    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12238    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
12239    EXPORT_PC                                   # could throw, need to export
12240    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12241    movl     %eax,OUT_ARG1(%esp)
12242    movl     %ecx,OUT_ARG0(%esp)
12243    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12244    testl    %eax,%eax
12245    jne      .LOP_SGET_JUMBO_finish                 # success, continue
12246    jmp      common_exceptionThrown             # no, handle exception
12247
12248/* continuation for OP_SGET_WIDE_JUMBO */
12249
12250    /*
12251     * Go resolve the field
12252     */
12253.LOP_SGET_WIDE_JUMBO_resolve:
12254    movl     rGLUE,%ecx
12255    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12256    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
12257    EXPORT_PC                                   # could throw, need to export
12258    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12259    movl     %eax,OUT_ARG1(%esp)
12260    movl     %ecx,OUT_ARG0(%esp)
12261    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12262    testl    %eax,%eax
12263    jne      .LOP_SGET_WIDE_JUMBO_finish                 # success, continue
12264    jmp      common_exceptionThrown             # no, handle exception
12265
12266/* continuation for OP_SGET_OBJECT_JUMBO */
12267
12268    /*
12269     * Go resolve the field
12270     */
12271.LOP_SGET_OBJECT_JUMBO_resolve:
12272    movl     rGLUE,%ecx
12273    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12274    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
12275    EXPORT_PC                                   # could throw, need to export
12276    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12277    movl     %eax,OUT_ARG1(%esp)
12278    movl     %ecx,OUT_ARG0(%esp)
12279    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12280    testl    %eax,%eax
12281    jne      .LOP_SGET_OBJECT_JUMBO_finish                 # success, continue
12282    jmp      common_exceptionThrown             # no, handle exception
12283
12284/* continuation for OP_SGET_BOOLEAN_JUMBO */
12285
12286    /*
12287     * Go resolve the field
12288     */
12289.LOP_SGET_BOOLEAN_JUMBO_resolve:
12290    movl     rGLUE,%ecx
12291    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12292    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
12293    EXPORT_PC                                   # could throw, need to export
12294    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12295    movl     %eax,OUT_ARG1(%esp)
12296    movl     %ecx,OUT_ARG0(%esp)
12297    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12298    testl    %eax,%eax
12299    jne      .LOP_SGET_BOOLEAN_JUMBO_finish                 # success, continue
12300    jmp      common_exceptionThrown             # no, handle exception
12301
12302/* continuation for OP_SGET_BYTE_JUMBO */
12303
12304    /*
12305     * Go resolve the field
12306     */
12307.LOP_SGET_BYTE_JUMBO_resolve:
12308    movl     rGLUE,%ecx
12309    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12310    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
12311    EXPORT_PC                                   # could throw, need to export
12312    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12313    movl     %eax,OUT_ARG1(%esp)
12314    movl     %ecx,OUT_ARG0(%esp)
12315    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12316    testl    %eax,%eax
12317    jne      .LOP_SGET_BYTE_JUMBO_finish                 # success, continue
12318    jmp      common_exceptionThrown             # no, handle exception
12319
12320/* continuation for OP_SGET_CHAR_JUMBO */
12321
12322    /*
12323     * Go resolve the field
12324     */
12325.LOP_SGET_CHAR_JUMBO_resolve:
12326    movl     rGLUE,%ecx
12327    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12328    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
12329    EXPORT_PC                                   # could throw, need to export
12330    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12331    movl     %eax,OUT_ARG1(%esp)
12332    movl     %ecx,OUT_ARG0(%esp)
12333    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12334    testl    %eax,%eax
12335    jne      .LOP_SGET_CHAR_JUMBO_finish                 # success, continue
12336    jmp      common_exceptionThrown             # no, handle exception
12337
12338/* continuation for OP_SGET_SHORT_JUMBO */
12339
12340    /*
12341     * Go resolve the field
12342     */
12343.LOP_SGET_SHORT_JUMBO_resolve:
12344    movl     rGLUE,%ecx
12345    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12346    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
12347    EXPORT_PC                                   # could throw, need to export
12348    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12349    movl     %eax,OUT_ARG1(%esp)
12350    movl     %ecx,OUT_ARG0(%esp)
12351    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12352    testl    %eax,%eax
12353    jne      .LOP_SGET_SHORT_JUMBO_finish                 # success, continue
12354    jmp      common_exceptionThrown             # no, handle exception
12355
12356/* continuation for OP_SPUT_JUMBO */
12357
12358    /*
12359     * Go resolve the field
12360     */
12361.LOP_SPUT_JUMBO_resolve:
12362    movl     rGLUE,%ecx
12363    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12364    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
12365    EXPORT_PC                                   # could throw, need to export
12366    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12367    movl     %eax,OUT_ARG1(%esp)
12368    movl     %ecx,OUT_ARG0(%esp)
12369    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12370    testl    %eax,%eax
12371    jne      .LOP_SPUT_JUMBO_finish                 # success, continue
12372    jmp      common_exceptionThrown             # no, handle exception
12373
12374/* continuation for OP_SPUT_WIDE_JUMBO */
12375
12376    /*
12377     * Go resolve the field
12378     */
12379.LOP_SPUT_WIDE_JUMBO_resolve:
12380    movl     rGLUE,%ecx
12381    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12382    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
12383    EXPORT_PC                                   # could throw, need to export
12384    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12385    movl     %eax,OUT_ARG1(%esp)
12386    movl     %ecx,OUT_ARG0(%esp)
12387    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12388    testl    %eax,%eax
12389    jne      .LOP_SPUT_WIDE_JUMBO_finish                 # success, continue
12390    jmp      common_exceptionThrown             # no, handle exception
12391
12392/* continuation for OP_SPUT_OBJECT_JUMBO */
12393
12394
12395.LOP_SPUT_OBJECT_JUMBO_continue:
12396    movl      %ecx,offStaticField_value(%eax)    # do the store
12397    testl     %ecx,%ecx                          # stored null object ptr?
12398    FETCH_INST_OPCODE 4 %edx
12399    je        1f                                 # skip card mark if null
12400    movl      rGLUE,%ecx
12401    movl      offField_clazz(%eax),%eax          # eax<- method->clazz
12402    movl      offGlue_cardTable(%ecx),%ecx       # get card table base
12403    shrl      $GC_CARD_SHIFT,%eax               # head to card number
12404    movb      %cl,(%ecx,%eax)                    # mark card
124051:
12406    ADVANCE_PC 4
12407    GOTO_NEXT_R %edx
12408
12409.LOP_SPUT_OBJECT_JUMBO_resolve:
12410    movl     rGLUE,%ecx
12411    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12412    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
12413    EXPORT_PC                                   # could throw, need to export
12414    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12415    movl     %eax,OUT_ARG1(%esp)
12416    movl     %ecx,OUT_ARG0(%esp)
12417    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12418    testl    %eax,%eax
12419    jne      .LOP_SPUT_OBJECT_JUMBO_finish                 # success, continue
12420    jmp      common_exceptionThrown             # no, handle exception
12421
12422/* continuation for OP_SPUT_BOOLEAN_JUMBO */
12423
12424    /*
12425     * Go resolve the field
12426     */
12427.LOP_SPUT_BOOLEAN_JUMBO_resolve:
12428    movl     rGLUE,%ecx
12429    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12430    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
12431    EXPORT_PC                                   # could throw, need to export
12432    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12433    movl     %eax,OUT_ARG1(%esp)
12434    movl     %ecx,OUT_ARG0(%esp)
12435    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12436    testl    %eax,%eax
12437    jne      .LOP_SPUT_BOOLEAN_JUMBO_finish                 # success, continue
12438    jmp      common_exceptionThrown             # no, handle exception
12439
12440/* continuation for OP_SPUT_BYTE_JUMBO */
12441
12442    /*
12443     * Go resolve the field
12444     */
12445.LOP_SPUT_BYTE_JUMBO_resolve:
12446    movl     rGLUE,%ecx
12447    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12448    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
12449    EXPORT_PC                                   # could throw, need to export
12450    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12451    movl     %eax,OUT_ARG1(%esp)
12452    movl     %ecx,OUT_ARG0(%esp)
12453    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12454    testl    %eax,%eax
12455    jne      .LOP_SPUT_BYTE_JUMBO_finish                 # success, continue
12456    jmp      common_exceptionThrown             # no, handle exception
12457
12458/* continuation for OP_SPUT_CHAR_JUMBO */
12459
12460    /*
12461     * Go resolve the field
12462     */
12463.LOP_SPUT_CHAR_JUMBO_resolve:
12464    movl     rGLUE,%ecx
12465    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12466    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
12467    EXPORT_PC                                   # could throw, need to export
12468    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12469    movl     %eax,OUT_ARG1(%esp)
12470    movl     %ecx,OUT_ARG0(%esp)
12471    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12472    testl    %eax,%eax
12473    jne      .LOP_SPUT_CHAR_JUMBO_finish                 # success, continue
12474    jmp      common_exceptionThrown             # no, handle exception
12475
12476/* continuation for OP_SPUT_SHORT_JUMBO */
12477
12478    /*
12479     * Go resolve the field
12480     */
12481.LOP_SPUT_SHORT_JUMBO_resolve:
12482    movl     rGLUE,%ecx
12483    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12484    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
12485    EXPORT_PC                                   # could throw, need to export
12486    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12487    movl     %eax,OUT_ARG1(%esp)
12488    movl     %ecx,OUT_ARG0(%esp)
12489    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12490    testl    %eax,%eax
12491    jne      .LOP_SPUT_SHORT_JUMBO_finish                 # success, continue
12492    jmp      common_exceptionThrown             # no, handle exception
12493
12494/* continuation for OP_INVOKE_VIRTUAL_JUMBO */
12495
12496
12497.LOP_INVOKE_VIRTUAL_JUMBO_more:
12498    movl      offMethod_clazz(%eax),%eax  # ecx<- method->clazz
12499    movl      %eax,OUT_ARG0(%esp)         # arg0<- clazz
12500    movl      $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags
12501    call      dvmResolveMethod            # eax<- call(clazz, ref, flags)
12502    testl     %eax,%eax                   # got null?
12503    jne       .LOP_INVOKE_VIRTUAL_JUMBO_continue        # no, continue
12504    jmp       common_exceptionThrown      # yes, handle exception
12505
12506    /* At this point:
12507     *   eax = resolved base method
12508     *   ecx = scratch
12509     */
12510.LOP_INVOKE_VIRTUAL_JUMBO_continue:
12511    movzwl    8(rPC),%ecx               # ecx<- CCCC
12512    GET_VREG_R  %ecx %ecx               # ecx<- "this"
12513    movzwl    offMethod_methodIndex(%eax),%eax  # eax<- baseMethod->methodIndex
12514    testl     %ecx,%ecx                 # null this?
12515    je        common_errNullObject      # go if so
12516    movl      offObject_clazz(%ecx),%ecx  # ecx<- thisPtr->clazz
12517    movl      offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable
12518    movl      (%ecx,%eax,4),%eax        # eax<- vtable[methodIndex]
12519    jmp       common_invokeMethodJumbo
12520
12521/* continuation for OP_INVOKE_SUPER_JUMBO */
12522
12523    /*
12524     * At this point:
12525     *  ecx = resolved base method [r0]
12526     *  eax = method->clazz [r9]
12527     */
12528.LOP_INVOKE_SUPER_JUMBO_continue:
12529    movl    offClassObject_super(%eax),%eax   # eax<- method->clazz->super
12530    movzwl  offMethod_methodIndex(%ecx),%ecx  # ecx<- baseMthod->methodIndex
12531    cmpl    offClassObject_vtableCount(%eax),%ecx # compare(methodIndex,vtableCount)
12532    jae     .LOP_INVOKE_SUPER_JUMBO_nsm           # method not present in superclass
12533    movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
12534    movl    (%eax,%ecx,4),%eax        # eax<- vtable[methodIndex]
12535    jmp     common_invokeMethodJumbo
12536
12537
12538    /* At this point:
12539     * ecx = null (needs to be resolved base method)
12540     * eax = method->clazz
12541    */
12542.LOP_INVOKE_SUPER_JUMBO_resolve:
12543    SPILL_TMP1(%eax)                    # method->clazz
12544    movl    %eax,OUT_ARG0(%esp)         # arg0<- method->clazz
12545    movl    2(rPC),%ecx                 # ecx<- AAAAAAAA
12546    movl    $METHOD_VIRTUAL,OUT_ARG2(%esp)  # arg2<- resolver method type
12547    movl    %ecx,OUT_ARG1(%esp)         # arg1<- ref
12548    call    dvmResolveMethod            # eax<- call(clazz, ref, flags)
12549    testl   %eax,%eax                   # got null?
12550    movl    %eax,%ecx                   # ecx<- resolved base method
12551    UNSPILL_TMP1(%eax)                  # restore method->clazz
12552    jne     .LOP_INVOKE_SUPER_JUMBO_continue        # good to go - continue
12553    jmp     common_exceptionThrown      # handle exception
12554
12555    /*
12556     * Throw a NoSuchMethodError with the method name as the message.
12557     *  ecx = resolved base method
12558     */
12559.LOP_INVOKE_SUPER_JUMBO_nsm:
12560    movl    offMethod_name(%ecx),%eax
12561    mov     %eax,OUT_ARG1(%esp)
12562    jmp     common_errNoSuchMethod
12563
12564/* continuation for OP_INVOKE_DIRECT_JUMBO */
12565
12566    /*
12567     * On entry:
12568     *   TMP_SPILL  <- "this" register
12569     * Things a bit ugly on this path, but it's the less
12570     * frequent one.  We'll have to do some reloading.
12571     */
12572.LOP_INVOKE_DIRECT_JUMBO_resolve:
12573     SPILL_TMP1(%ecx)
12574     movl     rGLUE,%ecx
12575     movl     offGlue_method(%ecx),%ecx  # ecx<- glue->method
12576     movl     2(rPC),%eax      # reference AAAAAAAA
12577     movl     offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
12578     movl     $METHOD_DIRECT,OUT_ARG2(%esp)
12579     movl     %eax,OUT_ARG1(%esp)
12580     movl     %ecx,OUT_ARG0(%esp)
12581     call     dvmResolveMethod # eax<- call(clazz, ref, flags)
12582     UNSPILL_TMP1(%ecx)
12583     testl    %eax,%eax
12584     jne      .LOP_INVOKE_DIRECT_JUMBO_finish
12585     jmp      common_exceptionThrown
12586
12587/* continuation for OP_INVOKE_STATIC_JUMBO */
12588
12589.LOP_INVOKE_STATIC_JUMBO_continue:
12590    movl      $METHOD_STATIC,%eax
12591    movl      %eax,OUT_ARG2(%esp)       # arg2<- flags
12592    call      dvmResolveMethod          # call(clazz,ref,flags)
12593    testl     %eax,%eax                 # got null?
12594    jne       common_invokeMethodJumbo
12595    jmp       common_exceptionThrown
12596
12597/* continuation for OP_INVOKE_INTERFACE_JUMBO */
12598
12599.LOP_INVOKE_INTERFACE_JUMBO_continue:
12600    call       dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex)
12601    testl      %eax,%eax
12602    je         common_exceptionThrown
12603    jmp        common_invokeMethodJumbo
12604
12605    .size   dvmAsmSisterStart, .-dvmAsmSisterStart
12606    .global dvmAsmSisterEnd
12607dvmAsmSisterEnd:
12608
12609/* File: x86/entry.S */
12610/*
12611 * Copyright (C) 2008 The Android Open Source Project
12612 *
12613 * Licensed under the Apache License, Version 2.0 (the "License");
12614 * you may not use this file except in compliance with the License.
12615 * You may obtain a copy of the License at
12616 *
12617 *      http://www.apache.org/licenses/LICENSE-2.0
12618 *
12619 * Unless required by applicable law or agreed to in writing, software
12620 * distributed under the License is distributed on an "AS IS" BASIS,
12621 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12622 * See the License for the specific language governing permissions and
12623 * limitations under the License.
12624 */
12625
12626
12627    .text
12628    .global dvmMterpStdRun
12629    .type   dvmMterpStdRun, %function
12630/*
12631 * bool dvmMterpStdRun(MterpGlue* glue)
12632 *
12633 * Interpreter entry point.  Returns changeInterp.
12634 *
12635 */
12636dvmMterpStdRun:
12637    movl    4(%esp), %ecx        # get incoming rGLUE
12638    push    %ebp                 # save caller base pointer
12639    push    %ecx                 # save rGLUE at (%ebp)
12640    movl    %esp, %ebp           # set our %ebp
12641/*
12642 * At this point we've allocated two slots on the stack
12643 * via push and stack is 8-byte aligned.  Allocate space
12644 * for 8 spill slots, 3 local slots, 5 arg slots + 2 slots for
12645 * padding to bring us to 16-byte alignment
12646 */
12647    subl    $(FRAME_SIZE-8), %esp
12648
12649/* Spill callee save regs */
12650    movl    %edi,EDI_SPILL(%ebp)
12651    movl    %esi,ESI_SPILL(%ebp)
12652    movl    %ebx,EBX_SPILL(%ebp)
12653
12654/* Set up "named" registers */
12655    movl    offGlue_pc(%ecx),rPC
12656    movl    offGlue_fp(%ecx),rFP
12657
12658/* Remember %esp for future "longjmp" */
12659    movl    %esp,offGlue_bailPtr(%ecx)
12660
12661/* How to start? */
12662    movb    offGlue_entryPoint(%ecx),%al
12663
12664/* Normal start? */
12665    cmpb    $kInterpEntryInstr,%al
12666    jne     .Lnot_instr
12667
12668   /* Normal case: start executing the instruction at rPC */
12669    FETCH_INST
12670    GOTO_NEXT
12671
12672.Lnot_instr:
12673    /* Reset to normal case */
12674    movb   $kInterpEntryInstr,offGlue_entryPoint(%ecx)
12675    cmpb   $kInterpEntryReturn,%al
12676    je     common_returnFromMethod
12677    cmpb   $kInterpEntryThrow,%al
12678    je     common_exceptionThrown
12679    movzx  %al,%eax
12680    movl   %eax,OUT_ARG1(%esp)
12681    movl   $.LstrBadEntryPoint,OUT_ARG0(%esp)
12682    call   printf
12683    call   dvmAbort
12684    /* Not reached */
12685
12686
12687    .global dvmMterpStdBail
12688    .type   dvmMterpStdBail, %function
12689/*
12690 * void dvmMterpStdBail(MterpGlue* glue, bool changeInterp)
12691 *
12692 * Restore the stack pointer and PC from the save point established on entry.
12693 * This is essentially the same as a longjmp, but should be cheaper.  The
12694 * last instruction causes us to return to whoever called dvmMterpStdRun.
12695 *
12696 * We're not going to build a standard frame here, so the arg accesses will
12697 * look a little strange.
12698 *
12699 * On entry:
12700 *  esp+4 (arg0)  MterpGlue* glue
12701 *  esp+8 (arg1)  bool changeInterp
12702 */
12703dvmMterpStdBail:
12704    movl    4(%esp),%ecx                 # grab glue
12705    movl    8(%esp),%eax                 # changeInterp to return reg
12706    movl    offGlue_bailPtr(%ecx),%esp   # Restore "setjmp" esp
12707    movl    %esp,%ebp
12708    addl    $(FRAME_SIZE-8), %ebp       # Restore %ebp at point of setjmp
12709    movl    EDI_SPILL(%ebp),%edi
12710    movl    ESI_SPILL(%ebp),%esi
12711    movl    EBX_SPILL(%ebp),%ebx
12712    movl    PREV_FP(%ebp),%ebp           # restore caller's ebp
12713    addl    $FRAME_SIZE,%esp                    # strip frame
12714    ret                                  # return to dvmMterpStdRun's caller
12715
12716
12717/*
12718 * Strings
12719 */
12720    .section    .rodata
12721.LstrBadEntryPoint:
12722    .asciz  "Bad entry point %d\n"
12723
12724
12725/*
12726 * FIXME: Should have the config/rebuild mechanism generate this
12727 * for targets that need it.
12728 */
12729
12730/* Jump table */
12731dvmAsmInstructionJmpTable = .LdvmAsmInstructionJmpTable
12732.LdvmAsmInstructionJmpTable:
12733.long .L_OP_NOP
12734.long .L_OP_MOVE
12735.long .L_OP_MOVE_FROM16
12736.long .L_OP_MOVE_16
12737.long .L_OP_MOVE_WIDE
12738.long .L_OP_MOVE_WIDE_FROM16
12739.long .L_OP_MOVE_WIDE_16
12740.long .L_OP_MOVE_OBJECT
12741.long .L_OP_MOVE_OBJECT_FROM16
12742.long .L_OP_MOVE_OBJECT_16
12743.long .L_OP_MOVE_RESULT
12744.long .L_OP_MOVE_RESULT_WIDE
12745.long .L_OP_MOVE_RESULT_OBJECT
12746.long .L_OP_MOVE_EXCEPTION
12747.long .L_OP_RETURN_VOID
12748.long .L_OP_RETURN
12749.long .L_OP_RETURN_WIDE
12750.long .L_OP_RETURN_OBJECT
12751.long .L_OP_CONST_4
12752.long .L_OP_CONST_16
12753.long .L_OP_CONST
12754.long .L_OP_CONST_HIGH16
12755.long .L_OP_CONST_WIDE_16
12756.long .L_OP_CONST_WIDE_32
12757.long .L_OP_CONST_WIDE
12758.long .L_OP_CONST_WIDE_HIGH16
12759.long .L_OP_CONST_STRING
12760.long .L_OP_CONST_STRING_JUMBO
12761.long .L_OP_CONST_CLASS
12762.long .L_OP_MONITOR_ENTER
12763.long .L_OP_MONITOR_EXIT
12764.long .L_OP_CHECK_CAST
12765.long .L_OP_INSTANCE_OF
12766.long .L_OP_ARRAY_LENGTH
12767.long .L_OP_NEW_INSTANCE
12768.long .L_OP_NEW_ARRAY
12769.long .L_OP_FILLED_NEW_ARRAY
12770.long .L_OP_FILLED_NEW_ARRAY_RANGE
12771.long .L_OP_FILL_ARRAY_DATA
12772.long .L_OP_THROW
12773.long .L_OP_GOTO
12774.long .L_OP_GOTO_16
12775.long .L_OP_GOTO_32
12776.long .L_OP_PACKED_SWITCH
12777.long .L_OP_SPARSE_SWITCH
12778.long .L_OP_CMPL_FLOAT
12779.long .L_OP_CMPG_FLOAT
12780.long .L_OP_CMPL_DOUBLE
12781.long .L_OP_CMPG_DOUBLE
12782.long .L_OP_CMP_LONG
12783.long .L_OP_IF_EQ
12784.long .L_OP_IF_NE
12785.long .L_OP_IF_LT
12786.long .L_OP_IF_GE
12787.long .L_OP_IF_GT
12788.long .L_OP_IF_LE
12789.long .L_OP_IF_EQZ
12790.long .L_OP_IF_NEZ
12791.long .L_OP_IF_LTZ
12792.long .L_OP_IF_GEZ
12793.long .L_OP_IF_GTZ
12794.long .L_OP_IF_LEZ
12795.long .L_OP_UNUSED_3E
12796.long .L_OP_UNUSED_3F
12797.long .L_OP_UNUSED_40
12798.long .L_OP_UNUSED_41
12799.long .L_OP_UNUSED_42
12800.long .L_OP_UNUSED_43
12801.long .L_OP_AGET
12802.long .L_OP_AGET_WIDE
12803.long .L_OP_AGET_OBJECT
12804.long .L_OP_AGET_BOOLEAN
12805.long .L_OP_AGET_BYTE
12806.long .L_OP_AGET_CHAR
12807.long .L_OP_AGET_SHORT
12808.long .L_OP_APUT
12809.long .L_OP_APUT_WIDE
12810.long .L_OP_APUT_OBJECT
12811.long .L_OP_APUT_BOOLEAN
12812.long .L_OP_APUT_BYTE
12813.long .L_OP_APUT_CHAR
12814.long .L_OP_APUT_SHORT
12815.long .L_OP_IGET
12816.long .L_OP_IGET_WIDE
12817.long .L_OP_IGET_OBJECT
12818.long .L_OP_IGET_BOOLEAN
12819.long .L_OP_IGET_BYTE
12820.long .L_OP_IGET_CHAR
12821.long .L_OP_IGET_SHORT
12822.long .L_OP_IPUT
12823.long .L_OP_IPUT_WIDE
12824.long .L_OP_IPUT_OBJECT
12825.long .L_OP_IPUT_BOOLEAN
12826.long .L_OP_IPUT_BYTE
12827.long .L_OP_IPUT_CHAR
12828.long .L_OP_IPUT_SHORT
12829.long .L_OP_SGET
12830.long .L_OP_SGET_WIDE
12831.long .L_OP_SGET_OBJECT
12832.long .L_OP_SGET_BOOLEAN
12833.long .L_OP_SGET_BYTE
12834.long .L_OP_SGET_CHAR
12835.long .L_OP_SGET_SHORT
12836.long .L_OP_SPUT
12837.long .L_OP_SPUT_WIDE
12838.long .L_OP_SPUT_OBJECT
12839.long .L_OP_SPUT_BOOLEAN
12840.long .L_OP_SPUT_BYTE
12841.long .L_OP_SPUT_CHAR
12842.long .L_OP_SPUT_SHORT
12843.long .L_OP_INVOKE_VIRTUAL
12844.long .L_OP_INVOKE_SUPER
12845.long .L_OP_INVOKE_DIRECT
12846.long .L_OP_INVOKE_STATIC
12847.long .L_OP_INVOKE_INTERFACE
12848.long .L_OP_UNUSED_73
12849.long .L_OP_INVOKE_VIRTUAL_RANGE
12850.long .L_OP_INVOKE_SUPER_RANGE
12851.long .L_OP_INVOKE_DIRECT_RANGE
12852.long .L_OP_INVOKE_STATIC_RANGE
12853.long .L_OP_INVOKE_INTERFACE_RANGE
12854.long .L_OP_UNUSED_79
12855.long .L_OP_UNUSED_7A
12856.long .L_OP_NEG_INT
12857.long .L_OP_NOT_INT
12858.long .L_OP_NEG_LONG
12859.long .L_OP_NOT_LONG
12860.long .L_OP_NEG_FLOAT
12861.long .L_OP_NEG_DOUBLE
12862.long .L_OP_INT_TO_LONG
12863.long .L_OP_INT_TO_FLOAT
12864.long .L_OP_INT_TO_DOUBLE
12865.long .L_OP_LONG_TO_INT
12866.long .L_OP_LONG_TO_FLOAT
12867.long .L_OP_LONG_TO_DOUBLE
12868.long .L_OP_FLOAT_TO_INT
12869.long .L_OP_FLOAT_TO_LONG
12870.long .L_OP_FLOAT_TO_DOUBLE
12871.long .L_OP_DOUBLE_TO_INT
12872.long .L_OP_DOUBLE_TO_LONG
12873.long .L_OP_DOUBLE_TO_FLOAT
12874.long .L_OP_INT_TO_BYTE
12875.long .L_OP_INT_TO_CHAR
12876.long .L_OP_INT_TO_SHORT
12877.long .L_OP_ADD_INT
12878.long .L_OP_SUB_INT
12879.long .L_OP_MUL_INT
12880.long .L_OP_DIV_INT
12881.long .L_OP_REM_INT
12882.long .L_OP_AND_INT
12883.long .L_OP_OR_INT
12884.long .L_OP_XOR_INT
12885.long .L_OP_SHL_INT
12886.long .L_OP_SHR_INT
12887.long .L_OP_USHR_INT
12888.long .L_OP_ADD_LONG
12889.long .L_OP_SUB_LONG
12890.long .L_OP_MUL_LONG
12891.long .L_OP_DIV_LONG
12892.long .L_OP_REM_LONG
12893.long .L_OP_AND_LONG
12894.long .L_OP_OR_LONG
12895.long .L_OP_XOR_LONG
12896.long .L_OP_SHL_LONG
12897.long .L_OP_SHR_LONG
12898.long .L_OP_USHR_LONG
12899.long .L_OP_ADD_FLOAT
12900.long .L_OP_SUB_FLOAT
12901.long .L_OP_MUL_FLOAT
12902.long .L_OP_DIV_FLOAT
12903.long .L_OP_REM_FLOAT
12904.long .L_OP_ADD_DOUBLE
12905.long .L_OP_SUB_DOUBLE
12906.long .L_OP_MUL_DOUBLE
12907.long .L_OP_DIV_DOUBLE
12908.long .L_OP_REM_DOUBLE
12909.long .L_OP_ADD_INT_2ADDR
12910.long .L_OP_SUB_INT_2ADDR
12911.long .L_OP_MUL_INT_2ADDR
12912.long .L_OP_DIV_INT_2ADDR
12913.long .L_OP_REM_INT_2ADDR
12914.long .L_OP_AND_INT_2ADDR
12915.long .L_OP_OR_INT_2ADDR
12916.long .L_OP_XOR_INT_2ADDR
12917.long .L_OP_SHL_INT_2ADDR
12918.long .L_OP_SHR_INT_2ADDR
12919.long .L_OP_USHR_INT_2ADDR
12920.long .L_OP_ADD_LONG_2ADDR
12921.long .L_OP_SUB_LONG_2ADDR
12922.long .L_OP_MUL_LONG_2ADDR
12923.long .L_OP_DIV_LONG_2ADDR
12924.long .L_OP_REM_LONG_2ADDR
12925.long .L_OP_AND_LONG_2ADDR
12926.long .L_OP_OR_LONG_2ADDR
12927.long .L_OP_XOR_LONG_2ADDR
12928.long .L_OP_SHL_LONG_2ADDR
12929.long .L_OP_SHR_LONG_2ADDR
12930.long .L_OP_USHR_LONG_2ADDR
12931.long .L_OP_ADD_FLOAT_2ADDR
12932.long .L_OP_SUB_FLOAT_2ADDR
12933.long .L_OP_MUL_FLOAT_2ADDR
12934.long .L_OP_DIV_FLOAT_2ADDR
12935.long .L_OP_REM_FLOAT_2ADDR
12936.long .L_OP_ADD_DOUBLE_2ADDR
12937.long .L_OP_SUB_DOUBLE_2ADDR
12938.long .L_OP_MUL_DOUBLE_2ADDR
12939.long .L_OP_DIV_DOUBLE_2ADDR
12940.long .L_OP_REM_DOUBLE_2ADDR
12941.long .L_OP_ADD_INT_LIT16
12942.long .L_OP_RSUB_INT
12943.long .L_OP_MUL_INT_LIT16
12944.long .L_OP_DIV_INT_LIT16
12945.long .L_OP_REM_INT_LIT16
12946.long .L_OP_AND_INT_LIT16
12947.long .L_OP_OR_INT_LIT16
12948.long .L_OP_XOR_INT_LIT16
12949.long .L_OP_ADD_INT_LIT8
12950.long .L_OP_RSUB_INT_LIT8
12951.long .L_OP_MUL_INT_LIT8
12952.long .L_OP_DIV_INT_LIT8
12953.long .L_OP_REM_INT_LIT8
12954.long .L_OP_AND_INT_LIT8
12955.long .L_OP_OR_INT_LIT8
12956.long .L_OP_XOR_INT_LIT8
12957.long .L_OP_SHL_INT_LIT8
12958.long .L_OP_SHR_INT_LIT8
12959.long .L_OP_USHR_INT_LIT8
12960.long .L_OP_IGET_VOLATILE
12961.long .L_OP_IPUT_VOLATILE
12962.long .L_OP_SGET_VOLATILE
12963.long .L_OP_SPUT_VOLATILE
12964.long .L_OP_IGET_OBJECT_VOLATILE
12965.long .L_OP_IGET_WIDE_VOLATILE
12966.long .L_OP_IPUT_WIDE_VOLATILE
12967.long .L_OP_SGET_WIDE_VOLATILE
12968.long .L_OP_SPUT_WIDE_VOLATILE
12969.long .L_OP_BREAKPOINT
12970.long .L_OP_THROW_VERIFICATION_ERROR
12971.long .L_OP_EXECUTE_INLINE
12972.long .L_OP_EXECUTE_INLINE_RANGE
12973.long .L_OP_INVOKE_DIRECT_EMPTY
12974.long .L_OP_RETURN_VOID_BARRIER
12975.long .L_OP_IGET_QUICK
12976.long .L_OP_IGET_WIDE_QUICK
12977.long .L_OP_IGET_OBJECT_QUICK
12978.long .L_OP_IPUT_QUICK
12979.long .L_OP_IPUT_WIDE_QUICK
12980.long .L_OP_IPUT_OBJECT_QUICK
12981.long .L_OP_INVOKE_VIRTUAL_QUICK
12982.long .L_OP_INVOKE_VIRTUAL_QUICK_RANGE
12983.long .L_OP_INVOKE_SUPER_QUICK
12984.long .L_OP_INVOKE_SUPER_QUICK_RANGE
12985.long .L_OP_IPUT_OBJECT_VOLATILE
12986.long .L_OP_SGET_OBJECT_VOLATILE
12987.long .L_OP_SPUT_OBJECT_VOLATILE
12988.long .L_OP_DISPATCH_FF
12989.long .L_OP_CONST_CLASS_JUMBO
12990.long .L_OP_CHECK_CAST_JUMBO
12991.long .L_OP_INSTANCE_OF_JUMBO
12992.long .L_OP_NEW_INSTANCE_JUMBO
12993.long .L_OP_NEW_ARRAY_JUMBO
12994.long .L_OP_FILLED_NEW_ARRAY_JUMBO
12995.long .L_OP_IGET_JUMBO
12996.long .L_OP_IGET_WIDE_JUMBO
12997.long .L_OP_IGET_OBJECT_JUMBO
12998.long .L_OP_IGET_BOOLEAN_JUMBO
12999.long .L_OP_IGET_BYTE_JUMBO
13000.long .L_OP_IGET_CHAR_JUMBO
13001.long .L_OP_IGET_SHORT_JUMBO
13002.long .L_OP_IPUT_JUMBO
13003.long .L_OP_IPUT_WIDE_JUMBO
13004.long .L_OP_IPUT_OBJECT_JUMBO
13005.long .L_OP_IPUT_BOOLEAN_JUMBO
13006.long .L_OP_IPUT_BYTE_JUMBO
13007.long .L_OP_IPUT_CHAR_JUMBO
13008.long .L_OP_IPUT_SHORT_JUMBO
13009.long .L_OP_SGET_JUMBO
13010.long .L_OP_SGET_WIDE_JUMBO
13011.long .L_OP_SGET_OBJECT_JUMBO
13012.long .L_OP_SGET_BOOLEAN_JUMBO
13013.long .L_OP_SGET_BYTE_JUMBO
13014.long .L_OP_SGET_CHAR_JUMBO
13015.long .L_OP_SGET_SHORT_JUMBO
13016.long .L_OP_SPUT_JUMBO
13017.long .L_OP_SPUT_WIDE_JUMBO
13018.long .L_OP_SPUT_OBJECT_JUMBO
13019.long .L_OP_SPUT_BOOLEAN_JUMBO
13020.long .L_OP_SPUT_BYTE_JUMBO
13021.long .L_OP_SPUT_CHAR_JUMBO
13022.long .L_OP_SPUT_SHORT_JUMBO
13023.long .L_OP_INVOKE_VIRTUAL_JUMBO
13024.long .L_OP_INVOKE_SUPER_JUMBO
13025.long .L_OP_INVOKE_DIRECT_JUMBO
13026.long .L_OP_INVOKE_STATIC_JUMBO
13027.long .L_OP_INVOKE_INTERFACE_JUMBO
13028.long .L_OP_UNUSED_27FF
13029.long .L_OP_UNUSED_28FF
13030.long .L_OP_UNUSED_29FF
13031.long .L_OP_UNUSED_2AFF
13032.long .L_OP_UNUSED_2BFF
13033.long .L_OP_UNUSED_2CFF
13034.long .L_OP_UNUSED_2DFF
13035.long .L_OP_UNUSED_2EFF
13036.long .L_OP_UNUSED_2FFF
13037.long .L_OP_UNUSED_30FF
13038.long .L_OP_UNUSED_31FF
13039.long .L_OP_UNUSED_32FF
13040.long .L_OP_UNUSED_33FF
13041.long .L_OP_UNUSED_34FF
13042.long .L_OP_UNUSED_35FF
13043.long .L_OP_UNUSED_36FF
13044.long .L_OP_UNUSED_37FF
13045.long .L_OP_UNUSED_38FF
13046.long .L_OP_UNUSED_39FF
13047.long .L_OP_UNUSED_3AFF
13048.long .L_OP_UNUSED_3BFF
13049.long .L_OP_UNUSED_3CFF
13050.long .L_OP_UNUSED_3DFF
13051.long .L_OP_UNUSED_3EFF
13052.long .L_OP_UNUSED_3FFF
13053.long .L_OP_UNUSED_40FF
13054.long .L_OP_UNUSED_41FF
13055.long .L_OP_UNUSED_42FF
13056.long .L_OP_UNUSED_43FF
13057.long .L_OP_UNUSED_44FF
13058.long .L_OP_UNUSED_45FF
13059.long .L_OP_UNUSED_46FF
13060.long .L_OP_UNUSED_47FF
13061.long .L_OP_UNUSED_48FF
13062.long .L_OP_UNUSED_49FF
13063.long .L_OP_UNUSED_4AFF
13064.long .L_OP_UNUSED_4BFF
13065.long .L_OP_UNUSED_4CFF
13066.long .L_OP_UNUSED_4DFF
13067.long .L_OP_UNUSED_4EFF
13068.long .L_OP_UNUSED_4FFF
13069.long .L_OP_UNUSED_50FF
13070.long .L_OP_UNUSED_51FF
13071.long .L_OP_UNUSED_52FF
13072.long .L_OP_UNUSED_53FF
13073.long .L_OP_UNUSED_54FF
13074.long .L_OP_UNUSED_55FF
13075.long .L_OP_UNUSED_56FF
13076.long .L_OP_UNUSED_57FF
13077.long .L_OP_UNUSED_58FF
13078.long .L_OP_UNUSED_59FF
13079.long .L_OP_UNUSED_5AFF
13080.long .L_OP_UNUSED_5BFF
13081.long .L_OP_UNUSED_5CFF
13082.long .L_OP_UNUSED_5DFF
13083.long .L_OP_UNUSED_5EFF
13084.long .L_OP_UNUSED_5FFF
13085.long .L_OP_UNUSED_60FF
13086.long .L_OP_UNUSED_61FF
13087.long .L_OP_UNUSED_62FF
13088.long .L_OP_UNUSED_63FF
13089.long .L_OP_UNUSED_64FF
13090.long .L_OP_UNUSED_65FF
13091.long .L_OP_UNUSED_66FF
13092.long .L_OP_UNUSED_67FF
13093.long .L_OP_UNUSED_68FF
13094.long .L_OP_UNUSED_69FF
13095.long .L_OP_UNUSED_6AFF
13096.long .L_OP_UNUSED_6BFF
13097.long .L_OP_UNUSED_6CFF
13098.long .L_OP_UNUSED_6DFF
13099.long .L_OP_UNUSED_6EFF
13100.long .L_OP_UNUSED_6FFF
13101.long .L_OP_UNUSED_70FF
13102.long .L_OP_UNUSED_71FF
13103.long .L_OP_UNUSED_72FF
13104.long .L_OP_UNUSED_73FF
13105.long .L_OP_UNUSED_74FF
13106.long .L_OP_UNUSED_75FF
13107.long .L_OP_UNUSED_76FF
13108.long .L_OP_UNUSED_77FF
13109.long .L_OP_UNUSED_78FF
13110.long .L_OP_UNUSED_79FF
13111.long .L_OP_UNUSED_7AFF
13112.long .L_OP_UNUSED_7BFF
13113.long .L_OP_UNUSED_7CFF
13114.long .L_OP_UNUSED_7DFF
13115.long .L_OP_UNUSED_7EFF
13116.long .L_OP_UNUSED_7FFF
13117.long .L_OP_UNUSED_80FF
13118.long .L_OP_UNUSED_81FF
13119.long .L_OP_UNUSED_82FF
13120.long .L_OP_UNUSED_83FF
13121.long .L_OP_UNUSED_84FF
13122.long .L_OP_UNUSED_85FF
13123.long .L_OP_UNUSED_86FF
13124.long .L_OP_UNUSED_87FF
13125.long .L_OP_UNUSED_88FF
13126.long .L_OP_UNUSED_89FF
13127.long .L_OP_UNUSED_8AFF
13128.long .L_OP_UNUSED_8BFF
13129.long .L_OP_UNUSED_8CFF
13130.long .L_OP_UNUSED_8DFF
13131.long .L_OP_UNUSED_8EFF
13132.long .L_OP_UNUSED_8FFF
13133.long .L_OP_UNUSED_90FF
13134.long .L_OP_UNUSED_91FF
13135.long .L_OP_UNUSED_92FF
13136.long .L_OP_UNUSED_93FF
13137.long .L_OP_UNUSED_94FF
13138.long .L_OP_UNUSED_95FF
13139.long .L_OP_UNUSED_96FF
13140.long .L_OP_UNUSED_97FF
13141.long .L_OP_UNUSED_98FF
13142.long .L_OP_UNUSED_99FF
13143.long .L_OP_UNUSED_9AFF
13144.long .L_OP_UNUSED_9BFF
13145.long .L_OP_UNUSED_9CFF
13146.long .L_OP_UNUSED_9DFF
13147.long .L_OP_UNUSED_9EFF
13148.long .L_OP_UNUSED_9FFF
13149.long .L_OP_UNUSED_A0FF
13150.long .L_OP_UNUSED_A1FF
13151.long .L_OP_UNUSED_A2FF
13152.long .L_OP_UNUSED_A3FF
13153.long .L_OP_UNUSED_A4FF
13154.long .L_OP_UNUSED_A5FF
13155.long .L_OP_UNUSED_A6FF
13156.long .L_OP_UNUSED_A7FF
13157.long .L_OP_UNUSED_A8FF
13158.long .L_OP_UNUSED_A9FF
13159.long .L_OP_UNUSED_AAFF
13160.long .L_OP_UNUSED_ABFF
13161.long .L_OP_UNUSED_ACFF
13162.long .L_OP_UNUSED_ADFF
13163.long .L_OP_UNUSED_AEFF
13164.long .L_OP_UNUSED_AFFF
13165.long .L_OP_UNUSED_B0FF
13166.long .L_OP_UNUSED_B1FF
13167.long .L_OP_UNUSED_B2FF
13168.long .L_OP_UNUSED_B3FF
13169.long .L_OP_UNUSED_B4FF
13170.long .L_OP_UNUSED_B5FF
13171.long .L_OP_UNUSED_B6FF
13172.long .L_OP_UNUSED_B7FF
13173.long .L_OP_UNUSED_B8FF
13174.long .L_OP_UNUSED_B9FF
13175.long .L_OP_UNUSED_BAFF
13176.long .L_OP_UNUSED_BBFF
13177.long .L_OP_UNUSED_BCFF
13178.long .L_OP_UNUSED_BDFF
13179.long .L_OP_UNUSED_BEFF
13180.long .L_OP_UNUSED_BFFF
13181.long .L_OP_UNUSED_C0FF
13182.long .L_OP_UNUSED_C1FF
13183.long .L_OP_UNUSED_C2FF
13184.long .L_OP_UNUSED_C3FF
13185.long .L_OP_UNUSED_C4FF
13186.long .L_OP_UNUSED_C5FF
13187.long .L_OP_UNUSED_C6FF
13188.long .L_OP_UNUSED_C7FF
13189.long .L_OP_UNUSED_C8FF
13190.long .L_OP_UNUSED_C9FF
13191.long .L_OP_UNUSED_CAFF
13192.long .L_OP_UNUSED_CBFF
13193.long .L_OP_UNUSED_CCFF
13194.long .L_OP_UNUSED_CDFF
13195.long .L_OP_UNUSED_CEFF
13196.long .L_OP_UNUSED_CFFF
13197.long .L_OP_UNUSED_D0FF
13198.long .L_OP_UNUSED_D1FF
13199.long .L_OP_UNUSED_D2FF
13200.long .L_OP_UNUSED_D3FF
13201.long .L_OP_UNUSED_D4FF
13202.long .L_OP_UNUSED_D5FF
13203.long .L_OP_UNUSED_D6FF
13204.long .L_OP_UNUSED_D7FF
13205.long .L_OP_UNUSED_D8FF
13206.long .L_OP_UNUSED_D9FF
13207.long .L_OP_UNUSED_DAFF
13208.long .L_OP_UNUSED_DBFF
13209.long .L_OP_UNUSED_DCFF
13210.long .L_OP_UNUSED_DDFF
13211.long .L_OP_UNUSED_DEFF
13212.long .L_OP_UNUSED_DFFF
13213.long .L_OP_UNUSED_E0FF
13214.long .L_OP_UNUSED_E1FF
13215.long .L_OP_UNUSED_E2FF
13216.long .L_OP_UNUSED_E3FF
13217.long .L_OP_UNUSED_E4FF
13218.long .L_OP_UNUSED_E5FF
13219.long .L_OP_UNUSED_E6FF
13220.long .L_OP_UNUSED_E7FF
13221.long .L_OP_UNUSED_E8FF
13222.long .L_OP_UNUSED_E9FF
13223.long .L_OP_UNUSED_EAFF
13224.long .L_OP_UNUSED_EBFF
13225.long .L_OP_UNUSED_ECFF
13226.long .L_OP_UNUSED_EDFF
13227.long .L_OP_UNUSED_EEFF
13228.long .L_OP_UNUSED_EFFF
13229.long .L_OP_UNUSED_F0FF
13230.long .L_OP_UNUSED_F1FF
13231.long .L_OP_UNUSED_F2FF
13232.long .L_OP_UNUSED_F3FF
13233.long .L_OP_UNUSED_F4FF
13234.long .L_OP_UNUSED_F5FF
13235.long .L_OP_UNUSED_F6FF
13236.long .L_OP_UNUSED_F7FF
13237.long .L_OP_UNUSED_F8FF
13238.long .L_OP_UNUSED_F9FF
13239.long .L_OP_UNUSED_FAFF
13240.long .L_OP_UNUSED_FBFF
13241.long .L_OP_UNUSED_FCFF
13242.long .L_OP_UNUSED_FDFF
13243.long .L_OP_UNUSED_FEFF
13244.long .L_OP_THROW_VERIFICATION_ERROR_JUMBO
13245
13246/* File: x86/footer.S */
13247/*
13248 * Copyright (C) 2008 The Android Open Source Project
13249 *
13250 * Licensed under the Apache License, Version 2.0 (the "License");
13251 * you may not use this file except in compliance with the License.
13252 * You may obtain a copy of the License at
13253 *
13254 *      http://www.apache.org/licenses/LICENSE-2.0
13255 *
13256 * Unless required by applicable law or agreed to in writing, software
13257 * distributed under the License is distributed on an "AS IS" BASIS,
13258 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13259 * See the License for the specific language governing permissions and
13260 * limitations under the License.
13261 */
13262/*
13263 * Common subroutines and data.
13264 */
13265
13266#if defined(WITH_JIT)
13267/*
13268 * JIT-related re-entries into the interpreter.  In general, if the
13269 * exit from a translation can at some point be chained, the entry
13270 * here requires that control arrived via a call, and that the "rp"
13271 * on TOS is actually a pointer to a 32-bit cell containing the Dalvik PC
13272 * of the next insn to handle.  If no chaining will happen, the entry
13273 * should be reached via a direct jump and rPC set beforehand.
13274 */
13275
13276    .global dvmJitToInterpPunt
13277/*
13278 * The compiler will generate a jump to this entry point when it is
13279 * having difficulty translating a Dalvik instruction.  We must skip
13280 * the code cache lookup & prevent chaining to avoid bouncing between
13281 * the interpreter and code cache. rPC must be set on entry.
13282 */
13283dvmJitToInterpPunt:
13284#if defined(WITH_JIT_TUNING)
13285    movl   rPC, OUT_ARG0(%esp)
13286    call   dvmBumpPunt
13287#endif
13288    FETCH_INST_R %edx
13289    GOTO_NEXT_R %edx
13290
13291    .global dvmJitToInterpSingleStep
13292/*
13293 * Return to the interpreter to handle a single instruction.
13294 * Should be reached via a call.
13295 * On entry:
13296 *   0(%esp)          <= native return address within trace
13297 *   rPC              <= Dalvik PC of this instruction
13298 *   OUT_ARG0+4(%esp) <= Dalvik PC of next instruction
13299 */
13300dvmJitToInterpSingleStep:
13301    pop    %eax
13302    movl   rGLUE, %ecx
13303    movl   OUT_ARG0(%esp), %edx
13304    movl   %eax,offGlue_jitResumeNPC(%ecx)
13305    movl   %edx,offGlue_jitResumeDPC(%ecx)
13306    movl   $kInterpEntryInstr,offGlue_entryPoint(%ecx)
13307    movl   $1,rINST     # changeInterp <= true
13308    jmp    common_gotoBail
13309
13310    .global dvmJitToInterpNoChainNoProfile
13311/*
13312 * Return from the translation cache to the interpreter to do method
13313 * invocation.  Check if the translation exists for the callee, but don't
13314 * chain to it. rPC must be set on entry.
13315 */
13316dvmJitToInterpNoChainNoProfile:
13317#if defined(WITH_JIT_TUNING)
13318    call   dvmBumpNoChain
13319#endif
13320    movl   rPC,OUT_ARG0(%esp)
13321    call   dvmJitGetCodeAddr         # is there a translation?
13322    movl   rGLUE,%ecx
13323    movl   offGlue_self(%ecx), %ecx  # ecx <- glue->self
13324    movl   %eax,offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
13325    cmpl   $0, %eax
13326    jz     1f
13327    call   *%eax                     # exec translation if we've got one
13328    # won't return
133291:
13330    FETCH_INST_R %edx
13331    GOTO_NEXT_R %edx
13332
13333/*
13334 * Return from the translation cache and immediately request a
13335 * translation fro the exit target, but don't attempt to chain.
13336 * rPC set on entry.
13337 */
13338    .global dvmJitToInterpTraceSelectNoChain
13339dvmJitToInterpTraceSelectNoChain:
13340#if defined(WITH_JIT_TUNING)
13341    call   dvmBumpNoChain
13342#endif
13343    movl   rPC,OUT_ARG0(%esp)
13344    call   dvmJitGetCodeAddr  # is there a translation?
13345    movl   rGLUE,%ecx
13346    movl   offGlue_self(%ecx),%ecx
13347    cmpl   $0,%eax
13348    movl   %eax,offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
13349    jz     1f
13350    call   *%eax              # jump to tranlation
13351    # won't return
13352
13353/* No Translation - request one */
133541:
13355    GET_JIT_PROF_TABLE %ecx %eax
13356    cmpl   $0, %eax          # JIT enabled?
13357    jnz    2f                 # Request one if so
13358    FETCH_INST_R %edx         # Continue interpreting if not
13359    GOTO_NEXT_R %edx
133602:
13361    movl   $kJitTSelectRequestHot,rINST  # ask for trace select
13362    jmp    common_selectTrace
13363
13364/*
13365 * Return from the translation cache and immediately request a
13366 * translation for the exit target.  Reached via a call, and
13367 * (TOS)->rPC.
13368 */
13369    .global dvmJitToInterpTraceSelect
13370dvmJitToInterpTraceSelect:
13371    pop    rINST           # save chain cell address in callee save reg
13372    movl   (rINST),rPC
13373    movl   rPC,OUT_ARG0(%esp)
13374    call   dvmJitGetCodeAddr  # is there a translation?
13375    cmpl   $0,%eax
13376    jz     1b                 # no - ask for one
13377    movl   %eax,OUT_ARG0(%esp)
13378# FIXME - need to adjust rINST to beginning of sequence
13379    movl   rINST,OUT_ARG1(%esp)
13380    call   dvmJitChain        # Attempt dvmJitChain(codeAddr,chainAddr)
13381    cmpl   $0,%eax           # Success?
13382    jz     toInterpreter      # didn't chain - interpret
13383    call   *%eax
13384    # won't return
13385
13386/*
13387 * Placeholder entries for x86 JIT
13388 */
13389    .global dvmJitToInterpBackwardBranch
13390dvmJitToInterpBackwardBranch:
13391    .global dvmJitToInterpNormal
13392dvmJitToInterpNormal:
13393    .global dvmJitToInterpNoChain
13394dvmJitToInterpNoChain:
13395toInterpreter:
13396    jmp  common_abort
13397#endif
13398
13399/*
13400 * Common code when a backwards branch is taken
13401 *
13402 * On entry:
13403 *   ebx (a.k.a. rINST) -> PC adjustment in 16-bit words
13404 */
13405common_backwardBranch:
13406    movl    rGLUE,%ecx
13407    call   common_periodicChecks  # rPC and ecx/rGLUE preserved
13408#if defined(WITH_JIT)
13409    GET_JIT_PROF_TABLE %ecx %edx
13410    ADVANCE_PC_INDEXED rINST
13411    cmpl   $0,%edx
13412    FETCH_INST
13413    jz    1f                    # Profiling off - continue
13414    .global updateProfile
13415updateProfile:
13416common_updateProfile:
13417    # quick & dirty hash
13418    movl   rPC, %eax
13419    shrl   $12, %eax
13420    xorl   rPC, %eax
13421    andl   $((1<<JIT_PROF_SIZE_LOG_2)-1),%eax
13422    decb   (%edx,%eax)
13423    jz     2f
134241:
13425    GOTO_NEXT
134262:
13427/*
13428 * Here, we switch to the debug interpreter to request
13429 * trace selection.  First, though, check to see if there
13430 * is already a native translation in place (and, if so,
13431 * jump to it now.
13432 */
13433    GET_JIT_THRESHOLD %ecx rINST
13434    EXPORT_PC
13435    movb   rINSTbl,(%edx,%eax)   # reset counter
13436    movl   offGlue_self(%ecx),rINST
13437    movl   rPC,OUT_ARG0(%esp)
13438    call   dvmJitGetCodeAddr   # already have one?
13439    movl   %eax,offThread_inJitCodeCache(rINST)   # set the inJitCodeCache flag
13440    cmpl   $0,%eax
13441    jz     1f
13442    call   *%eax        # FIXME: decide call vs/ jmp!.  No return either way
134431:
13444    movl   $kJitTSelectRequest,%eax
13445    # On entry, eax<- jitState, rPC valid
13446common_selectTrace:
13447    movl   rGLUE,%ecx
13448    movl   %eax,offGlue_jitState(%ecx)
13449    movl   $kInterpEntryInstr,offGlue_entryPoint(%ecx)
13450    movl   $1,rINST
13451    jmp    common_gotoBail
13452#else
13453    ADVANCE_PC_INDEXED rINST
13454    FETCH_INST
13455    GOTO_NEXT
13456#endif
13457
13458
13459
13460/*
13461 * Common code for jumbo method invocation.
13462 *
13463 * On entry:
13464 *   eax = Method* methodToCall
13465 *   rINSTw trashed, must reload
13466 */
13467
13468common_invokeMethodJumbo:
13469.LinvokeNewJumbo:
13470
13471   /*
13472    * prepare to copy args to "outs" area of current frame
13473    */
13474    movzwl      6(rPC),rINST            # rINST<- BBBB
13475    movzwl      8(rPC), %ecx            # %ecx<- CCCC
13476    ADVANCE_PC 2                        # adjust pc to make return similar
13477    SAVEAREA_FROM_FP %edx               # %edx<- &StackSaveArea
13478    test        rINST, rINST
13479    movl        rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- BBBB
13480    jz          .LinvokeArgsDone        # no args; jump to args done
13481    jmp         .LinvokeRangeArgs       # handle args like invoke range
13482
13483/*
13484 * Common code for method invocation with range.
13485 *
13486 * On entry:
13487 *   eax = Method* methodToCall
13488 *   rINSTw trashed, must reload
13489 */
13490
13491common_invokeMethodRange:
13492.LinvokeNewRange:
13493
13494   /*
13495    * prepare to copy args to "outs" area of current frame
13496    */
13497
13498    movzbl      1(rPC),rINST       # rINST<- AA
13499    movzwl      4(rPC), %ecx            # %ecx<- CCCC
13500    SAVEAREA_FROM_FP %edx               # %edx<- &StackSaveArea
13501    test        rINST, rINST
13502    movl        rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- AA
13503    jz          .LinvokeArgsDone        # no args; jump to args done
13504
13505
13506   /*
13507    * %eax=methodToCall, %ecx=CCCC, LOCAL0_OFFSET(%ebp)=count, %edx=&outs (&stackSaveArea)
13508    * (very few methods have > 10 args; could unroll for common cases)
13509    */
13510
13511.LinvokeRangeArgs:
13512    movl        %ebx, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- save %ebx
13513    lea         (rFP, %ecx, 4), %ecx    # %ecx<- &vCCCC
13514    shll        $2, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- offset
13515    subl        LOCAL0_OFFSET(%ebp), %edx       # %edx<- update &outs
13516    shrl        $2, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- offset
135171:
13518    movl        (%ecx), %ebx            # %ebx<- vCCCC
13519    lea         4(%ecx), %ecx           # %ecx<- &vCCCC++
13520    subl        $1, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET<- LOCAL0_OFFSET--
13521    movl        %ebx, (%edx)            # *outs<- vCCCC
13522    lea         4(%edx), %edx           # outs++
13523    jne         1b                      # loop if count (LOCAL0_OFFSET(%ebp)) not zero
13524    movl        LOCAL1_OFFSET(%ebp), %ebx       # %ebx<- restore %ebx
13525    jmp         .LinvokeArgsDone        # continue
13526
13527   /*
13528    * %eax is "Method* methodToCall", the method we're trying to call
13529    * prepare to copy args to "outs" area of current frame
13530    */
13531
13532common_invokeMethodNoRange:
13533.LinvokeNewNoRange:
13534    movzbl      1(rPC),rINST       # rINST<- BA
13535    movl        rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- BA
13536    shrl        $4, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- B
13537    je          .LinvokeArgsDone        # no args; jump to args done
13538    movzwl      4(rPC), %ecx            # %ecx<- GFED
13539    SAVEAREA_FROM_FP %edx               # %edx<- &StackSaveArea
13540
13541   /*
13542    * %eax=methodToCall, %ecx=GFED, LOCAL0_OFFSET(%ebp)=count, %edx=outs
13543    */
13544
13545.LinvokeNonRange:
13546    cmp         $2, LOCAL0_OFFSET(%ebp)        # compare LOCAL0_OFFSET(%ebp) to 2
13547    movl        %ecx, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- GFED
13548    jl          1f                      # handle 1 arg
13549    je          2f                      # handle 2 args
13550    cmp         $4, LOCAL0_OFFSET(%ebp)        # compare LOCAL0_OFFSET(%ebp) to 4
13551    jl          3f                      # handle 3 args
13552    je          4f                      # handle 4 args
135535:
13554    andl        $15, rINST             # rINSTw<- A
13555    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
13556    movl        (rFP, rINST, 4), %ecx   # %ecx<- vA
13557    movl        %ecx, (%edx)            # *outs<- vA
13558    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
135594:
13560    shr         $12, %ecx              # %ecx<- G
13561    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
13562    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vG
13563    movl        %ecx, (%edx)            # *outs<- vG
13564    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
135653:
13566    and         $0x0f00, %ecx          # %ecx<- 0F00
13567    shr         $8, %ecx               # %ecx<- F
13568    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
13569    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vF
13570    movl        %ecx, (%edx)            # *outs<- vF
13571    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
135722:
13573    and         $0x00f0, %ecx          # %ecx<- 00E0
13574    shr         $4, %ecx               # %ecx<- E
13575    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
13576    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vE
13577    movl        %ecx, (%edx)            # *outs<- vE
13578    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
135791:
13580    and         $0x000f, %ecx          # %ecx<- 000D
13581    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vD
13582    movl        %ecx, -4(%edx)          # *--outs<- vD
135830:
13584
13585   /*
13586    * %eax is "Method* methodToCall", the method we're trying to call
13587    * find space for the new stack frame, check for overflow
13588    */
13589
13590.LinvokeArgsDone:
13591    movzwl      offMethod_registersSize(%eax), %edx # %edx<- methodToCall->regsSize
13592    movzwl      offMethod_outsSize(%eax), %ecx # %ecx<- methodToCall->outsSize
13593    movl        %eax, LOCAL0_OFFSET(%ebp)       # LOCAL0_OFFSET<- methodToCall
13594    shl         $2, %edx               # %edx<- update offset
13595    SAVEAREA_FROM_FP %eax               # %eax<- &StackSaveArea
13596    subl        %edx, %eax              # %eax<- newFP; (old savearea - regsSize)
13597    movl        rGLUE,%edx              # %edx<- pMterpGlue
13598    movl        %eax, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- &outs
13599    subl        $sizeofStackSaveArea, %eax # %eax<- newSaveArea (stack save area using newFP)
13600    movl        offGlue_interpStackEnd(%edx), %edx # %edx<- glue->interpStackEnd
13601    movl        %edx, LOCAL2_OFFSET(%ebp)       # LOCAL2_OFFSET<- glue->interpStackEnd
13602    shl         $2, %ecx               # %ecx<- update offset for outsSize
13603    movl        %eax, %edx              # %edx<- newSaveArea
13604    sub         %ecx, %eax              # %eax<- bottom; (newSaveArea - outsSize)
13605    cmp         LOCAL2_OFFSET(%ebp), %eax       # compare interpStackEnd and bottom
13606    movl        LOCAL0_OFFSET(%ebp), %eax       # %eax<- restore methodToCall
13607    jl          .LstackOverflow         # handle frame overflow
13608
13609   /*
13610    * set up newSaveArea
13611    */
13612
13613#ifdef EASY_GDB
13614    SAVEAREA_FROM_FP %ecx               # %ecx<- &StackSaveArea
13615    movl        %ecx, offStackSaveArea_prevSave(%edx) # newSaveArea->prevSave<- &outs
13616#endif
13617    movl        rFP, offStackSaveArea_prevFrame(%edx) # newSaveArea->prevFrame<- rFP
13618    movl        rPC, offStackSaveArea_savedPc(%edx) # newSaveArea->savedPc<- rPC
13619    testl       $ACC_NATIVE, offMethod_accessFlags(%eax) # check for native call
13620    movl        %eax, offStackSaveArea_method(%edx) # newSaveArea->method<- method to call
13621    jne         .LinvokeNative          # handle native call
13622
13623   /*
13624    * Update "glue" values for the new method
13625    * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFp
13626    */
13627
13628    movl        offMethod_clazz(%eax), %edx # %edx<- method->clazz
13629    movl        rGLUE,%ecx                  # %ecx<- pMterpGlue
13630    movl        offClassObject_pDvmDex(%edx), %edx # %edx<- method->clazz->pDvmDex
13631    movl        %eax, offGlue_method(%ecx) # glue->method<- methodToCall
13632    movl        %edx, offGlue_methodClassDex(%ecx) # glue->methodClassDex<- method->clazz->pDvmDex
13633    movl        offMethod_insns(%eax), rPC # rPC<- methodToCall->insns
13634    movl        offGlue_self(%ecx), %eax # %eax<- glue->self
13635    movl        LOCAL1_OFFSET(%ebp), rFP # rFP<- newFP
13636    movl        rFP, offThread_curFrame(%eax) # glue->self->curFrame<- newFP
13637    FETCH_INST
13638    GOTO_NEXT                           # jump to methodToCall->insns
13639
13640   /*
13641    * Prep for the native call
13642    * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFP, %edx=newSaveArea
13643    */
13644
13645.LinvokeNative:
13646    movl        rGLUE,%ecx              # %ecx<- pMterpGlue
13647    movl        %eax, OUT_ARG1(%esp)    # push parameter methodToCall
13648    movl        offGlue_self(%ecx), %ecx        # %ecx<- glue->self
13649    movl        offThread_jniLocal_topCookie(%ecx), %eax # %eax<- self->localRef->...
13650    movl        %eax, offStackSaveArea_localRefCookie(%edx) # newSaveArea->localRefCookie<- top
13651    movl        %edx, OUT_ARG4(%esp)    # save newSaveArea
13652    movl        LOCAL1_OFFSET(%ebp), %edx # %edx<- newFP
13653    movl        %edx, offThread_curFrame(%ecx)  # glue->self->curFrame<- newFP
13654    movl        %ecx, OUT_ARG3(%esp)    # save glue->self
13655    movl        %ecx, OUT_ARG2(%esp)    # push parameter glue->self
13656    movl        rGLUE,%ecx              # %ecx<- pMterpGlue
13657    movl        OUT_ARG1(%esp), %eax    # %eax<- methodToCall
13658    lea         offGlue_retval(%ecx), %ecx # %ecx<- &retval
13659    movl        %ecx, OUT_ARG0(%esp)    # push parameter pMterpGlue
13660    push        %edx                    # push parameter newFP
13661
13662    call        *offMethod_nativeFunc(%eax) # call methodToCall->nativeFunc
13663    lea         4(%esp), %esp
13664    movl        OUT_ARG4(%esp), %ecx    # %ecx<- newSaveArea
13665    movl        OUT_ARG3(%esp), %eax    # %eax<- glue->self
13666    movl        offStackSaveArea_localRefCookie(%ecx), %edx # %edx<- old top
13667    cmp         $0, offThread_exception(%eax) # check for exception
13668    movl        rFP, offThread_curFrame(%eax) # glue->self->curFrame<- rFP
13669    movl        %edx, offThread_jniLocal_topCookie(%eax) # new top <- old top
13670    jne         common_exceptionThrown  # handle exception
13671    FETCH_INST_OPCODE 3 %edx
13672    ADVANCE_PC 3
13673    GOTO_NEXT_R %edx                    # jump to next instruction
13674
13675.LstackOverflow:    # eax=methodToCall
13676    movl        %eax, OUT_ARG1(%esp)    # push parameter methodToCall
13677    movl        rGLUE,%eax              # %eax<- pMterpGlue
13678    movl        offGlue_self(%eax), %eax # %eax<- glue->self
13679    movl        %eax, OUT_ARG0(%esp)    # push parameter self
13680    call        dvmHandleStackOverflow  # call: (Thread* self, Method* meth)
13681    jmp         common_exceptionThrown  # handle exception
13682
13683
13684/*
13685 * Do we need the thread to be suspended or have debugger/profiling activity?
13686 *
13687 * On entry:
13688 *   ebx  -> PC adjustment in 16-bit words (must be preserved)
13689 *   ecx  -> GLUE pointer
13690 *   reentry type, e.g. kInterpEntryInstr stored in rGLUE->entryPoint
13691 *
13692 * Note: A call will normally kill %eax and %ecx.  To
13693 *       streamline the normal case, this routine will preserve
13694 *       %ecx in addition to the normal caller save regs.  The save/restore
13695 *       is a bit ugly, but will happen in the relatively uncommon path.
13696 * TODO: Basic-block style Jit will need a hook here as well.  Fold it into
13697 *       the suspendCount check so we can get both in 1 shot.
13698 * TUNING: Improve scheduling here & do initial single test for all.
13699 */
13700common_periodicChecks:
13701    movl    offGlue_pSelfSuspendCount(%ecx),%eax    # eax <- &suspendCount
13702    cmpl    $0,(%eax)
13703    jne     1f
13704
137056:
13706    movl   offGlue_pInterpBreak(%ecx),%eax    # eax <- &interpBreak
13707    cmpl   $0,(%eax)              # something interesting happening?
13708    jne    3f                      # yes - switch interpreters
13709    ret
13710
13711    /* Check for suspend */
137121:
13713    /*  At this point, the return pointer to the caller of
13714     *  common_periodicChecks is on the top of stack.  We need to preserve
13715     *  GLUE(ecx).
13716     *  The outgoing profile is:
13717     *      bool dvmCheckSuspendPending(Thread* self)
13718     *  Because we reached here via a call, go ahead and build a new frame.
13719     */
13720    EXPORT_PC                         # need for precise GC
13721    movl    offGlue_self(%ecx),%eax      # eax<- glue->self
13722    push    %ebp
13723    movl    %esp,%ebp
13724    subl    $24,%esp
13725    movl    %eax,OUT_ARG0(%esp)
13726    call    dvmCheckSuspendPending
13727    addl    $24,%esp
13728    pop     %ebp
13729    movl    rGLUE,%ecx
13730
13731    /*
13732     * Need to check to see if debugger or profiler flags got set
13733     * while we were suspended.
13734     */
13735    jmp    6b
13736
13737    /* Switch interpreters */
13738    /* Note: %ebx contains the 16-bit word offset to be applied to rPC to
13739     * "complete" the interpretation of backwards branches.  In effect, we
13740     * are completing the interpretation of the branch instruction here,
13741     * and the new interpreter will resume interpretation at the branch
13742     * target. However, a switch request recognized during the handling
13743     * of a return from method instruction results in an immediate abort,
13744     * and the new interpreter will resume by re-interpreting the return
13745     * instruction.
13746     */
137473:
13748    leal    (rPC,%ebx,2),rPC       # adjust pc to show target
13749    movl    rGLUE,%ecx             # bail expect GLUE already loaded
13750    movl    $1,rINST              # set changeInterp to true
13751    jmp     common_gotoBail
13752
13753
13754/*
13755 * Common code for handling a return instruction
13756 */
13757common_returnFromMethod:
13758    movl    rGLUE,%ecx
13759    /* Set entry mode in case we bail */
13760    movb    $kInterpEntryReturn,offGlue_entryPoint(%ecx)
13761    xorl    rINST,rINST   # zero offset in case we switch interps
13762    call    common_periodicChecks   # Note: expects %ecx to be preserved
13763
13764    SAVEAREA_FROM_FP %eax                         # eax<- saveArea (old)
13765    movl    offStackSaveArea_prevFrame(%eax),rFP  # rFP<- prevFrame
13766    movl    (offStackSaveArea_method-sizeofStackSaveArea)(rFP),rINST
13767    cmpl    $0,rINST                             # break?
13768    je      common_gotoBail    # break frame, bail out completely
13769
13770    movl    offStackSaveArea_savedPc(%eax),rPC    # pc<- saveArea->savedPC
13771    movl    offGlue_self(%ecx),%eax               # eax<- self
13772    movl    rINST,offGlue_method(%ecx)  # glue->method = newSave->meethod
13773    movl    rFP,offThread_curFrame(%eax)     # self->curFrame = fp
13774    movl    offMethod_clazz(rINST),%eax      # eax<- method->clazz
13775    FETCH_INST_OPCODE 3 %edx
13776    movl    offClassObject_pDvmDex(%eax),%eax # eax<- method->clazz->pDvmDex
13777    ADVANCE_PC 3
13778    movl    %eax,offGlue_methodClassDex(%ecx)
13779    /* not bailing - restore entry mode to default */
13780    movb    $kInterpEntryInstr,offGlue_entryPoint(%ecx)
13781    GOTO_NEXT_R %edx
13782
13783/*
13784 * Prepare to strip the current frame and "longjump" back to caller of
13785 * dvmMterpStdRun.
13786 *
13787 * on entry:
13788 *    rINST holds changeInterp
13789 *    ecx holds glue pointer
13790 *
13791 * expected profile: dvmMterpStdBail(MterpGlue *glue, bool changeInterp)
13792 */
13793common_gotoBail:
13794    movl   rPC,offGlue_pc(%ecx)     # export state to glue
13795    movl   rFP,offGlue_fp(%ecx)
13796    movl   %ecx,OUT_ARG0(%esp)      # glue in arg0
13797    movl   rINST,OUT_ARG1(%esp)     # changeInterp in arg1
13798    call   dvmMterpStdBail          # bail out....
13799
13800
13801/*
13802 * After returning from a "glued" function, pull out the updated values
13803 * and start executing at the next instruction.
13804 */
13805 common_resumeAfterGlueCall:
13806     LOAD_PC_FP_FROM_GLUE
13807     FETCH_INST
13808     GOTO_NEXT
13809
13810/*
13811 * Integer divide or mod by zero
13812 */
13813common_errDivideByZero:
13814    EXPORT_PC
13815    movl    $.LstrArithmeticException,%eax
13816    movl    %eax,OUT_ARG0(%esp)
13817    movl    $.LstrDivideByZero,%eax
13818    movl    %eax,OUT_ARG1(%esp)
13819    call    dvmThrowException
13820    jmp     common_exceptionThrown
13821
13822/*
13823 * Attempt to allocate an array with a negative size.
13824 */
13825common_errNegativeArraySize:
13826    EXPORT_PC
13827    movl    $.LstrNegativeArraySizeException,%eax
13828    movl    %eax,OUT_ARG0(%esp)
13829    xorl    %eax,%eax
13830    movl    %eax,OUT_ARG1(%esp)
13831    call    dvmThrowException
13832    jmp     common_exceptionThrown
13833
13834/*
13835 * Attempt to allocate an array with a negative size.
13836 */
13837common_errNoSuchMethod:
13838
13839    EXPORT_PC
13840    movl    $.LstrNoSuchMethodError,%eax
13841    movl    %eax,OUT_ARG0(%esp)
13842    xorl    %eax,%eax
13843    movl    %eax,OUT_ARG1(%esp)
13844    call    dvmThrowException
13845    jmp     common_exceptionThrown
13846
13847/*
13848 * Hit a null object when we weren't expecting one.  Export the PC, throw a
13849 * NullPointerException and goto the exception processing code.
13850 */
13851common_errNullObject:
13852    EXPORT_PC
13853    movl    $.LstrNullPointerException,%eax
13854    movl    %eax,OUT_ARG0(%esp)
13855    xorl    %eax,%eax
13856    movl    %eax,OUT_ARG1(%esp)
13857    call    dvmThrowException
13858    jmp     common_exceptionThrown
13859
13860/*
13861 * Array index exceeds max.
13862 * On entry:
13863 *    eax <- array object
13864 *    ecx <- index
13865 */
13866common_errArrayIndex:
13867    EXPORT_PC
13868    movl    offArrayObject_length(%eax), %eax
13869    movl    %ecx,OUT_ARG0(%esp)
13870    movl    %eax,OUT_ARG1(%esp)
13871    call    dvmThrowAIOOBE        # dvmThrowAIOO(index, length)
13872    jmp     common_exceptionThrown
13873
13874/*
13875 * Somebody has thrown an exception.  Handle it.
13876 *
13877 * If the exception processing code returns to us (instead of falling
13878 * out of the interpreter), continue with whatever the next instruction
13879 * now happens to be.
13880 *
13881 * This does not return.
13882 */
13883common_exceptionThrown:
13884    movl    rGLUE,%ecx
13885    movl    rPC,offGlue_pc(%ecx)
13886    movl    rFP,offGlue_fp(%ecx)
13887    movl    %ecx,OUT_ARG0(%esp)
13888    call    dvmMterp_exceptionThrown
13889    jmp     common_resumeAfterGlueCall
13890
13891common_abort:
13892    movl    $0xdeadf00d,%eax
13893    call     *%eax
13894
13895
13896/*
13897 * Strings
13898 */
13899
13900    .section     .rodata
13901.LstrNullPointerException:
13902    .asciz    "Ljava/lang/NullPointerException;"
13903.LstrArithmeticException:
13904    .asciz  "Ljava/lang/ArithmeticException;"
13905.LstrDivideByZero:
13906    .asciz  "divide by zero"
13907.LstrNegativeArraySizeException:
13908    .asciz  "Ljava/lang/NegativeArraySizeException;"
13909.LstrInstantiationError:
13910    .asciz  "Ljava/lang/InstantiationError;"
13911.LstrNoSuchMethodError:
13912    .asciz  "Ljava/lang/NoSuchMethodError;"
13913.LstrInternalErrorA:
13914    .asciz  "Ljava/lang/InternalError;"
13915.LstrFilledNewArrayNotImplA:
13916    .asciz  "filled-new-array only implemented for 'int'"
13917
13918