InterpAsm-x86.S revision 9f601a917c8878204482c37aec7005054b6776fa
1/*
2 * This file was generated automatically by gen-mterp.py for 'x86'.
3 *
4 * --> DO NOT EDIT <--
5 */
6
7/* File: x86/header.S */
8/*
9 * Copyright (C) 2008 The Android Open Source Project
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 *      http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 */
23/*
24 * 32-bit x86 definitions and declarations.
25 */
26
27/*
28386 ABI general notes:
29
30Caller save set:
31   eax, edx, ecx, st(0)-st(7)
32Callee save set:
33   ebx, esi, edi, ebp
34Return regs:
35   32-bit in eax
36   64-bit in edx:eax (low-order 32 in eax)
37   fp on top of fp stack st(0)
38
39Parameters passed on stack, pushed right-to-left.  On entry to target, first
40parm is at 4(%esp).  Traditional entry code is:
41
42functEntry:
43    push    %ebp             # save old frame pointer
44    mov     %ebp,%esp        # establish new frame pointer
45    sub     FrameSize,%esp   # Allocate storage for spill, locals & outs
46
47Once past the prologue, arguments are referenced at ((argno + 2)*4)(%ebp)
48
49Alignment of stack not strictly required, but should be for performance.  We'll
50align frame sizes to 16-byte multiples.
51
52If we're not doing variable stack allocation (alloca), the frame pointer can be
53eliminated and all arg references adjusted to be esp relative.
54
55Mterp notes:
56
57Some key interpreter variables will be assigned to registers.  Note that each
58will also have an associated spill location (mostly useful for those assigned
59to callee save registers).
60
61  nick     reg   purpose
62  rPC      edi   interpreted program counter, used for fetching instructions
63  rFP      esi   interpreted frame pointer, used for accessing locals and args
64  rINSTw   bx    first 16-bit code of current instruction
65  rINSTbl  bl    opcode portion of instruction word
66  rINSTbh  bh    high byte of inst word, usually contains src/tgt reg names
67
68Notes:
69   o High order 16 bits of ebx must be zero on entry to handler
70   o rPC, rFP, rINSTw/rINSTbl valid on handler entry and exit
71   o eax, edx and ecx are scratch, rINSTw/ebx sometimes scratch
72
73*/
74
75#define rSELF    (%ebp)
76#define rPC      %esi
77#define rFP      %edi
78#define rINST    %ebx
79#define rINSTw   %bx
80#define rINSTbh  %bh
81#define rINSTbl  %bl
82
83
84/* Frame diagram while executing dvmMterpStdRun, high to low addresses */
85#define IN_ARG0        ( 12)
86#define CALLER_RP      (  8)
87#define PREV_FP        (  4)
88#define rSELF_SPILL    (  0) /* <- dvmMterpStdRun ebp */
89/* Spill offsets relative to %ebp */
90#define EDI_SPILL      ( -4)
91#define ESI_SPILL      ( -8)
92#define EBX_SPILL      (-12) /* <- esp following dmMterpStdRun header */
93#define rPC_SPILL      (-16)
94#define rFP_SPILL      (-20)
95#define rINST_SPILL    (-24)
96#define TMP_SPILL1     (-28)
97#define TMP_SPILL2     (-32)
98#define TMP_SPILL3     (-36)
99#define LOCAL0_OFFSET  (-40)
100#define LOCAL1_OFFSET  (-44)
101#define LOCAL2_OFFSET  (-48)
102#define LOCAL3_OFFSET  (-52)
103/* Out Arg offsets, relative to %sp */
104#define OUT_ARG4       ( 16)
105#define OUT_ARG3       ( 12)
106#define OUT_ARG2       (  8)
107#define OUT_ARG1       (  4)
108#define OUT_ARG0       (  0)  /* <- dvmMterpStdRun esp */
109#define FRAME_SIZE     80
110
111#define SPILL(reg) movl reg##,reg##_SPILL(%ebp)
112#define UNSPILL(reg) movl reg##_SPILL(%ebp),reg
113#define SPILL_TMP1(reg) movl reg,TMP_SPILL1(%ebp)
114#define UNSPILL_TMP1(reg) movl TMP_SPILL1(%ebp),reg
115#define SPILL_TMP2(reg) movl reg,TMP_SPILL2(%ebp)
116#define UNSPILL_TMP2(reg) movl TMP_SPILL2(%ebp),reg
117#define SPILL_TMP3(reg) movl reg,TMP_SPILL3(%ebp)
118#define UNSPILL_TMP3(reg) movl TMP_SPILL3(%ebp),reg
119
120#if defined(WITH_JIT)
121.macro GET_JIT_PROF_TABLE _self _reg
122    movl    offThread_pJitProfTable(\_self),\_reg
123.endm
124.macro GET_JIT_THRESHOLD _self _reg
125    movl    offThread_jitThreshold(\_self),\_reg
126.endm
127#endif
128
129/* save/restore the PC and/or FP from the self struct */
130.macro SAVE_PC_FP_TO_SELF _reg
131    movl     rSELF,\_reg
132    movl     rPC,offThread_pc(\_reg)
133    movl     rFP,offThread_fp(\_reg)
134.endm
135
136.macro LOAD_PC_FP_FROM_SELF
137    movl    rSELF,rFP
138    movl    offThread_pc(rFP),rPC
139    movl    offThread_fp(rFP),rFP
140.endm
141
142/* The interpreter assumes a properly aligned stack on entry, and
143 * will preserve 16-byte alignment.
144 */
145
146/*
147 * "export" the PC to the interpreted stack frame, f/b/o future exception
148 * objects.  Must * be done *before* something calls dvmThrowException.
149 *
150 * In C this is "SAVEAREA_FROM_FP(fp)->xtra.currentPc = pc", i.e.
151 * fp - sizeof(StackSaveArea) + offsetof(SaveArea, xtra.currentPc)
152 *
153 * It's okay to do this more than once.
154 */
155.macro EXPORT_PC
156    movl     rPC, (-sizeofStackSaveArea + offStackSaveArea_currentPc)(rFP)
157.endm
158
159/*
160 * Given a frame pointer, find the stack save area.
161 *
162 * In C this is "((StackSaveArea*)(_fp) -1)".
163 */
164.macro SAVEAREA_FROM_FP _reg
165    leal    -sizeofStackSaveArea(rFP), \_reg
166.endm
167
168/*
169 * Fetch the next instruction from rPC into rINSTw.  Does not advance rPC.
170 */
171.macro FETCH_INST
172    movzwl    (rPC),rINST
173.endm
174
175/*
176 * Fetch the opcode byte and zero-extend it into _reg.  Must be used
177 * in conjunction with GOTO_NEXT_R
178 */
179.macro FETCH_INST_R _reg
180    movzbl    (rPC),\_reg
181.endm
182
183/*
184 * Fetch the opcode byte at _count words offset from rPC and zero-extend
185 * it into _reg.  Must be used in conjunction with GOTO_NEXT_R
186 */
187.macro FETCH_INST_OPCODE _count _reg
188    movzbl  \_count*2(rPC),\_reg
189.endm
190
191/*
192 * Fetch the nth instruction word from rPC into rINSTw.  Does not advance
193 * rPC, and _count is in words
194 */
195.macro FETCH_INST_WORD _count
196    movzwl  \_count*2(rPC),rINST
197.endm
198
199/*
200 * Fetch instruction word indexed (used for branching).
201 * Index is in instruction word units.
202 */
203.macro FETCH_INST_INDEXED _reg
204    movzwl  (rPC,\_reg,2),rINST
205.endm
206
207/*
208 * Advance rPC by instruction count
209 */
210.macro ADVANCE_PC _count
211    leal  2*\_count(rPC),rPC
212.endm
213
214/*
215 * Advance rPC by branch offset in register
216 */
217.macro ADVANCE_PC_INDEXED _reg
218    leal (rPC,\_reg,2),rPC
219.endm
220
221.macro GOTO_NEXT
222     movzx   rINSTbl,%eax
223     movzbl  rINSTbh,rINST
224     jmp     *dvmAsmInstructionJmpTable(,%eax,4)
225.endm
226
227   /*
228    * Version of GOTO_NEXT that assumes _reg preloaded with opcode.
229    * Should be paired with FETCH_INST_R
230    */
231.macro GOTO_NEXT_R _reg
232     movzbl  1(rPC),rINST
233     jmp     *dvmAsmInstructionJmpTable(,\_reg,4)
234.endm
235
236   /*
237    * Jumbo version of GOTO_NEXT that assumes _reg preloaded with table
238    * offset of the jumbo instruction, which is the top half of the extended
239    * opcode + 0x100.  Loads rINST with BBBB field, similar to GOTO_NEXT_R
240    */
241.macro GOTO_NEXT_JUMBO_R _reg
242     movzwl  6(rPC),rINST
243     jmp     *dvmAsmInstructionJmpTable(,\_reg,4)
244.endm
245
246/*
247 * Get/set the 32-bit value from a Dalvik register.
248 */
249.macro GET_VREG_R _reg _vreg
250    movl     (rFP,\_vreg,4),\_reg
251.endm
252
253.macro SET_VREG _reg _vreg
254    movl     \_reg,(rFP,\_vreg,4)
255.endm
256
257.macro GET_VREG_WORD _reg _vreg _offset
258    movl     4*(\_offset)(rFP,\_vreg,4),\_reg
259.endm
260
261.macro SET_VREG_WORD _reg _vreg _offset
262    movl     \_reg,4*(\_offset)(rFP,\_vreg,4)
263.endm
264
265#if 1
266
267#define rFinish %edx
268
269/* Macros for x86-atom handlers */
270    /*
271    * Get the 32-bit value from a dalvik register.
272    */
273
274    .macro      GET_VREG _vreg
275    movl        (rFP,\_vreg, 4), \_vreg
276    .endm
277
278   /*
279    * Fetch the next instruction from the specified offset. Advances rPC
280    * to point to the next instruction. "_count" is in 16-bit code units.
281    *
282    * This must come AFTER anything that can throw an exception, or the
283    * exception catch may miss. (This also implies that it must come after
284    * EXPORT_PC())
285    */
286
287    .macro      FETCH_ADVANCE_INST _count
288    add         $(\_count*2), rPC
289    movzwl      (rPC), rINST
290    .endm
291
292   /*
293    * Fetch the next instruction from an offset specified by _reg. Updates
294    * rPC to point to the next instruction. "_reg" must specify the distance
295    * in bytes, *not* 16-bit code units, and may be a signed value.
296    */
297
298    .macro      FETCH_ADVANCE_INST_RB _reg
299    addl        \_reg, rPC
300    movzwl      (rPC), rINST
301    .endm
302
303   /*
304    * Fetch a half-word code unit from an offset past the current PC. The
305    * "_count" value is in 16-bit code units. Does not advance rPC.
306    * For example, given instruction of format: AA|op BBBB, it
307    * fetches BBBB.
308    */
309
310    .macro      FETCH _count _reg
311    movzwl      (\_count*2)(rPC), \_reg
312    .endm
313
314   /*
315    * Fetch a half-word code unit from an offset past the current PC. The
316    * "_count" value is in 16-bit code units. Does not advance rPC.
317    * This variant treats the value as signed.
318    */
319
320    .macro      FETCHs _count _reg
321    movswl      (\_count*2)(rPC), \_reg
322    .endm
323
324   /*
325    * Fetch the first byte from an offset past the current PC. The
326    * "_count" value is in 16-bit code units. Does not advance rPC.
327    * For example, given instruction of format: AA|op CC|BB, it
328    * fetches BB.
329    */
330
331    .macro      FETCH_BB _count _reg
332    movzbl      (\_count*2)(rPC), \_reg
333    .endm
334
335    /*
336    * Fetch the second byte from an offset past the current PC. The
337    * "_count" value is in 16-bit code units. Does not advance rPC.
338    * For example, given instruction of format: AA|op CC|BB, it
339    * fetches CC.
340    */
341
342    .macro      FETCH_CC _count _reg
343    movzbl      (\_count*2 + 1)(rPC), \_reg
344    .endm
345
346   /*
347    * Fetch the second byte from an offset past the current PC. The
348    * "_count" value is in 16-bit code units. Does not advance rPC.
349    * This variant treats the value as signed.
350    */
351
352    .macro      FETCH_CCs _count _reg
353    movsbl      (\_count*2 + 1)(rPC), \_reg
354    .endm
355
356
357   /*
358    * Fetch one byte from an offset past the current PC.  Pass in the same
359    * "_count" as you would for FETCH, and an additional 0/1 indicating which
360    * byte of the halfword you want (lo/hi).
361    */
362
363    .macro      FETCH_B _reg  _count  _byte
364    movzbl      (\_count*2+\_byte)(rPC), \_reg
365    .endm
366
367   /*
368    * Put the instruction's opcode field into the specified register.
369    */
370
371    .macro      GET_INST_OPCODE _reg
372    movzbl      rINSTbl, \_reg
373    .endm
374
375   /*
376    * Begin executing the opcode in _reg.
377    */
378
379    .macro      GOTO_OPCODE _reg
380    shl         $6, \_reg
381    addl        $dvmAsmInstructionStart,\_reg
382    jmp         *\_reg
383    .endm
384
385
386
387   /*
388    * Macros pair attempts to speed up FETCH_INST, GET_INST_OPCODE and GOTO_OPCODE
389    * by using a jump table. _rFinish should must be the same register for
390    * both macros.
391    */
392
393    .macro      FFETCH _rFinish
394    movzbl      (rPC), \_rFinish
395    .endm
396
397    .macro      FGETOP_JMPa _rFinish
398    movzbl      1(rPC), rINST
399    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
400    .endm
401
402   /*
403    * Macro pair attempts to speed up FETCH_INST, GET_INST_OPCODE and GOTO_OPCODE
404    * by using a jump table. _rFinish and _count should must be the same register for
405    * both macros.
406    */
407
408    .macro      FFETCH_ADV _count _rFinish
409    movzbl      (\_count*2)(rPC), \_rFinish
410    .endm
411
412    .macro      FGETOP_JMP _count _rFinish
413    movzbl      (\_count*2 + 1)(rPC), rINST
414    addl        $(\_count*2), rPC
415    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
416    .endm
417
418    .macro      FGETOP_JMP2 _rFinish
419    movzbl      1(rPC), rINST
420    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
421    .endm
422
423    .macro      OLD_JMP_1 _count _rFinish
424    movzbl      (\_count*2)(rPC), \_rFinish
425    shl         $6, \_rFinish
426    .endm
427
428    .macro      OLD_JMP_2 _rFinish
429    addl        $dvmAsmInstructionStart,\_rFinish
430    .endm
431
432    .macro      OLD_JMP_3 _count
433    addl        $(\_count*2), rPC
434    .endm
435
436    .macro      OLD_JMP_4 _rFinish
437    movzbl      1(rPC), rINST
438    jmp         *\_rFinish
439    .endm
440
441    .macro      OLD_JMP_A_1 _reg _rFinish
442    movzbl      (rPC, \_reg), \_rFinish
443    shl         $6, \_rFinish
444    .endm
445
446    .macro      OLD_JMP_A_2 _rFinish
447    addl        $dvmAsmInstructionStart,\_rFinish
448    .endm
449
450    .macro      OLD_JMP_A_3 _reg _rFinish
451    addl        \_reg, rPC
452    movzbl      1(rPC, \_reg), rINST
453    jmp         *\_rFinish
454    .endm
455
456   /*
457    * Macro pair attempts to speed up FETCH_INST, GET_INST_OPCODE and GOTO_OPCODE
458    * by using a jump table. _rFinish and _reg should must be the same register for
459    * both macros.
460    */
461
462    .macro      FFETCH_ADV_RB _reg _rFinish
463    movzbl      (\_reg, rPC), \_rFinish
464    .endm
465
466    .macro      FGETOP_RB_JMP _reg _rFinish
467    movzbl      1(\_reg, rPC), rINST
468    addl        \_reg, rPC
469    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
470    .endm
471
472   /*
473    * Attempts to speed up FETCH_INST, GET_INST_OPCODE using
474    * a jump table. This macro should be called before FINISH_JMP where
475    * rFinish should be the same register containing the opcode value.
476    * This is an attempt to split up FINISH in order to reduce or remove
477    * potential stalls due to the wait for rFINISH.
478    */
479
480    .macro      FINISH_FETCH _rFinish
481    movzbl      (rPC), \_rFinish
482    movzbl      1(rPC), rINST
483    .endm
484
485
486   /*
487    * Attempts to speed up FETCH_ADVANCE_INST, GET_INST_OPCODE using
488    * a jump table. This macro should be called before FINISH_JMP where
489    * rFinish should be the same register containing the opcode value.
490    * This is an attempt to split up FINISH in order to reduce or remove
491    * potential stalls due to the wait for rFINISH.
492    */
493
494    .macro      FINISH_FETCH_ADVANCE _count _rFinish
495    movzbl      (\_count*2)(rPC), \_rFinish
496    movzbl      (\_count*2 + 1)(rPC), rINST
497    addl        $(\_count*2), rPC
498    .endm
499
500   /*
501    * Attempts to speed up FETCH_ADVANCE_INST_RB, GET_INST_OPCODE using
502    * a jump table. This macro should be called before FINISH_JMP where
503    * rFinish should be the same register containing the opcode value.
504    * This is an attempt to split up FINISH in order to reduce or remove
505    * potential stalls due to the wait for rFINISH.
506    */
507
508    .macro      FINISH_FETCH_ADVANCE_RB _reg _rFinish
509    movzbl      (\_reg, rPC), \_rFinish
510    movzbl      1(\_reg, rPC), rINST
511    addl        \_reg, rPC
512    .endm
513
514   /*
515    * Attempts to speed up GOTO_OPCODE using a jump table. This macro should
516    * be called after a FINISH_FETCH* instruction where rFinish should be the
517    * same register containing the opcode value. This is an attempt to split up
518    * FINISH in order to reduce or remove potential stalls due to the wait for rFINISH.
519    */
520
521    .macro      FINISH_JMP _rFinish
522    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
523    .endm
524
525   /*
526    * Attempts to speed up FETCH_INST, GET_INST_OPCODE, GOTO_OPCODE by using
527    * a jump table. Uses a single macro - but it should be faster if we
528    * split up the fetch for rFinish and the jump using rFinish.
529    */
530
531    .macro      FINISH_A
532    movzbl      (rPC), rFinish
533    movzbl      1(rPC), rINST
534    jmp         *dvmAsmInstructionJmpTable(,rFinish, 4)
535    .endm
536
537   /*
538    * Attempts to speed up FETCH_ADVANCE_INST, GET_INST_OPCODE,
539    * GOTO_OPCODE by using a jump table. Uses a single macro -
540    * but it should be faster if we split up the fetch for rFinish
541    * and the jump using rFinish.
542    */
543
544    .macro      FINISH _count
545    movzbl      (\_count*2)(rPC), rFinish
546    movzbl      (\_count*2 + 1)(rPC), rINST
547    addl        $(\_count*2), rPC
548    jmp         *dvmAsmInstructionJmpTable(,rFinish, 4)
549    .endm
550
551   /*
552    * Attempts to speed up FETCH_ADVANCE_INST_RB, GET_INST_OPCODE,
553    * GOTO_OPCODE by using a jump table. Uses a single macro -
554    * but it should be faster if we split up the fetch for rFinish
555    * and the jump using rFinish.
556    */
557
558    .macro      FINISH_RB _reg _rFinish
559    movzbl      (\_reg, rPC), \_rFinish
560    movzbl      1(\_reg, rPC), rINST
561    addl        \_reg, rPC
562    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
563    .endm
564
565#define sReg0 LOCAL0_OFFSET(%ebp)
566#define sReg1 LOCAL1_OFFSET(%ebp)
567#define sReg2 LOCAL2_OFFSET(%ebp)
568#define sReg3 LOCAL3_OFFSET(%ebp)
569
570   /*
571    * Hard coded helper values.
572    */
573
574.balign 16
575
576.LdoubNeg:
577    .quad       0x8000000000000000
578
579.L64bits:
580    .quad       0xFFFFFFFFFFFFFFFF
581
582.LshiftMask2:
583    .quad       0x0000000000000000
584.LshiftMask:
585    .quad       0x000000000000003F
586
587.Lvalue64:
588    .quad       0x0000000000000040
589
590.LvaluePosInfLong:
591    .quad       0x7FFFFFFFFFFFFFFF
592
593.LvalueNegInfLong:
594    .quad       0x8000000000000000
595
596.LvalueNanLong:
597    .quad       0x0000000000000000
598
599.LintMin:
600.long   0x80000000
601
602.LintMax:
603.long   0x7FFFFFFF
604#endif
605
606
607/*
608 * This is a #include, not a %include, because we want the C pre-processor
609 * to expand the macros into assembler assignment statements.
610 */
611#include "../common/asm-constants.h"
612
613#if defined(WITH_JIT)
614#include "../common/jit-config.h"
615#endif
616
617
618    .global dvmAsmInstructionStart
619    .type   dvmAsmInstructionStart, %function
620dvmAsmInstructionStart = .L_OP_NOP
621    .text
622
623/* ------------------------------ */
624    .balign 64
625.L_OP_NOP: /* 0x00 */
626/* File: x86/OP_NOP.S */
627    FETCH_INST_OPCODE 1 %edx
628    ADVANCE_PC 1
629    GOTO_NEXT_R %edx
630
631/* ------------------------------ */
632    .balign 64
633.L_OP_MOVE: /* 0x01 */
634/* File: x86/OP_MOVE.S */
635    /* for move, move-object, long-to-int */
636    /* op vA, vB */
637    movzbl rINSTbl,%eax          # eax<- BA
638    andb   $0xf,%al             # eax<- A
639    shrl   $4,rINST            # rINST<- B
640    GET_VREG_R %ecx rINST
641    FETCH_INST_OPCODE 1 %edx
642    ADVANCE_PC 1
643    SET_VREG %ecx %eax           # fp[A]<-fp[B]
644    GOTO_NEXT_R %edx
645
646/* ------------------------------ */
647    .balign 64
648.L_OP_MOVE_FROM16: /* 0x02 */
649/* File: x86/OP_MOVE_FROM16.S */
650    /* for: move/from16, move-object/from16 */
651    /* op vAA, vBBBB */
652    movzx    rINSTbl,%eax              # eax <= AA
653    movw     2(rPC),rINSTw             # rINSTw <= BBBB
654    GET_VREG_R %ecx rINST              # ecx<- fp[BBBB]
655    FETCH_INST_OPCODE 2 %edx
656    ADVANCE_PC 2
657    SET_VREG %ecx %eax                # fp[AA]<- ecx]
658    GOTO_NEXT_R %edx
659
660/* ------------------------------ */
661    .balign 64
662.L_OP_MOVE_16: /* 0x03 */
663/* File: x86/OP_MOVE_16.S */
664    /* for: move/16, move-object/16 */
665    /* op vAAAA, vBBBB */
666    movzwl    4(rPC),%ecx              # ecx<- BBBB
667    movzwl    2(rPC),%eax              # eax<- AAAA
668    GET_VREG_R  %ecx %ecx
669    FETCH_INST_OPCODE 3 %edx
670    ADVANCE_PC 3
671    SET_VREG  %ecx %eax
672    GOTO_NEXT_R %edx
673
674/* ------------------------------ */
675    .balign 64
676.L_OP_MOVE_WIDE: /* 0x04 */
677/* File: x86/OP_MOVE_WIDE.S */
678    /* move-wide vA, vB */
679    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
680    movzbl    rINSTbl,%ecx                # ecx <- BA
681    sarl      $4,rINST                   # rINST<- B
682    GET_VREG_WORD %eax rINST 0            # eax<- v[B+0]
683    GET_VREG_WORD rINST rINST 1           # rINST<- v[B+1]
684    andb      $0xf,%cl                   # ecx <- A
685    FETCH_INST_OPCODE 1 %edx
686    SET_VREG_WORD rINST %ecx 1            # v[A+1]<- rINST
687    ADVANCE_PC 1
688    SET_VREG_WORD %eax %ecx 0             # v[A+0]<- eax
689    GOTO_NEXT_R %edx
690
691/* ------------------------------ */
692    .balign 64
693.L_OP_MOVE_WIDE_FROM16: /* 0x05 */
694/* File: x86/OP_MOVE_WIDE_FROM16.S */
695    /* move-wide/from16 vAA, vBBBB */
696    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
697    movzwl    2(rPC),%ecx              # ecx<- BBBB
698    movzbl    rINSTbl,%eax             # eax<- AAAA
699    GET_VREG_WORD rINST %ecx 0         # rINST<- v[BBBB+0]
700    GET_VREG_WORD %ecx %ecx 1          # ecx<- v[BBBB+1]
701    FETCH_INST_OPCODE 2 %edx
702    ADVANCE_PC 2
703    SET_VREG_WORD rINST %eax 0         # v[AAAA+0]<- rINST
704    SET_VREG_WORD %ecx %eax 1          # v[AAAA+1]<- eax
705    GOTO_NEXT_R %edx
706
707/* ------------------------------ */
708    .balign 64
709.L_OP_MOVE_WIDE_16: /* 0x06 */
710/* File: x86/OP_MOVE_WIDE_16.S */
711    /* move-wide/16 vAAAA, vBBBB */
712    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
713    movzwl    4(rPC),%ecx            # ecx<- BBBB
714    movzwl    2(rPC),%eax            # eax<- AAAA
715    GET_VREG_WORD rINST %ecx 0       # rINSTw_WORD<- v[BBBB+0]
716    GET_VREG_WORD %ecx %ecx 1        # ecx<- v[BBBB+1]
717    FETCH_INST_OPCODE 3 %edx
718    SET_VREG_WORD rINST %eax 0       # v[AAAA+0]<- rINST
719    ADVANCE_PC 3
720    SET_VREG_WORD %ecx %eax 1        # v[AAAA+1]<- ecx
721    GOTO_NEXT_R %edx
722
723/* ------------------------------ */
724    .balign 64
725.L_OP_MOVE_OBJECT: /* 0x07 */
726/* File: x86/OP_MOVE_OBJECT.S */
727/* File: x86/OP_MOVE.S */
728    /* for move, move-object, long-to-int */
729    /* op vA, vB */
730    movzbl rINSTbl,%eax          # eax<- BA
731    andb   $0xf,%al             # eax<- A
732    shrl   $4,rINST            # rINST<- B
733    GET_VREG_R %ecx rINST
734    FETCH_INST_OPCODE 1 %edx
735    ADVANCE_PC 1
736    SET_VREG %ecx %eax           # fp[A]<-fp[B]
737    GOTO_NEXT_R %edx
738
739
740/* ------------------------------ */
741    .balign 64
742.L_OP_MOVE_OBJECT_FROM16: /* 0x08 */
743/* File: x86/OP_MOVE_OBJECT_FROM16.S */
744/* File: x86/OP_MOVE_FROM16.S */
745    /* for: move/from16, move-object/from16 */
746    /* op vAA, vBBBB */
747    movzx    rINSTbl,%eax              # eax <= AA
748    movw     2(rPC),rINSTw             # rINSTw <= BBBB
749    GET_VREG_R %ecx rINST              # ecx<- fp[BBBB]
750    FETCH_INST_OPCODE 2 %edx
751    ADVANCE_PC 2
752    SET_VREG %ecx %eax                # fp[AA]<- ecx]
753    GOTO_NEXT_R %edx
754
755
756/* ------------------------------ */
757    .balign 64
758.L_OP_MOVE_OBJECT_16: /* 0x09 */
759/* File: x86/OP_MOVE_OBJECT_16.S */
760/* File: x86/OP_MOVE_16.S */
761    /* for: move/16, move-object/16 */
762    /* op vAAAA, vBBBB */
763    movzwl    4(rPC),%ecx              # ecx<- BBBB
764    movzwl    2(rPC),%eax              # eax<- AAAA
765    GET_VREG_R  %ecx %ecx
766    FETCH_INST_OPCODE 3 %edx
767    ADVANCE_PC 3
768    SET_VREG  %ecx %eax
769    GOTO_NEXT_R %edx
770
771
772/* ------------------------------ */
773    .balign 64
774.L_OP_MOVE_RESULT: /* 0x0a */
775/* File: x86/OP_MOVE_RESULT.S */
776    /* for: move-result, move-result-object */
777    /* op vAA */
778    movl     rSELF,%eax                    # eax<- rSELF
779    movzx    rINSTbl,%ecx                  # ecx<- AA
780    movl     offThread_retval(%eax),%eax     # eax<- self->retval.l
781    FETCH_INST_OPCODE 1 %edx
782    ADVANCE_PC 1
783    SET_VREG  %eax %ecx                    # fp[AA]<- retval.l
784    GOTO_NEXT_R %edx
785
786/* ------------------------------ */
787    .balign 64
788.L_OP_MOVE_RESULT_WIDE: /* 0x0b */
789/* File: x86/OP_MOVE_RESULT_WIDE.S */
790    /* move-result-wide vAA */
791    movl    rSELF,%ecx
792    movl    offThread_retval(%ecx),%eax
793    movl    4+offThread_retval(%ecx),%ecx
794    FETCH_INST_OPCODE 1 %edx
795    SET_VREG_WORD %eax rINST 0     # v[AA+0] <- eax
796    SET_VREG_WORD %ecx rINST 1     # v[AA+1] <- ecx
797    ADVANCE_PC 1
798    GOTO_NEXT_R %edx
799
800/* ------------------------------ */
801    .balign 64
802.L_OP_MOVE_RESULT_OBJECT: /* 0x0c */
803/* File: x86/OP_MOVE_RESULT_OBJECT.S */
804/* File: x86/OP_MOVE_RESULT.S */
805    /* for: move-result, move-result-object */
806    /* op vAA */
807    movl     rSELF,%eax                    # eax<- rSELF
808    movzx    rINSTbl,%ecx                  # ecx<- AA
809    movl     offThread_retval(%eax),%eax     # eax<- self->retval.l
810    FETCH_INST_OPCODE 1 %edx
811    ADVANCE_PC 1
812    SET_VREG  %eax %ecx                    # fp[AA]<- retval.l
813    GOTO_NEXT_R %edx
814
815
816/* ------------------------------ */
817    .balign 64
818.L_OP_MOVE_EXCEPTION: /* 0x0d */
819/* File: x86/OP_MOVE_EXCEPTION.S */
820    /* move-exception vAA */
821    movl    rSELF,%ecx
822    movl    offThread_exception(%ecx),%eax # eax<- dvmGetException bypass
823    SET_VREG %eax rINST                # fp[AA]<- exception object
824    FETCH_INST_OPCODE 1 %edx
825    ADVANCE_PC 1
826    movl    $0,offThread_exception(%ecx) # dvmClearException bypass
827    GOTO_NEXT_R %edx
828
829/* ------------------------------ */
830    .balign 64
831.L_OP_RETURN_VOID: /* 0x0e */
832/* File: x86/OP_RETURN_VOID.S */
833    jmp       common_returnFromMethod
834
835/* ------------------------------ */
836    .balign 64
837.L_OP_RETURN: /* 0x0f */
838/* File: x86/OP_RETURN.S */
839    /*
840     * Return a 32-bit value.  Copies the return value into the "self"
841     * structure, then jumps to the return handler.
842     *
843     * for: return, return-object
844     */
845    /* op vAA */
846    movl    rSELF,%ecx
847    GET_VREG_R %eax rINST               # eax<- vAA
848    movl    %eax,offThread_retval(%ecx)   # retval.i <- AA
849    jmp     common_returnFromMethod
850
851/* ------------------------------ */
852    .balign 64
853.L_OP_RETURN_WIDE: /* 0x10 */
854/* File: x86/OP_RETURN_WIDE.S */
855    /*
856     * Return a 64-bit value.  Copies the return value into the "self"
857     * structure, then jumps to the return handler.
858     */
859    /* return-wide vAA */
860    movl    rSELF,%ecx
861    GET_VREG_WORD %eax rINST 0       # eax<- v[AA+0]
862    GET_VREG_WORD rINST rINST 1      # rINST<- v[AA+1]
863    movl    %eax,offThread_retval(%ecx)
864    movl    rINST,4+offThread_retval(%ecx)
865    jmp     common_returnFromMethod
866
867/* ------------------------------ */
868    .balign 64
869.L_OP_RETURN_OBJECT: /* 0x11 */
870/* File: x86/OP_RETURN_OBJECT.S */
871/* File: x86/OP_RETURN.S */
872    /*
873     * Return a 32-bit value.  Copies the return value into the "self"
874     * structure, then jumps to the return handler.
875     *
876     * for: return, return-object
877     */
878    /* op vAA */
879    movl    rSELF,%ecx
880    GET_VREG_R %eax rINST               # eax<- vAA
881    movl    %eax,offThread_retval(%ecx)   # retval.i <- AA
882    jmp     common_returnFromMethod
883
884
885/* ------------------------------ */
886    .balign 64
887.L_OP_CONST_4: /* 0x12 */
888/* File: x86/OP_CONST_4.S */
889    /* const/4 vA, #+B */
890    movsx   rINSTbl,%eax              # eax<-ssssssBx
891    movl    $0xf,%ecx
892    andl    %eax,%ecx                 # ecx<- A
893    FETCH_INST_OPCODE 1 %edx
894    ADVANCE_PC 1
895    sarl    $4,%eax
896    SET_VREG %eax %ecx
897    GOTO_NEXT_R %edx
898
899/* ------------------------------ */
900    .balign 64
901.L_OP_CONST_16: /* 0x13 */
902/* File: x86/OP_CONST_16.S */
903    /* const/16 vAA, #+BBBB */
904    movswl  2(rPC),%ecx                # ecx<- ssssBBBB
905    movl    rINST,%eax                 # eax<- AA
906    FETCH_INST_OPCODE 2 %edx
907    ADVANCE_PC 2
908    SET_VREG %ecx %eax                 # vAA<- ssssBBBB
909    GOTO_NEXT_R %edx
910
911/* ------------------------------ */
912    .balign 64
913.L_OP_CONST: /* 0x14 */
914/* File: x86/OP_CONST.S */
915    /* const vAA, #+BBBBbbbb */
916    movl      2(rPC),%eax             # grab all 32 bits at once
917    movl      rINST,%ecx              # ecx<- AA
918    FETCH_INST_OPCODE 3 %edx
919    ADVANCE_PC 3
920    SET_VREG %eax %ecx                # vAA<- eax
921    GOTO_NEXT_R %edx
922
923/* ------------------------------ */
924    .balign 64
925.L_OP_CONST_HIGH16: /* 0x15 */
926/* File: x86/OP_CONST_HIGH16.S */
927    /* const/high16 vAA, #+BBBB0000 */
928    movzwl     2(rPC),%eax                # eax<- 0000BBBB
929    movl       rINST,%ecx                 # ecx<- AA
930    FETCH_INST_OPCODE 2 %edx
931    ADVANCE_PC 2
932    sall       $16,%eax                  # eax<- BBBB0000
933    SET_VREG %eax %ecx                    # vAA<- eax
934    GOTO_NEXT_R %edx
935
936/* ------------------------------ */
937    .balign 64
938.L_OP_CONST_WIDE_16: /* 0x16 */
939/* File: x86/OP_CONST_WIDE_16.S */
940    /* const-wide/16 vAA, #+BBBB */
941    movswl    2(rPC),%eax               # eax<- ssssBBBB
942    cltd                                # rPC:eax<- ssssssssssssBBBB
943    SET_VREG_WORD %edx rINST 1          # store msw
944    FETCH_INST_OPCODE 2 %edx
945    SET_VREG_WORD %eax rINST 0          # store lsw
946    ADVANCE_PC 2
947    GOTO_NEXT_R %edx
948
949/* ------------------------------ */
950    .balign 64
951.L_OP_CONST_WIDE_32: /* 0x17 */
952/* File: x86/OP_CONST_WIDE_32.S */
953    /* const-wide/32 vAA, #+BBBBbbbb */
954    movl     2(rPC),%eax                # eax<- BBBBbbbb
955    cltd                                # rPC:eax<- ssssssssssssBBBB
956    SET_VREG_WORD %edx rINST,1          # store msw
957    FETCH_INST_OPCODE 3 %edx
958    SET_VREG_WORD %eax rINST 0          # store lsw
959    ADVANCE_PC 3
960    GOTO_NEXT_R %edx
961
962/* ------------------------------ */
963    .balign 64
964.L_OP_CONST_WIDE: /* 0x18 */
965/* File: x86/OP_CONST_WIDE.S */
966    /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
967    movl      2(rPC),%eax         # eax<- lsw
968    movzbl    rINSTbl,%ecx        # ecx<- AA
969    movl      6(rPC),rINST        # rINST<- msw
970    leal      (rFP,%ecx,4),%ecx   # dst addr
971    movl      rINST,4(%ecx)
972    FETCH_INST_OPCODE 5 %edx
973    movl      %eax,(%ecx)
974    ADVANCE_PC 5
975    GOTO_NEXT_R %edx
976
977/* ------------------------------ */
978    .balign 64
979.L_OP_CONST_WIDE_HIGH16: /* 0x19 */
980/* File: x86/OP_CONST_WIDE_HIGH16.S */
981    /* const-wide/high16 vAA, #+BBBB000000000000 */
982    movzwl     2(rPC),%eax                # eax<- 0000BBBB
983    FETCH_INST_OPCODE 2 %edx
984    ADVANCE_PC 2
985    sall       $16,%eax                  # eax<- BBBB0000
986    SET_VREG_WORD %eax rINST 1            # v[AA+1]<- eax
987    xorl       %eax,%eax
988    SET_VREG_WORD %eax rINST 0            # v[AA+0]<- eax
989    GOTO_NEXT_R %edx
990
991/* ------------------------------ */
992    .balign 64
993.L_OP_CONST_STRING: /* 0x1a */
994/* File: x86/OP_CONST_STRING.S */
995
996    /* const/string vAA, String@BBBB */
997    movl      rSELF,%ecx
998    movzwl    2(rPC),%eax              # eax<- BBBB
999    movl      offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex
1000    movl      offDvmDex_pResStrings(%ecx),%ecx # ecx<- dvmDex->pResStrings
1001    movl      (%ecx,%eax,4),%eax       # eax<- rResString[BBBB]
1002    movl      rINST,%ecx
1003    FETCH_INST_OPCODE 2 %edx
1004    testl     %eax,%eax                # resolved yet?
1005    je        .LOP_CONST_STRING_resolve
1006    SET_VREG  %eax %ecx                # vAA<- rResString[BBBB]
1007    ADVANCE_PC 2
1008    GOTO_NEXT_R %edx
1009
1010/* ------------------------------ */
1011    .balign 64
1012.L_OP_CONST_STRING_JUMBO: /* 0x1b */
1013/* File: x86/OP_CONST_STRING_JUMBO.S */
1014
1015    /* const/string vAA, String@BBBBBBBB */
1016    movl      rSELF,%ecx
1017    movl      2(rPC),%eax              # eax<- BBBBBBBB
1018    movl      offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex
1019    movl      offDvmDex_pResStrings(%ecx),%ecx # ecx<- dvmDex->pResStrings
1020    movl      (%ecx,%eax,4),%eax       # eax<- rResString[BBBB]
1021    movl      rINST,%ecx
1022    FETCH_INST_OPCODE 3 %edx
1023    testl     %eax,%eax                # resolved yet?
1024    je        .LOP_CONST_STRING_JUMBO_resolve
1025    SET_VREG  %eax %ecx                # vAA<- rResString[BBBB]
1026    ADVANCE_PC 3
1027    GOTO_NEXT_R %edx
1028
1029/* ------------------------------ */
1030    .balign 64
1031.L_OP_CONST_CLASS: /* 0x1c */
1032/* File: x86/OP_CONST_CLASS.S */
1033
1034    /* const/class vAA, Class@BBBB */
1035    movl      rSELF,%ecx
1036    movzwl    2(rPC),%eax              # eax<- BBBB
1037    movl      offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex
1038    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- dvmDex->pResClasses
1039    movl      (%ecx,%eax,4),%eax       # eax<- rResClasses[BBBB]
1040    movl      rINST,%ecx
1041    FETCH_INST_OPCODE 2 %edx
1042    testl     %eax,%eax                # resolved yet?
1043    je        .LOP_CONST_CLASS_resolve
1044    SET_VREG  %eax %ecx                # vAA<- rResClasses[BBBB]
1045    ADVANCE_PC 2
1046    GOTO_NEXT_R %edx
1047
1048/* ------------------------------ */
1049    .balign 64
1050.L_OP_MONITOR_ENTER: /* 0x1d */
1051/* File: x86/OP_MONITOR_ENTER.S */
1052    /*
1053     * Synchronize on an object.
1054     */
1055    /* monitor-enter vAA */
1056    movl    rSELF,%ecx
1057    GET_VREG_R %eax rINST               # eax<- vAA
1058    FETCH_INST_WORD 1
1059    testl   %eax,%eax                   # null object?
1060    EXPORT_PC                           # need for precise GC
1061    jne     .LOP_MONITOR_ENTER_continue
1062    jmp     common_errNullObject
1063
1064/* ------------------------------ */
1065    .balign 64
1066.L_OP_MONITOR_EXIT: /* 0x1e */
1067/* File: x86/OP_MONITOR_EXIT.S */
1068    /*
1069     * Unlock an object.
1070     *
1071     * Exceptions that occur when unlocking a monitor need to appear as
1072     * if they happened at the following instruction.  See the Dalvik
1073     * instruction spec.
1074     */
1075    /* monitor-exit vAA */
1076    GET_VREG_R %eax rINST
1077    movl    rSELF,%ecx
1078    EXPORT_PC
1079    testl   %eax,%eax                   # null object?
1080    je      .LOP_MONITOR_EXIT_errNullObject   # go if so
1081    movl    %eax,OUT_ARG1(%esp)
1082    movl    %ecx,OUT_ARG0(%esp)
1083    jmp     .LOP_MONITOR_EXIT_continue
1084
1085/* ------------------------------ */
1086    .balign 64
1087.L_OP_CHECK_CAST: /* 0x1f */
1088/* File: x86/OP_CHECK_CAST.S */
1089    /*
1090     * Check to see if a cast from one class to another is allowed.
1091     */
1092    /* check-cast vAA, class@BBBB */
1093    movl      rSELF,%ecx
1094    GET_VREG_R  rINST,rINST             # rINST<- vAA (object)
1095    movzwl    2(rPC),%eax               # eax<- BBBB
1096    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
1097    testl     rINST,rINST               # is oject null?
1098    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
1099    je        .LOP_CHECK_CAST_okay          # null obj, cast always succeeds
1100    movl      (%ecx,%eax,4),%eax        # eax<- resolved class
1101    movl      offObject_clazz(rINST),%ecx # ecx<- obj->clazz
1102    testl     %eax,%eax                 # have we resolved this before?
1103    je        .LOP_CHECK_CAST_resolve       # no, go do it now
1104.LOP_CHECK_CAST_resolved:
1105    cmpl      %eax,%ecx                 # same class (trivial success)?
1106    jne       .LOP_CHECK_CAST_fullcheck     # no, do full check
1107.LOP_CHECK_CAST_okay:
1108    FETCH_INST_OPCODE 2 %edx
1109    ADVANCE_PC 2
1110    GOTO_NEXT_R %edx
1111
1112/* ------------------------------ */
1113    .balign 64
1114.L_OP_INSTANCE_OF: /* 0x20 */
1115/* File: x86/OP_INSTANCE_OF.S */
1116    /*
1117     * Check to see if an object reference is an instance of a class.
1118     *
1119     * Most common situation is a non-null object, being compared against
1120     * an already-resolved class.
1121     */
1122    /* instance-of vA, vB, class@CCCC */
1123    movl    rINST,%eax                # eax<- BA
1124    sarl    $4,%eax                    # eax<- B
1125    GET_VREG_R %eax %eax                # eax<- vB (obj)
1126    movl    rSELF,%ecx
1127    testl   %eax,%eax                   # object null?
1128    movl    offThread_methodClassDex(%ecx),%ecx  # ecx<- pDvmDex
1129    je      .LOP_INSTANCE_OF_store           # null obj, not instance, store it
1130    movzwl  2(rPC),%edx                 # edx<- CCCC
1131    movl    offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
1132    movl    (%ecx,%edx,4),%ecx          # ecx<- resolved class
1133    movl    offObject_clazz(%eax),%eax  # eax<- obj->clazz
1134    testl   %ecx,%ecx                   # have we resolved this before?
1135    je      .LOP_INSTANCE_OF_resolve         # not resolved, do it now
1136.LOP_INSTANCE_OF_resolved:  # eax<- obj->clazz, ecx<- resolved class
1137    cmpl    %eax,%ecx                   # same class (trivial success)?
1138    je      .LOP_INSTANCE_OF_trivial         # yes, trivial finish
1139    jmp     .LOP_INSTANCE_OF_fullcheck       # no, do full check
1140
1141/* ------------------------------ */
1142    .balign 64
1143.L_OP_ARRAY_LENGTH: /* 0x21 */
1144/* File: x86/OP_ARRAY_LENGTH.S */
1145    /*
1146     * Return the length of an array.
1147     */
1148   mov      rINST,%eax                # eax<- BA
1149   sarl     $4,rINST                 # rINST<- B
1150   GET_VREG_R %ecx rINST              # ecx<- vB (object ref)
1151   andb     $0xf,%al                 # eax<- A
1152   testl    %ecx,%ecx                 # is null?
1153   je       common_errNullObject
1154   FETCH_INST_OPCODE 1 %edx
1155   movl     offArrayObject_length(%ecx),%ecx
1156   ADVANCE_PC 1
1157   SET_VREG %ecx %eax
1158   GOTO_NEXT_R %edx
1159
1160/* ------------------------------ */
1161    .balign 64
1162.L_OP_NEW_INSTANCE: /* 0x22 */
1163/* File: x86/OP_NEW_INSTANCE.S */
1164    /*
1165     * Create a new instance of a class.
1166     */
1167    /* new-instance vAA, class@BBBB */
1168    movl      rSELF,%ecx
1169    movzwl    2(rPC),%eax               # eax<- BBBB
1170    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- pDvmDex
1171    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
1172    EXPORT_PC
1173    movl      (%ecx,%eax,4),%ecx        # ecx<- resolved class
1174    testl     %ecx,%ecx                 # resolved?
1175    je        .LOP_NEW_INSTANCE_resolve       # no, go do it
1176.LOP_NEW_INSTANCE_resolved:  # on entry, ecx<- class
1177    cmpb      $CLASS_INITIALIZED,offClassObject_status(%ecx)
1178    je        .LOP_NEW_INSTANCE_initialized
1179    jmp       .LOP_NEW_INSTANCE_needinit
1180
1181/* ------------------------------ */
1182    .balign 64
1183.L_OP_NEW_ARRAY: /* 0x23 */
1184/* File: x86/OP_NEW_ARRAY.S */
1185    /*
1186     * Allocate an array of objects, specified with the array class
1187     * and a count.
1188     *
1189     * The verifier guarantees that this is an array class, so we don't
1190     * check for it here.
1191     */
1192    /* new-array vA, vB, class@CCCC */
1193    movl    rSELF,%ecx
1194    EXPORT_PC
1195    movl    offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
1196    movzwl  2(rPC),%eax                       # eax<- CCCC
1197    movl    offDvmDex_pResClasses(%ecx),%ecx  # ecx<- pDvmDex->pResClasses
1198    movl    (%ecx,%eax,4),%ecx                # ecx<- resolved class
1199    movzbl  rINSTbl,%eax
1200    sarl    $4,%eax                          # eax<- B
1201    GET_VREG_R %eax %eax                      # eax<- vB (array length)
1202    andb    $0xf,rINSTbl                     # rINST<- A
1203    testl   %eax,%eax
1204    js      common_errNegativeArraySize       # bail
1205    testl   %ecx,%ecx                         # already resolved?
1206    jne     .LOP_NEW_ARRAY_finish                # yes, fast path
1207    jmp     .LOP_NEW_ARRAY_resolve               # resolve now
1208
1209/* ------------------------------ */
1210    .balign 64
1211.L_OP_FILLED_NEW_ARRAY: /* 0x24 */
1212/* File: x86/OP_FILLED_NEW_ARRAY.S */
1213    /*
1214     * Create a new array with elements filled from registers.
1215     *
1216     * for: filled-new-array, filled-new-array/range
1217     */
1218    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1219    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1220    movl    rSELF,%eax
1221    movl    offThread_methodClassDex(%eax),%eax # eax<- pDvmDex
1222    movzwl  2(rPC),%ecx                       # ecx<- BBBB
1223    movl    offDvmDex_pResClasses(%eax),%eax  # eax<- pDvmDex->pResClasses
1224    movl    (%eax,%ecx,4),%eax                # eax<- resolved class
1225    EXPORT_PC
1226    testl   %eax,%eax                         # already resolved?
1227    jne     .LOP_FILLED_NEW_ARRAY_continue              # yes, continue
1228    # less frequent path, so we'll redo some work
1229    movl    rSELF,%eax
1230    movl    $0,OUT_ARG2(%esp)                # arg2<- false
1231    movl    %ecx,OUT_ARG1(%esp)               # arg1<- BBBB
1232    movl    offThread_method(%eax),%eax         # eax<- self->method
1233    jmp     .LOP_FILLED_NEW_ARRAY_more
1234
1235/* ------------------------------ */
1236    .balign 64
1237.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
1238/* File: x86/OP_FILLED_NEW_ARRAY_RANGE.S */
1239/* File: x86/OP_FILLED_NEW_ARRAY.S */
1240    /*
1241     * Create a new array with elements filled from registers.
1242     *
1243     * for: filled-new-array, filled-new-array/range
1244     */
1245    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1246    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1247    movl    rSELF,%eax
1248    movl    offThread_methodClassDex(%eax),%eax # eax<- pDvmDex
1249    movzwl  2(rPC),%ecx                       # ecx<- BBBB
1250    movl    offDvmDex_pResClasses(%eax),%eax  # eax<- pDvmDex->pResClasses
1251    movl    (%eax,%ecx,4),%eax                # eax<- resolved class
1252    EXPORT_PC
1253    testl   %eax,%eax                         # already resolved?
1254    jne     .LOP_FILLED_NEW_ARRAY_RANGE_continue              # yes, continue
1255    # less frequent path, so we'll redo some work
1256    movl    rSELF,%eax
1257    movl    $0,OUT_ARG2(%esp)                # arg2<- false
1258    movl    %ecx,OUT_ARG1(%esp)               # arg1<- BBBB
1259    movl    offThread_method(%eax),%eax         # eax<- self->method
1260    jmp     .LOP_FILLED_NEW_ARRAY_RANGE_more
1261
1262
1263/* ------------------------------ */
1264    .balign 64
1265.L_OP_FILL_ARRAY_DATA: /* 0x26 */
1266/* File: x86/OP_FILL_ARRAY_DATA.S */
1267    /* fill-array-data vAA, +BBBBBBBB */
1268    movl    2(rPC),%ecx                # ecx<- BBBBbbbb
1269    leal    (rPC,%ecx,2),%ecx          # ecx<- PC + BBBBbbbb*2
1270    GET_VREG_R %eax rINST
1271    EXPORT_PC
1272    movl    %eax,OUT_ARG0(%esp)
1273    movl    %ecx,OUT_ARG1(%esp)
1274    call    dvmInterpHandleFillArrayData
1275    FETCH_INST_OPCODE 3 %edx
1276    testl   %eax,%eax                   # exception thrown?
1277    je      common_exceptionThrown
1278    ADVANCE_PC 3
1279    GOTO_NEXT_R %edx
1280
1281/* ------------------------------ */
1282    .balign 64
1283.L_OP_THROW: /* 0x27 */
1284/* File: x86/OP_THROW.S */
1285    /*
1286     * Throw an exception object in the current thread.
1287     */
1288    /* throw vAA */
1289    EXPORT_PC
1290    GET_VREG_R %eax rINST              # eax<- exception object
1291    movl     rSELF,%ecx                # ecx<- self
1292    testl    %eax,%eax                 # null object?
1293    je       common_errNullObject
1294    movl     %eax,offThread_exception(%ecx) # thread->exception<- obj
1295    jmp      common_exceptionThrown
1296
1297/* ------------------------------ */
1298    .balign 64
1299.L_OP_GOTO: /* 0x28 */
1300/* File: x86/OP_GOTO.S */
1301    /*
1302     * Unconditional branch, 8-bit offset.
1303     *
1304     * The branch distance is a signed code-unit offset, which we need to
1305     * double to get a byte offset.
1306     */
1307    /* goto +AA */
1308    movsbl  rINSTbl,rINST         # ebx<- ssssssAA
1309    testl   rINST,rINST           # test for <0
1310    js      common_backwardBranch
1311    movl    rINST,%eax
1312    FETCH_INST_INDEXED %eax
1313    ADVANCE_PC_INDEXED %eax
1314    GOTO_NEXT
1315
1316/* ------------------------------ */
1317    .balign 64
1318.L_OP_GOTO_16: /* 0x29 */
1319/* File: x86/OP_GOTO_16.S */
1320    /*
1321     * Unconditional branch, 16-bit offset.
1322     *
1323     * The branch distance is a signed code-unit offset
1324     */
1325    /* goto/16 +AAAA */
1326    movswl  2(rPC),rINST           # rINST<- ssssAAAA
1327    testl   rINST,rINST            # test for <0
1328    js      common_backwardBranch
1329    movl    rINST,%eax
1330    FETCH_INST_INDEXED %eax
1331    ADVANCE_PC_INDEXED %eax
1332    GOTO_NEXT
1333
1334/* ------------------------------ */
1335    .balign 64
1336.L_OP_GOTO_32: /* 0x2a */
1337/* File: x86/OP_GOTO_32.S */
1338    /*
1339     * Unconditional branch, 32-bit offset.
1340     *
1341     * The branch distance is a signed code-unit offset.
1342     *
1343     * Unlike most opcodes, this one is allowed to branch to itself, so
1344     * our "backward branch" test must be "<=0" instead of "<0".
1345     */
1346    /* goto/32 AAAAAAAA */
1347    movl    2(rPC),rINST           # rINST<- AAAAAAAA
1348    cmpl    $0,rINST              # test for <= 0
1349    jle     common_backwardBranch
1350    movl    rINST,%eax
1351    FETCH_INST_INDEXED %eax
1352    ADVANCE_PC_INDEXED %eax
1353    GOTO_NEXT
1354
1355/* ------------------------------ */
1356    .balign 64
1357.L_OP_PACKED_SWITCH: /* 0x2b */
1358/* File: x86/OP_PACKED_SWITCH.S */
1359    /*
1360     * Handle a packed-switch or sparse-switch instruction.  In both cases
1361     * we decode it and hand it off to a helper function.
1362     *
1363     * We don't really expect backward branches in a switch statement, but
1364     * they're perfectly legal, so we check for them here.
1365     *
1366     * for: packed-switch, sparse-switch
1367     */
1368    /* op vAA, +BBBB */
1369    movl    2(rPC),%ecx           # ecx<- BBBBbbbb
1370    GET_VREG_R %eax rINST         # eax<- vAA
1371    leal    (rPC,%ecx,2),%ecx     # ecx<- PC + BBBBbbbb*2
1372    movl    %eax,OUT_ARG1(%esp)   # ARG1<- vAA
1373    movl    %ecx,OUT_ARG0(%esp)   # ARG0<- switchData
1374    call    dvmInterpHandlePackedSwitch
1375    testl   %eax,%eax
1376    movl    %eax,rINST            # set up word offset
1377    jle     common_backwardBranch # check on special actions
1378    ADVANCE_PC_INDEXED rINST
1379    FETCH_INST
1380    GOTO_NEXT
1381
1382/* ------------------------------ */
1383    .balign 64
1384.L_OP_SPARSE_SWITCH: /* 0x2c */
1385/* File: x86/OP_SPARSE_SWITCH.S */
1386/* File: x86/OP_PACKED_SWITCH.S */
1387    /*
1388     * Handle a packed-switch or sparse-switch instruction.  In both cases
1389     * we decode it and hand it off to a helper function.
1390     *
1391     * We don't really expect backward branches in a switch statement, but
1392     * they're perfectly legal, so we check for them here.
1393     *
1394     * for: packed-switch, sparse-switch
1395     */
1396    /* op vAA, +BBBB */
1397    movl    2(rPC),%ecx           # ecx<- BBBBbbbb
1398    GET_VREG_R %eax rINST         # eax<- vAA
1399    leal    (rPC,%ecx,2),%ecx     # ecx<- PC + BBBBbbbb*2
1400    movl    %eax,OUT_ARG1(%esp)   # ARG1<- vAA
1401    movl    %ecx,OUT_ARG0(%esp)   # ARG0<- switchData
1402    call    dvmInterpHandleSparseSwitch
1403    testl   %eax,%eax
1404    movl    %eax,rINST            # set up word offset
1405    jle     common_backwardBranch # check on special actions
1406    ADVANCE_PC_INDEXED rINST
1407    FETCH_INST
1408    GOTO_NEXT
1409
1410
1411/* ------------------------------ */
1412    .balign 64
1413.L_OP_CMPL_FLOAT: /* 0x2d */
1414/* File: x86/OP_CMPL_FLOAT.S */
1415/* File: x86/OP_CMPG_DOUBLE.S */
1416    /* float/double_cmp[gl] vAA, vBB, vCC */
1417    movzbl    3(rPC),%eax             # eax<- CC
1418    movzbl    2(rPC),%ecx             # ecx<- BB
1419    .if 0
1420    fldl     (rFP,%eax,4)
1421    fldl     (rFP,%ecx,4)
1422    .else
1423    flds     (rFP,%eax,4)
1424    flds     (rFP,%ecx,4)
1425    .endif
1426    xorl     %ecx,%ecx
1427    fucompp     # z if equal, p set if NaN, c set if st0 < st1
1428    fnstsw   %ax
1429    sahf
1430    movl      rINST,%eax
1431    FETCH_INST_OPCODE 2 %edx
1432    jp       .LOP_CMPL_FLOAT_isNaN
1433    je       .LOP_CMPL_FLOAT_finish
1434    sbbl     %ecx,%ecx
1435    jb       .LOP_CMPL_FLOAT_finish
1436    incl     %ecx
1437.LOP_CMPL_FLOAT_finish:
1438    SET_VREG %ecx %eax
1439    ADVANCE_PC 2
1440    GOTO_NEXT_R %edx
1441
1442
1443/* ------------------------------ */
1444    .balign 64
1445.L_OP_CMPG_FLOAT: /* 0x2e */
1446/* File: x86/OP_CMPG_FLOAT.S */
1447/* File: x86/OP_CMPG_DOUBLE.S */
1448    /* float/double_cmp[gl] vAA, vBB, vCC */
1449    movzbl    3(rPC),%eax             # eax<- CC
1450    movzbl    2(rPC),%ecx             # ecx<- BB
1451    .if 0
1452    fldl     (rFP,%eax,4)
1453    fldl     (rFP,%ecx,4)
1454    .else
1455    flds     (rFP,%eax,4)
1456    flds     (rFP,%ecx,4)
1457    .endif
1458    xorl     %ecx,%ecx
1459    fucompp     # z if equal, p set if NaN, c set if st0 < st1
1460    fnstsw   %ax
1461    sahf
1462    movl      rINST,%eax
1463    FETCH_INST_OPCODE 2 %edx
1464    jp       .LOP_CMPG_FLOAT_isNaN
1465    je       .LOP_CMPG_FLOAT_finish
1466    sbbl     %ecx,%ecx
1467    jb       .LOP_CMPG_FLOAT_finish
1468    incl     %ecx
1469.LOP_CMPG_FLOAT_finish:
1470    SET_VREG %ecx %eax
1471    ADVANCE_PC 2
1472    GOTO_NEXT_R %edx
1473
1474
1475/* ------------------------------ */
1476    .balign 64
1477.L_OP_CMPL_DOUBLE: /* 0x2f */
1478/* File: x86/OP_CMPL_DOUBLE.S */
1479/* File: x86/OP_CMPG_DOUBLE.S */
1480    /* float/double_cmp[gl] vAA, vBB, vCC */
1481    movzbl    3(rPC),%eax             # eax<- CC
1482    movzbl    2(rPC),%ecx             # ecx<- BB
1483    .if 1
1484    fldl     (rFP,%eax,4)
1485    fldl     (rFP,%ecx,4)
1486    .else
1487    flds     (rFP,%eax,4)
1488    flds     (rFP,%ecx,4)
1489    .endif
1490    xorl     %ecx,%ecx
1491    fucompp     # z if equal, p set if NaN, c set if st0 < st1
1492    fnstsw   %ax
1493    sahf
1494    movl      rINST,%eax
1495    FETCH_INST_OPCODE 2 %edx
1496    jp       .LOP_CMPL_DOUBLE_isNaN
1497    je       .LOP_CMPL_DOUBLE_finish
1498    sbbl     %ecx,%ecx
1499    jb       .LOP_CMPL_DOUBLE_finish
1500    incl     %ecx
1501.LOP_CMPL_DOUBLE_finish:
1502    SET_VREG %ecx %eax
1503    ADVANCE_PC 2
1504    GOTO_NEXT_R %edx
1505
1506
1507/* ------------------------------ */
1508    .balign 64
1509.L_OP_CMPG_DOUBLE: /* 0x30 */
1510/* File: x86/OP_CMPG_DOUBLE.S */
1511    /* float/double_cmp[gl] vAA, vBB, vCC */
1512    movzbl    3(rPC),%eax             # eax<- CC
1513    movzbl    2(rPC),%ecx             # ecx<- BB
1514    .if 1
1515    fldl     (rFP,%eax,4)
1516    fldl     (rFP,%ecx,4)
1517    .else
1518    flds     (rFP,%eax,4)
1519    flds     (rFP,%ecx,4)
1520    .endif
1521    xorl     %ecx,%ecx
1522    fucompp     # z if equal, p set if NaN, c set if st0 < st1
1523    fnstsw   %ax
1524    sahf
1525    movl      rINST,%eax
1526    FETCH_INST_OPCODE 2 %edx
1527    jp       .LOP_CMPG_DOUBLE_isNaN
1528    je       .LOP_CMPG_DOUBLE_finish
1529    sbbl     %ecx,%ecx
1530    jb       .LOP_CMPG_DOUBLE_finish
1531    incl     %ecx
1532.LOP_CMPG_DOUBLE_finish:
1533    SET_VREG %ecx %eax
1534    ADVANCE_PC 2
1535    GOTO_NEXT_R %edx
1536
1537/* ------------------------------ */
1538    .balign 64
1539.L_OP_CMP_LONG: /* 0x31 */
1540/* File: x86/OP_CMP_LONG.S */
1541    /*
1542     * Compare two 64-bit values.  Puts 0, 1, or -1 into the destination
1543     * register based on the results of the comparison.
1544     */
1545    /* cmp-long vAA, vBB, vCC */
1546    movzbl    2(rPC),%ecx              # ecx<- BB
1547    movzbl    3(rPC),%edx              # edx<- CC
1548    GET_VREG_WORD %eax %ecx,1          # eax<- v[BB+1]
1549    GET_VREG_WORD %ecx %ecx 0          # ecx<- v[BB+0]
1550    cmpl      4(rFP,%edx,4),%eax
1551    jl        .LOP_CMP_LONG_smaller
1552    jg        .LOP_CMP_LONG_bigger
1553    sub       (rFP,%edx,4),%ecx
1554    ja        .LOP_CMP_LONG_bigger
1555    jb        .LOP_CMP_LONG_smaller
1556    jmp       .LOP_CMP_LONG_finish
1557
1558/* ------------------------------ */
1559    .balign 64
1560.L_OP_IF_EQ: /* 0x32 */
1561/* File: x86/OP_IF_EQ.S */
1562/* File: x86/bincmp.S */
1563    /*
1564     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1565     * fragment that specifies the *reverse* comparison to perform, e.g.
1566     * for "if-le" you would use "gt".
1567     *
1568     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1569     */
1570    /* if-cmp vA, vB, +CCCC */
1571    movzx    rINSTbl,%ecx          # ecx <- A+
1572    andb     $0xf,%cl             # ecx <- A
1573    GET_VREG_R %eax %ecx           # eax <- vA
1574    sarl     $4,rINST            # rINST<- B
1575    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1576    movswl   2(rPC),rINST          # Get signed branch offset
1577    movl     $2,%eax              # assume not taken
1578    jne   1f
1579    testl    rINST,rINST
1580    js       common_backwardBranch
1581    movl     rINST,%eax
15821:
1583    FETCH_INST_INDEXED %eax
1584    ADVANCE_PC_INDEXED %eax
1585    GOTO_NEXT
1586
1587
1588/* ------------------------------ */
1589    .balign 64
1590.L_OP_IF_NE: /* 0x33 */
1591/* File: x86/OP_IF_NE.S */
1592/* File: x86/bincmp.S */
1593    /*
1594     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1595     * fragment that specifies the *reverse* comparison to perform, e.g.
1596     * for "if-le" you would use "gt".
1597     *
1598     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1599     */
1600    /* if-cmp vA, vB, +CCCC */
1601    movzx    rINSTbl,%ecx          # ecx <- A+
1602    andb     $0xf,%cl             # ecx <- A
1603    GET_VREG_R %eax %ecx           # eax <- vA
1604    sarl     $4,rINST            # rINST<- B
1605    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1606    movswl   2(rPC),rINST          # Get signed branch offset
1607    movl     $2,%eax              # assume not taken
1608    je   1f
1609    testl    rINST,rINST
1610    js       common_backwardBranch
1611    movl     rINST,%eax
16121:
1613    FETCH_INST_INDEXED %eax
1614    ADVANCE_PC_INDEXED %eax
1615    GOTO_NEXT
1616
1617
1618/* ------------------------------ */
1619    .balign 64
1620.L_OP_IF_LT: /* 0x34 */
1621/* File: x86/OP_IF_LT.S */
1622/* File: x86/bincmp.S */
1623    /*
1624     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1625     * fragment that specifies the *reverse* comparison to perform, e.g.
1626     * for "if-le" you would use "gt".
1627     *
1628     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1629     */
1630    /* if-cmp vA, vB, +CCCC */
1631    movzx    rINSTbl,%ecx          # ecx <- A+
1632    andb     $0xf,%cl             # ecx <- A
1633    GET_VREG_R %eax %ecx           # eax <- vA
1634    sarl     $4,rINST            # rINST<- B
1635    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1636    movswl   2(rPC),rINST          # Get signed branch offset
1637    movl     $2,%eax              # assume not taken
1638    jge   1f
1639    testl    rINST,rINST
1640    js       common_backwardBranch
1641    movl     rINST,%eax
16421:
1643    FETCH_INST_INDEXED %eax
1644    ADVANCE_PC_INDEXED %eax
1645    GOTO_NEXT
1646
1647
1648/* ------------------------------ */
1649    .balign 64
1650.L_OP_IF_GE: /* 0x35 */
1651/* File: x86/OP_IF_GE.S */
1652/* File: x86/bincmp.S */
1653    /*
1654     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1655     * fragment that specifies the *reverse* comparison to perform, e.g.
1656     * for "if-le" you would use "gt".
1657     *
1658     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1659     */
1660    /* if-cmp vA, vB, +CCCC */
1661    movzx    rINSTbl,%ecx          # ecx <- A+
1662    andb     $0xf,%cl             # ecx <- A
1663    GET_VREG_R %eax %ecx           # eax <- vA
1664    sarl     $4,rINST            # rINST<- B
1665    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1666    movswl   2(rPC),rINST          # Get signed branch offset
1667    movl     $2,%eax              # assume not taken
1668    jl   1f
1669    testl    rINST,rINST
1670    js       common_backwardBranch
1671    movl     rINST,%eax
16721:
1673    FETCH_INST_INDEXED %eax
1674    ADVANCE_PC_INDEXED %eax
1675    GOTO_NEXT
1676
1677
1678/* ------------------------------ */
1679    .balign 64
1680.L_OP_IF_GT: /* 0x36 */
1681/* File: x86/OP_IF_GT.S */
1682/* File: x86/bincmp.S */
1683    /*
1684     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1685     * fragment that specifies the *reverse* comparison to perform, e.g.
1686     * for "if-le" you would use "gt".
1687     *
1688     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1689     */
1690    /* if-cmp vA, vB, +CCCC */
1691    movzx    rINSTbl,%ecx          # ecx <- A+
1692    andb     $0xf,%cl             # ecx <- A
1693    GET_VREG_R %eax %ecx           # eax <- vA
1694    sarl     $4,rINST            # rINST<- B
1695    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1696    movswl   2(rPC),rINST          # Get signed branch offset
1697    movl     $2,%eax              # assume not taken
1698    jle   1f
1699    testl    rINST,rINST
1700    js       common_backwardBranch
1701    movl     rINST,%eax
17021:
1703    FETCH_INST_INDEXED %eax
1704    ADVANCE_PC_INDEXED %eax
1705    GOTO_NEXT
1706
1707
1708/* ------------------------------ */
1709    .balign 64
1710.L_OP_IF_LE: /* 0x37 */
1711/* File: x86/OP_IF_LE.S */
1712/* File: x86/bincmp.S */
1713    /*
1714     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1715     * fragment that specifies the *reverse* comparison to perform, e.g.
1716     * for "if-le" you would use "gt".
1717     *
1718     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1719     */
1720    /* if-cmp vA, vB, +CCCC */
1721    movzx    rINSTbl,%ecx          # ecx <- A+
1722    andb     $0xf,%cl             # ecx <- A
1723    GET_VREG_R %eax %ecx           # eax <- vA
1724    sarl     $4,rINST            # rINST<- B
1725    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1726    movswl   2(rPC),rINST          # Get signed branch offset
1727    movl     $2,%eax              # assume not taken
1728    jg   1f
1729    testl    rINST,rINST
1730    js       common_backwardBranch
1731    movl     rINST,%eax
17321:
1733    FETCH_INST_INDEXED %eax
1734    ADVANCE_PC_INDEXED %eax
1735    GOTO_NEXT
1736
1737
1738/* ------------------------------ */
1739    .balign 64
1740.L_OP_IF_EQZ: /* 0x38 */
1741/* File: x86/OP_IF_EQZ.S */
1742/* File: x86/zcmp.S */
1743    /*
1744     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1745     * fragment that specifies the *reverse* comparison to perform, e.g.
1746     * for "if-le" you would use "gt".
1747     *
1748     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1749     */
1750    /* if-cmp vAA, +BBBB */
1751    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
1752    movswl   2(rPC),rINST         # fetch signed displacement
1753    movl     $2,%eax             # assume branch not taken
1754    jne   1f
1755    testl    rINST,rINST
1756    js       common_backwardBranch
1757    movl     rINST,%eax
17581:
1759    FETCH_INST_INDEXED %eax
1760    ADVANCE_PC_INDEXED %eax
1761    GOTO_NEXT
1762
1763
1764/* ------------------------------ */
1765    .balign 64
1766.L_OP_IF_NEZ: /* 0x39 */
1767/* File: x86/OP_IF_NEZ.S */
1768/* File: x86/zcmp.S */
1769    /*
1770     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1771     * fragment that specifies the *reverse* comparison to perform, e.g.
1772     * for "if-le" you would use "gt".
1773     *
1774     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1775     */
1776    /* if-cmp vAA, +BBBB */
1777    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
1778    movswl   2(rPC),rINST         # fetch signed displacement
1779    movl     $2,%eax             # assume branch not taken
1780    je   1f
1781    testl    rINST,rINST
1782    js       common_backwardBranch
1783    movl     rINST,%eax
17841:
1785    FETCH_INST_INDEXED %eax
1786    ADVANCE_PC_INDEXED %eax
1787    GOTO_NEXT
1788
1789
1790/* ------------------------------ */
1791    .balign 64
1792.L_OP_IF_LTZ: /* 0x3a */
1793/* File: x86/OP_IF_LTZ.S */
1794/* File: x86/zcmp.S */
1795    /*
1796     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1797     * fragment that specifies the *reverse* comparison to perform, e.g.
1798     * for "if-le" you would use "gt".
1799     *
1800     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1801     */
1802    /* if-cmp vAA, +BBBB */
1803    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
1804    movswl   2(rPC),rINST         # fetch signed displacement
1805    movl     $2,%eax             # assume branch not taken
1806    jge   1f
1807    testl    rINST,rINST
1808    js       common_backwardBranch
1809    movl     rINST,%eax
18101:
1811    FETCH_INST_INDEXED %eax
1812    ADVANCE_PC_INDEXED %eax
1813    GOTO_NEXT
1814
1815
1816/* ------------------------------ */
1817    .balign 64
1818.L_OP_IF_GEZ: /* 0x3b */
1819/* File: x86/OP_IF_GEZ.S */
1820/* File: x86/zcmp.S */
1821    /*
1822     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1823     * fragment that specifies the *reverse* comparison to perform, e.g.
1824     * for "if-le" you would use "gt".
1825     *
1826     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1827     */
1828    /* if-cmp vAA, +BBBB */
1829    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
1830    movswl   2(rPC),rINST         # fetch signed displacement
1831    movl     $2,%eax             # assume branch not taken
1832    jl   1f
1833    testl    rINST,rINST
1834    js       common_backwardBranch
1835    movl     rINST,%eax
18361:
1837    FETCH_INST_INDEXED %eax
1838    ADVANCE_PC_INDEXED %eax
1839    GOTO_NEXT
1840
1841
1842/* ------------------------------ */
1843    .balign 64
1844.L_OP_IF_GTZ: /* 0x3c */
1845/* File: x86/OP_IF_GTZ.S */
1846/* File: x86/zcmp.S */
1847    /*
1848     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1849     * fragment that specifies the *reverse* comparison to perform, e.g.
1850     * for "if-le" you would use "gt".
1851     *
1852     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1853     */
1854    /* if-cmp vAA, +BBBB */
1855    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
1856    movswl   2(rPC),rINST         # fetch signed displacement
1857    movl     $2,%eax             # assume branch not taken
1858    jle   1f
1859    testl    rINST,rINST
1860    js       common_backwardBranch
1861    movl     rINST,%eax
18621:
1863    FETCH_INST_INDEXED %eax
1864    ADVANCE_PC_INDEXED %eax
1865    GOTO_NEXT
1866
1867
1868/* ------------------------------ */
1869    .balign 64
1870.L_OP_IF_LEZ: /* 0x3d */
1871/* File: x86/OP_IF_LEZ.S */
1872/* File: x86/zcmp.S */
1873    /*
1874     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1875     * fragment that specifies the *reverse* comparison to perform, e.g.
1876     * for "if-le" you would use "gt".
1877     *
1878     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1879     */
1880    /* if-cmp vAA, +BBBB */
1881    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
1882    movswl   2(rPC),rINST         # fetch signed displacement
1883    movl     $2,%eax             # assume branch not taken
1884    jg   1f
1885    testl    rINST,rINST
1886    js       common_backwardBranch
1887    movl     rINST,%eax
18881:
1889    FETCH_INST_INDEXED %eax
1890    ADVANCE_PC_INDEXED %eax
1891    GOTO_NEXT
1892
1893
1894/* ------------------------------ */
1895    .balign 64
1896.L_OP_UNUSED_3E: /* 0x3e */
1897/* File: x86/OP_UNUSED_3E.S */
1898/* File: x86/unused.S */
1899    jmp     common_abort
1900
1901
1902/* ------------------------------ */
1903    .balign 64
1904.L_OP_UNUSED_3F: /* 0x3f */
1905/* File: x86/OP_UNUSED_3F.S */
1906/* File: x86/unused.S */
1907    jmp     common_abort
1908
1909
1910/* ------------------------------ */
1911    .balign 64
1912.L_OP_UNUSED_40: /* 0x40 */
1913/* File: x86/OP_UNUSED_40.S */
1914/* File: x86/unused.S */
1915    jmp     common_abort
1916
1917
1918/* ------------------------------ */
1919    .balign 64
1920.L_OP_UNUSED_41: /* 0x41 */
1921/* File: x86/OP_UNUSED_41.S */
1922/* File: x86/unused.S */
1923    jmp     common_abort
1924
1925
1926/* ------------------------------ */
1927    .balign 64
1928.L_OP_UNUSED_42: /* 0x42 */
1929/* File: x86/OP_UNUSED_42.S */
1930/* File: x86/unused.S */
1931    jmp     common_abort
1932
1933
1934/* ------------------------------ */
1935    .balign 64
1936.L_OP_UNUSED_43: /* 0x43 */
1937/* File: x86/OP_UNUSED_43.S */
1938/* File: x86/unused.S */
1939    jmp     common_abort
1940
1941
1942/* ------------------------------ */
1943    .balign 64
1944.L_OP_AGET: /* 0x44 */
1945/* File: x86/OP_AGET.S */
1946    /*
1947     * Array get, 32 bits or less.  vAA <- vBB[vCC].
1948     *
1949     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
1950     */
1951    /* op vAA, vBB, vCC */
1952    movzbl    2(rPC),%eax               # eax<- BB
1953    movzbl    3(rPC),%ecx               # ecx<- CC
1954    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
1955    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
1956    testl     %eax,%eax                 # null array object?
1957    je        common_errNullObject      # bail if so
1958    cmpl      offArrayObject_length(%eax),%ecx
1959    jae       common_errArrayIndex      # index >= length, bail.  Expects
1960                                        #    arrayObj in eax
1961                                        #    index in ecx
1962    movl     offArrayObject_contents(%eax,%ecx,4),%eax
1963.LOP_AGET_finish:
1964    FETCH_INST_OPCODE 2 %edx
1965    SET_VREG  %eax rINST
1966    ADVANCE_PC 2
1967    GOTO_NEXT_R %edx
1968
1969/* ------------------------------ */
1970    .balign 64
1971.L_OP_AGET_WIDE: /* 0x45 */
1972/* File: x86/OP_AGET_WIDE.S */
1973    /*
1974     * Array get, 64 bits.  vAA <- vBB[vCC].
1975     *
1976     */
1977    /* op vAA, vBB, vCC */
1978    movzbl    2(rPC),%eax               # eax<- BB
1979    movzbl    3(rPC),%ecx               # ecx<- CC
1980    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
1981    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
1982    testl     %eax,%eax                 # null array object?
1983    je        common_errNullObject      # bail if so
1984    cmpl      offArrayObject_length(%eax),%ecx
1985    jb        .LOP_AGET_WIDE_finish        # index < length, OK
1986    jmp       common_errArrayIndex      # index >= length, bail.  Expects
1987                                        #    arrayObj in eax
1988                                        #    index in ecx
1989
1990/* ------------------------------ */
1991    .balign 64
1992.L_OP_AGET_OBJECT: /* 0x46 */
1993/* File: x86/OP_AGET_OBJECT.S */
1994/* File: x86/OP_AGET.S */
1995    /*
1996     * Array get, 32 bits or less.  vAA <- vBB[vCC].
1997     *
1998     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
1999     */
2000    /* op vAA, vBB, vCC */
2001    movzbl    2(rPC),%eax               # eax<- BB
2002    movzbl    3(rPC),%ecx               # ecx<- CC
2003    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2004    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2005    testl     %eax,%eax                 # null array object?
2006    je        common_errNullObject      # bail if so
2007    cmpl      offArrayObject_length(%eax),%ecx
2008    jae       common_errArrayIndex      # index >= length, bail.  Expects
2009                                        #    arrayObj in eax
2010                                        #    index in ecx
2011    movl     offArrayObject_contents(%eax,%ecx,4),%eax
2012.LOP_AGET_OBJECT_finish:
2013    FETCH_INST_OPCODE 2 %edx
2014    SET_VREG  %eax rINST
2015    ADVANCE_PC 2
2016    GOTO_NEXT_R %edx
2017
2018
2019/* ------------------------------ */
2020    .balign 64
2021.L_OP_AGET_BOOLEAN: /* 0x47 */
2022/* File: x86/OP_AGET_BOOLEAN.S */
2023/* File: x86/OP_AGET.S */
2024    /*
2025     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2026     *
2027     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2028     */
2029    /* op vAA, vBB, vCC */
2030    movzbl    2(rPC),%eax               # eax<- BB
2031    movzbl    3(rPC),%ecx               # ecx<- CC
2032    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2033    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2034    testl     %eax,%eax                 # null array object?
2035    je        common_errNullObject      # bail if so
2036    cmpl      offArrayObject_length(%eax),%ecx
2037    jae       common_errArrayIndex      # index >= length, bail.  Expects
2038                                        #    arrayObj in eax
2039                                        #    index in ecx
2040    movzbl     offArrayObject_contents(%eax,%ecx,1),%eax
2041.LOP_AGET_BOOLEAN_finish:
2042    FETCH_INST_OPCODE 2 %edx
2043    SET_VREG  %eax rINST
2044    ADVANCE_PC 2
2045    GOTO_NEXT_R %edx
2046
2047
2048/* ------------------------------ */
2049    .balign 64
2050.L_OP_AGET_BYTE: /* 0x48 */
2051/* File: x86/OP_AGET_BYTE.S */
2052/* File: x86/OP_AGET.S */
2053    /*
2054     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2055     *
2056     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2057     */
2058    /* op vAA, vBB, vCC */
2059    movzbl    2(rPC),%eax               # eax<- BB
2060    movzbl    3(rPC),%ecx               # ecx<- CC
2061    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2062    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2063    testl     %eax,%eax                 # null array object?
2064    je        common_errNullObject      # bail if so
2065    cmpl      offArrayObject_length(%eax),%ecx
2066    jae       common_errArrayIndex      # index >= length, bail.  Expects
2067                                        #    arrayObj in eax
2068                                        #    index in ecx
2069    movsbl     offArrayObject_contents(%eax,%ecx,1),%eax
2070.LOP_AGET_BYTE_finish:
2071    FETCH_INST_OPCODE 2 %edx
2072    SET_VREG  %eax rINST
2073    ADVANCE_PC 2
2074    GOTO_NEXT_R %edx
2075
2076
2077/* ------------------------------ */
2078    .balign 64
2079.L_OP_AGET_CHAR: /* 0x49 */
2080/* File: x86/OP_AGET_CHAR.S */
2081/* File: x86/OP_AGET.S */
2082    /*
2083     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2084     *
2085     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2086     */
2087    /* op vAA, vBB, vCC */
2088    movzbl    2(rPC),%eax               # eax<- BB
2089    movzbl    3(rPC),%ecx               # ecx<- CC
2090    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2091    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2092    testl     %eax,%eax                 # null array object?
2093    je        common_errNullObject      # bail if so
2094    cmpl      offArrayObject_length(%eax),%ecx
2095    jae       common_errArrayIndex      # index >= length, bail.  Expects
2096                                        #    arrayObj in eax
2097                                        #    index in ecx
2098    movzwl     offArrayObject_contents(%eax,%ecx,2),%eax
2099.LOP_AGET_CHAR_finish:
2100    FETCH_INST_OPCODE 2 %edx
2101    SET_VREG  %eax rINST
2102    ADVANCE_PC 2
2103    GOTO_NEXT_R %edx
2104
2105
2106/* ------------------------------ */
2107    .balign 64
2108.L_OP_AGET_SHORT: /* 0x4a */
2109/* File: x86/OP_AGET_SHORT.S */
2110/* File: x86/OP_AGET.S */
2111    /*
2112     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2113     *
2114     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2115     */
2116    /* op vAA, vBB, vCC */
2117    movzbl    2(rPC),%eax               # eax<- BB
2118    movzbl    3(rPC),%ecx               # ecx<- CC
2119    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2120    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2121    testl     %eax,%eax                 # null array object?
2122    je        common_errNullObject      # bail if so
2123    cmpl      offArrayObject_length(%eax),%ecx
2124    jae       common_errArrayIndex      # index >= length, bail.  Expects
2125                                        #    arrayObj in eax
2126                                        #    index in ecx
2127    movswl     offArrayObject_contents(%eax,%ecx,2),%eax
2128.LOP_AGET_SHORT_finish:
2129    FETCH_INST_OPCODE 2 %edx
2130    SET_VREG  %eax rINST
2131    ADVANCE_PC 2
2132    GOTO_NEXT_R %edx
2133
2134
2135/* ------------------------------ */
2136    .balign 64
2137.L_OP_APUT: /* 0x4b */
2138/* File: x86/OP_APUT.S */
2139    /*
2140     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2141     *
2142     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2143     */
2144    /* op vAA, vBB, vCC */
2145    movzbl    2(rPC),%eax               # eax<- BB
2146    movzbl    3(rPC),%ecx               # ecx<- CC
2147    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2148    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2149    testl     %eax,%eax                 # null array object?
2150    je        common_errNullObject      # bail if so
2151    cmpl      offArrayObject_length(%eax),%ecx
2152    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2153                                        #   arrayObj in eax
2154                                        #   index in ecx
2155    leal      offArrayObject_contents(%eax,%ecx,4),%eax
2156.LOP_APUT_finish:
2157    GET_VREG_R  %ecx rINST
2158    FETCH_INST_OPCODE 2 %edx
2159    movl     %ecx,(%eax)
2160    ADVANCE_PC 2
2161    GOTO_NEXT_R %edx
2162
2163/* ------------------------------ */
2164    .balign 64
2165.L_OP_APUT_WIDE: /* 0x4c */
2166/* File: x86/OP_APUT_WIDE.S */
2167    /*
2168     * Array put, 64 bits.  vBB[vCC]<-vAA.
2169     *
2170     */
2171    /* op vAA, vBB, vCC */
2172    movzbl    2(rPC),%eax               # eax<- BB
2173    movzbl    3(rPC),%ecx               # ecx<- CC
2174    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2175    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2176    testl     %eax,%eax                 # null array object?
2177    je        common_errNullObject      # bail if so
2178    cmpl      offArrayObject_length(%eax),%ecx
2179    jb        .LOP_APUT_WIDE_finish        # index < length, OK
2180    jmp       common_errArrayIndex      # index >= length, bail.  Expects:
2181                                        #   arrayObj in eax
2182                                        #   index in ecx
2183
2184/* ------------------------------ */
2185    .balign 64
2186.L_OP_APUT_OBJECT: /* 0x4d */
2187/* File: x86/OP_APUT_OBJECT.S */
2188    /*
2189     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2190     *
2191     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2192     */
2193    /* op vAA, vBB, vCC */
2194    movzbl    2(rPC),%eax               # eax<- BB
2195    movzbl    3(rPC),%ecx               # ecx<- CC
2196    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2197    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2198    GET_VREG_R  rINST rINST             # rINST<- vAA
2199    testl     %eax,%eax                 # null array object?
2200    je        common_errNullObject      # bail if so
2201    cmpl      offArrayObject_length(%eax),%ecx
2202    jb        .LOP_APUT_OBJECT_continue
2203    jmp       common_errArrayIndex      # index >= length, bail.  Expects
2204                                        #    arrayObj in eax
2205                                        #    index in ecx
2206
2207/* ------------------------------ */
2208    .balign 64
2209.L_OP_APUT_BOOLEAN: /* 0x4e */
2210/* File: x86/OP_APUT_BOOLEAN.S */
2211/* File: x86/OP_APUT.S */
2212    /*
2213     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2214     *
2215     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2216     */
2217    /* op vAA, vBB, vCC */
2218    movzbl    2(rPC),%eax               # eax<- BB
2219    movzbl    3(rPC),%ecx               # ecx<- CC
2220    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2221    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2222    testl     %eax,%eax                 # null array object?
2223    je        common_errNullObject      # bail if so
2224    cmpl      offArrayObject_length(%eax),%ecx
2225    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2226                                        #   arrayObj in eax
2227                                        #   index in ecx
2228    leal      offArrayObject_contents(%eax,%ecx,1),%eax
2229.LOP_APUT_BOOLEAN_finish:
2230    GET_VREG_R  %ecx rINST
2231    FETCH_INST_OPCODE 2 %edx
2232    movb     %cl,(%eax)
2233    ADVANCE_PC 2
2234    GOTO_NEXT_R %edx
2235
2236
2237/* ------------------------------ */
2238    .balign 64
2239.L_OP_APUT_BYTE: /* 0x4f */
2240/* File: x86/OP_APUT_BYTE.S */
2241/* File: x86/OP_APUT.S */
2242    /*
2243     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2244     *
2245     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2246     */
2247    /* op vAA, vBB, vCC */
2248    movzbl    2(rPC),%eax               # eax<- BB
2249    movzbl    3(rPC),%ecx               # ecx<- CC
2250    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2251    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2252    testl     %eax,%eax                 # null array object?
2253    je        common_errNullObject      # bail if so
2254    cmpl      offArrayObject_length(%eax),%ecx
2255    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2256                                        #   arrayObj in eax
2257                                        #   index in ecx
2258    leal      offArrayObject_contents(%eax,%ecx,1),%eax
2259.LOP_APUT_BYTE_finish:
2260    GET_VREG_R  %ecx rINST
2261    FETCH_INST_OPCODE 2 %edx
2262    movb     %cl,(%eax)
2263    ADVANCE_PC 2
2264    GOTO_NEXT_R %edx
2265
2266
2267/* ------------------------------ */
2268    .balign 64
2269.L_OP_APUT_CHAR: /* 0x50 */
2270/* File: x86/OP_APUT_CHAR.S */
2271/* File: x86/OP_APUT.S */
2272    /*
2273     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2274     *
2275     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2276     */
2277    /* op vAA, vBB, vCC */
2278    movzbl    2(rPC),%eax               # eax<- BB
2279    movzbl    3(rPC),%ecx               # ecx<- CC
2280    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2281    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2282    testl     %eax,%eax                 # null array object?
2283    je        common_errNullObject      # bail if so
2284    cmpl      offArrayObject_length(%eax),%ecx
2285    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2286                                        #   arrayObj in eax
2287                                        #   index in ecx
2288    leal      offArrayObject_contents(%eax,%ecx,2),%eax
2289.LOP_APUT_CHAR_finish:
2290    GET_VREG_R  %ecx rINST
2291    FETCH_INST_OPCODE 2 %edx
2292    movw     %cx,(%eax)
2293    ADVANCE_PC 2
2294    GOTO_NEXT_R %edx
2295
2296
2297/* ------------------------------ */
2298    .balign 64
2299.L_OP_APUT_SHORT: /* 0x51 */
2300/* File: x86/OP_APUT_SHORT.S */
2301/* File: x86/OP_APUT.S */
2302    /*
2303     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2304     *
2305     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2306     */
2307    /* op vAA, vBB, vCC */
2308    movzbl    2(rPC),%eax               # eax<- BB
2309    movzbl    3(rPC),%ecx               # ecx<- CC
2310    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2311    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2312    testl     %eax,%eax                 # null array object?
2313    je        common_errNullObject      # bail if so
2314    cmpl      offArrayObject_length(%eax),%ecx
2315    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2316                                        #   arrayObj in eax
2317                                        #   index in ecx
2318    leal      offArrayObject_contents(%eax,%ecx,2),%eax
2319.LOP_APUT_SHORT_finish:
2320    GET_VREG_R  %ecx rINST
2321    FETCH_INST_OPCODE 2 %edx
2322    movw     %cx,(%eax)
2323    ADVANCE_PC 2
2324    GOTO_NEXT_R %edx
2325
2326
2327/* ------------------------------ */
2328    .balign 64
2329.L_OP_IGET: /* 0x52 */
2330/* File: x86/OP_IGET.S */
2331    /*
2332     * General 32-bit instance field get.
2333     *
2334     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2335     */
2336    /* op vA, vB, field@CCCC */
2337    movl    rSELF,%ecx
2338    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
2339    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
2340    movzbl  rINSTbl,%ecx                        # ecx<- BA
2341    sarl    $4,%ecx                            # ecx<- B
2342    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2343    andb    $0xf,rINSTbl                       # rINST<- A
2344    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2345    movl    (%eax,%edx,4),%eax                  # resolved entry
2346    testl   %eax,%eax                           # is resolved entry null?
2347    jne     .LOP_IGET_finish                  # no, already resolved
2348    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
2349    movl    rSELF,%edx
2350    jmp     .LOP_IGET_resolve
2351
2352/* ------------------------------ */
2353    .balign 64
2354.L_OP_IGET_WIDE: /* 0x53 */
2355/* File: x86/OP_IGET_WIDE.S */
2356    /*
2357     * 64-bit instance field get.
2358     *
2359     */
2360    /* op vA, vB, field@CCCC */
2361    movl    rSELF,%ecx
2362    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
2363    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
2364    movzbl  rINSTbl,%ecx                        # ecx<- BA
2365    sarl    $4,%ecx                            # ecx<- B
2366    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2367    andb    $0xf,rINSTbl                       # rINST<- A
2368    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2369    movl    (%eax,%edx,4),%eax                  # resolved entry
2370    testl   %eax,%eax                           # is resolved entry null?
2371    jne     .LOP_IGET_WIDE_finish                  # no, already resolved
2372    movl    %edx,OUT_ARG1(%esp)                 # for dvmResolveInstField
2373    movl    rSELF,%edx
2374    jmp     .LOP_IGET_WIDE_resolve
2375
2376/* ------------------------------ */
2377    .balign 64
2378.L_OP_IGET_OBJECT: /* 0x54 */
2379/* File: x86/OP_IGET_OBJECT.S */
2380/* File: x86/OP_IGET.S */
2381    /*
2382     * General 32-bit instance field get.
2383     *
2384     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2385     */
2386    /* op vA, vB, field@CCCC */
2387    movl    rSELF,%ecx
2388    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
2389    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
2390    movzbl  rINSTbl,%ecx                        # ecx<- BA
2391    sarl    $4,%ecx                            # ecx<- B
2392    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2393    andb    $0xf,rINSTbl                       # rINST<- A
2394    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2395    movl    (%eax,%edx,4),%eax                  # resolved entry
2396    testl   %eax,%eax                           # is resolved entry null?
2397    jne     .LOP_IGET_OBJECT_finish                  # no, already resolved
2398    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
2399    movl    rSELF,%edx
2400    jmp     .LOP_IGET_OBJECT_resolve
2401
2402
2403/* ------------------------------ */
2404    .balign 64
2405.L_OP_IGET_BOOLEAN: /* 0x55 */
2406/* File: x86/OP_IGET_BOOLEAN.S */
2407/* File: x86/OP_IGET.S */
2408    /*
2409     * General 32-bit instance field get.
2410     *
2411     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2412     */
2413    /* op vA, vB, field@CCCC */
2414    movl    rSELF,%ecx
2415    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
2416    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
2417    movzbl  rINSTbl,%ecx                        # ecx<- BA
2418    sarl    $4,%ecx                            # ecx<- B
2419    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2420    andb    $0xf,rINSTbl                       # rINST<- A
2421    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2422    movl    (%eax,%edx,4),%eax                  # resolved entry
2423    testl   %eax,%eax                           # is resolved entry null?
2424    jne     .LOP_IGET_BOOLEAN_finish                  # no, already resolved
2425    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
2426    movl    rSELF,%edx
2427    jmp     .LOP_IGET_BOOLEAN_resolve
2428
2429
2430/* ------------------------------ */
2431    .balign 64
2432.L_OP_IGET_BYTE: /* 0x56 */
2433/* File: x86/OP_IGET_BYTE.S */
2434/* File: x86/OP_IGET.S */
2435    /*
2436     * General 32-bit instance field get.
2437     *
2438     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2439     */
2440    /* op vA, vB, field@CCCC */
2441    movl    rSELF,%ecx
2442    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
2443    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
2444    movzbl  rINSTbl,%ecx                        # ecx<- BA
2445    sarl    $4,%ecx                            # ecx<- B
2446    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2447    andb    $0xf,rINSTbl                       # rINST<- A
2448    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2449    movl    (%eax,%edx,4),%eax                  # resolved entry
2450    testl   %eax,%eax                           # is resolved entry null?
2451    jne     .LOP_IGET_BYTE_finish                  # no, already resolved
2452    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
2453    movl    rSELF,%edx
2454    jmp     .LOP_IGET_BYTE_resolve
2455
2456
2457/* ------------------------------ */
2458    .balign 64
2459.L_OP_IGET_CHAR: /* 0x57 */
2460/* File: x86/OP_IGET_CHAR.S */
2461/* File: x86/OP_IGET.S */
2462    /*
2463     * General 32-bit instance field get.
2464     *
2465     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2466     */
2467    /* op vA, vB, field@CCCC */
2468    movl    rSELF,%ecx
2469    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
2470    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
2471    movzbl  rINSTbl,%ecx                        # ecx<- BA
2472    sarl    $4,%ecx                            # ecx<- B
2473    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2474    andb    $0xf,rINSTbl                       # rINST<- A
2475    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2476    movl    (%eax,%edx,4),%eax                  # resolved entry
2477    testl   %eax,%eax                           # is resolved entry null?
2478    jne     .LOP_IGET_CHAR_finish                  # no, already resolved
2479    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
2480    movl    rSELF,%edx
2481    jmp     .LOP_IGET_CHAR_resolve
2482
2483
2484/* ------------------------------ */
2485    .balign 64
2486.L_OP_IGET_SHORT: /* 0x58 */
2487/* File: x86/OP_IGET_SHORT.S */
2488/* File: x86/OP_IGET.S */
2489    /*
2490     * General 32-bit instance field get.
2491     *
2492     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2493     */
2494    /* op vA, vB, field@CCCC */
2495    movl    rSELF,%ecx
2496    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
2497    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
2498    movzbl  rINSTbl,%ecx                        # ecx<- BA
2499    sarl    $4,%ecx                            # ecx<- B
2500    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2501    andb    $0xf,rINSTbl                       # rINST<- A
2502    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2503    movl    (%eax,%edx,4),%eax                  # resolved entry
2504    testl   %eax,%eax                           # is resolved entry null?
2505    jne     .LOP_IGET_SHORT_finish                  # no, already resolved
2506    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
2507    movl    rSELF,%edx
2508    jmp     .LOP_IGET_SHORT_resolve
2509
2510
2511/* ------------------------------ */
2512    .balign 64
2513.L_OP_IPUT: /* 0x59 */
2514/* File: x86/OP_IPUT.S */
2515
2516    /*
2517     * General 32-bit instance field put.
2518     *
2519     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
2520     */
2521    /* op vA, vB, field@CCCC */
2522    movl    rSELF,%ecx
2523    movzwl  2(rPC),%edx                         # %edx<- 0000CCCC
2524    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
2525    movzbl  rINSTbl,%ecx                        # ecx<- BA
2526    sarl    $4,%ecx                            # ecx<- B
2527    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2528    andb    $0xf,rINSTbl                       # rINST<- A
2529    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2530    movl    (%eax,%edx,4),%eax                  # resolved entry
2531    testl   %eax,%eax                           # is resolved entry null?
2532    jne     .LOP_IPUT_finish                  # no, already resolved
2533    movl    %edx,OUT_ARG1(%esp)
2534    movl    rSELF,%edx
2535    jmp     .LOP_IPUT_resolve
2536
2537/* ------------------------------ */
2538    .balign 64
2539.L_OP_IPUT_WIDE: /* 0x5a */
2540/* File: x86/OP_IPUT_WIDE.S */
2541    /*
2542     * 64-bit instance field put.
2543     *
2544     */
2545    /* op vA, vB, field@CCCC */
2546    movl    rSELF,%ecx
2547    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
2548    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
2549    movzbl  rINSTbl,%ecx                        # ecx<- BA
2550    sarl    $4,%ecx                            # ecx<- B
2551    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2552    andb    $0xf,rINSTbl                       # rINST<- A
2553    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2554    movl    (%eax,%edx,4),%eax                  # resolved entry
2555    testl   %eax,%eax                           # is resolved entry null?
2556    jne     .LOP_IPUT_WIDE_finish                  # no, already resolved
2557    movl    %edx,OUT_ARG1(%esp)
2558    movl    rSELF,%edx
2559    jmp     .LOP_IPUT_WIDE_resolve
2560
2561/* ------------------------------ */
2562    .balign 64
2563.L_OP_IPUT_OBJECT: /* 0x5b */
2564/* File: x86/OP_IPUT_OBJECT.S */
2565    /*
2566     * Object field put.
2567     *
2568     * for: iput-object
2569     */
2570    /* op vA, vB, field@CCCC */
2571    movl    rSELF,%ecx
2572    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
2573    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
2574    movzbl  rINSTbl,%ecx                        # ecx<- BA
2575    sarl    $4,%ecx                            # ecx<- B
2576    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2577    andb    $0xf,rINSTbl                       # rINST<- A
2578    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2579    movl    (%eax,%edx,4),%eax                  # resolved entry
2580    testl   %eax,%eax                           # is resolved entry null?
2581    jne     .LOP_IPUT_OBJECT_finish                  # no, already resolved
2582    movl    %edx,OUT_ARG1(%esp)
2583    movl    rSELF,%edx
2584    jmp     .LOP_IPUT_OBJECT_resolve
2585
2586/* ------------------------------ */
2587    .balign 64
2588.L_OP_IPUT_BOOLEAN: /* 0x5c */
2589/* File: x86/OP_IPUT_BOOLEAN.S */
2590/* File: x86/OP_IPUT.S */
2591
2592    /*
2593     * General 32-bit instance field put.
2594     *
2595     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
2596     */
2597    /* op vA, vB, field@CCCC */
2598    movl    rSELF,%ecx
2599    movzwl  2(rPC),%edx                         # %edx<- 0000CCCC
2600    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
2601    movzbl  rINSTbl,%ecx                        # ecx<- BA
2602    sarl    $4,%ecx                            # ecx<- B
2603    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2604    andb    $0xf,rINSTbl                       # rINST<- A
2605    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2606    movl    (%eax,%edx,4),%eax                  # resolved entry
2607    testl   %eax,%eax                           # is resolved entry null?
2608    jne     .LOP_IPUT_BOOLEAN_finish                  # no, already resolved
2609    movl    %edx,OUT_ARG1(%esp)
2610    movl    rSELF,%edx
2611    jmp     .LOP_IPUT_BOOLEAN_resolve
2612
2613
2614/* ------------------------------ */
2615    .balign 64
2616.L_OP_IPUT_BYTE: /* 0x5d */
2617/* File: x86/OP_IPUT_BYTE.S */
2618/* File: x86/OP_IPUT.S */
2619
2620    /*
2621     * General 32-bit instance field put.
2622     *
2623     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
2624     */
2625    /* op vA, vB, field@CCCC */
2626    movl    rSELF,%ecx
2627    movzwl  2(rPC),%edx                         # %edx<- 0000CCCC
2628    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
2629    movzbl  rINSTbl,%ecx                        # ecx<- BA
2630    sarl    $4,%ecx                            # ecx<- B
2631    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2632    andb    $0xf,rINSTbl                       # rINST<- A
2633    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2634    movl    (%eax,%edx,4),%eax                  # resolved entry
2635    testl   %eax,%eax                           # is resolved entry null?
2636    jne     .LOP_IPUT_BYTE_finish                  # no, already resolved
2637    movl    %edx,OUT_ARG1(%esp)
2638    movl    rSELF,%edx
2639    jmp     .LOP_IPUT_BYTE_resolve
2640
2641
2642/* ------------------------------ */
2643    .balign 64
2644.L_OP_IPUT_CHAR: /* 0x5e */
2645/* File: x86/OP_IPUT_CHAR.S */
2646/* File: x86/OP_IPUT.S */
2647
2648    /*
2649     * General 32-bit instance field put.
2650     *
2651     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
2652     */
2653    /* op vA, vB, field@CCCC */
2654    movl    rSELF,%ecx
2655    movzwl  2(rPC),%edx                         # %edx<- 0000CCCC
2656    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
2657    movzbl  rINSTbl,%ecx                        # ecx<- BA
2658    sarl    $4,%ecx                            # ecx<- B
2659    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2660    andb    $0xf,rINSTbl                       # rINST<- A
2661    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2662    movl    (%eax,%edx,4),%eax                  # resolved entry
2663    testl   %eax,%eax                           # is resolved entry null?
2664    jne     .LOP_IPUT_CHAR_finish                  # no, already resolved
2665    movl    %edx,OUT_ARG1(%esp)
2666    movl    rSELF,%edx
2667    jmp     .LOP_IPUT_CHAR_resolve
2668
2669
2670/* ------------------------------ */
2671    .balign 64
2672.L_OP_IPUT_SHORT: /* 0x5f */
2673/* File: x86/OP_IPUT_SHORT.S */
2674/* File: x86/OP_IPUT.S */
2675
2676    /*
2677     * General 32-bit instance field put.
2678     *
2679     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
2680     */
2681    /* op vA, vB, field@CCCC */
2682    movl    rSELF,%ecx
2683    movzwl  2(rPC),%edx                         # %edx<- 0000CCCC
2684    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
2685    movzbl  rINSTbl,%ecx                        # ecx<- BA
2686    sarl    $4,%ecx                            # ecx<- B
2687    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2688    andb    $0xf,rINSTbl                       # rINST<- A
2689    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2690    movl    (%eax,%edx,4),%eax                  # resolved entry
2691    testl   %eax,%eax                           # is resolved entry null?
2692    jne     .LOP_IPUT_SHORT_finish                  # no, already resolved
2693    movl    %edx,OUT_ARG1(%esp)
2694    movl    rSELF,%edx
2695    jmp     .LOP_IPUT_SHORT_resolve
2696
2697
2698/* ------------------------------ */
2699    .balign 64
2700.L_OP_SGET: /* 0x60 */
2701/* File: x86/OP_SGET.S */
2702    /*
2703     * General 32-bit SGET handler.
2704     *
2705     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2706     */
2707    /* op vAA, field@BBBB */
2708    movl      rSELF,%ecx
2709    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2710    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2711    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2712    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2713    testl     %eax,%eax                          # resolved entry null?
2714    je        .LOP_SGET_resolve                # if not, make it so
2715.LOP_SGET_finish:     # field ptr in eax
2716    movl      offStaticField_value(%eax),%eax
2717    FETCH_INST_OPCODE 2 %edx
2718    ADVANCE_PC 2
2719    SET_VREG %eax rINST
2720    GOTO_NEXT_R %edx
2721
2722/* ------------------------------ */
2723    .balign 64
2724.L_OP_SGET_WIDE: /* 0x61 */
2725/* File: x86/OP_SGET_WIDE.S */
2726    /*
2727     * 64-bit SGET handler.
2728     *
2729     */
2730    /* sget-wide vAA, field@BBBB */
2731    movl      rSELF,%ecx
2732    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2733    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2734    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2735    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2736    testl     %eax,%eax                          # resolved entry null?
2737    je        .LOP_SGET_WIDE_resolve                # if not, make it so
2738.LOP_SGET_WIDE_finish:     # field ptr in eax
2739    movl      offStaticField_value(%eax),%ecx    # ecx<- lsw
2740    movl      4+offStaticField_value(%eax),%eax  # eax<- msw
2741    FETCH_INST_OPCODE 2 %edx
2742    ADVANCE_PC 2
2743    SET_VREG_WORD %ecx rINST 0
2744    SET_VREG_WORD %eax rINST 1
2745    GOTO_NEXT_R %edx
2746
2747/* ------------------------------ */
2748    .balign 64
2749.L_OP_SGET_OBJECT: /* 0x62 */
2750/* File: x86/OP_SGET_OBJECT.S */
2751/* File: x86/OP_SGET.S */
2752    /*
2753     * General 32-bit SGET handler.
2754     *
2755     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2756     */
2757    /* op vAA, field@BBBB */
2758    movl      rSELF,%ecx
2759    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2760    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2761    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2762    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2763    testl     %eax,%eax                          # resolved entry null?
2764    je        .LOP_SGET_OBJECT_resolve                # if not, make it so
2765.LOP_SGET_OBJECT_finish:     # field ptr in eax
2766    movl      offStaticField_value(%eax),%eax
2767    FETCH_INST_OPCODE 2 %edx
2768    ADVANCE_PC 2
2769    SET_VREG %eax rINST
2770    GOTO_NEXT_R %edx
2771
2772
2773/* ------------------------------ */
2774    .balign 64
2775.L_OP_SGET_BOOLEAN: /* 0x63 */
2776/* File: x86/OP_SGET_BOOLEAN.S */
2777/* File: x86/OP_SGET.S */
2778    /*
2779     * General 32-bit SGET handler.
2780     *
2781     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2782     */
2783    /* op vAA, field@BBBB */
2784    movl      rSELF,%ecx
2785    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2786    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2787    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2788    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2789    testl     %eax,%eax                          # resolved entry null?
2790    je        .LOP_SGET_BOOLEAN_resolve                # if not, make it so
2791.LOP_SGET_BOOLEAN_finish:     # field ptr in eax
2792    movl      offStaticField_value(%eax),%eax
2793    FETCH_INST_OPCODE 2 %edx
2794    ADVANCE_PC 2
2795    SET_VREG %eax rINST
2796    GOTO_NEXT_R %edx
2797
2798
2799/* ------------------------------ */
2800    .balign 64
2801.L_OP_SGET_BYTE: /* 0x64 */
2802/* File: x86/OP_SGET_BYTE.S */
2803/* File: x86/OP_SGET.S */
2804    /*
2805     * General 32-bit SGET handler.
2806     *
2807     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2808     */
2809    /* op vAA, field@BBBB */
2810    movl      rSELF,%ecx
2811    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2812    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2813    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2814    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2815    testl     %eax,%eax                          # resolved entry null?
2816    je        .LOP_SGET_BYTE_resolve                # if not, make it so
2817.LOP_SGET_BYTE_finish:     # field ptr in eax
2818    movl      offStaticField_value(%eax),%eax
2819    FETCH_INST_OPCODE 2 %edx
2820    ADVANCE_PC 2
2821    SET_VREG %eax rINST
2822    GOTO_NEXT_R %edx
2823
2824
2825/* ------------------------------ */
2826    .balign 64
2827.L_OP_SGET_CHAR: /* 0x65 */
2828/* File: x86/OP_SGET_CHAR.S */
2829/* File: x86/OP_SGET.S */
2830    /*
2831     * General 32-bit SGET handler.
2832     *
2833     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2834     */
2835    /* op vAA, field@BBBB */
2836    movl      rSELF,%ecx
2837    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2838    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2839    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2840    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2841    testl     %eax,%eax                          # resolved entry null?
2842    je        .LOP_SGET_CHAR_resolve                # if not, make it so
2843.LOP_SGET_CHAR_finish:     # field ptr in eax
2844    movl      offStaticField_value(%eax),%eax
2845    FETCH_INST_OPCODE 2 %edx
2846    ADVANCE_PC 2
2847    SET_VREG %eax rINST
2848    GOTO_NEXT_R %edx
2849
2850
2851/* ------------------------------ */
2852    .balign 64
2853.L_OP_SGET_SHORT: /* 0x66 */
2854/* File: x86/OP_SGET_SHORT.S */
2855/* File: x86/OP_SGET.S */
2856    /*
2857     * General 32-bit SGET handler.
2858     *
2859     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2860     */
2861    /* op vAA, field@BBBB */
2862    movl      rSELF,%ecx
2863    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2864    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2865    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2866    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2867    testl     %eax,%eax                          # resolved entry null?
2868    je        .LOP_SGET_SHORT_resolve                # if not, make it so
2869.LOP_SGET_SHORT_finish:     # field ptr in eax
2870    movl      offStaticField_value(%eax),%eax
2871    FETCH_INST_OPCODE 2 %edx
2872    ADVANCE_PC 2
2873    SET_VREG %eax rINST
2874    GOTO_NEXT_R %edx
2875
2876
2877/* ------------------------------ */
2878    .balign 64
2879.L_OP_SPUT: /* 0x67 */
2880/* File: x86/OP_SPUT.S */
2881    /*
2882     * General 32-bit SPUT handler.
2883     *
2884     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2885     */
2886    /* op vAA, field@BBBB */
2887    movl      rSELF,%ecx
2888    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2889    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2890    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2891    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2892    testl     %eax,%eax                          # resolved entry null?
2893    je        .LOP_SPUT_resolve                # if not, make it so
2894.LOP_SPUT_finish:     # field ptr in eax
2895    GET_VREG_R  %ecx rINST
2896    FETCH_INST_OPCODE 2 %edx
2897    ADVANCE_PC 2
2898    movl      %ecx,offStaticField_value(%eax)
2899    GOTO_NEXT_R %edx
2900
2901/* ------------------------------ */
2902    .balign 64
2903.L_OP_SPUT_WIDE: /* 0x68 */
2904/* File: x86/OP_SPUT_WIDE.S */
2905    /*
2906     * General 32-bit SPUT handler.
2907     *
2908     * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
2909     */
2910    /* op vAA, field@BBBB */
2911    movl      rSELF,%ecx
2912    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2913    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2914    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2915    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2916    testl     %eax,%eax                          # resolved entry null?
2917    je        .LOP_SPUT_WIDE_resolve                # if not, make it so
2918.LOP_SPUT_WIDE_finish:     # field ptr in eax
2919    GET_VREG_WORD %ecx rINST 0                  # rINST<- lsw
2920    GET_VREG_WORD rINST rINST 1                 # ecx<- msw
2921    FETCH_INST_OPCODE 2 %edx
2922    ADVANCE_PC 2
2923    movl      %ecx,offStaticField_value(%eax)
2924    movl      rINST,4+offStaticField_value(%eax)
2925    GOTO_NEXT_R %edx
2926
2927/* ------------------------------ */
2928    .balign 64
2929.L_OP_SPUT_OBJECT: /* 0x69 */
2930/* File: x86/OP_SPUT_OBJECT.S */
2931    /*
2932     * SPUT object handler.
2933     */
2934    /* op vAA, field@BBBB */
2935    movl      rSELF,%ecx
2936    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2937    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2938    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2939    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField
2940    testl     %eax,%eax                          # resolved entry null?
2941    je        .LOP_SPUT_OBJECT_resolve                # if not, make it so
2942.LOP_SPUT_OBJECT_finish:                              # field ptr in eax
2943    movzbl    rINSTbl,%ecx                       # ecx<- AA
2944    GET_VREG_R  %ecx %ecx
2945    jmp       .LOP_SPUT_OBJECT_continue
2946
2947/* ------------------------------ */
2948    .balign 64
2949.L_OP_SPUT_BOOLEAN: /* 0x6a */
2950/* File: x86/OP_SPUT_BOOLEAN.S */
2951/* File: x86/OP_SPUT.S */
2952    /*
2953     * General 32-bit SPUT handler.
2954     *
2955     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2956     */
2957    /* op vAA, field@BBBB */
2958    movl      rSELF,%ecx
2959    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2960    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2961    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2962    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2963    testl     %eax,%eax                          # resolved entry null?
2964    je        .LOP_SPUT_BOOLEAN_resolve                # if not, make it so
2965.LOP_SPUT_BOOLEAN_finish:     # field ptr in eax
2966    GET_VREG_R  %ecx rINST
2967    FETCH_INST_OPCODE 2 %edx
2968    ADVANCE_PC 2
2969    movl      %ecx,offStaticField_value(%eax)
2970    GOTO_NEXT_R %edx
2971
2972
2973/* ------------------------------ */
2974    .balign 64
2975.L_OP_SPUT_BYTE: /* 0x6b */
2976/* File: x86/OP_SPUT_BYTE.S */
2977/* File: x86/OP_SPUT.S */
2978    /*
2979     * General 32-bit SPUT handler.
2980     *
2981     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2982     */
2983    /* op vAA, field@BBBB */
2984    movl      rSELF,%ecx
2985    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
2986    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
2987    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
2988    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
2989    testl     %eax,%eax                          # resolved entry null?
2990    je        .LOP_SPUT_BYTE_resolve                # if not, make it so
2991.LOP_SPUT_BYTE_finish:     # field ptr in eax
2992    GET_VREG_R  %ecx rINST
2993    FETCH_INST_OPCODE 2 %edx
2994    ADVANCE_PC 2
2995    movl      %ecx,offStaticField_value(%eax)
2996    GOTO_NEXT_R %edx
2997
2998
2999/* ------------------------------ */
3000    .balign 64
3001.L_OP_SPUT_CHAR: /* 0x6c */
3002/* File: x86/OP_SPUT_CHAR.S */
3003/* File: x86/OP_SPUT.S */
3004    /*
3005     * General 32-bit SPUT handler.
3006     *
3007     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3008     */
3009    /* op vAA, field@BBBB */
3010    movl      rSELF,%ecx
3011    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3012    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3013    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3014    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3015    testl     %eax,%eax                          # resolved entry null?
3016    je        .LOP_SPUT_CHAR_resolve                # if not, make it so
3017.LOP_SPUT_CHAR_finish:     # field ptr in eax
3018    GET_VREG_R  %ecx rINST
3019    FETCH_INST_OPCODE 2 %edx
3020    ADVANCE_PC 2
3021    movl      %ecx,offStaticField_value(%eax)
3022    GOTO_NEXT_R %edx
3023
3024
3025/* ------------------------------ */
3026    .balign 64
3027.L_OP_SPUT_SHORT: /* 0x6d */
3028/* File: x86/OP_SPUT_SHORT.S */
3029/* File: x86/OP_SPUT.S */
3030    /*
3031     * General 32-bit SPUT handler.
3032     *
3033     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3034     */
3035    /* op vAA, field@BBBB */
3036    movl      rSELF,%ecx
3037    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3038    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3039    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3040    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3041    testl     %eax,%eax                          # resolved entry null?
3042    je        .LOP_SPUT_SHORT_resolve                # if not, make it so
3043.LOP_SPUT_SHORT_finish:     # field ptr in eax
3044    GET_VREG_R  %ecx rINST
3045    FETCH_INST_OPCODE 2 %edx
3046    ADVANCE_PC 2
3047    movl      %ecx,offStaticField_value(%eax)
3048    GOTO_NEXT_R %edx
3049
3050
3051/* ------------------------------ */
3052    .balign 64
3053.L_OP_INVOKE_VIRTUAL: /* 0x6e */
3054/* File: x86/OP_INVOKE_VIRTUAL.S */
3055
3056    /*
3057     * Handle a virtual method call.
3058     *
3059     * for: invoke-virtual, invoke-virtual/range
3060     */
3061    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3062    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3063    movl      rSELF,%eax
3064    movzwl    2(rPC),%ecx                 # ecx<- BBBB
3065    movl      offThread_methodClassDex(%eax),%eax  # eax<- pDvmDex
3066    EXPORT_PC
3067    movl      offDvmDex_pResMethods(%eax),%eax   # eax<- pDvmDex->pResMethods
3068    movl      (%eax,%ecx,4),%eax          # eax<- resolved baseMethod
3069    testl     %eax,%eax                   # already resolved?
3070    jne       .LOP_INVOKE_VIRTUAL_continue        # yes, continue
3071    movl      rSELF,%eax
3072    movl      %ecx,OUT_ARG1(%esp)         # arg1<- ref
3073    movl      offThread_method(%eax),%eax   # eax<- self->method
3074    jmp       .LOP_INVOKE_VIRTUAL_more
3075
3076/* ------------------------------ */
3077    .balign 64
3078.L_OP_INVOKE_SUPER: /* 0x6f */
3079/* File: x86/OP_INVOKE_SUPER.S */
3080    /*
3081     * Handle a "super" method call.
3082     *
3083     * for: invoke-super, invoke-super/range
3084     */
3085    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3086    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3087    movl      rSELF,rINST
3088    movzwl    2(rPC),%eax               # eax<- BBBB
3089    movl      offThread_methodClassDex(rINST),%ecx # ecx<- pDvmDex
3090    EXPORT_PC
3091    movl      offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods
3092    movl      (%ecx,%eax,4),%ecx        # ecx<- resolved baseMethod
3093    movl      offThread_method(rINST),%eax # eax<- method
3094    movzwl    4(rPC),rINST              # rINST<- GFED or CCCC
3095    .if       (!0)
3096    andl      $0xf,rINST               # rINST<- D (or stays CCCC)
3097    .endif
3098    GET_VREG_R  rINST rINST             # rINST<- "this" ptr
3099    testl     rINST,rINST               # null "this"?
3100    je        common_errNullObject      # yes, throw
3101    movl      offMethod_clazz(%eax),%eax # eax<- method->clazz
3102    testl     %ecx,%ecx                 # already resolved?
3103    jne       .LOP_INVOKE_SUPER_continue      # yes - go on
3104    jmp       .LOP_INVOKE_SUPER_resolve
3105
3106/* ------------------------------ */
3107    .balign 64
3108.L_OP_INVOKE_DIRECT: /* 0x70 */
3109/* File: x86/OP_INVOKE_DIRECT.S */
3110    /*
3111     * Handle a direct method call.
3112     *
3113     * (We could defer the "is 'this' pointer null" test to the common
3114     * method invocation code, and use a flag to indicate that static
3115     * calls don't count.  If we do this as part of copying the arguments
3116     * out we could avoiding loading the first arg twice.)
3117     *
3118     * for: invoke-direct, invoke-direct/range
3119     */
3120    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3121    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3122    movl      rSELF,%ecx
3123    movzwl    2(rPC),%eax              # eax<- BBBB
3124    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
3125    EXPORT_PC
3126    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
3127    movzwl    4(rPC),%edx              # edx<- GFED or CCCC
3128    movl      (%ecx,%eax,4),%eax       # eax<- resolved methodToCall
3129    .if       (!0)
3130    andl      $0xf,%edx               # edx<- D (or stays CCCC)
3131    .endif
3132    testl     %eax,%eax                # already resolved?
3133    GET_VREG_R  %ecx %edx              # ecx<- "this" ptr
3134    je        .LOP_INVOKE_DIRECT_resolve      # not resolved, do it now
3135.LOP_INVOKE_DIRECT_finish:
3136    testl     %ecx,%ecx                # null "this"?
3137    jne       common_invokeMethodNoRange  # no, continue on
3138    jmp       common_errNullObject
3139
3140/* ------------------------------ */
3141    .balign 64
3142.L_OP_INVOKE_STATIC: /* 0x71 */
3143/* File: x86/OP_INVOKE_STATIC.S */
3144    /*
3145     * Handle a static method call.
3146     *
3147     * for: invoke-static, invoke-static/range
3148     */
3149    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3150    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3151    movl      rSELF,%ecx
3152    movzwl    2(rPC),%eax               # eax<- BBBB
3153    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
3154    EXPORT_PC
3155    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
3156    movl      (%ecx,%eax,4),%eax        # eax<- resolved methodToCall
3157    testl     %eax,%eax
3158    jne       common_invokeMethodNoRange
3159    movl      rSELF,%ecx
3160    movl      offThread_method(%ecx),%ecx # ecx<- self->method
3161    movzwl    2(rPC),%eax
3162    movl      offMethod_clazz(%ecx),%ecx# ecx<- method->clazz
3163    movl      %eax,OUT_ARG1(%esp)       # arg1<- BBBB
3164    movl      %ecx,OUT_ARG0(%esp)       # arg0<- clazz
3165    jmp       .LOP_INVOKE_STATIC_continue
3166
3167/* ------------------------------ */
3168    .balign 64
3169.L_OP_INVOKE_INTERFACE: /* 0x72 */
3170/* File: x86/OP_INVOKE_INTERFACE.S */
3171    /*
3172     * Handle an interface method call.
3173     *
3174     * for: invoke-interface, invoke-interface/range
3175     */
3176    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3177    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3178    movzwl     4(rPC),%eax              # eax<- FEDC or CCCC
3179    movl       rSELF,%ecx
3180    .if        (!0)
3181    andl       $0xf,%eax               # eax<- C (or stays CCCC)
3182    .endif
3183    GET_VREG_R   %eax %eax              # eax<- "this"
3184    EXPORT_PC
3185    testl      %eax,%eax                # null this?
3186    je         common_errNullObject     # yes, fail
3187    movl       offObject_clazz(%eax),%eax# eax<- thisPtr->clazz
3188    movl       %eax,OUT_ARG0(%esp)                 # arg0<- class
3189    movl       offThread_methodClassDex(%ecx),%eax   # eax<- methodClassDex
3190    movl       offThread_method(%ecx),%ecx           # ecx<- method
3191    movl       %eax,OUT_ARG3(%esp)                 # arg3<- dex
3192    movzwl     2(rPC),%eax                         # eax<- BBBB
3193    movl       %ecx,OUT_ARG2(%esp)                 # arg2<- method
3194    movl       %eax,OUT_ARG1(%esp)                 # arg1<- BBBB
3195    jmp        .LOP_INVOKE_INTERFACE_continue
3196
3197/* ------------------------------ */
3198    .balign 64
3199.L_OP_UNUSED_73: /* 0x73 */
3200/* File: x86/OP_UNUSED_73.S */
3201/* File: x86/unused.S */
3202    jmp     common_abort
3203
3204
3205/* ------------------------------ */
3206    .balign 64
3207.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
3208/* File: x86/OP_INVOKE_VIRTUAL_RANGE.S */
3209/* File: x86/OP_INVOKE_VIRTUAL.S */
3210
3211    /*
3212     * Handle a virtual method call.
3213     *
3214     * for: invoke-virtual, invoke-virtual/range
3215     */
3216    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3217    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3218    movl      rSELF,%eax
3219    movzwl    2(rPC),%ecx                 # ecx<- BBBB
3220    movl      offThread_methodClassDex(%eax),%eax  # eax<- pDvmDex
3221    EXPORT_PC
3222    movl      offDvmDex_pResMethods(%eax),%eax   # eax<- pDvmDex->pResMethods
3223    movl      (%eax,%ecx,4),%eax          # eax<- resolved baseMethod
3224    testl     %eax,%eax                   # already resolved?
3225    jne       .LOP_INVOKE_VIRTUAL_RANGE_continue        # yes, continue
3226    movl      rSELF,%eax
3227    movl      %ecx,OUT_ARG1(%esp)         # arg1<- ref
3228    movl      offThread_method(%eax),%eax   # eax<- self->method
3229    jmp       .LOP_INVOKE_VIRTUAL_RANGE_more
3230
3231
3232/* ------------------------------ */
3233    .balign 64
3234.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */
3235/* File: x86/OP_INVOKE_SUPER_RANGE.S */
3236/* File: x86/OP_INVOKE_SUPER.S */
3237    /*
3238     * Handle a "super" method call.
3239     *
3240     * for: invoke-super, invoke-super/range
3241     */
3242    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3243    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3244    movl      rSELF,rINST
3245    movzwl    2(rPC),%eax               # eax<- BBBB
3246    movl      offThread_methodClassDex(rINST),%ecx # ecx<- pDvmDex
3247    EXPORT_PC
3248    movl      offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods
3249    movl      (%ecx,%eax,4),%ecx        # ecx<- resolved baseMethod
3250    movl      offThread_method(rINST),%eax # eax<- method
3251    movzwl    4(rPC),rINST              # rINST<- GFED or CCCC
3252    .if       (!1)
3253    andl      $0xf,rINST               # rINST<- D (or stays CCCC)
3254    .endif
3255    GET_VREG_R  rINST rINST             # rINST<- "this" ptr
3256    testl     rINST,rINST               # null "this"?
3257    je        common_errNullObject      # yes, throw
3258    movl      offMethod_clazz(%eax),%eax # eax<- method->clazz
3259    testl     %ecx,%ecx                 # already resolved?
3260    jne       .LOP_INVOKE_SUPER_RANGE_continue      # yes - go on
3261    jmp       .LOP_INVOKE_SUPER_RANGE_resolve
3262
3263
3264/* ------------------------------ */
3265    .balign 64
3266.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
3267/* File: x86/OP_INVOKE_DIRECT_RANGE.S */
3268/* File: x86/OP_INVOKE_DIRECT.S */
3269    /*
3270     * Handle a direct method call.
3271     *
3272     * (We could defer the "is 'this' pointer null" test to the common
3273     * method invocation code, and use a flag to indicate that static
3274     * calls don't count.  If we do this as part of copying the arguments
3275     * out we could avoiding loading the first arg twice.)
3276     *
3277     * for: invoke-direct, invoke-direct/range
3278     */
3279    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3280    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3281    movl      rSELF,%ecx
3282    movzwl    2(rPC),%eax              # eax<- BBBB
3283    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
3284    EXPORT_PC
3285    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
3286    movzwl    4(rPC),%edx              # edx<- GFED or CCCC
3287    movl      (%ecx,%eax,4),%eax       # eax<- resolved methodToCall
3288    .if       (!1)
3289    andl      $0xf,%edx               # edx<- D (or stays CCCC)
3290    .endif
3291    testl     %eax,%eax                # already resolved?
3292    GET_VREG_R  %ecx %edx              # ecx<- "this" ptr
3293    je        .LOP_INVOKE_DIRECT_RANGE_resolve      # not resolved, do it now
3294.LOP_INVOKE_DIRECT_RANGE_finish:
3295    testl     %ecx,%ecx                # null "this"?
3296    jne       common_invokeMethodRange  # no, continue on
3297    jmp       common_errNullObject
3298
3299
3300/* ------------------------------ */
3301    .balign 64
3302.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */
3303/* File: x86/OP_INVOKE_STATIC_RANGE.S */
3304/* File: x86/OP_INVOKE_STATIC.S */
3305    /*
3306     * Handle a static method call.
3307     *
3308     * for: invoke-static, invoke-static/range
3309     */
3310    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3311    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3312    movl      rSELF,%ecx
3313    movzwl    2(rPC),%eax               # eax<- BBBB
3314    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
3315    EXPORT_PC
3316    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
3317    movl      (%ecx,%eax,4),%eax        # eax<- resolved methodToCall
3318    testl     %eax,%eax
3319    jne       common_invokeMethodRange
3320    movl      rSELF,%ecx
3321    movl      offThread_method(%ecx),%ecx # ecx<- self->method
3322    movzwl    2(rPC),%eax
3323    movl      offMethod_clazz(%ecx),%ecx# ecx<- method->clazz
3324    movl      %eax,OUT_ARG1(%esp)       # arg1<- BBBB
3325    movl      %ecx,OUT_ARG0(%esp)       # arg0<- clazz
3326    jmp       .LOP_INVOKE_STATIC_RANGE_continue
3327
3328
3329/* ------------------------------ */
3330    .balign 64
3331.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
3332/* File: x86/OP_INVOKE_INTERFACE_RANGE.S */
3333/* File: x86/OP_INVOKE_INTERFACE.S */
3334    /*
3335     * Handle an interface method call.
3336     *
3337     * for: invoke-interface, invoke-interface/range
3338     */
3339    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3340    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3341    movzwl     4(rPC),%eax              # eax<- FEDC or CCCC
3342    movl       rSELF,%ecx
3343    .if        (!1)
3344    andl       $0xf,%eax               # eax<- C (or stays CCCC)
3345    .endif
3346    GET_VREG_R   %eax %eax              # eax<- "this"
3347    EXPORT_PC
3348    testl      %eax,%eax                # null this?
3349    je         common_errNullObject     # yes, fail
3350    movl       offObject_clazz(%eax),%eax# eax<- thisPtr->clazz
3351    movl       %eax,OUT_ARG0(%esp)                 # arg0<- class
3352    movl       offThread_methodClassDex(%ecx),%eax   # eax<- methodClassDex
3353    movl       offThread_method(%ecx),%ecx           # ecx<- method
3354    movl       %eax,OUT_ARG3(%esp)                 # arg3<- dex
3355    movzwl     2(rPC),%eax                         # eax<- BBBB
3356    movl       %ecx,OUT_ARG2(%esp)                 # arg2<- method
3357    movl       %eax,OUT_ARG1(%esp)                 # arg1<- BBBB
3358    jmp        .LOP_INVOKE_INTERFACE_RANGE_continue
3359
3360
3361/* ------------------------------ */
3362    .balign 64
3363.L_OP_UNUSED_79: /* 0x79 */
3364/* File: x86/OP_UNUSED_79.S */
3365/* File: x86/unused.S */
3366    jmp     common_abort
3367
3368
3369/* ------------------------------ */
3370    .balign 64
3371.L_OP_UNUSED_7A: /* 0x7a */
3372/* File: x86/OP_UNUSED_7A.S */
3373/* File: x86/unused.S */
3374    jmp     common_abort
3375
3376
3377/* ------------------------------ */
3378    .balign 64
3379.L_OP_NEG_INT: /* 0x7b */
3380/* File: x86/OP_NEG_INT.S */
3381/* File: x86/unop.S */
3382    /*
3383     * Generic 32-bit unary operation.  Provide an "instr" line that
3384     * specifies an instruction that performs "result = op eax".
3385     */
3386    /* unop vA, vB */
3387    movzbl   rINSTbl,%ecx           # ecx<- A+
3388    sarl     $4,rINST             # rINST<- B
3389    GET_VREG_R %eax rINST           # eax<- vB
3390    andb     $0xf,%cl              # ecx<- A
3391    FETCH_INST_OPCODE 1 %edx
3392    ADVANCE_PC 1
3393
3394
3395    negl %eax
3396    SET_VREG %eax %ecx
3397    GOTO_NEXT_R %edx
3398
3399
3400/* ------------------------------ */
3401    .balign 64
3402.L_OP_NOT_INT: /* 0x7c */
3403/* File: x86/OP_NOT_INT.S */
3404/* File: x86/unop.S */
3405    /*
3406     * Generic 32-bit unary operation.  Provide an "instr" line that
3407     * specifies an instruction that performs "result = op eax".
3408     */
3409    /* unop vA, vB */
3410    movzbl   rINSTbl,%ecx           # ecx<- A+
3411    sarl     $4,rINST             # rINST<- B
3412    GET_VREG_R %eax rINST           # eax<- vB
3413    andb     $0xf,%cl              # ecx<- A
3414    FETCH_INST_OPCODE 1 %edx
3415    ADVANCE_PC 1
3416
3417
3418    notl %eax
3419    SET_VREG %eax %ecx
3420    GOTO_NEXT_R %edx
3421
3422
3423/* ------------------------------ */
3424    .balign 64
3425.L_OP_NEG_LONG: /* 0x7d */
3426/* File: x86/OP_NEG_LONG.S */
3427    /* unop vA, vB */
3428    movzbl    rINSTbl,%ecx        # ecx<- BA
3429    sarl      $4,%ecx            # ecx<- B
3430    andb      $0xf,rINSTbl       # rINST<- A
3431    GET_VREG_WORD %eax %ecx 0     # eax<- v[B+0]
3432    GET_VREG_WORD %ecx %ecx 1     # ecx<- v[B+1]
3433    negl      %eax
3434    adcl      $0,%ecx
3435    negl      %ecx
3436    FETCH_INST_OPCODE 1 %edx
3437    SET_VREG_WORD %eax rINST 0    # v[A+0]<- eax
3438    SET_VREG_WORD %ecx rINST 1    # v[A+1]<- ecx
3439    ADVANCE_PC 1
3440    GOTO_NEXT_R %edx
3441
3442/* ------------------------------ */
3443    .balign 64
3444.L_OP_NOT_LONG: /* 0x7e */
3445/* File: x86/OP_NOT_LONG.S */
3446    /* unop vA, vB */
3447    movzbl    rINSTbl,%ecx       # ecx<- BA
3448    sarl      $4,%ecx           # ecx<- B
3449    andb      $0xf,rINSTbl      # rINST<- A
3450    GET_VREG_WORD %eax %ecx 0    # eax<- v[B+0]
3451    GET_VREG_WORD %ecx %ecx 1    # ecx<- v[B+1]
3452    FETCH_INST_OPCODE 1 %edx
3453    notl      %eax
3454    notl      %ecx
3455    SET_VREG_WORD %eax rINST 0   # v[A+0]<- eax
3456    SET_VREG_WORD %ecx rINST 1   # v[A+1]<- ecx
3457    ADVANCE_PC 1
3458    GOTO_NEXT_R %edx
3459
3460/* ------------------------------ */
3461    .balign 64
3462.L_OP_NEG_FLOAT: /* 0x7f */
3463/* File: x86/OP_NEG_FLOAT.S */
3464/* File: x86/fpcvt.S */
3465    /*
3466     * Generic 32-bit FP conversion operation.
3467     */
3468    /* unop vA, vB */
3469    movzbl   rINSTbl,%ecx       # ecx<- A+
3470    sarl     $4,rINST         # rINST<- B
3471    flds    (rFP,rINST,4)      # %st0<- vB
3472    andb     $0xf,%cl          # ecx<- A
3473    FETCH_INST_OPCODE 1 %edx
3474    ADVANCE_PC 1
3475    fchs
3476    fstps  (rFP,%ecx,4)        # vA<- %st0
3477    GOTO_NEXT_R %edx
3478
3479
3480/* ------------------------------ */
3481    .balign 64
3482.L_OP_NEG_DOUBLE: /* 0x80 */
3483/* File: x86/OP_NEG_DOUBLE.S */
3484/* File: x86/fpcvt.S */
3485    /*
3486     * Generic 32-bit FP conversion operation.
3487     */
3488    /* unop vA, vB */
3489    movzbl   rINSTbl,%ecx       # ecx<- A+
3490    sarl     $4,rINST         # rINST<- B
3491    fldl    (rFP,rINST,4)      # %st0<- vB
3492    andb     $0xf,%cl          # ecx<- A
3493    FETCH_INST_OPCODE 1 %edx
3494    ADVANCE_PC 1
3495    fchs
3496    fstpl  (rFP,%ecx,4)        # vA<- %st0
3497    GOTO_NEXT_R %edx
3498
3499
3500/* ------------------------------ */
3501    .balign 64
3502.L_OP_INT_TO_LONG: /* 0x81 */
3503/* File: x86/OP_INT_TO_LONG.S */
3504    /* int to long vA, vB */
3505    movzbl  rINSTbl,%eax                # eax<- +A
3506    sarl    $4,%eax                    # eax<- B
3507    GET_VREG_R %eax %eax                # eax<- vB
3508    andb    $0xf,rINSTbl               # rINST<- A
3509    cltd                                # edx:eax<- sssssssBBBBBBBB
3510    SET_VREG_WORD %edx rINST 1          # v[A+1]<- edx/rPC
3511    FETCH_INST_OPCODE 1 %edx
3512    SET_VREG_WORD %eax rINST 0          # v[A+0]<- %eax
3513    ADVANCE_PC 1
3514    GOTO_NEXT_R %edx
3515
3516/* ------------------------------ */
3517    .balign 64
3518.L_OP_INT_TO_FLOAT: /* 0x82 */
3519/* File: x86/OP_INT_TO_FLOAT.S */
3520/* File: x86/fpcvt.S */
3521    /*
3522     * Generic 32-bit FP conversion operation.
3523     */
3524    /* unop vA, vB */
3525    movzbl   rINSTbl,%ecx       # ecx<- A+
3526    sarl     $4,rINST         # rINST<- B
3527    fildl    (rFP,rINST,4)      # %st0<- vB
3528    andb     $0xf,%cl          # ecx<- A
3529    FETCH_INST_OPCODE 1 %edx
3530    ADVANCE_PC 1
3531
3532    fstps  (rFP,%ecx,4)        # vA<- %st0
3533    GOTO_NEXT_R %edx
3534
3535
3536/* ------------------------------ */
3537    .balign 64
3538.L_OP_INT_TO_DOUBLE: /* 0x83 */
3539/* File: x86/OP_INT_TO_DOUBLE.S */
3540/* File: x86/fpcvt.S */
3541    /*
3542     * Generic 32-bit FP conversion operation.
3543     */
3544    /* unop vA, vB */
3545    movzbl   rINSTbl,%ecx       # ecx<- A+
3546    sarl     $4,rINST         # rINST<- B
3547    fildl    (rFP,rINST,4)      # %st0<- vB
3548    andb     $0xf,%cl          # ecx<- A
3549    FETCH_INST_OPCODE 1 %edx
3550    ADVANCE_PC 1
3551
3552    fstpl  (rFP,%ecx,4)        # vA<- %st0
3553    GOTO_NEXT_R %edx
3554
3555
3556/* ------------------------------ */
3557    .balign 64
3558.L_OP_LONG_TO_INT: /* 0x84 */
3559/* File: x86/OP_LONG_TO_INT.S */
3560/* we ignore the high word, making this equivalent to a 32-bit reg move */
3561/* File: x86/OP_MOVE.S */
3562    /* for move, move-object, long-to-int */
3563    /* op vA, vB */
3564    movzbl rINSTbl,%eax          # eax<- BA
3565    andb   $0xf,%al             # eax<- A
3566    shrl   $4,rINST            # rINST<- B
3567    GET_VREG_R %ecx rINST
3568    FETCH_INST_OPCODE 1 %edx
3569    ADVANCE_PC 1
3570    SET_VREG %ecx %eax           # fp[A]<-fp[B]
3571    GOTO_NEXT_R %edx
3572
3573
3574/* ------------------------------ */
3575    .balign 64
3576.L_OP_LONG_TO_FLOAT: /* 0x85 */
3577/* File: x86/OP_LONG_TO_FLOAT.S */
3578/* File: x86/fpcvt.S */
3579    /*
3580     * Generic 32-bit FP conversion operation.
3581     */
3582    /* unop vA, vB */
3583    movzbl   rINSTbl,%ecx       # ecx<- A+
3584    sarl     $4,rINST         # rINST<- B
3585    fildll    (rFP,rINST,4)      # %st0<- vB
3586    andb     $0xf,%cl          # ecx<- A
3587    FETCH_INST_OPCODE 1 %edx
3588    ADVANCE_PC 1
3589
3590    fstps  (rFP,%ecx,4)        # vA<- %st0
3591    GOTO_NEXT_R %edx
3592
3593
3594/* ------------------------------ */
3595    .balign 64
3596.L_OP_LONG_TO_DOUBLE: /* 0x86 */
3597/* File: x86/OP_LONG_TO_DOUBLE.S */
3598/* File: x86/fpcvt.S */
3599    /*
3600     * Generic 32-bit FP conversion operation.
3601     */
3602    /* unop vA, vB */
3603    movzbl   rINSTbl,%ecx       # ecx<- A+
3604    sarl     $4,rINST         # rINST<- B
3605    fildll    (rFP,rINST,4)      # %st0<- vB
3606    andb     $0xf,%cl          # ecx<- A
3607    FETCH_INST_OPCODE 1 %edx
3608    ADVANCE_PC 1
3609
3610    fstpl  (rFP,%ecx,4)        # vA<- %st0
3611    GOTO_NEXT_R %edx
3612
3613
3614/* ------------------------------ */
3615    .balign 64
3616.L_OP_FLOAT_TO_INT: /* 0x87 */
3617/* File: x86/OP_FLOAT_TO_INT.S */
3618/* File: x86/cvtfp_int.S */
3619/* On fp to int conversions, Java requires that
3620 * if the result > maxint, it should be clamped to maxint.  If it is less
3621 * than minint, it should be clamped to minint.  If it is a nan, the result
3622 * should be zero.  Further, the rounding mode is to truncate.  This model
3623 * differs from what is delivered normally via the x86 fpu, so we have
3624 * to play some games.
3625 */
3626    /* float/double to int/long vA, vB */
3627    movzbl    rINSTbl,%ecx       # ecx<- A+
3628    sarl      $4,rINST         # rINST<- B
3629    .if 0
3630    fldl     (rFP,rINST,4)       # %st0<- vB
3631    .else
3632    flds     (rFP,rINST,4)       # %st0<- vB
3633    .endif
3634    ftst
3635    fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
3636    movzwl   LOCAL0_OFFSET(%ebp),%eax
3637    movb     $0xc,%ah
3638    movw     %ax,LOCAL0_OFFSET+2(%ebp)
3639    fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
3640    FETCH_INST_OPCODE 1 %edx
3641    andb     $0xf,%cl                # ecx<- A
3642    .if 0
3643    fistpll  (rFP,%ecx,4)             # convert and store
3644    .else
3645    fistpl   (rFP,%ecx,4)             # convert and store
3646    .endif
3647    fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
3648    jmp      .LOP_FLOAT_TO_INT_continue
3649
3650
3651/* ------------------------------ */
3652    .balign 64
3653.L_OP_FLOAT_TO_LONG: /* 0x88 */
3654/* File: x86/OP_FLOAT_TO_LONG.S */
3655/* File: x86/cvtfp_int.S */
3656/* On fp to int conversions, Java requires that
3657 * if the result > maxint, it should be clamped to maxint.  If it is less
3658 * than minint, it should be clamped to minint.  If it is a nan, the result
3659 * should be zero.  Further, the rounding mode is to truncate.  This model
3660 * differs from what is delivered normally via the x86 fpu, so we have
3661 * to play some games.
3662 */
3663    /* float/double to int/long vA, vB */
3664    movzbl    rINSTbl,%ecx       # ecx<- A+
3665    sarl      $4,rINST         # rINST<- B
3666    .if 0
3667    fldl     (rFP,rINST,4)       # %st0<- vB
3668    .else
3669    flds     (rFP,rINST,4)       # %st0<- vB
3670    .endif
3671    ftst
3672    fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
3673    movzwl   LOCAL0_OFFSET(%ebp),%eax
3674    movb     $0xc,%ah
3675    movw     %ax,LOCAL0_OFFSET+2(%ebp)
3676    fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
3677    FETCH_INST_OPCODE 1 %edx
3678    andb     $0xf,%cl                # ecx<- A
3679    .if 1
3680    fistpll  (rFP,%ecx,4)             # convert and store
3681    .else
3682    fistpl   (rFP,%ecx,4)             # convert and store
3683    .endif
3684    fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
3685    jmp      .LOP_FLOAT_TO_LONG_continue
3686
3687
3688/* ------------------------------ */
3689    .balign 64
3690.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */
3691/* File: x86/OP_FLOAT_TO_DOUBLE.S */
3692/* File: x86/fpcvt.S */
3693    /*
3694     * Generic 32-bit FP conversion operation.
3695     */
3696    /* unop vA, vB */
3697    movzbl   rINSTbl,%ecx       # ecx<- A+
3698    sarl     $4,rINST         # rINST<- B
3699    flds    (rFP,rINST,4)      # %st0<- vB
3700    andb     $0xf,%cl          # ecx<- A
3701    FETCH_INST_OPCODE 1 %edx
3702    ADVANCE_PC 1
3703
3704    fstpl  (rFP,%ecx,4)        # vA<- %st0
3705    GOTO_NEXT_R %edx
3706
3707
3708/* ------------------------------ */
3709    .balign 64
3710.L_OP_DOUBLE_TO_INT: /* 0x8a */
3711/* File: x86/OP_DOUBLE_TO_INT.S */
3712/* File: x86/cvtfp_int.S */
3713/* On fp to int conversions, Java requires that
3714 * if the result > maxint, it should be clamped to maxint.  If it is less
3715 * than minint, it should be clamped to minint.  If it is a nan, the result
3716 * should be zero.  Further, the rounding mode is to truncate.  This model
3717 * differs from what is delivered normally via the x86 fpu, so we have
3718 * to play some games.
3719 */
3720    /* float/double to int/long vA, vB */
3721    movzbl    rINSTbl,%ecx       # ecx<- A+
3722    sarl      $4,rINST         # rINST<- B
3723    .if 1
3724    fldl     (rFP,rINST,4)       # %st0<- vB
3725    .else
3726    flds     (rFP,rINST,4)       # %st0<- vB
3727    .endif
3728    ftst
3729    fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
3730    movzwl   LOCAL0_OFFSET(%ebp),%eax
3731    movb     $0xc,%ah
3732    movw     %ax,LOCAL0_OFFSET+2(%ebp)
3733    fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
3734    FETCH_INST_OPCODE 1 %edx
3735    andb     $0xf,%cl                # ecx<- A
3736    .if 0
3737    fistpll  (rFP,%ecx,4)             # convert and store
3738    .else
3739    fistpl   (rFP,%ecx,4)             # convert and store
3740    .endif
3741    fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
3742    jmp      .LOP_DOUBLE_TO_INT_continue
3743
3744
3745/* ------------------------------ */
3746    .balign 64
3747.L_OP_DOUBLE_TO_LONG: /* 0x8b */
3748/* File: x86/OP_DOUBLE_TO_LONG.S */
3749/* File: x86/cvtfp_int.S */
3750/* On fp to int conversions, Java requires that
3751 * if the result > maxint, it should be clamped to maxint.  If it is less
3752 * than minint, it should be clamped to minint.  If it is a nan, the result
3753 * should be zero.  Further, the rounding mode is to truncate.  This model
3754 * differs from what is delivered normally via the x86 fpu, so we have
3755 * to play some games.
3756 */
3757    /* float/double to int/long vA, vB */
3758    movzbl    rINSTbl,%ecx       # ecx<- A+
3759    sarl      $4,rINST         # rINST<- B
3760    .if 1
3761    fldl     (rFP,rINST,4)       # %st0<- vB
3762    .else
3763    flds     (rFP,rINST,4)       # %st0<- vB
3764    .endif
3765    ftst
3766    fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
3767    movzwl   LOCAL0_OFFSET(%ebp),%eax
3768    movb     $0xc,%ah
3769    movw     %ax,LOCAL0_OFFSET+2(%ebp)
3770    fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
3771    FETCH_INST_OPCODE 1 %edx
3772    andb     $0xf,%cl                # ecx<- A
3773    .if 1
3774    fistpll  (rFP,%ecx,4)             # convert and store
3775    .else
3776    fistpl   (rFP,%ecx,4)             # convert and store
3777    .endif
3778    fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
3779    jmp      .LOP_DOUBLE_TO_LONG_continue
3780
3781
3782/* ------------------------------ */
3783    .balign 64
3784.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */
3785/* File: x86/OP_DOUBLE_TO_FLOAT.S */
3786/* File: x86/fpcvt.S */
3787    /*
3788     * Generic 32-bit FP conversion operation.
3789     */
3790    /* unop vA, vB */
3791    movzbl   rINSTbl,%ecx       # ecx<- A+
3792    sarl     $4,rINST         # rINST<- B
3793    fldl    (rFP,rINST,4)      # %st0<- vB
3794    andb     $0xf,%cl          # ecx<- A
3795    FETCH_INST_OPCODE 1 %edx
3796    ADVANCE_PC 1
3797
3798    fstps  (rFP,%ecx,4)        # vA<- %st0
3799    GOTO_NEXT_R %edx
3800
3801
3802/* ------------------------------ */
3803    .balign 64
3804.L_OP_INT_TO_BYTE: /* 0x8d */
3805/* File: x86/OP_INT_TO_BYTE.S */
3806/* File: x86/unop.S */
3807    /*
3808     * Generic 32-bit unary operation.  Provide an "instr" line that
3809     * specifies an instruction that performs "result = op eax".
3810     */
3811    /* unop vA, vB */
3812    movzbl   rINSTbl,%ecx           # ecx<- A+
3813    sarl     $4,rINST             # rINST<- B
3814    GET_VREG_R %eax rINST           # eax<- vB
3815    andb     $0xf,%cl              # ecx<- A
3816    FETCH_INST_OPCODE 1 %edx
3817    ADVANCE_PC 1
3818
3819
3820    movsbl %al,%eax
3821    SET_VREG %eax %ecx
3822    GOTO_NEXT_R %edx
3823
3824
3825/* ------------------------------ */
3826    .balign 64
3827.L_OP_INT_TO_CHAR: /* 0x8e */
3828/* File: x86/OP_INT_TO_CHAR.S */
3829/* File: x86/unop.S */
3830    /*
3831     * Generic 32-bit unary operation.  Provide an "instr" line that
3832     * specifies an instruction that performs "result = op eax".
3833     */
3834    /* unop vA, vB */
3835    movzbl   rINSTbl,%ecx           # ecx<- A+
3836    sarl     $4,rINST             # rINST<- B
3837    GET_VREG_R %eax rINST           # eax<- vB
3838    andb     $0xf,%cl              # ecx<- A
3839    FETCH_INST_OPCODE 1 %edx
3840    ADVANCE_PC 1
3841
3842
3843    movzwl %ax,%eax
3844    SET_VREG %eax %ecx
3845    GOTO_NEXT_R %edx
3846
3847
3848/* ------------------------------ */
3849    .balign 64
3850.L_OP_INT_TO_SHORT: /* 0x8f */
3851/* File: x86/OP_INT_TO_SHORT.S */
3852/* File: x86/unop.S */
3853    /*
3854     * Generic 32-bit unary operation.  Provide an "instr" line that
3855     * specifies an instruction that performs "result = op eax".
3856     */
3857    /* unop vA, vB */
3858    movzbl   rINSTbl,%ecx           # ecx<- A+
3859    sarl     $4,rINST             # rINST<- B
3860    GET_VREG_R %eax rINST           # eax<- vB
3861    andb     $0xf,%cl              # ecx<- A
3862    FETCH_INST_OPCODE 1 %edx
3863    ADVANCE_PC 1
3864
3865
3866    movswl %ax,%eax
3867    SET_VREG %eax %ecx
3868    GOTO_NEXT_R %edx
3869
3870
3871/* ------------------------------ */
3872    .balign 64
3873.L_OP_ADD_INT: /* 0x90 */
3874/* File: x86/OP_ADD_INT.S */
3875/* File: x86/binop.S */
3876    /*
3877     * Generic 32-bit binary operation.  Provide an "instr" line that
3878     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
3879     * This could be an x86 instruction or a function call.  (If the result
3880     * comes back in a register other than eax, you can override "result".)
3881     *
3882     * For: add-int, sub-int, and-int, or-int,
3883     *      xor-int, shl-int, shr-int, ushr-int
3884     */
3885    /* binop vAA, vBB, vCC */
3886    movzbl   2(rPC),%eax   # eax<- BB
3887    movzbl   3(rPC),%ecx   # ecx<- CC
3888    GET_VREG_R %eax %eax   # eax<- vBB
3889    addl (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
3890    FETCH_INST_OPCODE 2 %edx
3891    ADVANCE_PC 2
3892    SET_VREG %eax rINST
3893    GOTO_NEXT_R %edx
3894
3895
3896/* ------------------------------ */
3897    .balign 64
3898.L_OP_SUB_INT: /* 0x91 */
3899/* File: x86/OP_SUB_INT.S */
3900/* File: x86/binop.S */
3901    /*
3902     * Generic 32-bit binary operation.  Provide an "instr" line that
3903     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
3904     * This could be an x86 instruction or a function call.  (If the result
3905     * comes back in a register other than eax, you can override "result".)
3906     *
3907     * For: add-int, sub-int, and-int, or-int,
3908     *      xor-int, shl-int, shr-int, ushr-int
3909     */
3910    /* binop vAA, vBB, vCC */
3911    movzbl   2(rPC),%eax   # eax<- BB
3912    movzbl   3(rPC),%ecx   # ecx<- CC
3913    GET_VREG_R %eax %eax   # eax<- vBB
3914    subl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
3915    FETCH_INST_OPCODE 2 %edx
3916    ADVANCE_PC 2
3917    SET_VREG %eax rINST
3918    GOTO_NEXT_R %edx
3919
3920
3921/* ------------------------------ */
3922    .balign 64
3923.L_OP_MUL_INT: /* 0x92 */
3924/* File: x86/OP_MUL_INT.S */
3925    /*
3926     * 32-bit binary multiplication.
3927     */
3928    /* mul vAA, vBB, vCC */
3929    movzbl   2(rPC),%eax            # eax<- BB
3930    movzbl   3(rPC),%ecx            # ecx<- CC
3931    GET_VREG_R %eax %eax            # eax<- vBB
3932    imull    (rFP,%ecx,4),%eax      # trashes edx
3933    FETCH_INST_OPCODE 2 %edx
3934    ADVANCE_PC 2
3935    SET_VREG %eax rINST
3936    GOTO_NEXT_R %edx
3937
3938/* ------------------------------ */
3939    .balign 64
3940.L_OP_DIV_INT: /* 0x93 */
3941/* File: x86/OP_DIV_INT.S */
3942/* File: x86/bindiv.S */
3943
3944    /*
3945     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
3946     * op1=-1.
3947     */
3948    /* binop vAA, vBB, vCC */
3949    movzbl   2(rPC),%eax            # eax<- BB
3950    movzbl   3(rPC),%ecx            # ecx<- CC
3951    GET_VREG_R %eax %eax            # eax<- vBB
3952    GET_VREG_R %ecx %ecx            # eax<- vBB
3953    cmpl     $0,%ecx
3954    je       common_errDivideByZero
3955    cmpl     $-1,%ecx
3956    jne      .LOP_DIV_INT_continue_div
3957    cmpl     $0x80000000,%eax
3958    jne      .LOP_DIV_INT_continue_div
3959    movl     $0x80000000,%eax
3960    jmp      .LOP_DIV_INT_finish_div
3961
3962
3963
3964/* ------------------------------ */
3965    .balign 64
3966.L_OP_REM_INT: /* 0x94 */
3967/* File: x86/OP_REM_INT.S */
3968/* File: x86/bindiv.S */
3969
3970    /*
3971     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
3972     * op1=-1.
3973     */
3974    /* binop vAA, vBB, vCC */
3975    movzbl   2(rPC),%eax            # eax<- BB
3976    movzbl   3(rPC),%ecx            # ecx<- CC
3977    GET_VREG_R %eax %eax            # eax<- vBB
3978    GET_VREG_R %ecx %ecx            # eax<- vBB
3979    cmpl     $0,%ecx
3980    je       common_errDivideByZero
3981    cmpl     $-1,%ecx
3982    jne      .LOP_REM_INT_continue_div
3983    cmpl     $0x80000000,%eax
3984    jne      .LOP_REM_INT_continue_div
3985    movl     $0,%edx
3986    jmp      .LOP_REM_INT_finish_div
3987
3988
3989
3990/* ------------------------------ */
3991    .balign 64
3992.L_OP_AND_INT: /* 0x95 */
3993/* File: x86/OP_AND_INT.S */
3994/* File: x86/binop.S */
3995    /*
3996     * Generic 32-bit binary operation.  Provide an "instr" line that
3997     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
3998     * This could be an x86 instruction or a function call.  (If the result
3999     * comes back in a register other than eax, you can override "result".)
4000     *
4001     * For: add-int, sub-int, and-int, or-int,
4002     *      xor-int, shl-int, shr-int, ushr-int
4003     */
4004    /* binop vAA, vBB, vCC */
4005    movzbl   2(rPC),%eax   # eax<- BB
4006    movzbl   3(rPC),%ecx   # ecx<- CC
4007    GET_VREG_R %eax %eax   # eax<- vBB
4008    andl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
4009    FETCH_INST_OPCODE 2 %edx
4010    ADVANCE_PC 2
4011    SET_VREG %eax rINST
4012    GOTO_NEXT_R %edx
4013
4014
4015/* ------------------------------ */
4016    .balign 64
4017.L_OP_OR_INT: /* 0x96 */
4018/* File: x86/OP_OR_INT.S */
4019/* File: x86/binop.S */
4020    /*
4021     * Generic 32-bit binary operation.  Provide an "instr" line that
4022     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
4023     * This could be an x86 instruction or a function call.  (If the result
4024     * comes back in a register other than eax, you can override "result".)
4025     *
4026     * For: add-int, sub-int, and-int, or-int,
4027     *      xor-int, shl-int, shr-int, ushr-int
4028     */
4029    /* binop vAA, vBB, vCC */
4030    movzbl   2(rPC),%eax   # eax<- BB
4031    movzbl   3(rPC),%ecx   # ecx<- CC
4032    GET_VREG_R %eax %eax   # eax<- vBB
4033    orl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
4034    FETCH_INST_OPCODE 2 %edx
4035    ADVANCE_PC 2
4036    SET_VREG %eax rINST
4037    GOTO_NEXT_R %edx
4038
4039
4040/* ------------------------------ */
4041    .balign 64
4042.L_OP_XOR_INT: /* 0x97 */
4043/* File: x86/OP_XOR_INT.S */
4044/* File: x86/binop.S */
4045    /*
4046     * Generic 32-bit binary operation.  Provide an "instr" line that
4047     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
4048     * This could be an x86 instruction or a function call.  (If the result
4049     * comes back in a register other than eax, you can override "result".)
4050     *
4051     * For: add-int, sub-int, and-int, or-int,
4052     *      xor-int, shl-int, shr-int, ushr-int
4053     */
4054    /* binop vAA, vBB, vCC */
4055    movzbl   2(rPC),%eax   # eax<- BB
4056    movzbl   3(rPC),%ecx   # ecx<- CC
4057    GET_VREG_R %eax %eax   # eax<- vBB
4058    xorl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
4059    FETCH_INST_OPCODE 2 %edx
4060    ADVANCE_PC 2
4061    SET_VREG %eax rINST
4062    GOTO_NEXT_R %edx
4063
4064
4065/* ------------------------------ */
4066    .balign 64
4067.L_OP_SHL_INT: /* 0x98 */
4068/* File: x86/OP_SHL_INT.S */
4069/* File: x86/binop1.S */
4070    /*
4071     * Generic 32-bit binary operation in which both operands loaded to
4072     * registers (op0 in eax, op1 in ecx).
4073     */
4074    /* binop vAA, vBB, vCC */
4075    movzbl   2(rPC),%eax            # eax<- BB
4076    movzbl   3(rPC),%ecx            # ecx<- CC
4077    GET_VREG_R %eax %eax            # eax<- vBB
4078    GET_VREG_R %ecx %ecx            # eax<- vBB
4079    sall    %cl,%eax                          # ex: addl    %ecx,%eax
4080    FETCH_INST_OPCODE 2 %edx
4081    ADVANCE_PC 2
4082    SET_VREG %eax rINST
4083    GOTO_NEXT_R %edx
4084
4085
4086/* ------------------------------ */
4087    .balign 64
4088.L_OP_SHR_INT: /* 0x99 */
4089/* File: x86/OP_SHR_INT.S */
4090/* File: x86/binop1.S */
4091    /*
4092     * Generic 32-bit binary operation in which both operands loaded to
4093     * registers (op0 in eax, op1 in ecx).
4094     */
4095    /* binop vAA, vBB, vCC */
4096    movzbl   2(rPC),%eax            # eax<- BB
4097    movzbl   3(rPC),%ecx            # ecx<- CC
4098    GET_VREG_R %eax %eax            # eax<- vBB
4099    GET_VREG_R %ecx %ecx            # eax<- vBB
4100    sarl    %cl,%eax                          # ex: addl    %ecx,%eax
4101    FETCH_INST_OPCODE 2 %edx
4102    ADVANCE_PC 2
4103    SET_VREG %eax rINST
4104    GOTO_NEXT_R %edx
4105
4106
4107/* ------------------------------ */
4108    .balign 64
4109.L_OP_USHR_INT: /* 0x9a */
4110/* File: x86/OP_USHR_INT.S */
4111/* File: x86/binop1.S */
4112    /*
4113     * Generic 32-bit binary operation in which both operands loaded to
4114     * registers (op0 in eax, op1 in ecx).
4115     */
4116    /* binop vAA, vBB, vCC */
4117    movzbl   2(rPC),%eax            # eax<- BB
4118    movzbl   3(rPC),%ecx            # ecx<- CC
4119    GET_VREG_R %eax %eax            # eax<- vBB
4120    GET_VREG_R %ecx %ecx            # eax<- vBB
4121    shrl    %cl,%eax                          # ex: addl    %ecx,%eax
4122    FETCH_INST_OPCODE 2 %edx
4123    ADVANCE_PC 2
4124    SET_VREG %eax rINST
4125    GOTO_NEXT_R %edx
4126
4127
4128/* ------------------------------ */
4129    .balign 64
4130.L_OP_ADD_LONG: /* 0x9b */
4131/* File: x86/OP_ADD_LONG.S */
4132/* File: x86/binopWide.S */
4133    /*
4134     * Generic 64-bit binary operation.
4135     */
4136    /* binop vAA, vBB, vCC */
4137
4138    movzbl    2(rPC),%eax               # eax<- BB
4139    movzbl    3(rPC),%ecx               # ecx<- CC
4140    GET_VREG_WORD %edx %eax 0           # edx<- v[BB+0]
4141    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
4142    addl (rFP,%ecx,4),%edx         # ex: addl   (rFP,%ecx,4),%edx
4143    adcl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
4144    SET_VREG_WORD %edx rINST 0          # v[AA+0] <- edx
4145    FETCH_INST_OPCODE 2 %edx
4146    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
4147    ADVANCE_PC 2
4148    GOTO_NEXT_R %edx
4149
4150
4151/* ------------------------------ */
4152    .balign 64
4153.L_OP_SUB_LONG: /* 0x9c */
4154/* File: x86/OP_SUB_LONG.S */
4155/* File: x86/binopWide.S */
4156    /*
4157     * Generic 64-bit binary operation.
4158     */
4159    /* binop vAA, vBB, vCC */
4160
4161    movzbl    2(rPC),%eax               # eax<- BB
4162    movzbl    3(rPC),%ecx               # ecx<- CC
4163    GET_VREG_WORD %edx %eax 0           # edx<- v[BB+0]
4164    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
4165    subl (rFP,%ecx,4),%edx         # ex: addl   (rFP,%ecx,4),%edx
4166    sbbl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
4167    SET_VREG_WORD %edx rINST 0          # v[AA+0] <- edx
4168    FETCH_INST_OPCODE 2 %edx
4169    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
4170    ADVANCE_PC 2
4171    GOTO_NEXT_R %edx
4172
4173
4174/* ------------------------------ */
4175    .balign 64
4176.L_OP_MUL_LONG: /* 0x9d */
4177/* File: x86/OP_MUL_LONG.S */
4178    /*
4179     * Signed 64-bit integer multiply.
4180     *
4181     * We could definately use more free registers for
4182     * this code.   We spill rINSTw (ebx),
4183     * giving us eax, ebc, ecx and edx as computational
4184     * temps.  On top of that, we'll spill edi (rFP)
4185     * for use as the vB pointer and esi (rPC) for use
4186     * as the vC pointer.  Yuck.
4187     */
4188    /* mul-long vAA, vBB, vCC */
4189    movzbl    2(rPC),%eax              # eax<- B
4190    movzbl    3(rPC),%ecx              # ecx<- C
4191    SPILL_TMP2(%esi)                   # save Dalvik PC
4192    SPILL(rFP)
4193    SPILL(rINST)
4194    leal      (rFP,%eax,4),%esi        # esi<- &v[B]
4195    leal      (rFP,%ecx,4),rFP         # rFP<- &v[C]
4196    movl      4(%esi),%ecx             # ecx<- Bmsw
4197    imull     (rFP),%ecx               # ecx<- (Bmsw*Clsw)
4198    movl      4(rFP),%eax              # eax<- Cmsw
4199    imull     (%esi),%eax              # eax<- (Cmsw*Blsw)
4200    addl      %eax,%ecx                # ecx<- (Bmsw*Clsw)+(Cmsw*Blsw)
4201    movl      (rFP),%eax               # eax<- Clsw
4202    mull      (%esi)                   # eax<- (Clsw*Alsw)
4203    UNSPILL(rINST)
4204    UNSPILL(rFP)
4205    jmp       .LOP_MUL_LONG_continue
4206
4207/* ------------------------------ */
4208    .balign 64
4209.L_OP_DIV_LONG: /* 0x9e */
4210/* File: x86/OP_DIV_LONG.S */
4211    /* div vAA, vBB, vCC */
4212    movzbl    3(rPC),%eax              # eax<- CC
4213    movzbl    2(rPC),%ecx              # ecx<- BB
4214    GET_VREG_WORD %edx %eax 0
4215    GET_VREG_WORD %eax %eax 1
4216    movl     %edx,OUT_ARG2(%esp)
4217    testl    %eax,%eax
4218    je       .LOP_DIV_LONG_check_zero
4219    cmpl     $-1,%eax
4220    je       .LOP_DIV_LONG_check_neg1
4221.LOP_DIV_LONG_notSpecial:
4222    GET_VREG_WORD %edx %ecx 0
4223    GET_VREG_WORD %ecx %ecx 1
4224.LOP_DIV_LONG_notSpecial1:
4225    movl     %eax,OUT_ARG3(%esp)
4226    movl     %edx,OUT_ARG0(%esp)
4227    movl     %ecx,OUT_ARG1(%esp)
4228    jmp      .LOP_DIV_LONG_continue
4229
4230/* ------------------------------ */
4231    .balign 64
4232.L_OP_REM_LONG: /* 0x9f */
4233/* File: x86/OP_REM_LONG.S */
4234/* File: x86/OP_DIV_LONG.S */
4235    /* div vAA, vBB, vCC */
4236    movzbl    3(rPC),%eax              # eax<- CC
4237    movzbl    2(rPC),%ecx              # ecx<- BB
4238    GET_VREG_WORD %edx %eax 0
4239    GET_VREG_WORD %eax %eax 1
4240    movl     %edx,OUT_ARG2(%esp)
4241    testl    %eax,%eax
4242    je       .LOP_REM_LONG_check_zero
4243    cmpl     $-1,%eax
4244    je       .LOP_REM_LONG_check_neg1
4245.LOP_REM_LONG_notSpecial:
4246    GET_VREG_WORD %edx %ecx 0
4247    GET_VREG_WORD %ecx %ecx 1
4248.LOP_REM_LONG_notSpecial1:
4249    movl     %eax,OUT_ARG3(%esp)
4250    movl     %edx,OUT_ARG0(%esp)
4251    movl     %ecx,OUT_ARG1(%esp)
4252    jmp      .LOP_REM_LONG_continue
4253
4254
4255/* ------------------------------ */
4256    .balign 64
4257.L_OP_AND_LONG: /* 0xa0 */
4258/* File: x86/OP_AND_LONG.S */
4259/* File: x86/binopWide.S */
4260    /*
4261     * Generic 64-bit binary operation.
4262     */
4263    /* binop vAA, vBB, vCC */
4264
4265    movzbl    2(rPC),%eax               # eax<- BB
4266    movzbl    3(rPC),%ecx               # ecx<- CC
4267    GET_VREG_WORD %edx %eax 0           # edx<- v[BB+0]
4268    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
4269    andl (rFP,%ecx,4),%edx         # ex: addl   (rFP,%ecx,4),%edx
4270    andl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
4271    SET_VREG_WORD %edx rINST 0          # v[AA+0] <- edx
4272    FETCH_INST_OPCODE 2 %edx
4273    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
4274    ADVANCE_PC 2
4275    GOTO_NEXT_R %edx
4276
4277
4278/* ------------------------------ */
4279    .balign 64
4280.L_OP_OR_LONG: /* 0xa1 */
4281/* File: x86/OP_OR_LONG.S */
4282/* File: x86/binopWide.S */
4283    /*
4284     * Generic 64-bit binary operation.
4285     */
4286    /* binop vAA, vBB, vCC */
4287
4288    movzbl    2(rPC),%eax               # eax<- BB
4289    movzbl    3(rPC),%ecx               # ecx<- CC
4290    GET_VREG_WORD %edx %eax 0           # edx<- v[BB+0]
4291    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
4292    orl (rFP,%ecx,4),%edx         # ex: addl   (rFP,%ecx,4),%edx
4293    orl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
4294    SET_VREG_WORD %edx rINST 0          # v[AA+0] <- edx
4295    FETCH_INST_OPCODE 2 %edx
4296    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
4297    ADVANCE_PC 2
4298    GOTO_NEXT_R %edx
4299
4300
4301/* ------------------------------ */
4302    .balign 64
4303.L_OP_XOR_LONG: /* 0xa2 */
4304/* File: x86/OP_XOR_LONG.S */
4305/* File: x86/binopWide.S */
4306    /*
4307     * Generic 64-bit binary operation.
4308     */
4309    /* binop vAA, vBB, vCC */
4310
4311    movzbl    2(rPC),%eax               # eax<- BB
4312    movzbl    3(rPC),%ecx               # ecx<- CC
4313    GET_VREG_WORD %edx %eax 0           # edx<- v[BB+0]
4314    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
4315    xorl (rFP,%ecx,4),%edx         # ex: addl   (rFP,%ecx,4),%edx
4316    xorl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
4317    SET_VREG_WORD %edx rINST 0          # v[AA+0] <- edx
4318    FETCH_INST_OPCODE 2 %edx
4319    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
4320    ADVANCE_PC 2
4321    GOTO_NEXT_R %edx
4322
4323
4324/* ------------------------------ */
4325    .balign 64
4326.L_OP_SHL_LONG: /* 0xa3 */
4327/* File: x86/OP_SHL_LONG.S */
4328    /*
4329     * Long integer shift.  This is different from the generic 32/64-bit
4330     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4331     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4332     * 6 bits of the shift distance.  x86 shifts automatically mask off
4333     * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
4334     * case specially.
4335     */
4336    /* shl-long vAA, vBB, vCC */
4337    /* ecx gets shift count */
4338    /* Need to spill edx */
4339    /* rINSTw gets AA */
4340    movzbl    2(rPC),%eax               # eax<- BB
4341    movzbl    3(rPC),%ecx               # ecx<- CC
4342    GET_VREG_WORD %edx %eax 1           # ecx<- v[BB+1]
4343    GET_VREG_R   %ecx %ecx              # ecx<- vCC
4344    GET_VREG_WORD %eax %eax 0           # eax<- v[BB+0]
4345    shldl     %eax,%edx
4346    sall      %cl,%eax
4347    testb     $32,%cl
4348    je        2f
4349    movl      %eax,%edx
4350    xorl      %eax,%eax
43512:
4352    SET_VREG_WORD %edx rINST 1          # v[AA+1]<- %edx
4353    FETCH_INST_OPCODE 2 %edx
4354    jmp       .LOP_SHL_LONG_finish
4355
4356/* ------------------------------ */
4357    .balign 64
4358.L_OP_SHR_LONG: /* 0xa4 */
4359/* File: x86/OP_SHR_LONG.S */
4360    /*
4361     * Long integer shift.  This is different from the generic 32/64-bit
4362     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4363     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4364     * 6 bits of the shift distance.  x86 shifts automatically mask off
4365     * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
4366     * case specially.
4367     */
4368    /* shr-long vAA, vBB, vCC */
4369    /* ecx gets shift count */
4370    /* Need to spill edx */
4371    /* rINSTw gets AA */
4372    movzbl    2(rPC),%eax               # eax<- BB
4373    movzbl    3(rPC),%ecx               # ecx<- CC
4374    GET_VREG_WORD %edx %eax 1           # edx<- v[BB+1]
4375    GET_VREG_R   %ecx %ecx              # ecx<- vCC
4376    GET_VREG_WORD %eax %eax 0           # eax<- v[BB+0]
4377    shrdl     %edx,%eax
4378    sarl      %cl,%edx
4379    testb     $32,%cl
4380    je        2f
4381    movl      %edx,%eax
4382    sarl      $31,%edx
43832:
4384    SET_VREG_WORD %edx rINST 1          # v[AA+1]<- edx
4385    FETCH_INST_OPCODE 2 %edx
4386    jmp       .LOP_SHR_LONG_finish
4387
4388/* ------------------------------ */
4389    .balign 64
4390.L_OP_USHR_LONG: /* 0xa5 */
4391/* File: x86/OP_USHR_LONG.S */
4392    /*
4393     * Long integer shift.  This is different from the generic 32/64-bit
4394     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4395     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4396     * 6 bits of the shift distance.  x86 shifts automatically mask off
4397     * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
4398     * case specially.
4399     */
4400    /* shr-long vAA, vBB, vCC */
4401    /* ecx gets shift count */
4402    /* Need to spill edx */
4403    /* rINSTw gets AA */
4404    movzbl    2(rPC),%eax               # eax<- BB
4405    movzbl    3(rPC),%ecx               # ecx<- CC
4406    GET_VREG_WORD %edx %eax 1           # edx<- v[BB+1]
4407    GET_VREG_R  %ecx %ecx               # ecx<- vCC
4408    GET_VREG_WORD %eax %eax 0           # eax<- v[BB+0]
4409    shrdl     %edx,%eax
4410    shrl      %cl,%edx
4411    testb     $32,%cl
4412    je        2f
4413    movl      %edx,%eax
4414    xorl      %edx,%edx
44152:
4416    SET_VREG_WORD %edx rINST 1          # v[AA+1]<- edx
4417    FETCH_INST_OPCODE 2 %edx
4418    jmp       .LOP_USHR_LONG_finish
4419
4420/* ------------------------------ */
4421    .balign 64
4422.L_OP_ADD_FLOAT: /* 0xa6 */
4423/* File: x86/OP_ADD_FLOAT.S */
4424/* File: x86/binflop.S */
4425    /*
4426     * Generic 32-bit binary float operation.
4427     *
4428     * For: add-fp, sub-fp, mul-fp, div-fp
4429     */
4430    /* binop vAA, vBB, vCC */
4431    movzbl   2(rPC),%eax          # eax<- CC
4432    movzbl   3(rPC),%ecx          # ecx<- BB
4433    flds    (rFP,%eax,4)         # vCC to fp stack
4434    fadds   (rFP,%ecx,4)         # ex: faddp
4435    FETCH_INST_OPCODE 2 %edx
4436    ADVANCE_PC 2
4437    fstps   (rFP,rINST,4)         # %st to vAA
4438    GOTO_NEXT_R %edx
4439
4440
4441/* ------------------------------ */
4442    .balign 64
4443.L_OP_SUB_FLOAT: /* 0xa7 */
4444/* File: x86/OP_SUB_FLOAT.S */
4445/* File: x86/binflop.S */
4446    /*
4447     * Generic 32-bit binary float operation.
4448     *
4449     * For: add-fp, sub-fp, mul-fp, div-fp
4450     */
4451    /* binop vAA, vBB, vCC */
4452    movzbl   2(rPC),%eax          # eax<- CC
4453    movzbl   3(rPC),%ecx          # ecx<- BB
4454    flds    (rFP,%eax,4)         # vCC to fp stack
4455    fsubs   (rFP,%ecx,4)         # ex: faddp
4456    FETCH_INST_OPCODE 2 %edx
4457    ADVANCE_PC 2
4458    fstps   (rFP,rINST,4)         # %st to vAA
4459    GOTO_NEXT_R %edx
4460
4461
4462/* ------------------------------ */
4463    .balign 64
4464.L_OP_MUL_FLOAT: /* 0xa8 */
4465/* File: x86/OP_MUL_FLOAT.S */
4466/* File: x86/binflop.S */
4467    /*
4468     * Generic 32-bit binary float operation.
4469     *
4470     * For: add-fp, sub-fp, mul-fp, div-fp
4471     */
4472    /* binop vAA, vBB, vCC */
4473    movzbl   2(rPC),%eax          # eax<- CC
4474    movzbl   3(rPC),%ecx          # ecx<- BB
4475    flds    (rFP,%eax,4)         # vCC to fp stack
4476    fmuls   (rFP,%ecx,4)         # ex: faddp
4477    FETCH_INST_OPCODE 2 %edx
4478    ADVANCE_PC 2
4479    fstps   (rFP,rINST,4)         # %st to vAA
4480    GOTO_NEXT_R %edx
4481
4482
4483/* ------------------------------ */
4484    .balign 64
4485.L_OP_DIV_FLOAT: /* 0xa9 */
4486/* File: x86/OP_DIV_FLOAT.S */
4487/* File: x86/binflop.S */
4488    /*
4489     * Generic 32-bit binary float operation.
4490     *
4491     * For: add-fp, sub-fp, mul-fp, div-fp
4492     */
4493    /* binop vAA, vBB, vCC */
4494    movzbl   2(rPC),%eax          # eax<- CC
4495    movzbl   3(rPC),%ecx          # ecx<- BB
4496    flds    (rFP,%eax,4)         # vCC to fp stack
4497    fdivs   (rFP,%ecx,4)         # ex: faddp
4498    FETCH_INST_OPCODE 2 %edx
4499    ADVANCE_PC 2
4500    fstps   (rFP,rINST,4)         # %st to vAA
4501    GOTO_NEXT_R %edx
4502
4503
4504/* ------------------------------ */
4505    .balign 64
4506.L_OP_REM_FLOAT: /* 0xaa */
4507/* File: x86/OP_REM_FLOAT.S */
4508    /* rem_float vAA, vBB, vCC */
4509    movzbl   3(rPC),%ecx            # ecx<- BB
4510    movzbl   2(rPC),%eax            # eax<- CC
4511    flds     (rFP,%ecx,4)           # vCC to fp stack
4512    flds     (rFP,%eax,4)           # vCC to fp stack
4513    movzbl   rINSTbl,%ecx           # ecx<- AA
4514    FETCH_INST_OPCODE 2 %edx
45151:
4516    fprem
4517    fstsw     %ax
4518    sahf
4519    jp        1b
4520    fstp      %st(1)
4521    ADVANCE_PC 2
4522    fstps    (rFP,%ecx,4)           # %st to vAA
4523    GOTO_NEXT_R %edx
4524
4525/* ------------------------------ */
4526    .balign 64
4527.L_OP_ADD_DOUBLE: /* 0xab */
4528/* File: x86/OP_ADD_DOUBLE.S */
4529/* File: x86/binflop.S */
4530    /*
4531     * Generic 32-bit binary float operation.
4532     *
4533     * For: add-fp, sub-fp, mul-fp, div-fp
4534     */
4535    /* binop vAA, vBB, vCC */
4536    movzbl   2(rPC),%eax          # eax<- CC
4537    movzbl   3(rPC),%ecx          # ecx<- BB
4538    fldl    (rFP,%eax,4)         # vCC to fp stack
4539    faddl   (rFP,%ecx,4)         # ex: faddp
4540    FETCH_INST_OPCODE 2 %edx
4541    ADVANCE_PC 2
4542    fstpl   (rFP,rINST,4)         # %st to vAA
4543    GOTO_NEXT_R %edx
4544
4545
4546/* ------------------------------ */
4547    .balign 64
4548.L_OP_SUB_DOUBLE: /* 0xac */
4549/* File: x86/OP_SUB_DOUBLE.S */
4550/* File: x86/binflop.S */
4551    /*
4552     * Generic 32-bit binary float operation.
4553     *
4554     * For: add-fp, sub-fp, mul-fp, div-fp
4555     */
4556    /* binop vAA, vBB, vCC */
4557    movzbl   2(rPC),%eax          # eax<- CC
4558    movzbl   3(rPC),%ecx          # ecx<- BB
4559    fldl    (rFP,%eax,4)         # vCC to fp stack
4560    fsubl   (rFP,%ecx,4)         # ex: faddp
4561    FETCH_INST_OPCODE 2 %edx
4562    ADVANCE_PC 2
4563    fstpl   (rFP,rINST,4)         # %st to vAA
4564    GOTO_NEXT_R %edx
4565
4566
4567/* ------------------------------ */
4568    .balign 64
4569.L_OP_MUL_DOUBLE: /* 0xad */
4570/* File: x86/OP_MUL_DOUBLE.S */
4571/* File: x86/binflop.S */
4572    /*
4573     * Generic 32-bit binary float operation.
4574     *
4575     * For: add-fp, sub-fp, mul-fp, div-fp
4576     */
4577    /* binop vAA, vBB, vCC */
4578    movzbl   2(rPC),%eax          # eax<- CC
4579    movzbl   3(rPC),%ecx          # ecx<- BB
4580    fldl    (rFP,%eax,4)         # vCC to fp stack
4581    fmull   (rFP,%ecx,4)         # ex: faddp
4582    FETCH_INST_OPCODE 2 %edx
4583    ADVANCE_PC 2
4584    fstpl   (rFP,rINST,4)         # %st to vAA
4585    GOTO_NEXT_R %edx
4586
4587
4588/* ------------------------------ */
4589    .balign 64
4590.L_OP_DIV_DOUBLE: /* 0xae */
4591/* File: x86/OP_DIV_DOUBLE.S */
4592/* File: x86/binflop.S */
4593    /*
4594     * Generic 32-bit binary float operation.
4595     *
4596     * For: add-fp, sub-fp, mul-fp, div-fp
4597     */
4598    /* binop vAA, vBB, vCC */
4599    movzbl   2(rPC),%eax          # eax<- CC
4600    movzbl   3(rPC),%ecx          # ecx<- BB
4601    fldl    (rFP,%eax,4)         # vCC to fp stack
4602    fdivl   (rFP,%ecx,4)         # ex: faddp
4603    FETCH_INST_OPCODE 2 %edx
4604    ADVANCE_PC 2
4605    fstpl   (rFP,rINST,4)         # %st to vAA
4606    GOTO_NEXT_R %edx
4607
4608
4609/* ------------------------------ */
4610    .balign 64
4611.L_OP_REM_DOUBLE: /* 0xaf */
4612/* File: x86/OP_REM_DOUBLE.S */
4613    /* rem_float vAA, vBB, vCC */
4614    movzbl   3(rPC),%ecx            # ecx<- BB
4615    movzbl   2(rPC),%eax            # eax<- CC
4616    fldl     (rFP,%ecx,4)           # vCC to fp stack
4617    fldl     (rFP,%eax,4)           # vCC to fp stack
4618    movzbl   rINSTbl,%ecx           # ecx<- AA
4619    FETCH_INST_OPCODE 2 %edx
46201:
4621    fprem
4622    fstsw     %ax
4623    sahf
4624    jp        1b
4625    fstp      %st(1)
4626    ADVANCE_PC 2
4627    fstpl    (rFP,%ecx,4)           # %st to vAA
4628    GOTO_NEXT_R %edx
4629
4630/* ------------------------------ */
4631    .balign 64
4632.L_OP_ADD_INT_2ADDR: /* 0xb0 */
4633/* File: x86/OP_ADD_INT_2ADDR.S */
4634/* File: x86/binop2addr.S */
4635    /*
4636     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
4637     * that specifies an instruction that performs "result = r0 op r1".
4638     * This could be an ARM instruction or a function call.  (If the result
4639     * comes back in a register other than r0, you can override "result".)
4640     *
4641     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4642     * vCC (r1).  Useful for integer division and modulus.
4643     *
4644     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
4645     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
4646     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
4647     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
4648     */
4649    /* binop/2addr vA, vB */
4650    movzx   rINSTbl,%ecx               # ecx<- A+
4651    sarl    $4,rINST                 # rINST<- B
4652    GET_VREG_R %eax rINST              # eax<- vB
4653    FETCH_INST_OPCODE 1 %edx
4654    andb    $0xf,%cl                  # ecx<- A
4655    addl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
4656    ADVANCE_PC 1
4657    GOTO_NEXT_R %edx
4658
4659
4660/* ------------------------------ */
4661    .balign 64
4662.L_OP_SUB_INT_2ADDR: /* 0xb1 */
4663/* File: x86/OP_SUB_INT_2ADDR.S */
4664/* File: x86/binop2addr.S */
4665    /*
4666     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
4667     * that specifies an instruction that performs "result = r0 op r1".
4668     * This could be an ARM instruction or a function call.  (If the result
4669     * comes back in a register other than r0, you can override "result".)
4670     *
4671     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4672     * vCC (r1).  Useful for integer division and modulus.
4673     *
4674     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
4675     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
4676     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
4677     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
4678     */
4679    /* binop/2addr vA, vB */
4680    movzx   rINSTbl,%ecx               # ecx<- A+
4681    sarl    $4,rINST                 # rINST<- B
4682    GET_VREG_R %eax rINST              # eax<- vB
4683    FETCH_INST_OPCODE 1 %edx
4684    andb    $0xf,%cl                  # ecx<- A
4685    subl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
4686    ADVANCE_PC 1
4687    GOTO_NEXT_R %edx
4688
4689
4690/* ------------------------------ */
4691    .balign 64
4692.L_OP_MUL_INT_2ADDR: /* 0xb2 */
4693/* File: x86/OP_MUL_INT_2ADDR.S */
4694    /* mul vA, vB */
4695    movzx   rINSTbl,%ecx               # ecx<- A+
4696    sarl    $4,rINST                 # rINST<- B
4697    GET_VREG_R %eax rINST              # eax<- vB
4698    andb    $0xf,%cl                  # ecx<- A
4699    imull   (rFP,%ecx,4),%eax
4700    FETCH_INST_OPCODE 1 %edx
4701    SET_VREG %eax %ecx
4702    ADVANCE_PC 1
4703    GOTO_NEXT_R %edx
4704
4705/* ------------------------------ */
4706    .balign 64
4707.L_OP_DIV_INT_2ADDR: /* 0xb3 */
4708/* File: x86/OP_DIV_INT_2ADDR.S */
4709/* File: x86/bindiv2addr.S */
4710    /*
4711     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
4712     * op1=-1.
4713     */
4714    /* div/rem/2addr vA, vB */
4715    movzx    rINSTbl,%ecx          # eax<- BA
4716    sarl     $4,%ecx              # ecx<- B
4717    GET_VREG_R %ecx %ecx           # eax<- vBB
4718    andb     $0xf,rINSTbl         # rINST<- A
4719    GET_VREG_R %eax rINST          # eax<- vBB
4720    cmpl     $0,%ecx
4721    je       common_errDivideByZero
4722    cmpl     $-1,%ecx
4723    jne      .LOP_DIV_INT_2ADDR_continue_div2addr
4724    cmpl     $0x80000000,%eax
4725    jne      .LOP_DIV_INT_2ADDR_continue_div2addr
4726    movl     $0x80000000,%eax
4727    jmp      .LOP_DIV_INT_2ADDR_finish_div2addr
4728
4729
4730
4731/* ------------------------------ */
4732    .balign 64
4733.L_OP_REM_INT_2ADDR: /* 0xb4 */
4734/* File: x86/OP_REM_INT_2ADDR.S */
4735/* File: x86/bindiv2addr.S */
4736    /*
4737     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
4738     * op1=-1.
4739     */
4740    /* div/rem/2addr vA, vB */
4741    movzx    rINSTbl,%ecx          # eax<- BA
4742    sarl     $4,%ecx              # ecx<- B
4743    GET_VREG_R %ecx %ecx           # eax<- vBB
4744    andb     $0xf,rINSTbl         # rINST<- A
4745    GET_VREG_R %eax rINST          # eax<- vBB
4746    cmpl     $0,%ecx
4747    je       common_errDivideByZero
4748    cmpl     $-1,%ecx
4749    jne      .LOP_REM_INT_2ADDR_continue_div2addr
4750    cmpl     $0x80000000,%eax
4751    jne      .LOP_REM_INT_2ADDR_continue_div2addr
4752    movl     $0,%edx
4753    jmp      .LOP_REM_INT_2ADDR_finish_div2addr
4754
4755
4756
4757/* ------------------------------ */
4758    .balign 64
4759.L_OP_AND_INT_2ADDR: /* 0xb5 */
4760/* File: x86/OP_AND_INT_2ADDR.S */
4761/* File: x86/binop2addr.S */
4762    /*
4763     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
4764     * that specifies an instruction that performs "result = r0 op r1".
4765     * This could be an ARM instruction or a function call.  (If the result
4766     * comes back in a register other than r0, you can override "result".)
4767     *
4768     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4769     * vCC (r1).  Useful for integer division and modulus.
4770     *
4771     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
4772     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
4773     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
4774     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
4775     */
4776    /* binop/2addr vA, vB */
4777    movzx   rINSTbl,%ecx               # ecx<- A+
4778    sarl    $4,rINST                 # rINST<- B
4779    GET_VREG_R %eax rINST              # eax<- vB
4780    FETCH_INST_OPCODE 1 %edx
4781    andb    $0xf,%cl                  # ecx<- A
4782    andl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
4783    ADVANCE_PC 1
4784    GOTO_NEXT_R %edx
4785
4786
4787/* ------------------------------ */
4788    .balign 64
4789.L_OP_OR_INT_2ADDR: /* 0xb6 */
4790/* File: x86/OP_OR_INT_2ADDR.S */
4791/* File: x86/binop2addr.S */
4792    /*
4793     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
4794     * that specifies an instruction that performs "result = r0 op r1".
4795     * This could be an ARM instruction or a function call.  (If the result
4796     * comes back in a register other than r0, you can override "result".)
4797     *
4798     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4799     * vCC (r1).  Useful for integer division and modulus.
4800     *
4801     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
4802     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
4803     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
4804     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
4805     */
4806    /* binop/2addr vA, vB */
4807    movzx   rINSTbl,%ecx               # ecx<- A+
4808    sarl    $4,rINST                 # rINST<- B
4809    GET_VREG_R %eax rINST              # eax<- vB
4810    FETCH_INST_OPCODE 1 %edx
4811    andb    $0xf,%cl                  # ecx<- A
4812    orl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
4813    ADVANCE_PC 1
4814    GOTO_NEXT_R %edx
4815
4816
4817/* ------------------------------ */
4818    .balign 64
4819.L_OP_XOR_INT_2ADDR: /* 0xb7 */
4820/* File: x86/OP_XOR_INT_2ADDR.S */
4821/* File: x86/binop2addr.S */
4822    /*
4823     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
4824     * that specifies an instruction that performs "result = r0 op r1".
4825     * This could be an ARM instruction or a function call.  (If the result
4826     * comes back in a register other than r0, you can override "result".)
4827     *
4828     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4829     * vCC (r1).  Useful for integer division and modulus.
4830     *
4831     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
4832     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
4833     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
4834     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
4835     */
4836    /* binop/2addr vA, vB */
4837    movzx   rINSTbl,%ecx               # ecx<- A+
4838    sarl    $4,rINST                 # rINST<- B
4839    GET_VREG_R %eax rINST              # eax<- vB
4840    FETCH_INST_OPCODE 1 %edx
4841    andb    $0xf,%cl                  # ecx<- A
4842    xorl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
4843    ADVANCE_PC 1
4844    GOTO_NEXT_R %edx
4845
4846
4847/* ------------------------------ */
4848    .balign 64
4849.L_OP_SHL_INT_2ADDR: /* 0xb8 */
4850/* File: x86/OP_SHL_INT_2ADDR.S */
4851/* File: x86/shop2addr.S */
4852    /*
4853     * Generic 32-bit "shift/2addr" operation.
4854     */
4855    /* shift/2addr vA, vB */
4856    movzx    rINSTbl,%ecx           # eax<- BA
4857    sarl     $4,%ecx               # ecx<- B
4858    GET_VREG_R %ecx %ecx            # eax<- vBB
4859    andb     $0xf,rINSTbl          # rINST<- A
4860    GET_VREG_R %eax rINST           # eax<- vAA
4861    sall    %cl,%eax                          # ex: sarl %cl,%eax
4862    FETCH_INST_OPCODE 1 %edx
4863    SET_VREG %eax rINST
4864    ADVANCE_PC 1
4865    GOTO_NEXT_R %edx
4866
4867
4868/* ------------------------------ */
4869    .balign 64
4870.L_OP_SHR_INT_2ADDR: /* 0xb9 */
4871/* File: x86/OP_SHR_INT_2ADDR.S */
4872/* File: x86/shop2addr.S */
4873    /*
4874     * Generic 32-bit "shift/2addr" operation.
4875     */
4876    /* shift/2addr vA, vB */
4877    movzx    rINSTbl,%ecx           # eax<- BA
4878    sarl     $4,%ecx               # ecx<- B
4879    GET_VREG_R %ecx %ecx            # eax<- vBB
4880    andb     $0xf,rINSTbl          # rINST<- A
4881    GET_VREG_R %eax rINST           # eax<- vAA
4882    sarl    %cl,%eax                          # ex: sarl %cl,%eax
4883    FETCH_INST_OPCODE 1 %edx
4884    SET_VREG %eax rINST
4885    ADVANCE_PC 1
4886    GOTO_NEXT_R %edx
4887
4888
4889/* ------------------------------ */
4890    .balign 64
4891.L_OP_USHR_INT_2ADDR: /* 0xba */
4892/* File: x86/OP_USHR_INT_2ADDR.S */
4893/* File: x86/shop2addr.S */
4894    /*
4895     * Generic 32-bit "shift/2addr" operation.
4896     */
4897    /* shift/2addr vA, vB */
4898    movzx    rINSTbl,%ecx           # eax<- BA
4899    sarl     $4,%ecx               # ecx<- B
4900    GET_VREG_R %ecx %ecx            # eax<- vBB
4901    andb     $0xf,rINSTbl          # rINST<- A
4902    GET_VREG_R %eax rINST           # eax<- vAA
4903    shrl    %cl,%eax                          # ex: sarl %cl,%eax
4904    FETCH_INST_OPCODE 1 %edx
4905    SET_VREG %eax rINST
4906    ADVANCE_PC 1
4907    GOTO_NEXT_R %edx
4908
4909
4910/* ------------------------------ */
4911    .balign 64
4912.L_OP_ADD_LONG_2ADDR: /* 0xbb */
4913/* File: x86/OP_ADD_LONG_2ADDR.S */
4914/* File: x86/binopWide2addr.S */
4915    /*
4916     * Generic 64-bit binary operation.
4917     */
4918    /* binop/2addr vA, vB */
4919    movzbl    rINSTbl,%ecx              # ecx<- BA
4920    sarl      $4,%ecx                  # ecx<- B
4921    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
4922    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
4923    andb      $0xF,rINSTbl             # rINST<- A
4924    addl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
4925    adcl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
4926    FETCH_INST_OPCODE 1 %edx
4927    ADVANCE_PC 1
4928    GOTO_NEXT_R %edx
4929
4930
4931/* ------------------------------ */
4932    .balign 64
4933.L_OP_SUB_LONG_2ADDR: /* 0xbc */
4934/* File: x86/OP_SUB_LONG_2ADDR.S */
4935/* File: x86/binopWide2addr.S */
4936    /*
4937     * Generic 64-bit binary operation.
4938     */
4939    /* binop/2addr vA, vB */
4940    movzbl    rINSTbl,%ecx              # ecx<- BA
4941    sarl      $4,%ecx                  # ecx<- B
4942    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
4943    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
4944    andb      $0xF,rINSTbl             # rINST<- A
4945    subl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
4946    sbbl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
4947    FETCH_INST_OPCODE 1 %edx
4948    ADVANCE_PC 1
4949    GOTO_NEXT_R %edx
4950
4951
4952/* ------------------------------ */
4953    .balign 64
4954.L_OP_MUL_LONG_2ADDR: /* 0xbd */
4955/* File: x86/OP_MUL_LONG_2ADDR.S */
4956    /*
4957     * Signed 64-bit integer multiply, 2-addr version
4958     *
4959     * We could definately use more free registers for
4960     * this code.  We must spill %edx (edx) because it
4961     * is used by imul.  We'll also spill rINST (ebx),
4962     * giving us eax, ebc, ecx and edx as computational
4963     * temps.  On top of that, we'll spill %esi (edi)
4964     * for use as the vA pointer and rFP (esi) for use
4965     * as the vB pointer.  Yuck.
4966     */
4967    /* mul-long/2addr vA, vB */
4968    movzbl    rINSTbl,%eax             # eax<- BA
4969    andb      $0xf,%al                # eax<- A
4970    sarl      $4,rINST                # rINST<- B
4971    SPILL_TMP2(%esi)
4972    SPILL(rFP)
4973    leal      (rFP,%eax,4),%esi        # %esi<- &v[A]
4974    leal      (rFP,rINST,4),rFP        # rFP<- &v[B]
4975    movl      4(%esi),%ecx             # ecx<- Amsw
4976    imull     (rFP),%ecx               # ecx<- (Amsw*Blsw)
4977    movl      4(rFP),%eax              # eax<- Bmsw
4978    imull     (%esi),%eax              # eax<- (Bmsw*Alsw)
4979    addl      %eax,%ecx                # ecx<- (Amsw*Blsw)+(Bmsw*Alsw)
4980    movl      (rFP),%eax               # eax<- Blsw
4981    mull      (%esi)                   # eax<- (Blsw*Alsw)
4982    jmp       .LOP_MUL_LONG_2ADDR_continue
4983
4984/* ------------------------------ */
4985    .balign 64
4986.L_OP_DIV_LONG_2ADDR: /* 0xbe */
4987/* File: x86/OP_DIV_LONG_2ADDR.S */
4988    /* div/2addr vA, vB */
4989    movzbl    rINSTbl,%eax
4990    shrl      $4,%eax                  # eax<- B
4991    andb      $0xf,rINSTbl             # rINST<- A
4992    GET_VREG_WORD %edx %eax 0
4993    GET_VREG_WORD %eax %eax 1
4994    movl     %edx,OUT_ARG2(%esp)
4995    testl    %eax,%eax
4996    je       .LOP_DIV_LONG_2ADDR_check_zero
4997    cmpl     $-1,%eax
4998    je       .LOP_DIV_LONG_2ADDR_check_neg1
4999.LOP_DIV_LONG_2ADDR_notSpecial:
5000    GET_VREG_WORD %edx rINST 0
5001    GET_VREG_WORD %ecx rINST 1
5002.LOP_DIV_LONG_2ADDR_notSpecial1:
5003    jmp      .LOP_DIV_LONG_2ADDR_continue
5004
5005/* ------------------------------ */
5006    .balign 64
5007.L_OP_REM_LONG_2ADDR: /* 0xbf */
5008/* File: x86/OP_REM_LONG_2ADDR.S */
5009/* File: x86/OP_DIV_LONG_2ADDR.S */
5010    /* div/2addr vA, vB */
5011    movzbl    rINSTbl,%eax
5012    shrl      $4,%eax                  # eax<- B
5013    andb      $0xf,rINSTbl             # rINST<- A
5014    GET_VREG_WORD %edx %eax 0
5015    GET_VREG_WORD %eax %eax 1
5016    movl     %edx,OUT_ARG2(%esp)
5017    testl    %eax,%eax
5018    je       .LOP_REM_LONG_2ADDR_check_zero
5019    cmpl     $-1,%eax
5020    je       .LOP_REM_LONG_2ADDR_check_neg1
5021.LOP_REM_LONG_2ADDR_notSpecial:
5022    GET_VREG_WORD %edx rINST 0
5023    GET_VREG_WORD %ecx rINST 1
5024.LOP_REM_LONG_2ADDR_notSpecial1:
5025    jmp      .LOP_REM_LONG_2ADDR_continue
5026
5027
5028/* ------------------------------ */
5029    .balign 64
5030.L_OP_AND_LONG_2ADDR: /* 0xc0 */
5031/* File: x86/OP_AND_LONG_2ADDR.S */
5032/* File: x86/binopWide2addr.S */
5033    /*
5034     * Generic 64-bit binary operation.
5035     */
5036    /* binop/2addr vA, vB */
5037    movzbl    rINSTbl,%ecx              # ecx<- BA
5038    sarl      $4,%ecx                  # ecx<- B
5039    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
5040    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
5041    andb      $0xF,rINSTbl             # rINST<- A
5042    andl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
5043    andl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
5044    FETCH_INST_OPCODE 1 %edx
5045    ADVANCE_PC 1
5046    GOTO_NEXT_R %edx
5047
5048
5049/* ------------------------------ */
5050    .balign 64
5051.L_OP_OR_LONG_2ADDR: /* 0xc1 */
5052/* File: x86/OP_OR_LONG_2ADDR.S */
5053/* File: x86/binopWide2addr.S */
5054    /*
5055     * Generic 64-bit binary operation.
5056     */
5057    /* binop/2addr vA, vB */
5058    movzbl    rINSTbl,%ecx              # ecx<- BA
5059    sarl      $4,%ecx                  # ecx<- B
5060    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
5061    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
5062    andb      $0xF,rINSTbl             # rINST<- A
5063    orl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
5064    orl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
5065    FETCH_INST_OPCODE 1 %edx
5066    ADVANCE_PC 1
5067    GOTO_NEXT_R %edx
5068
5069
5070/* ------------------------------ */
5071    .balign 64
5072.L_OP_XOR_LONG_2ADDR: /* 0xc2 */
5073/* File: x86/OP_XOR_LONG_2ADDR.S */
5074/* File: x86/binopWide2addr.S */
5075    /*
5076     * Generic 64-bit binary operation.
5077     */
5078    /* binop/2addr vA, vB */
5079    movzbl    rINSTbl,%ecx              # ecx<- BA
5080    sarl      $4,%ecx                  # ecx<- B
5081    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
5082    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
5083    andb      $0xF,rINSTbl             # rINST<- A
5084    xorl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
5085    xorl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
5086    FETCH_INST_OPCODE 1 %edx
5087    ADVANCE_PC 1
5088    GOTO_NEXT_R %edx
5089
5090
5091/* ------------------------------ */
5092    .balign 64
5093.L_OP_SHL_LONG_2ADDR: /* 0xc3 */
5094/* File: x86/OP_SHL_LONG_2ADDR.S */
5095    /*
5096     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
5097     * 32-bit shift distance.
5098     */
5099    /* shl-long/2addr vA, vB */
5100    /* ecx gets shift count */
5101    /* Need to spill edx */
5102    /* rINSTw gets AA */
5103    movzbl    rINSTbl,%ecx             # ecx<- BA
5104    andb      $0xf,rINSTbl            # rINST<- A
5105    GET_VREG_WORD %eax rINST 0         # eax<- v[AA+0]
5106    sarl      $4,%ecx                 # ecx<- B
5107    GET_VREG_WORD %edx rINST 1         # edx<- v[AA+1]
5108    GET_VREG_R  %ecx %ecx              # ecx<- vBB
5109    shldl     %eax,%edx
5110    sall      %cl,%eax
5111    testb     $32,%cl
5112    je        2f
5113    movl      %eax,%edx
5114    xorl      %eax,%eax
51152:
5116    SET_VREG_WORD %edx rINST 1         # v[AA+1]<- edx
5117    jmp       .LOP_SHL_LONG_2ADDR_finish
5118
5119/* ------------------------------ */
5120    .balign 64
5121.L_OP_SHR_LONG_2ADDR: /* 0xc4 */
5122/* File: x86/OP_SHR_LONG_2ADDR.S */
5123    /*
5124     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
5125     * 32-bit shift distance.
5126     */
5127    /* shl-long/2addr vA, vB */
5128    /* ecx gets shift count */
5129    /* Need to spill edx */
5130    /* rINSTw gets AA */
5131    movzbl    rINSTbl,%ecx         # ecx<- BA
5132    andb      $0xf,rINSTbl        # rINST<- A
5133    GET_VREG_WORD %eax rINST 0     # eax<- v[AA+0]
5134    sarl      $4,%ecx             # ecx<- B
5135    GET_VREG_WORD %edx rINST 1     # edx<- v[AA+1]
5136    GET_VREG_R %ecx %ecx           # ecx<- vBB
5137    shrdl     %edx,%eax
5138    sarl      %cl,%edx
5139    testb     $32,%cl
5140    je        2f
5141    movl      %edx,%eax
5142    sarl      $31,%edx
51432:
5144    SET_VREG_WORD %edx rINST 1     # v[AA+1]<- edx
5145    jmp       .LOP_SHR_LONG_2ADDR_finish
5146
5147/* ------------------------------ */
5148    .balign 64
5149.L_OP_USHR_LONG_2ADDR: /* 0xc5 */
5150/* File: x86/OP_USHR_LONG_2ADDR.S */
5151    /*
5152     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
5153     * 32-bit shift distance.
5154     */
5155    /* shl-long/2addr vA, vB */
5156    /* ecx gets shift count */
5157    /* Need to spill edx */
5158    /* rINSTw gets AA */
5159    movzbl    rINSTbl,%ecx             # ecx<- BA
5160    andb      $0xf,rINSTbl            # rINST<- A
5161    GET_VREG_WORD %eax rINST 0         # eax<- v[AA+0]
5162    sarl      $4,%ecx                 # ecx<- B
5163    GET_VREG_WORD %edx rINST 1         # edx<- v[AA+1]
5164    GET_VREG_R %ecx %ecx               # ecx<- vBB
5165    shrdl     %edx,%eax
5166    shrl      %cl,%edx
5167    testb     $32,%cl
5168    je        2f
5169    movl      %edx,%eax
5170    xorl      %edx,%edx
51712:
5172    SET_VREG_WORD %edx rINST 1         # v[AA+1]<- edx
5173    jmp       .LOP_USHR_LONG_2ADDR_finish
5174
5175/* ------------------------------ */
5176    .balign 64
5177.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
5178/* File: x86/OP_ADD_FLOAT_2ADDR.S */
5179/* File: x86/binflop2addr.S */
5180    /*
5181     * Generic 32-bit binary float operation.
5182     *
5183     * For: add-fp, sub-fp, mul-fp, div-fp
5184     */
5185
5186    /* binop/2addr vA, vB */
5187    movzx   rINSTbl,%ecx           # ecx<- A+
5188    andb    $0xf,%cl              # ecx<- A
5189    flds    (rFP,%ecx,4)          # vAA to fp stack
5190    sarl    $4,rINST             # rINST<- B
5191    fadds   (rFP,rINST,4)         # ex: faddp
5192    FETCH_INST_OPCODE 1 %edx
5193    ADVANCE_PC 1
5194    fstps    (rFP,%ecx,4)         # %st to vA
5195    GOTO_NEXT_R %edx
5196
5197
5198/* ------------------------------ */
5199    .balign 64
5200.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
5201/* File: x86/OP_SUB_FLOAT_2ADDR.S */
5202/* File: x86/binflop2addr.S */
5203    /*
5204     * Generic 32-bit binary float operation.
5205     *
5206     * For: add-fp, sub-fp, mul-fp, div-fp
5207     */
5208
5209    /* binop/2addr vA, vB */
5210    movzx   rINSTbl,%ecx           # ecx<- A+
5211    andb    $0xf,%cl              # ecx<- A
5212    flds    (rFP,%ecx,4)          # vAA to fp stack
5213    sarl    $4,rINST             # rINST<- B
5214    fsubs   (rFP,rINST,4)         # ex: faddp
5215    FETCH_INST_OPCODE 1 %edx
5216    ADVANCE_PC 1
5217    fstps    (rFP,%ecx,4)         # %st to vA
5218    GOTO_NEXT_R %edx
5219
5220
5221/* ------------------------------ */
5222    .balign 64
5223.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
5224/* File: x86/OP_MUL_FLOAT_2ADDR.S */
5225/* File: x86/binflop2addr.S */
5226    /*
5227     * Generic 32-bit binary float operation.
5228     *
5229     * For: add-fp, sub-fp, mul-fp, div-fp
5230     */
5231
5232    /* binop/2addr vA, vB */
5233    movzx   rINSTbl,%ecx           # ecx<- A+
5234    andb    $0xf,%cl              # ecx<- A
5235    flds    (rFP,%ecx,4)          # vAA to fp stack
5236    sarl    $4,rINST             # rINST<- B
5237    fmuls   (rFP,rINST,4)         # ex: faddp
5238    FETCH_INST_OPCODE 1 %edx
5239    ADVANCE_PC 1
5240    fstps    (rFP,%ecx,4)         # %st to vA
5241    GOTO_NEXT_R %edx
5242
5243
5244/* ------------------------------ */
5245    .balign 64
5246.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
5247/* File: x86/OP_DIV_FLOAT_2ADDR.S */
5248/* File: x86/binflop2addr.S */
5249    /*
5250     * Generic 32-bit binary float operation.
5251     *
5252     * For: add-fp, sub-fp, mul-fp, div-fp
5253     */
5254
5255    /* binop/2addr vA, vB */
5256    movzx   rINSTbl,%ecx           # ecx<- A+
5257    andb    $0xf,%cl              # ecx<- A
5258    flds    (rFP,%ecx,4)          # vAA to fp stack
5259    sarl    $4,rINST             # rINST<- B
5260    fdivs   (rFP,rINST,4)         # ex: faddp
5261    FETCH_INST_OPCODE 1 %edx
5262    ADVANCE_PC 1
5263    fstps    (rFP,%ecx,4)         # %st to vA
5264    GOTO_NEXT_R %edx
5265
5266
5267/* ------------------------------ */
5268    .balign 64
5269.L_OP_REM_FLOAT_2ADDR: /* 0xca */
5270/* File: x86/OP_REM_FLOAT_2ADDR.S */
5271    /* rem_float/2addr vA, vB */
5272    movzx   rINSTbl,%ecx                # ecx<- A+
5273    sarl    $4,rINST                  # rINST<- B
5274    flds     (rFP,rINST,4)              # vBB to fp stack
5275    andb    $0xf,%cl                   # ecx<- A
5276    flds     (rFP,%ecx,4)               # vAA to fp stack
5277    FETCH_INST_OPCODE 1 %edx
52781:
5279    fprem
5280    fstsw     %ax
5281    sahf
5282    jp        1b
5283    fstp      %st(1)
5284    ADVANCE_PC 1
5285    fstps    (rFP,%ecx,4)               # %st to vA
5286    GOTO_NEXT_R %edx
5287
5288/* ------------------------------ */
5289    .balign 64
5290.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
5291/* File: x86/OP_ADD_DOUBLE_2ADDR.S */
5292/* File: x86/binflop2addr.S */
5293    /*
5294     * Generic 32-bit binary float operation.
5295     *
5296     * For: add-fp, sub-fp, mul-fp, div-fp
5297     */
5298
5299    /* binop/2addr vA, vB */
5300    movzx   rINSTbl,%ecx           # ecx<- A+
5301    andb    $0xf,%cl              # ecx<- A
5302    fldl    (rFP,%ecx,4)          # vAA to fp stack
5303    sarl    $4,rINST             # rINST<- B
5304    faddl   (rFP,rINST,4)         # ex: faddp
5305    FETCH_INST_OPCODE 1 %edx
5306    ADVANCE_PC 1
5307    fstpl    (rFP,%ecx,4)         # %st to vA
5308    GOTO_NEXT_R %edx
5309
5310
5311/* ------------------------------ */
5312    .balign 64
5313.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
5314/* File: x86/OP_SUB_DOUBLE_2ADDR.S */
5315/* File: x86/binflop2addr.S */
5316    /*
5317     * Generic 32-bit binary float operation.
5318     *
5319     * For: add-fp, sub-fp, mul-fp, div-fp
5320     */
5321
5322    /* binop/2addr vA, vB */
5323    movzx   rINSTbl,%ecx           # ecx<- A+
5324    andb    $0xf,%cl              # ecx<- A
5325    fldl    (rFP,%ecx,4)          # vAA to fp stack
5326    sarl    $4,rINST             # rINST<- B
5327    fsubl   (rFP,rINST,4)         # ex: faddp
5328    FETCH_INST_OPCODE 1 %edx
5329    ADVANCE_PC 1
5330    fstpl    (rFP,%ecx,4)         # %st to vA
5331    GOTO_NEXT_R %edx
5332
5333
5334/* ------------------------------ */
5335    .balign 64
5336.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
5337/* File: x86/OP_MUL_DOUBLE_2ADDR.S */
5338/* File: x86/binflop2addr.S */
5339    /*
5340     * Generic 32-bit binary float operation.
5341     *
5342     * For: add-fp, sub-fp, mul-fp, div-fp
5343     */
5344
5345    /* binop/2addr vA, vB */
5346    movzx   rINSTbl,%ecx           # ecx<- A+
5347    andb    $0xf,%cl              # ecx<- A
5348    fldl    (rFP,%ecx,4)          # vAA to fp stack
5349    sarl    $4,rINST             # rINST<- B
5350    fmull   (rFP,rINST,4)         # ex: faddp
5351    FETCH_INST_OPCODE 1 %edx
5352    ADVANCE_PC 1
5353    fstpl    (rFP,%ecx,4)         # %st to vA
5354    GOTO_NEXT_R %edx
5355
5356
5357/* ------------------------------ */
5358    .balign 64
5359.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */
5360/* File: x86/OP_DIV_DOUBLE_2ADDR.S */
5361/* File: x86/binflop2addr.S */
5362    /*
5363     * Generic 32-bit binary float operation.
5364     *
5365     * For: add-fp, sub-fp, mul-fp, div-fp
5366     */
5367
5368    /* binop/2addr vA, vB */
5369    movzx   rINSTbl,%ecx           # ecx<- A+
5370    andb    $0xf,%cl              # ecx<- A
5371    fldl    (rFP,%ecx,4)          # vAA to fp stack
5372    sarl    $4,rINST             # rINST<- B
5373    fdivl   (rFP,rINST,4)         # ex: faddp
5374    FETCH_INST_OPCODE 1 %edx
5375    ADVANCE_PC 1
5376    fstpl    (rFP,%ecx,4)         # %st to vA
5377    GOTO_NEXT_R %edx
5378
5379
5380/* ------------------------------ */
5381    .balign 64
5382.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */
5383/* File: x86/OP_REM_DOUBLE_2ADDR.S */
5384    /* rem_float/2addr vA, vB */
5385    movzx   rINSTbl,%ecx                # ecx<- A+
5386    sarl    $4,rINST                  # rINST<- B
5387    fldl     (rFP,rINST,4)              # vBB to fp stack
5388    andb    $0xf,%cl                   # ecx<- A
5389    fldl     (rFP,%ecx,4)               # vAA to fp stack
5390    FETCH_INST_OPCODE 1 %edx
53911:
5392    fprem
5393    fstsw     %ax
5394    sahf
5395    jp        1b
5396    fstp      %st(1)
5397    ADVANCE_PC 1
5398    fstpl    (rFP,%ecx,4)               # %st to vA
5399    GOTO_NEXT_R %edx
5400
5401/* ------------------------------ */
5402    .balign 64
5403.L_OP_ADD_INT_LIT16: /* 0xd0 */
5404/* File: x86/OP_ADD_INT_LIT16.S */
5405/* File: x86/binopLit16.S */
5406    /*
5407     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
5408     * that specifies an instruction that performs "result = eax op ecx".
5409     * This could be an x86 instruction or a function call.  (If the result
5410     * comes back in a register other than eax, you can override "result".)
5411     *
5412     * For: add-int/lit16, rsub-int,
5413     *      and-int/lit16, or-int/lit16, xor-int/lit16
5414     */
5415    /* binop/lit16 vA, vB, #+CCCC */
5416    movzbl   rINSTbl,%eax               # eax<- 000000BA
5417    sarl     $4,%eax                   # eax<- B
5418    GET_VREG_R %eax %eax                # eax<- vB
5419    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
5420    andb     $0xf,rINSTbl              # rINST<- A
5421    addl %ecx,%eax                              # for example: addl %ecx, %eax
5422    SET_VREG %eax rINST
5423    FETCH_INST_OPCODE 2 %edx
5424    ADVANCE_PC 2
5425    GOTO_NEXT_R %edx
5426
5427
5428/* ------------------------------ */
5429    .balign 64
5430.L_OP_RSUB_INT: /* 0xd1 */
5431/* File: x86/OP_RSUB_INT.S */
5432/* File: x86/binopLit16.S */
5433    /*
5434     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
5435     * that specifies an instruction that performs "result = eax op ecx".
5436     * This could be an x86 instruction or a function call.  (If the result
5437     * comes back in a register other than eax, you can override "result".)
5438     *
5439     * For: add-int/lit16, rsub-int,
5440     *      and-int/lit16, or-int/lit16, xor-int/lit16
5441     */
5442    /* binop/lit16 vA, vB, #+CCCC */
5443    movzbl   rINSTbl,%eax               # eax<- 000000BA
5444    sarl     $4,%eax                   # eax<- B
5445    GET_VREG_R %eax %eax                # eax<- vB
5446    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
5447    andb     $0xf,rINSTbl              # rINST<- A
5448    subl %eax,%ecx                              # for example: addl %ecx, %eax
5449    SET_VREG %ecx rINST
5450    FETCH_INST_OPCODE 2 %edx
5451    ADVANCE_PC 2
5452    GOTO_NEXT_R %edx
5453
5454
5455/* ------------------------------ */
5456    .balign 64
5457.L_OP_MUL_INT_LIT16: /* 0xd2 */
5458/* File: x86/OP_MUL_INT_LIT16.S */
5459    /* mul/lit16 vA, vB, #+CCCC */
5460    /* Need A in rINST, ssssCCCC in ecx, vB in eax */
5461    movzbl   rINSTbl,%eax               # eax<- 000000BA
5462    sarl     $4,%eax                   # eax<- B
5463    GET_VREG_R %eax %eax                # eax<- vB
5464    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
5465    andb     $0xf,rINSTbl              # rINST<- A
5466    imull     %ecx,%eax                 # trashes edx
5467    FETCH_INST_OPCODE 2 %edx
5468    ADVANCE_PC 2
5469    SET_VREG %eax rINST
5470    GOTO_NEXT_R %edx
5471
5472/* ------------------------------ */
5473    .balign 64
5474.L_OP_DIV_INT_LIT16: /* 0xd3 */
5475/* File: x86/OP_DIV_INT_LIT16.S */
5476/* File: x86/bindivLit16.S */
5477    /*
5478     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
5479     * op1=-1.
5480     */
5481    /* div/rem/lit16 vA, vB, #+CCCC */
5482    /* Need A in rINST, ssssCCCC in ecx, vB in eax */
5483    movzbl   rINSTbl,%eax         # eax<- 000000BA
5484    sarl     $4,%eax             # eax<- B
5485    GET_VREG_R %eax %eax          # eax<- vB
5486    movswl   2(rPC),%ecx          # ecx<- ssssCCCC
5487    andb     $0xf,rINSTbl        # rINST<- A
5488    cmpl     $0,%ecx
5489    je       common_errDivideByZero
5490    cmpl     $-1,%ecx
5491    jne      .LOP_DIV_INT_LIT16_continue_div
5492    cmpl     $0x80000000,%eax
5493    jne      .LOP_DIV_INT_LIT16_continue_div
5494    movl     $0x80000000,%eax
5495    jmp      .LOP_DIV_INT_LIT16_finish_div
5496
5497
5498
5499/* ------------------------------ */
5500    .balign 64
5501.L_OP_REM_INT_LIT16: /* 0xd4 */
5502/* File: x86/OP_REM_INT_LIT16.S */
5503/* File: x86/bindivLit16.S */
5504    /*
5505     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
5506     * op1=-1.
5507     */
5508    /* div/rem/lit16 vA, vB, #+CCCC */
5509    /* Need A in rINST, ssssCCCC in ecx, vB in eax */
5510    movzbl   rINSTbl,%eax         # eax<- 000000BA
5511    sarl     $4,%eax             # eax<- B
5512    GET_VREG_R %eax %eax          # eax<- vB
5513    movswl   2(rPC),%ecx          # ecx<- ssssCCCC
5514    andb     $0xf,rINSTbl        # rINST<- A
5515    cmpl     $0,%ecx
5516    je       common_errDivideByZero
5517    cmpl     $-1,%ecx
5518    jne      .LOP_REM_INT_LIT16_continue_div
5519    cmpl     $0x80000000,%eax
5520    jne      .LOP_REM_INT_LIT16_continue_div
5521    movl     $0,%edx
5522    jmp      .LOP_REM_INT_LIT16_finish_div
5523
5524
5525
5526/* ------------------------------ */
5527    .balign 64
5528.L_OP_AND_INT_LIT16: /* 0xd5 */
5529/* File: x86/OP_AND_INT_LIT16.S */
5530/* File: x86/binopLit16.S */
5531    /*
5532     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
5533     * that specifies an instruction that performs "result = eax op ecx".
5534     * This could be an x86 instruction or a function call.  (If the result
5535     * comes back in a register other than eax, you can override "result".)
5536     *
5537     * For: add-int/lit16, rsub-int,
5538     *      and-int/lit16, or-int/lit16, xor-int/lit16
5539     */
5540    /* binop/lit16 vA, vB, #+CCCC */
5541    movzbl   rINSTbl,%eax               # eax<- 000000BA
5542    sarl     $4,%eax                   # eax<- B
5543    GET_VREG_R %eax %eax                # eax<- vB
5544    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
5545    andb     $0xf,rINSTbl              # rINST<- A
5546    andl %ecx,%eax                              # for example: addl %ecx, %eax
5547    SET_VREG %eax rINST
5548    FETCH_INST_OPCODE 2 %edx
5549    ADVANCE_PC 2
5550    GOTO_NEXT_R %edx
5551
5552
5553/* ------------------------------ */
5554    .balign 64
5555.L_OP_OR_INT_LIT16: /* 0xd6 */
5556/* File: x86/OP_OR_INT_LIT16.S */
5557/* File: x86/binopLit16.S */
5558    /*
5559     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
5560     * that specifies an instruction that performs "result = eax op ecx".
5561     * This could be an x86 instruction or a function call.  (If the result
5562     * comes back in a register other than eax, you can override "result".)
5563     *
5564     * For: add-int/lit16, rsub-int,
5565     *      and-int/lit16, or-int/lit16, xor-int/lit16
5566     */
5567    /* binop/lit16 vA, vB, #+CCCC */
5568    movzbl   rINSTbl,%eax               # eax<- 000000BA
5569    sarl     $4,%eax                   # eax<- B
5570    GET_VREG_R %eax %eax                # eax<- vB
5571    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
5572    andb     $0xf,rINSTbl              # rINST<- A
5573    orl     %ecx,%eax                              # for example: addl %ecx, %eax
5574    SET_VREG %eax rINST
5575    FETCH_INST_OPCODE 2 %edx
5576    ADVANCE_PC 2
5577    GOTO_NEXT_R %edx
5578
5579
5580/* ------------------------------ */
5581    .balign 64
5582.L_OP_XOR_INT_LIT16: /* 0xd7 */
5583/* File: x86/OP_XOR_INT_LIT16.S */
5584/* File: x86/binopLit16.S */
5585    /*
5586     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
5587     * that specifies an instruction that performs "result = eax op ecx".
5588     * This could be an x86 instruction or a function call.  (If the result
5589     * comes back in a register other than eax, you can override "result".)
5590     *
5591     * For: add-int/lit16, rsub-int,
5592     *      and-int/lit16, or-int/lit16, xor-int/lit16
5593     */
5594    /* binop/lit16 vA, vB, #+CCCC */
5595    movzbl   rINSTbl,%eax               # eax<- 000000BA
5596    sarl     $4,%eax                   # eax<- B
5597    GET_VREG_R %eax %eax                # eax<- vB
5598    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
5599    andb     $0xf,rINSTbl              # rINST<- A
5600    xor    %ecx,%eax                              # for example: addl %ecx, %eax
5601    SET_VREG %eax rINST
5602    FETCH_INST_OPCODE 2 %edx
5603    ADVANCE_PC 2
5604    GOTO_NEXT_R %edx
5605
5606
5607/* ------------------------------ */
5608    .balign 64
5609.L_OP_ADD_INT_LIT8: /* 0xd8 */
5610/* File: x86/OP_ADD_INT_LIT8.S */
5611/* File: x86/binopLit8.S */
5612    /*
5613     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
5614     * that specifies an instruction that performs "result = eax op ecx".
5615     * This could be an x86 instruction or a function call.  (If the result
5616     * comes back in a register other than r0, you can override "result".)
5617     *
5618     * For: add-int/lit8, rsub-int/lit8
5619     *      and-int/lit8, or-int/lit8, xor-int/lit8,
5620     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
5621     */
5622    /* binop/lit8 vAA, vBB, #+CC */
5623    movzbl    2(rPC),%eax              # eax<- BB
5624    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
5625    GET_VREG_R   %eax %eax             # eax<- rBB
5626    addl %ecx,%eax                             # ex: addl %ecx,%eax
5627    FETCH_INST_OPCODE 2 %edx
5628    SET_VREG   %eax rINST
5629    ADVANCE_PC 2
5630    GOTO_NEXT_R %edx
5631
5632
5633/* ------------------------------ */
5634    .balign 64
5635.L_OP_RSUB_INT_LIT8: /* 0xd9 */
5636/* File: x86/OP_RSUB_INT_LIT8.S */
5637/* File: x86/binopLit8.S */
5638    /*
5639     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
5640     * that specifies an instruction that performs "result = eax op ecx".
5641     * This could be an x86 instruction or a function call.  (If the result
5642     * comes back in a register other than r0, you can override "result".)
5643     *
5644     * For: add-int/lit8, rsub-int/lit8
5645     *      and-int/lit8, or-int/lit8, xor-int/lit8,
5646     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
5647     */
5648    /* binop/lit8 vAA, vBB, #+CC */
5649    movzbl    2(rPC),%eax              # eax<- BB
5650    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
5651    GET_VREG_R   %eax %eax             # eax<- rBB
5652    subl  %eax,%ecx                             # ex: addl %ecx,%eax
5653    FETCH_INST_OPCODE 2 %edx
5654    SET_VREG   %ecx rINST
5655    ADVANCE_PC 2
5656    GOTO_NEXT_R %edx
5657
5658
5659/* ------------------------------ */
5660    .balign 64
5661.L_OP_MUL_INT_LIT8: /* 0xda */
5662/* File: x86/OP_MUL_INT_LIT8.S */
5663    /* mul/lit8 vAA, vBB, #+CC */
5664    movzbl    2(rPC),%eax              # eax<- BB
5665    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
5666    GET_VREG_R   %eax %eax             # eax<- rBB
5667    imull     %ecx,%eax                # trashes edx
5668    FETCH_INST_OPCODE 2 %edx
5669    ADVANCE_PC 2
5670    SET_VREG  %eax rINST
5671    GOTO_NEXT_R %edx
5672
5673/* ------------------------------ */
5674    .balign 64
5675.L_OP_DIV_INT_LIT8: /* 0xdb */
5676/* File: x86/OP_DIV_INT_LIT8.S */
5677/* File: x86/bindivLit8.S */
5678    /*
5679     * 32-bit div/rem "lit8" binary operation.  Handles special case of
5680     * op0=minint & op1=-1
5681     */
5682    /* div/rem/lit8 vAA, vBB, #+CC */
5683    movzbl    2(rPC),%eax        # eax<- BB
5684    movsbl    3(rPC),%ecx        # ecx<- ssssssCC
5685    GET_VREG_R  %eax %eax        # eax<- rBB
5686    cmpl     $0,%ecx
5687    je       common_errDivideByZero
5688    cmpl     $0x80000000,%eax
5689    jne      .LOP_DIV_INT_LIT8_continue_div
5690    cmpl     $-1,%ecx
5691    jne      .LOP_DIV_INT_LIT8_continue_div
5692    movl     $0x80000000,%eax
5693    jmp      .LOP_DIV_INT_LIT8_finish_div
5694
5695
5696
5697/* ------------------------------ */
5698    .balign 64
5699.L_OP_REM_INT_LIT8: /* 0xdc */
5700/* File: x86/OP_REM_INT_LIT8.S */
5701/* File: x86/bindivLit8.S */
5702    /*
5703     * 32-bit div/rem "lit8" binary operation.  Handles special case of
5704     * op0=minint & op1=-1
5705     */
5706    /* div/rem/lit8 vAA, vBB, #+CC */
5707    movzbl    2(rPC),%eax        # eax<- BB
5708    movsbl    3(rPC),%ecx        # ecx<- ssssssCC
5709    GET_VREG_R  %eax %eax        # eax<- rBB
5710    cmpl     $0,%ecx
5711    je       common_errDivideByZero
5712    cmpl     $0x80000000,%eax
5713    jne      .LOP_REM_INT_LIT8_continue_div
5714    cmpl     $-1,%ecx
5715    jne      .LOP_REM_INT_LIT8_continue_div
5716    movl     $0,%edx
5717    jmp      .LOP_REM_INT_LIT8_finish_div
5718
5719
5720
5721/* ------------------------------ */
5722    .balign 64
5723.L_OP_AND_INT_LIT8: /* 0xdd */
5724/* File: x86/OP_AND_INT_LIT8.S */
5725/* File: x86/binopLit8.S */
5726    /*
5727     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
5728     * that specifies an instruction that performs "result = eax op ecx".
5729     * This could be an x86 instruction or a function call.  (If the result
5730     * comes back in a register other than r0, you can override "result".)
5731     *
5732     * For: add-int/lit8, rsub-int/lit8
5733     *      and-int/lit8, or-int/lit8, xor-int/lit8,
5734     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
5735     */
5736    /* binop/lit8 vAA, vBB, #+CC */
5737    movzbl    2(rPC),%eax              # eax<- BB
5738    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
5739    GET_VREG_R   %eax %eax             # eax<- rBB
5740    andl %ecx,%eax                             # ex: addl %ecx,%eax
5741    FETCH_INST_OPCODE 2 %edx
5742    SET_VREG   %eax rINST
5743    ADVANCE_PC 2
5744    GOTO_NEXT_R %edx
5745
5746
5747/* ------------------------------ */
5748    .balign 64
5749.L_OP_OR_INT_LIT8: /* 0xde */
5750/* File: x86/OP_OR_INT_LIT8.S */
5751/* File: x86/binopLit8.S */
5752    /*
5753     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
5754     * that specifies an instruction that performs "result = eax op ecx".
5755     * This could be an x86 instruction or a function call.  (If the result
5756     * comes back in a register other than r0, you can override "result".)
5757     *
5758     * For: add-int/lit8, rsub-int/lit8
5759     *      and-int/lit8, or-int/lit8, xor-int/lit8,
5760     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
5761     */
5762    /* binop/lit8 vAA, vBB, #+CC */
5763    movzbl    2(rPC),%eax              # eax<- BB
5764    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
5765    GET_VREG_R   %eax %eax             # eax<- rBB
5766    orl     %ecx,%eax                             # ex: addl %ecx,%eax
5767    FETCH_INST_OPCODE 2 %edx
5768    SET_VREG   %eax rINST
5769    ADVANCE_PC 2
5770    GOTO_NEXT_R %edx
5771
5772
5773/* ------------------------------ */
5774    .balign 64
5775.L_OP_XOR_INT_LIT8: /* 0xdf */
5776/* File: x86/OP_XOR_INT_LIT8.S */
5777/* File: x86/binopLit8.S */
5778    /*
5779     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
5780     * that specifies an instruction that performs "result = eax op ecx".
5781     * This could be an x86 instruction or a function call.  (If the result
5782     * comes back in a register other than r0, you can override "result".)
5783     *
5784     * For: add-int/lit8, rsub-int/lit8
5785     *      and-int/lit8, or-int/lit8, xor-int/lit8,
5786     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
5787     */
5788    /* binop/lit8 vAA, vBB, #+CC */
5789    movzbl    2(rPC),%eax              # eax<- BB
5790    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
5791    GET_VREG_R   %eax %eax             # eax<- rBB
5792    xor    %ecx,%eax                             # ex: addl %ecx,%eax
5793    FETCH_INST_OPCODE 2 %edx
5794    SET_VREG   %eax rINST
5795    ADVANCE_PC 2
5796    GOTO_NEXT_R %edx
5797
5798
5799/* ------------------------------ */
5800    .balign 64
5801.L_OP_SHL_INT_LIT8: /* 0xe0 */
5802/* File: x86/OP_SHL_INT_LIT8.S */
5803/* File: x86/binopLit8.S */
5804    /*
5805     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
5806     * that specifies an instruction that performs "result = eax op ecx".
5807     * This could be an x86 instruction or a function call.  (If the result
5808     * comes back in a register other than r0, you can override "result".)
5809     *
5810     * For: add-int/lit8, rsub-int/lit8
5811     *      and-int/lit8, or-int/lit8, xor-int/lit8,
5812     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
5813     */
5814    /* binop/lit8 vAA, vBB, #+CC */
5815    movzbl    2(rPC),%eax              # eax<- BB
5816    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
5817    GET_VREG_R   %eax %eax             # eax<- rBB
5818    sall  %cl,%eax                             # ex: addl %ecx,%eax
5819    FETCH_INST_OPCODE 2 %edx
5820    SET_VREG   %eax rINST
5821    ADVANCE_PC 2
5822    GOTO_NEXT_R %edx
5823
5824
5825/* ------------------------------ */
5826    .balign 64
5827.L_OP_SHR_INT_LIT8: /* 0xe1 */
5828/* File: x86/OP_SHR_INT_LIT8.S */
5829/* File: x86/binopLit8.S */
5830    /*
5831     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
5832     * that specifies an instruction that performs "result = eax op ecx".
5833     * This could be an x86 instruction or a function call.  (If the result
5834     * comes back in a register other than r0, you can override "result".)
5835     *
5836     * For: add-int/lit8, rsub-int/lit8
5837     *      and-int/lit8, or-int/lit8, xor-int/lit8,
5838     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
5839     */
5840    /* binop/lit8 vAA, vBB, #+CC */
5841    movzbl    2(rPC),%eax              # eax<- BB
5842    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
5843    GET_VREG_R   %eax %eax             # eax<- rBB
5844    sarl    %cl,%eax                             # ex: addl %ecx,%eax
5845    FETCH_INST_OPCODE 2 %edx
5846    SET_VREG   %eax rINST
5847    ADVANCE_PC 2
5848    GOTO_NEXT_R %edx
5849
5850
5851/* ------------------------------ */
5852    .balign 64
5853.L_OP_USHR_INT_LIT8: /* 0xe2 */
5854/* File: x86/OP_USHR_INT_LIT8.S */
5855/* File: x86/binopLit8.S */
5856    /*
5857     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
5858     * that specifies an instruction that performs "result = eax op ecx".
5859     * This could be an x86 instruction or a function call.  (If the result
5860     * comes back in a register other than r0, you can override "result".)
5861     *
5862     * For: add-int/lit8, rsub-int/lit8
5863     *      and-int/lit8, or-int/lit8, xor-int/lit8,
5864     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
5865     */
5866    /* binop/lit8 vAA, vBB, #+CC */
5867    movzbl    2(rPC),%eax              # eax<- BB
5868    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
5869    GET_VREG_R   %eax %eax             # eax<- rBB
5870    shrl     %cl,%eax                             # ex: addl %ecx,%eax
5871    FETCH_INST_OPCODE 2 %edx
5872    SET_VREG   %eax rINST
5873    ADVANCE_PC 2
5874    GOTO_NEXT_R %edx
5875
5876
5877/* ------------------------------ */
5878    .balign 64
5879.L_OP_IGET_VOLATILE: /* 0xe3 */
5880/* File: x86/OP_IGET_VOLATILE.S */
5881/* File: x86/OP_IGET.S */
5882    /*
5883     * General 32-bit instance field get.
5884     *
5885     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
5886     */
5887    /* op vA, vB, field@CCCC */
5888    movl    rSELF,%ecx
5889    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
5890    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
5891    movzbl  rINSTbl,%ecx                        # ecx<- BA
5892    sarl    $4,%ecx                            # ecx<- B
5893    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
5894    andb    $0xf,rINSTbl                       # rINST<- A
5895    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
5896    movl    (%eax,%edx,4),%eax                  # resolved entry
5897    testl   %eax,%eax                           # is resolved entry null?
5898    jne     .LOP_IGET_VOLATILE_finish                  # no, already resolved
5899    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
5900    movl    rSELF,%edx
5901    jmp     .LOP_IGET_VOLATILE_resolve
5902
5903
5904/* ------------------------------ */
5905    .balign 64
5906.L_OP_IPUT_VOLATILE: /* 0xe4 */
5907/* File: x86/OP_IPUT_VOLATILE.S */
5908/* File: x86/OP_IPUT.S */
5909
5910    /*
5911     * General 32-bit instance field put.
5912     *
5913     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
5914     */
5915    /* op vA, vB, field@CCCC */
5916    movl    rSELF,%ecx
5917    movzwl  2(rPC),%edx                         # %edx<- 0000CCCC
5918    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
5919    movzbl  rINSTbl,%ecx                        # ecx<- BA
5920    sarl    $4,%ecx                            # ecx<- B
5921    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
5922    andb    $0xf,rINSTbl                       # rINST<- A
5923    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
5924    movl    (%eax,%edx,4),%eax                  # resolved entry
5925    testl   %eax,%eax                           # is resolved entry null?
5926    jne     .LOP_IPUT_VOLATILE_finish                  # no, already resolved
5927    movl    %edx,OUT_ARG1(%esp)
5928    movl    rSELF,%edx
5929    jmp     .LOP_IPUT_VOLATILE_resolve
5930
5931
5932/* ------------------------------ */
5933    .balign 64
5934.L_OP_SGET_VOLATILE: /* 0xe5 */
5935/* File: x86/OP_SGET_VOLATILE.S */
5936/* File: x86/OP_SGET.S */
5937    /*
5938     * General 32-bit SGET handler.
5939     *
5940     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
5941     */
5942    /* op vAA, field@BBBB */
5943    movl      rSELF,%ecx
5944    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
5945    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
5946    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
5947    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
5948    testl     %eax,%eax                          # resolved entry null?
5949    je        .LOP_SGET_VOLATILE_resolve                # if not, make it so
5950.LOP_SGET_VOLATILE_finish:     # field ptr in eax
5951    movl      offStaticField_value(%eax),%eax
5952    FETCH_INST_OPCODE 2 %edx
5953    ADVANCE_PC 2
5954    SET_VREG %eax rINST
5955    GOTO_NEXT_R %edx
5956
5957
5958/* ------------------------------ */
5959    .balign 64
5960.L_OP_SPUT_VOLATILE: /* 0xe6 */
5961/* File: x86/OP_SPUT_VOLATILE.S */
5962/* File: x86/OP_SPUT.S */
5963    /*
5964     * General 32-bit SPUT handler.
5965     *
5966     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
5967     */
5968    /* op vAA, field@BBBB */
5969    movl      rSELF,%ecx
5970    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
5971    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
5972    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
5973    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
5974    testl     %eax,%eax                          # resolved entry null?
5975    je        .LOP_SPUT_VOLATILE_resolve                # if not, make it so
5976.LOP_SPUT_VOLATILE_finish:     # field ptr in eax
5977    GET_VREG_R  %ecx rINST
5978    FETCH_INST_OPCODE 2 %edx
5979    ADVANCE_PC 2
5980    movl      %ecx,offStaticField_value(%eax)
5981    GOTO_NEXT_R %edx
5982
5983
5984/* ------------------------------ */
5985    .balign 64
5986.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
5987/* File: x86/OP_IGET_OBJECT_VOLATILE.S */
5988/* File: x86/OP_IGET.S */
5989    /*
5990     * General 32-bit instance field get.
5991     *
5992     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
5993     */
5994    /* op vA, vB, field@CCCC */
5995    movl    rSELF,%ecx
5996    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
5997    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
5998    movzbl  rINSTbl,%ecx                        # ecx<- BA
5999    sarl    $4,%ecx                            # ecx<- B
6000    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6001    andb    $0xf,rINSTbl                       # rINST<- A
6002    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
6003    movl    (%eax,%edx,4),%eax                  # resolved entry
6004    testl   %eax,%eax                           # is resolved entry null?
6005    jne     .LOP_IGET_OBJECT_VOLATILE_finish                  # no, already resolved
6006    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
6007    movl    rSELF,%edx
6008    jmp     .LOP_IGET_OBJECT_VOLATILE_resolve
6009
6010
6011/* ------------------------------ */
6012    .balign 64
6013.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
6014    /* (stub) */
6015    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
6016    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
6017    call      dvmMterp_OP_IGET_WIDE_VOLATILE     # do the real work
6018    mov       rSELF,%ecx
6019    LOAD_PC_FP_FROM_SELF             # retrieve updated values
6020    FETCH_INST
6021    GOTO_NEXT
6022/* ------------------------------ */
6023    .balign 64
6024.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
6025    /* (stub) */
6026    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
6027    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
6028    call      dvmMterp_OP_IPUT_WIDE_VOLATILE     # do the real work
6029    mov       rSELF,%ecx
6030    LOAD_PC_FP_FROM_SELF             # retrieve updated values
6031    FETCH_INST
6032    GOTO_NEXT
6033/* ------------------------------ */
6034    .balign 64
6035.L_OP_SGET_WIDE_VOLATILE: /* 0xea */
6036    /* (stub) */
6037    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
6038    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
6039    call      dvmMterp_OP_SGET_WIDE_VOLATILE     # do the real work
6040    mov       rSELF,%ecx
6041    LOAD_PC_FP_FROM_SELF             # retrieve updated values
6042    FETCH_INST
6043    GOTO_NEXT
6044/* ------------------------------ */
6045    .balign 64
6046.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
6047    /* (stub) */
6048    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
6049    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
6050    call      dvmMterp_OP_SPUT_WIDE_VOLATILE     # do the real work
6051    mov       rSELF,%ecx
6052    LOAD_PC_FP_FROM_SELF             # retrieve updated values
6053    FETCH_INST
6054    GOTO_NEXT
6055/* ------------------------------ */
6056    .balign 64
6057.L_OP_BREAKPOINT: /* 0xec */
6058/* File: x86/OP_BREAKPOINT.S */
6059/* File: x86/unused.S */
6060    jmp     common_abort
6061
6062
6063/* ------------------------------ */
6064    .balign 64
6065.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */
6066/* File: x86/OP_THROW_VERIFICATION_ERROR.S */
6067    /*
6068     * Handle a throw-verification-error instruction.  This throws an
6069     * exception for an error discovered during verification.  The
6070     * exception is indicated by AA, with some detail provided by BBBB.
6071     */
6072    /* op AA, ref@BBBB */
6073    movl     rSELF,%ecx
6074    movzwl   2(rPC),%eax                     # eax<- BBBB
6075    movl     offThread_method(%ecx),%ecx       # ecx<- self->method
6076    EXPORT_PC
6077    movl     %eax,OUT_ARG2(%esp)             # arg2<- BBBB
6078    movl     rINST,OUT_ARG1(%esp)            # arg1<- AA
6079    movl     %ecx,OUT_ARG0(%esp)             # arg0<- method
6080    call     dvmThrowVerificationError       # call(method, kind, ref)
6081    jmp      common_exceptionThrown          # handle exception
6082
6083/* ------------------------------ */
6084    .balign 64
6085.L_OP_EXECUTE_INLINE: /* 0xee */
6086/* File: x86/OP_EXECUTE_INLINE.S */
6087    /*
6088     * Execute a "native inline" instruction.
6089     *
6090     * We will be calling through a function table:
6091     *
6092     * (*gDvmInlineOpsTable[opIndex].func)(arg0, arg1, arg2, arg3, pResult)
6093     *
6094     * Ignores argument count - always loads 4.
6095     *
6096     */
6097    /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */
6098    movl      rSELF,%ecx
6099    EXPORT_PC
6100    movzwl    2(rPC),%eax               # eax<- BBBB
6101    leal      offThread_retval(%ecx),%ecx # ecx<- & self->retval
6102    movl      %ecx,OUT_ARG4(%esp)
6103    call      .LOP_EXECUTE_INLINE_continue      # make call; will return after
6104    testl     %eax,%eax                 # successful?
6105    FETCH_INST_OPCODE 3 %edx
6106    je        common_exceptionThrown    # no, handle exception
6107    ADVANCE_PC 3
6108    GOTO_NEXT_R %edx
6109
6110/* ------------------------------ */
6111    .balign 64
6112.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */
6113    /* (stub) */
6114    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
6115    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
6116    call      dvmMterp_OP_EXECUTE_INLINE_RANGE     # do the real work
6117    mov       rSELF,%ecx
6118    LOAD_PC_FP_FROM_SELF             # retrieve updated values
6119    FETCH_INST
6120    GOTO_NEXT
6121/* ------------------------------ */
6122    .balign 64
6123.L_OP_INVOKE_OBJECT_INIT: /* 0xf0 */
6124    /* (stub) */
6125    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
6126    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
6127    call      dvmMterp_OP_INVOKE_OBJECT_INIT     # do the real work
6128    mov       rSELF,%ecx
6129    LOAD_PC_FP_FROM_SELF             # retrieve updated values
6130    FETCH_INST
6131    GOTO_NEXT
6132/* ------------------------------ */
6133    .balign 64
6134.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */
6135    /* (stub) */
6136    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
6137    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
6138    call      dvmMterp_OP_RETURN_VOID_BARRIER     # do the real work
6139    mov       rSELF,%ecx
6140    LOAD_PC_FP_FROM_SELF             # retrieve updated values
6141    FETCH_INST
6142    GOTO_NEXT
6143/* ------------------------------ */
6144    .balign 64
6145.L_OP_IGET_QUICK: /* 0xf2 */
6146/* File: x86/OP_IGET_QUICK.S */
6147    /* For: iget-quick, iget-object-quick */
6148    /* op vA, vB, offset@CCCC */
6149    movzbl    rINSTbl,%ecx              # ecx<- BA
6150    sarl      $4,%ecx                  # ecx<- B
6151    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
6152    movzwl    2(rPC),%eax               # eax<- field byte offset
6153    cmpl      $0,%ecx                  # is object null?
6154    je        common_errNullObject
6155    movl      (%ecx,%eax,1),%eax
6156    FETCH_INST_OPCODE 2 %edx
6157    ADVANCE_PC 2
6158    andb      $0xf,rINSTbl             # rINST<- A
6159    SET_VREG  %eax rINST                # fp[A]<- result
6160    GOTO_NEXT_R %edx
6161
6162/* ------------------------------ */
6163    .balign 64
6164.L_OP_IGET_WIDE_QUICK: /* 0xf3 */
6165/* File: x86/OP_IGET_WIDE_QUICK.S */
6166    /* For: iget-wide-quick */
6167    /* op vA, vB, offset@CCCC */
6168    movzbl    rINSTbl,%ecx              # ecx<- BA
6169    sarl      $4,%ecx                  # ecx<- B
6170    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
6171    movzwl    2(rPC),%eax               # eax<- field byte offset
6172    cmpl      $0,%ecx                  # is object null?
6173    je        common_errNullObject
6174    leal      (%ecx,%eax,1),%eax        # eax<- address of 64-bit source
6175    movl      (%eax),%ecx               # ecx<- lsw
6176    movl      4(%eax),%eax              # eax<- msw
6177    andb      $0xf,rINSTbl             # rINST<- A
6178    FETCH_INST_OPCODE 2 %edx
6179    SET_VREG_WORD %ecx rINST 0          # v[A+0]<- lsw
6180    SET_VREG_WORD %eax rINST 1          # v[A+1]<- msw
6181    ADVANCE_PC 2
6182    GOTO_NEXT_R %edx
6183
6184/* ------------------------------ */
6185    .balign 64
6186.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */
6187/* File: x86/OP_IGET_OBJECT_QUICK.S */
6188/* File: x86/OP_IGET_QUICK.S */
6189    /* For: iget-quick, iget-object-quick */
6190    /* op vA, vB, offset@CCCC */
6191    movzbl    rINSTbl,%ecx              # ecx<- BA
6192    sarl      $4,%ecx                  # ecx<- B
6193    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
6194    movzwl    2(rPC),%eax               # eax<- field byte offset
6195    cmpl      $0,%ecx                  # is object null?
6196    je        common_errNullObject
6197    movl      (%ecx,%eax,1),%eax
6198    FETCH_INST_OPCODE 2 %edx
6199    ADVANCE_PC 2
6200    andb      $0xf,rINSTbl             # rINST<- A
6201    SET_VREG  %eax rINST                # fp[A]<- result
6202    GOTO_NEXT_R %edx
6203
6204
6205/* ------------------------------ */
6206    .balign 64
6207.L_OP_IPUT_QUICK: /* 0xf5 */
6208/* File: x86/OP_IPUT_QUICK.S */
6209    /* For: iput-quick */
6210    /* op vA, vB, offset@CCCC */
6211    movzbl    rINSTbl,%ecx              # ecx<- BA
6212    sarl      $4,%ecx                  # ecx<- B
6213    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
6214    andb      $0xf,rINSTbl             # rINST<- A
6215    GET_VREG_R  rINST,rINST             # rINST<- v[A]
6216    movzwl    2(rPC),%eax               # eax<- field byte offset
6217    testl     %ecx,%ecx                 # is object null?
6218    FETCH_INST_OPCODE 2 %edx
6219    je        common_errNullObject
6220    movl      rINST,(%ecx,%eax,1)
6221    ADVANCE_PC 2
6222    GOTO_NEXT_R %edx
6223
6224/* ------------------------------ */
6225    .balign 64
6226.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */
6227/* File: x86/OP_IPUT_WIDE_QUICK.S */
6228    /* For: iput-wide-quick */
6229    /* op vA, vB, offset@CCCC */
6230    movzbl    rINSTbl,%ecx              # ecx<- BA
6231    sarl      $4,%ecx                  # ecx<- B
6232    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
6233    movzwl    2(rPC),%eax               # eax<- field byte offset
6234    testl      %ecx,%ecx                # is object null?
6235    je        common_errNullObject
6236    leal      (%ecx,%eax,1),%ecx        # ecx<- Address of 64-bit target
6237    andb      $0xf,rINSTbl             # rINST<- A
6238    GET_VREG_WORD %eax rINST 0          # eax<- lsw
6239    GET_VREG_WORD rINST rINST 1         # rINST<- msw
6240    FETCH_INST_OPCODE 2 %edx
6241    movl      %eax,(%ecx)
6242    movl      rINST,4(%ecx)
6243    ADVANCE_PC 2
6244    GOTO_NEXT_R %edx
6245
6246/* ------------------------------ */
6247    .balign 64
6248.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
6249/* File: x86/OP_IPUT_OBJECT_QUICK.S */
6250    /* For: iput-object-quick */
6251    /* op vA, vB, offset@CCCC */
6252    movzbl    rINSTbl,%ecx              # ecx<- BA
6253    sarl      $4,%ecx                  # ecx<- B
6254    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
6255    andb      $0xf,rINSTbl             # rINST<- A
6256    GET_VREG_R  rINST rINST             # rINST<- v[A]
6257    movzwl    2(rPC),%eax               # eax<- field byte offset
6258    testl     %ecx,%ecx                 # is object null?
6259    je        common_errNullObject
6260    movl      rINST,(%ecx,%eax,1)
6261    movl      rSELF,%eax
6262    jmp       .LOP_IPUT_OBJECT_QUICK_finish
6263
6264/* ------------------------------ */
6265    .balign 64
6266.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
6267/* File: x86/OP_INVOKE_VIRTUAL_QUICK.S */
6268    /*
6269     * Handle an optimized virtual method call.
6270     *
6271     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
6272     */
6273    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
6274    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
6275    movzwl    4(rPC),%eax               # eax<- FEDC or CCCC
6276    movzwl    2(rPC),%ecx               # ecx<- BBBB
6277    .if     (!0)
6278    andl      $0xf,%eax                # eax<- C (or stays CCCC)
6279    .endif
6280    GET_VREG_R  %eax %eax               # eax<- vC ("this" ptr)
6281    testl     %eax,%eax                 # null?
6282    je        common_errNullObject      # yep, throw exception
6283    movl      offObject_clazz(%eax),%eax # eax<- thisPtr->clazz
6284    movl      offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable
6285    EXPORT_PC                           # might throw later - get ready
6286    movl      (%eax,%ecx,4),%eax        # eax<- vtable[BBBB]
6287    jmp       common_invokeMethodNoRange
6288
6289/* ------------------------------ */
6290    .balign 64
6291.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
6292/* File: x86/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */
6293/* File: x86/OP_INVOKE_VIRTUAL_QUICK.S */
6294    /*
6295     * Handle an optimized virtual method call.
6296     *
6297     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
6298     */
6299    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
6300    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
6301    movzwl    4(rPC),%eax               # eax<- FEDC or CCCC
6302    movzwl    2(rPC),%ecx               # ecx<- BBBB
6303    .if     (!1)
6304    andl      $0xf,%eax                # eax<- C (or stays CCCC)
6305    .endif
6306    GET_VREG_R  %eax %eax               # eax<- vC ("this" ptr)
6307    testl     %eax,%eax                 # null?
6308    je        common_errNullObject      # yep, throw exception
6309    movl      offObject_clazz(%eax),%eax # eax<- thisPtr->clazz
6310    movl      offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable
6311    EXPORT_PC                           # might throw later - get ready
6312    movl      (%eax,%ecx,4),%eax        # eax<- vtable[BBBB]
6313    jmp       common_invokeMethodRange
6314
6315
6316/* ------------------------------ */
6317    .balign 64
6318.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */
6319/* File: x86/OP_INVOKE_SUPER_QUICK.S */
6320    /*
6321     * Handle an optimized "super" method call.
6322     *
6323     * for: [opt] invoke-super-quick, invoke-super-quick/range
6324     */
6325    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
6326    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
6327    movl      rSELF,%ecx
6328    movzwl    4(rPC),%eax               # eax<- GFED or CCCC
6329    movl      offThread_method(%ecx),%ecx # ecx<- current method
6330    .if       (!0)
6331    andl      $0xf,%eax                # eax<- D (or stays CCCC)
6332    .endif
6333    movl      offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
6334    GET_VREG_R  %eax %eax               # eax<- "this"
6335    movl      offClassObject_super(%ecx),%ecx # ecx<- method->clazz->super
6336    testl     %eax,%eax                 # null "this"?
6337    je        common_errNullObject      # "this" is null, throw exception
6338    movzwl    2(rPC),%eax               # eax<- BBBB
6339    movl      offClassObject_vtable(%ecx),%ecx # ecx<- vtable
6340    EXPORT_PC
6341    movl      (%ecx,%eax,4),%eax        # eax<- super->vtable[BBBB]
6342    jmp       common_invokeMethodNoRange
6343
6344/* ------------------------------ */
6345    .balign 64
6346.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
6347/* File: x86/OP_INVOKE_SUPER_QUICK_RANGE.S */
6348/* File: x86/OP_INVOKE_SUPER_QUICK.S */
6349    /*
6350     * Handle an optimized "super" method call.
6351     *
6352     * for: [opt] invoke-super-quick, invoke-super-quick/range
6353     */
6354    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
6355    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
6356    movl      rSELF,%ecx
6357    movzwl    4(rPC),%eax               # eax<- GFED or CCCC
6358    movl      offThread_method(%ecx),%ecx # ecx<- current method
6359    .if       (!1)
6360    andl      $0xf,%eax                # eax<- D (or stays CCCC)
6361    .endif
6362    movl      offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
6363    GET_VREG_R  %eax %eax               # eax<- "this"
6364    movl      offClassObject_super(%ecx),%ecx # ecx<- method->clazz->super
6365    testl     %eax,%eax                 # null "this"?
6366    je        common_errNullObject      # "this" is null, throw exception
6367    movzwl    2(rPC),%eax               # eax<- BBBB
6368    movl      offClassObject_vtable(%ecx),%ecx # ecx<- vtable
6369    EXPORT_PC
6370    movl      (%ecx,%eax,4),%eax        # eax<- super->vtable[BBBB]
6371    jmp       common_invokeMethodRange
6372
6373
6374/* ------------------------------ */
6375    .balign 64
6376.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
6377/* File: x86/OP_IPUT_OBJECT_VOLATILE.S */
6378/* File: x86/OP_IPUT_OBJECT.S */
6379    /*
6380     * Object field put.
6381     *
6382     * for: iput-object
6383     */
6384    /* op vA, vB, field@CCCC */
6385    movl    rSELF,%ecx
6386    movzwl  2(rPC),%edx                         # edx<- 0000CCCC
6387    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
6388    movzbl  rINSTbl,%ecx                        # ecx<- BA
6389    sarl    $4,%ecx                            # ecx<- B
6390    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6391    andb    $0xf,rINSTbl                       # rINST<- A
6392    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
6393    movl    (%eax,%edx,4),%eax                  # resolved entry
6394    testl   %eax,%eax                           # is resolved entry null?
6395    jne     .LOP_IPUT_OBJECT_VOLATILE_finish                  # no, already resolved
6396    movl    %edx,OUT_ARG1(%esp)
6397    movl    rSELF,%edx
6398    jmp     .LOP_IPUT_OBJECT_VOLATILE_resolve
6399
6400
6401/* ------------------------------ */
6402    .balign 64
6403.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
6404/* File: x86/OP_SGET_OBJECT_VOLATILE.S */
6405/* File: x86/OP_SGET.S */
6406    /*
6407     * General 32-bit SGET handler.
6408     *
6409     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
6410     */
6411    /* op vAA, field@BBBB */
6412    movl      rSELF,%ecx
6413    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
6414    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
6415    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
6416    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
6417    testl     %eax,%eax                          # resolved entry null?
6418    je        .LOP_SGET_OBJECT_VOLATILE_resolve                # if not, make it so
6419.LOP_SGET_OBJECT_VOLATILE_finish:     # field ptr in eax
6420    movl      offStaticField_value(%eax),%eax
6421    FETCH_INST_OPCODE 2 %edx
6422    ADVANCE_PC 2
6423    SET_VREG %eax rINST
6424    GOTO_NEXT_R %edx
6425
6426
6427/* ------------------------------ */
6428    .balign 64
6429.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
6430/* File: x86/OP_SPUT_OBJECT_VOLATILE.S */
6431/* File: x86/OP_SPUT_OBJECT.S */
6432    /*
6433     * SPUT object handler.
6434     */
6435    /* op vAA, field@BBBB */
6436    movl      rSELF,%ecx
6437    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
6438    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
6439    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
6440    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField
6441    testl     %eax,%eax                          # resolved entry null?
6442    je        .LOP_SPUT_OBJECT_VOLATILE_resolve                # if not, make it so
6443.LOP_SPUT_OBJECT_VOLATILE_finish:                              # field ptr in eax
6444    movzbl    rINSTbl,%ecx                       # ecx<- AA
6445    GET_VREG_R  %ecx %ecx
6446    jmp       .LOP_SPUT_OBJECT_VOLATILE_continue
6447
6448
6449/* ------------------------------ */
6450    .balign 64
6451.L_OP_DISPATCH_FF: /* 0xff */
6452/* File: x86/OP_DISPATCH_FF.S */
6453    leal      256(rINST),%edx
6454    GOTO_NEXT_JUMBO_R %edx
6455
6456/* ------------------------------ */
6457    .balign 64
6458.L_OP_CONST_CLASS_JUMBO: /* 0x100 */
6459/* File: x86/OP_CONST_CLASS_JUMBO.S */
6460    /* const-class/jumbo vBBBB, Class@AAAAAAAA */
6461    movl      rSELF,%ecx
6462    movl      2(rPC),%eax              # eax<- AAAAAAAA
6463    movl      offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex
6464    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- dvmDex->pResClasses
6465    movl      (%ecx,%eax,4),%eax       # eax<- rResClasses[AAAAAAAA]
6466    FETCH_INST_OPCODE 4 %edx
6467    testl     %eax,%eax                # resolved yet?
6468    je        .LOP_CONST_CLASS_JUMBO_resolve
6469    SET_VREG  %eax rINST               # vBBBB<- rResClasses[AAAAAAAA]
6470    ADVANCE_PC 4
6471    GOTO_NEXT_R %edx
6472
6473/* ------------------------------ */
6474    .balign 64
6475.L_OP_CHECK_CAST_JUMBO: /* 0x101 */
6476/* File: x86/OP_CHECK_CAST_JUMBO.S */
6477    /*
6478     * Check to see if a cast from one class to another is allowed.
6479     */
6480    /* check-cast/jumbo vBBBB, class@AAAAAAAA */
6481    movl      rSELF,%ecx
6482    GET_VREG_R  rINST,rINST             # rINST<- vBBBB (object)
6483    movl      2(rPC),%eax               # eax<- AAAAAAAA
6484    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
6485    testl     rINST,rINST               # is oject null?
6486    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
6487    je        .LOP_CHECK_CAST_JUMBO_okay          # null obj, cast always succeeds
6488    movl      (%ecx,%eax,4),%eax        # eax<- resolved class
6489    movl      offObject_clazz(rINST),%ecx # ecx<- obj->clazz
6490    testl     %eax,%eax                 # have we resolved this before?
6491    je        .LOP_CHECK_CAST_JUMBO_resolve       # no, go do it now
6492.LOP_CHECK_CAST_JUMBO_resolved:
6493    cmpl      %eax,%ecx                 # same class (trivial success)?
6494    jne       .LOP_CHECK_CAST_JUMBO_fullcheck     # no, do full check
6495.LOP_CHECK_CAST_JUMBO_okay:
6496    FETCH_INST_OPCODE 4 %edx
6497    ADVANCE_PC 4
6498    GOTO_NEXT_R %edx
6499
6500/* ------------------------------ */
6501    .balign 64
6502.L_OP_INSTANCE_OF_JUMBO: /* 0x102 */
6503/* File: x86/OP_INSTANCE_OF_JUMBO.S */
6504    /*
6505     * Check to see if an object reference is an instance of a class.
6506     *
6507     * Most common situation is a non-null object, being compared against
6508     * an already-resolved class.
6509     */
6510    /* instance-of/jumbo vBBBB, vCCCC, class@AAAAAAAA */
6511    movzwl  8(rPC),%eax                 # eax<- CCCC
6512    GET_VREG_R %eax %eax                # eax<- vCCCC (obj)
6513    movl    rSELF,%ecx
6514    testl   %eax,%eax                   # object null?
6515    movl    offThread_methodClassDex(%ecx),%ecx  # ecx<- pDvmDex
6516    je      .LOP_INSTANCE_OF_JUMBO_store           # null obj, not instance, store it
6517    movl    2(rPC),%edx                 # edx<- AAAAAAAA
6518    movl    offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
6519    movl    (%ecx,%edx,4),%ecx          # ecx<- resolved class
6520    movl    offObject_clazz(%eax),%eax  # eax<- obj->clazz
6521    testl   %ecx,%ecx                   # have we resolved this before?
6522    je      .LOP_INSTANCE_OF_JUMBO_resolve         # not resolved, do it now
6523.LOP_INSTANCE_OF_JUMBO_resolved:  # eax<- obj->clazz, ecx<- resolved class
6524    cmpl    %eax,%ecx                   # same class (trivial success)?
6525    je      .LOP_INSTANCE_OF_JUMBO_trivial         # yes, trivial finish
6526    jmp     .LOP_INSTANCE_OF_JUMBO_fullcheck       # no, do full check
6527
6528/* ------------------------------ */
6529    .balign 64
6530.L_OP_NEW_INSTANCE_JUMBO: /* 0x103 */
6531/* File: x86/OP_NEW_INSTANCE_JUMBO.S */
6532    /*
6533     * Create a new instance of a class.
6534     */
6535    /* new-instance/jumbo vBBBB, class@AAAAAAAA */
6536    movl      rSELF,%ecx
6537    movl      2(rPC),%eax               # eax<- AAAAAAAA
6538    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- pDvmDex
6539    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
6540    EXPORT_PC
6541    movl      (%ecx,%eax,4),%ecx        # ecx<- resolved class
6542    testl     %ecx,%ecx                 # resolved?
6543    je        .LOP_NEW_INSTANCE_JUMBO_resolve       # no, go do it
6544.LOP_NEW_INSTANCE_JUMBO_resolved:  # on entry, ecx<- class
6545    cmpb      $CLASS_INITIALIZED,offClassObject_status(%ecx)
6546    je        .LOP_NEW_INSTANCE_JUMBO_initialized
6547    jmp       .LOP_NEW_INSTANCE_JUMBO_needinit
6548
6549/* ------------------------------ */
6550    .balign 64
6551.L_OP_NEW_ARRAY_JUMBO: /* 0x104 */
6552/* File: x86/OP_NEW_ARRAY_JUMBO.S */
6553    /*
6554     * Allocate an array of objects, specified with the array class
6555     * and a count.
6556     *
6557     * The verifier guarantees that this is an array class, so we don't
6558     * check for it here.
6559     */
6560    /* new-array/jumbo vBBBB, vCCCC, class@AAAAAAAA */
6561    movl    rSELF,%ecx
6562    EXPORT_PC
6563    movl    offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
6564    movl    2(rPC),%eax                       # eax<- AAAAAAAA
6565    movl    offDvmDex_pResClasses(%ecx),%ecx  # ecx<- pDvmDex->pResClasses
6566    movl    (%ecx,%eax,4),%ecx                # ecx<- resolved class
6567    movzwl  8(rPC),%eax                       # eax<- CCCC
6568    GET_VREG_R %eax %eax                      # eax<- vCCCC (array length)
6569    testl   %eax,%eax
6570    js      common_errNegativeArraySize       # bail
6571    testl   %ecx,%ecx                         # already resolved?
6572    jne     .LOP_NEW_ARRAY_JUMBO_finish                # yes, fast path
6573    jmp     .LOP_NEW_ARRAY_JUMBO_resolve               # resolve now
6574
6575/* ------------------------------ */
6576    .balign 64
6577.L_OP_FILLED_NEW_ARRAY_JUMBO: /* 0x105 */
6578/* File: x86/OP_FILLED_NEW_ARRAY_JUMBO.S */
6579    /*
6580     * Create a new array with elements filled from registers.
6581     */
6582    /* filled-new-array/jumbo {vCCCC..v(CCCC+BBBB-1)}, type@AAAAAAAA */
6583    movl    rSELF,%eax
6584    movl    offThread_methodClassDex(%eax),%eax # eax<- pDvmDex
6585    movl    2(rPC),%ecx                       # ecx<- AAAAAAAA
6586    movl    offDvmDex_pResClasses(%eax),%eax  # eax<- pDvmDex->pResClasses
6587    movl    (%eax,%ecx,4),%eax                # eax<- resolved class
6588    EXPORT_PC
6589    testl   %eax,%eax                         # already resolved?
6590    jne     .LOP_FILLED_NEW_ARRAY_JUMBO_continue              # yes, continue
6591    # less frequent path, so we'll redo some work
6592    movl    rSELF,%eax
6593    movl    $0,OUT_ARG2(%esp)                # arg2<- false
6594    movl    %ecx,OUT_ARG1(%esp)               # arg1<- AAAAAAAA
6595    movl    offThread_method(%eax),%eax         # eax<- self->method
6596    jmp     .LOP_FILLED_NEW_ARRAY_JUMBO_more
6597
6598/* ------------------------------ */
6599    .balign 64
6600.L_OP_IGET_JUMBO: /* 0x106 */
6601/* File: x86/OP_IGET_JUMBO.S */
6602    /*
6603     * Jumbo 32-bit instance field get.
6604     *
6605     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
6606     *      iget-char/jumbo, iget-short/jumbo
6607     */
6608    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6609    movl    rSELF,%ecx
6610    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6611    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
6612    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6613    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6614    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6615    movl    (%eax,%edx,4),%eax                  # resolved entry
6616    testl   %eax,%eax                           # is resolved entry null?
6617    jne     .LOP_IGET_JUMBO_finish                  # no, already resolved
6618    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
6619    movl    rSELF,%edx
6620    jmp     .LOP_IGET_JUMBO_resolve
6621
6622/* ------------------------------ */
6623    .balign 64
6624.L_OP_IGET_WIDE_JUMBO: /* 0x107 */
6625/* File: x86/OP_IGET_WIDE_JUMBO.S */
6626    /*
6627     * Jumbo 64-bit instance field get.
6628     */
6629    /* iget-wide/jumbo vBBBB, vCCCC, field@AAAA */
6630    movl    rSELF,%ecx
6631    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6632    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
6633    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6634    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6635    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6636    movl    (%eax,%edx,4),%eax                  # resolved entry
6637    testl   %eax,%eax                           # is resolved entry null?
6638    jne     .LOP_IGET_WIDE_JUMBO_finish                  # no, already resolved
6639    movl    %edx,OUT_ARG1(%esp)                 # for dvmResolveInstField
6640    movl    rSELF,%edx
6641    jmp     .LOP_IGET_WIDE_JUMBO_resolve
6642
6643/* ------------------------------ */
6644    .balign 64
6645.L_OP_IGET_OBJECT_JUMBO: /* 0x108 */
6646/* File: x86/OP_IGET_OBJECT_JUMBO.S */
6647/* File: x86/OP_IGET_JUMBO.S */
6648    /*
6649     * Jumbo 32-bit instance field get.
6650     *
6651     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
6652     *      iget-char/jumbo, iget-short/jumbo
6653     */
6654    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6655    movl    rSELF,%ecx
6656    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6657    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
6658    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6659    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6660    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6661    movl    (%eax,%edx,4),%eax                  # resolved entry
6662    testl   %eax,%eax                           # is resolved entry null?
6663    jne     .LOP_IGET_OBJECT_JUMBO_finish                  # no, already resolved
6664    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
6665    movl    rSELF,%edx
6666    jmp     .LOP_IGET_OBJECT_JUMBO_resolve
6667
6668
6669/* ------------------------------ */
6670    .balign 64
6671.L_OP_IGET_BOOLEAN_JUMBO: /* 0x109 */
6672/* File: x86/OP_IGET_BOOLEAN_JUMBO.S */
6673/* File: x86/OP_IGET_JUMBO.S */
6674    /*
6675     * Jumbo 32-bit instance field get.
6676     *
6677     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
6678     *      iget-char/jumbo, iget-short/jumbo
6679     */
6680    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6681    movl    rSELF,%ecx
6682    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6683    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
6684    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6685    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6686    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6687    movl    (%eax,%edx,4),%eax                  # resolved entry
6688    testl   %eax,%eax                           # is resolved entry null?
6689    jne     .LOP_IGET_BOOLEAN_JUMBO_finish                  # no, already resolved
6690    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
6691    movl    rSELF,%edx
6692    jmp     .LOP_IGET_BOOLEAN_JUMBO_resolve
6693
6694
6695/* ------------------------------ */
6696    .balign 64
6697.L_OP_IGET_BYTE_JUMBO: /* 0x10a */
6698/* File: x86/OP_IGET_BYTE_JUMBO.S */
6699/* File: x86/OP_IGET_JUMBO.S */
6700    /*
6701     * Jumbo 32-bit instance field get.
6702     *
6703     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
6704     *      iget-char/jumbo, iget-short/jumbo
6705     */
6706    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6707    movl    rSELF,%ecx
6708    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6709    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
6710    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6711    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6712    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6713    movl    (%eax,%edx,4),%eax                  # resolved entry
6714    testl   %eax,%eax                           # is resolved entry null?
6715    jne     .LOP_IGET_BYTE_JUMBO_finish                  # no, already resolved
6716    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
6717    movl    rSELF,%edx
6718    jmp     .LOP_IGET_BYTE_JUMBO_resolve
6719
6720
6721/* ------------------------------ */
6722    .balign 64
6723.L_OP_IGET_CHAR_JUMBO: /* 0x10b */
6724/* File: x86/OP_IGET_CHAR_JUMBO.S */
6725/* File: x86/OP_IGET_JUMBO.S */
6726    /*
6727     * Jumbo 32-bit instance field get.
6728     *
6729     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
6730     *      iget-char/jumbo, iget-short/jumbo
6731     */
6732    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6733    movl    rSELF,%ecx
6734    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6735    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
6736    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6737    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6738    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6739    movl    (%eax,%edx,4),%eax                  # resolved entry
6740    testl   %eax,%eax                           # is resolved entry null?
6741    jne     .LOP_IGET_CHAR_JUMBO_finish                  # no, already resolved
6742    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
6743    movl    rSELF,%edx
6744    jmp     .LOP_IGET_CHAR_JUMBO_resolve
6745
6746
6747/* ------------------------------ */
6748    .balign 64
6749.L_OP_IGET_SHORT_JUMBO: /* 0x10c */
6750/* File: x86/OP_IGET_SHORT_JUMBO.S */
6751/* File: x86/OP_IGET_JUMBO.S */
6752    /*
6753     * Jumbo 32-bit instance field get.
6754     *
6755     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
6756     *      iget-char/jumbo, iget-short/jumbo
6757     */
6758    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6759    movl    rSELF,%ecx
6760    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6761    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
6762    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6763    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6764    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6765    movl    (%eax,%edx,4),%eax                  # resolved entry
6766    testl   %eax,%eax                           # is resolved entry null?
6767    jne     .LOP_IGET_SHORT_JUMBO_finish                  # no, already resolved
6768    movl    %edx,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
6769    movl    rSELF,%edx
6770    jmp     .LOP_IGET_SHORT_JUMBO_resolve
6771
6772
6773/* ------------------------------ */
6774    .balign 64
6775.L_OP_IPUT_JUMBO: /* 0x10d */
6776/* File: x86/OP_IPUT_JUMBO.S */
6777    /*
6778     * Jumbo 32-bit instance field put.
6779     *
6780     * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo,
6781            iput-char/jumbo, iput-short/jumbo
6782     */
6783    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6784    movl    rSELF,%ecx
6785    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6786    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
6787    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6788    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6789    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6790    movl    (%eax,%edx,4),%eax                  # resolved entry
6791    testl   %eax,%eax                           # is resolved entry null?
6792    jne     .LOP_IPUT_JUMBO_finish                  # no, already resolved
6793    movl    %edx,OUT_ARG1(%esp)
6794    movl    rSELF,%edx
6795    jmp     .LOP_IPUT_JUMBO_resolve
6796
6797/* ------------------------------ */
6798    .balign 64
6799.L_OP_IPUT_WIDE_JUMBO: /* 0x10e */
6800/* File: x86/OP_IPUT_WIDE_JUMBO.S */
6801    /*
6802     * Jumbo 64-bit instance field put.
6803     */
6804    /* iput-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */
6805    movl    rSELF,%ecx
6806    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6807    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
6808    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6809    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6810    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6811    movl    (%eax,%edx,4),%eax                  # resolved entry
6812    testl   %eax,%eax                           # is resolved entry null?
6813    jne     .LOP_IPUT_WIDE_JUMBO_finish                  # no, already resolved
6814    movl    %edx,OUT_ARG1(%esp)
6815    movl    rSELF,%edx
6816    jmp     .LOP_IPUT_WIDE_JUMBO_resolve
6817
6818/* ------------------------------ */
6819    .balign 64
6820.L_OP_IPUT_OBJECT_JUMBO: /* 0x10f */
6821/* File: x86/OP_IPUT_OBJECT_JUMBO.S */
6822    /*
6823     * Jumbo object field put.
6824     */
6825    /* iput-object/jumbo vBBBB, vCCCC, field@AAAAAAAA */
6826    movl    rSELF,%ecx
6827    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6828    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
6829    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6830    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6831    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6832    movl    (%eax,%edx,4),%eax                  # resolved entry
6833    testl   %eax,%eax                           # is resolved entry null?
6834    jne     .LOP_IPUT_OBJECT_JUMBO_finish                  # no, already resolved
6835    movl    %edx,OUT_ARG1(%esp)
6836    movl    rSELF,%edx
6837    jmp     .LOP_IPUT_OBJECT_JUMBO_resolve
6838
6839/* ------------------------------ */
6840    .balign 64
6841.L_OP_IPUT_BOOLEAN_JUMBO: /* 0x110 */
6842/* File: x86/OP_IPUT_BOOLEAN_JUMBO.S */
6843/* File: x86/OP_IPUT_JUMBO.S */
6844    /*
6845     * Jumbo 32-bit instance field put.
6846     *
6847     * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo,
6848            iput-char/jumbo, iput-short/jumbo
6849     */
6850    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6851    movl    rSELF,%ecx
6852    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6853    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
6854    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6855    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6856    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6857    movl    (%eax,%edx,4),%eax                  # resolved entry
6858    testl   %eax,%eax                           # is resolved entry null?
6859    jne     .LOP_IPUT_BOOLEAN_JUMBO_finish                  # no, already resolved
6860    movl    %edx,OUT_ARG1(%esp)
6861    movl    rSELF,%edx
6862    jmp     .LOP_IPUT_BOOLEAN_JUMBO_resolve
6863
6864
6865/* ------------------------------ */
6866    .balign 64
6867.L_OP_IPUT_BYTE_JUMBO: /* 0x111 */
6868/* File: x86/OP_IPUT_BYTE_JUMBO.S */
6869/* File: x86/OP_IPUT_JUMBO.S */
6870    /*
6871     * Jumbo 32-bit instance field put.
6872     *
6873     * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo,
6874            iput-char/jumbo, iput-short/jumbo
6875     */
6876    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6877    movl    rSELF,%ecx
6878    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6879    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
6880    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6881    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6882    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6883    movl    (%eax,%edx,4),%eax                  # resolved entry
6884    testl   %eax,%eax                           # is resolved entry null?
6885    jne     .LOP_IPUT_BYTE_JUMBO_finish                  # no, already resolved
6886    movl    %edx,OUT_ARG1(%esp)
6887    movl    rSELF,%edx
6888    jmp     .LOP_IPUT_BYTE_JUMBO_resolve
6889
6890
6891/* ------------------------------ */
6892    .balign 64
6893.L_OP_IPUT_CHAR_JUMBO: /* 0x112 */
6894/* File: x86/OP_IPUT_CHAR_JUMBO.S */
6895/* File: x86/OP_IPUT_JUMBO.S */
6896    /*
6897     * Jumbo 32-bit instance field put.
6898     *
6899     * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo,
6900            iput-char/jumbo, iput-short/jumbo
6901     */
6902    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6903    movl    rSELF,%ecx
6904    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6905    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
6906    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6907    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6908    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6909    movl    (%eax,%edx,4),%eax                  # resolved entry
6910    testl   %eax,%eax                           # is resolved entry null?
6911    jne     .LOP_IPUT_CHAR_JUMBO_finish                  # no, already resolved
6912    movl    %edx,OUT_ARG1(%esp)
6913    movl    rSELF,%edx
6914    jmp     .LOP_IPUT_CHAR_JUMBO_resolve
6915
6916
6917/* ------------------------------ */
6918    .balign 64
6919.L_OP_IPUT_SHORT_JUMBO: /* 0x113 */
6920/* File: x86/OP_IPUT_SHORT_JUMBO.S */
6921/* File: x86/OP_IPUT_JUMBO.S */
6922    /*
6923     * Jumbo 32-bit instance field put.
6924     *
6925     * for: iput/jumbo, iput-object/jumbo, iput-boolean/jumbo, iput-byte/jumbo,
6926            iput-char/jumbo, iput-short/jumbo
6927     */
6928    /* exop vBBBB, vCCCC, field@AAAAAAAA */
6929    movl    rSELF,%ecx
6930    movl    2(rPC),%edx                         # edx<- AAAAAAAA
6931    movl    offThread_methodClassDex(%ecx),%eax   # eax<- DvmDex
6932    movzwl  8(rPC),%ecx                         # ecx<- CCCC
6933    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
6934    GET_VREG_R %ecx %ecx                        # ecx<- fp[CCCC], the object ptr
6935    movl    (%eax,%edx,4),%eax                  # resolved entry
6936    testl   %eax,%eax                           # is resolved entry null?
6937    jne     .LOP_IPUT_SHORT_JUMBO_finish                  # no, already resolved
6938    movl    %edx,OUT_ARG1(%esp)
6939    movl    rSELF,%edx
6940    jmp     .LOP_IPUT_SHORT_JUMBO_resolve
6941
6942
6943/* ------------------------------ */
6944    .balign 64
6945.L_OP_SGET_JUMBO: /* 0x114 */
6946/* File: x86/OP_SGET_JUMBO.S */
6947    /*
6948     * Jumbo 32-bit SGET handler.
6949     *
6950     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
6951     *      sget-char/jumbo, sget-short/jumbo
6952     */
6953    /* exop vBBBB, field@AAAAAAAA */
6954    movl      rSELF,%ecx
6955    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
6956    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
6957    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
6958    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
6959    testl     %eax,%eax                          # resolved entry null?
6960    je        .LOP_SGET_JUMBO_resolve                # if not, make it so
6961.LOP_SGET_JUMBO_finish:     # field ptr in eax
6962    movl      offStaticField_value(%eax),%eax
6963    FETCH_INST_OPCODE 4 %edx
6964    ADVANCE_PC 4
6965    SET_VREG %eax rINST
6966    GOTO_NEXT_R %edx
6967
6968/* ------------------------------ */
6969    .balign 64
6970.L_OP_SGET_WIDE_JUMBO: /* 0x115 */
6971/* File: x86/OP_SGET_WIDE_JUMBO.S */
6972    /*
6973     * Jumbo 64-bit SGET handler.
6974     *
6975     */
6976    /* sget-wide/jumbo vBBBB, field@AAAAAAAA */
6977    movl      rSELF,%ecx
6978    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
6979    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
6980    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
6981    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
6982    testl     %eax,%eax                          # resolved entry null?
6983    je        .LOP_SGET_WIDE_JUMBO_resolve                # if not, make it so
6984.LOP_SGET_WIDE_JUMBO_finish:     # field ptr in eax
6985    movl      offStaticField_value(%eax),%ecx    # ecx<- lsw
6986    movl      4+offStaticField_value(%eax),%eax  # eax<- msw
6987    FETCH_INST_OPCODE 2 %edx
6988    ADVANCE_PC 2
6989    SET_VREG_WORD %ecx rINST 0
6990    SET_VREG_WORD %eax rINST 1
6991    GOTO_NEXT_R %edx
6992
6993/* ------------------------------ */
6994    .balign 64
6995.L_OP_SGET_OBJECT_JUMBO: /* 0x116 */
6996/* File: x86/OP_SGET_OBJECT_JUMBO.S */
6997/* File: x86/OP_SGET_JUMBO.S */
6998    /*
6999     * Jumbo 32-bit SGET handler.
7000     *
7001     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
7002     *      sget-char/jumbo, sget-short/jumbo
7003     */
7004    /* exop vBBBB, field@AAAAAAAA */
7005    movl      rSELF,%ecx
7006    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7007    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7008    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7009    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7010    testl     %eax,%eax                          # resolved entry null?
7011    je        .LOP_SGET_OBJECT_JUMBO_resolve                # if not, make it so
7012.LOP_SGET_OBJECT_JUMBO_finish:     # field ptr in eax
7013    movl      offStaticField_value(%eax),%eax
7014    FETCH_INST_OPCODE 4 %edx
7015    ADVANCE_PC 4
7016    SET_VREG %eax rINST
7017    GOTO_NEXT_R %edx
7018
7019
7020/* ------------------------------ */
7021    .balign 64
7022.L_OP_SGET_BOOLEAN_JUMBO: /* 0x117 */
7023/* File: x86/OP_SGET_BOOLEAN_JUMBO.S */
7024/* File: x86/OP_SGET_JUMBO.S */
7025    /*
7026     * Jumbo 32-bit SGET handler.
7027     *
7028     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
7029     *      sget-char/jumbo, sget-short/jumbo
7030     */
7031    /* exop vBBBB, field@AAAAAAAA */
7032    movl      rSELF,%ecx
7033    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7034    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7035    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7036    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7037    testl     %eax,%eax                          # resolved entry null?
7038    je        .LOP_SGET_BOOLEAN_JUMBO_resolve                # if not, make it so
7039.LOP_SGET_BOOLEAN_JUMBO_finish:     # field ptr in eax
7040    movl      offStaticField_value(%eax),%eax
7041    FETCH_INST_OPCODE 4 %edx
7042    ADVANCE_PC 4
7043    SET_VREG %eax rINST
7044    GOTO_NEXT_R %edx
7045
7046
7047/* ------------------------------ */
7048    .balign 64
7049.L_OP_SGET_BYTE_JUMBO: /* 0x118 */
7050/* File: x86/OP_SGET_BYTE_JUMBO.S */
7051/* File: x86/OP_SGET_JUMBO.S */
7052    /*
7053     * Jumbo 32-bit SGET handler.
7054     *
7055     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
7056     *      sget-char/jumbo, sget-short/jumbo
7057     */
7058    /* exop vBBBB, field@AAAAAAAA */
7059    movl      rSELF,%ecx
7060    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7061    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7062    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7063    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7064    testl     %eax,%eax                          # resolved entry null?
7065    je        .LOP_SGET_BYTE_JUMBO_resolve                # if not, make it so
7066.LOP_SGET_BYTE_JUMBO_finish:     # field ptr in eax
7067    movl      offStaticField_value(%eax),%eax
7068    FETCH_INST_OPCODE 4 %edx
7069    ADVANCE_PC 4
7070    SET_VREG %eax rINST
7071    GOTO_NEXT_R %edx
7072
7073
7074/* ------------------------------ */
7075    .balign 64
7076.L_OP_SGET_CHAR_JUMBO: /* 0x119 */
7077/* File: x86/OP_SGET_CHAR_JUMBO.S */
7078/* File: x86/OP_SGET_JUMBO.S */
7079    /*
7080     * Jumbo 32-bit SGET handler.
7081     *
7082     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
7083     *      sget-char/jumbo, sget-short/jumbo
7084     */
7085    /* exop vBBBB, field@AAAAAAAA */
7086    movl      rSELF,%ecx
7087    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7088    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7089    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7090    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7091    testl     %eax,%eax                          # resolved entry null?
7092    je        .LOP_SGET_CHAR_JUMBO_resolve                # if not, make it so
7093.LOP_SGET_CHAR_JUMBO_finish:     # field ptr in eax
7094    movl      offStaticField_value(%eax),%eax
7095    FETCH_INST_OPCODE 4 %edx
7096    ADVANCE_PC 4
7097    SET_VREG %eax rINST
7098    GOTO_NEXT_R %edx
7099
7100
7101/* ------------------------------ */
7102    .balign 64
7103.L_OP_SGET_SHORT_JUMBO: /* 0x11a */
7104/* File: x86/OP_SGET_SHORT_JUMBO.S */
7105/* File: x86/OP_SGET_JUMBO.S */
7106    /*
7107     * Jumbo 32-bit SGET handler.
7108     *
7109     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
7110     *      sget-char/jumbo, sget-short/jumbo
7111     */
7112    /* exop vBBBB, field@AAAAAAAA */
7113    movl      rSELF,%ecx
7114    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7115    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7116    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7117    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7118    testl     %eax,%eax                          # resolved entry null?
7119    je        .LOP_SGET_SHORT_JUMBO_resolve                # if not, make it so
7120.LOP_SGET_SHORT_JUMBO_finish:     # field ptr in eax
7121    movl      offStaticField_value(%eax),%eax
7122    FETCH_INST_OPCODE 4 %edx
7123    ADVANCE_PC 4
7124    SET_VREG %eax rINST
7125    GOTO_NEXT_R %edx
7126
7127
7128/* ------------------------------ */
7129    .balign 64
7130.L_OP_SPUT_JUMBO: /* 0x11b */
7131/* File: x86/OP_SPUT_JUMBO.S */
7132    /*
7133     * Jumbo 32-bit SPUT handler.
7134     *
7135     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
7136     *      sput-short/jumbo
7137     */
7138    /* exop vBBBB, field@AAAAAAAA */
7139    movl      rSELF,%ecx
7140    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7141    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7142    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7143    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7144    testl     %eax,%eax                          # resolved entry null?
7145    je        .LOP_SPUT_JUMBO_resolve                # if not, make it so
7146.LOP_SPUT_JUMBO_finish:     # field ptr in eax
7147    GET_VREG_R  %ecx rINST
7148    FETCH_INST_OPCODE 4 %edx
7149    ADVANCE_PC 4
7150    movl      %ecx,offStaticField_value(%eax)
7151    GOTO_NEXT_R %edx
7152
7153/* ------------------------------ */
7154    .balign 64
7155.L_OP_SPUT_WIDE_JUMBO: /* 0x11c */
7156/* File: x86/OP_SPUT_WIDE_JUMBO.S */
7157    /*
7158     * Jumbo 64-bit SPUT handler.
7159     */
7160    /* sput-wide/jumbo vBBBB, field@AAAAAAAA */
7161    movl      rSELF,%ecx
7162    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7163    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7164    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7165    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7166    testl     %eax,%eax                          # resolved entry null?
7167    je        .LOP_SPUT_WIDE_JUMBO_resolve                # if not, make it so
7168.LOP_SPUT_WIDE_JUMBO_finish:     # field ptr in eax
7169    GET_VREG_WORD %ecx rINST 0                  # ecx<- lsw
7170    GET_VREG_WORD rINST rINST 1                 # rINST<- msw
7171    FETCH_INST_OPCODE 4 %edx
7172    ADVANCE_PC 4
7173    movl      %ecx,offStaticField_value(%eax)
7174    movl      rINST,4+offStaticField_value(%eax)
7175    GOTO_NEXT_R %edx
7176
7177/* ------------------------------ */
7178    .balign 64
7179.L_OP_SPUT_OBJECT_JUMBO: /* 0x11d */
7180/* File: x86/OP_SPUT_OBJECT_JUMBO.S */
7181    /*
7182     * Jumbo SPUT object handler.
7183     */
7184    /* sput-object/jumbo vBBBB, field@AAAAAAAA */
7185    movl      rSELF,%ecx
7186    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7187    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7188    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7189    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField
7190    testl     %eax,%eax                          # resolved entry null?
7191    je        .LOP_SPUT_OBJECT_JUMBO_resolve                # if not, make it so
7192.LOP_SPUT_OBJECT_JUMBO_finish:                              # field ptr in eax
7193    GET_VREG_R  %ecx rINST
7194    jmp       .LOP_SPUT_OBJECT_JUMBO_continue
7195
7196/* ------------------------------ */
7197    .balign 64
7198.L_OP_SPUT_BOOLEAN_JUMBO: /* 0x11e */
7199/* File: x86/OP_SPUT_BOOLEAN_JUMBO.S */
7200/* File: x86/OP_SPUT_JUMBO.S */
7201    /*
7202     * Jumbo 32-bit SPUT handler.
7203     *
7204     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
7205     *      sput-short/jumbo
7206     */
7207    /* exop vBBBB, field@AAAAAAAA */
7208    movl      rSELF,%ecx
7209    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7210    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7211    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7212    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7213    testl     %eax,%eax                          # resolved entry null?
7214    je        .LOP_SPUT_BOOLEAN_JUMBO_resolve                # if not, make it so
7215.LOP_SPUT_BOOLEAN_JUMBO_finish:     # field ptr in eax
7216    GET_VREG_R  %ecx rINST
7217    FETCH_INST_OPCODE 4 %edx
7218    ADVANCE_PC 4
7219    movl      %ecx,offStaticField_value(%eax)
7220    GOTO_NEXT_R %edx
7221
7222
7223/* ------------------------------ */
7224    .balign 64
7225.L_OP_SPUT_BYTE_JUMBO: /* 0x11f */
7226/* File: x86/OP_SPUT_BYTE_JUMBO.S */
7227/* File: x86/OP_SPUT_JUMBO.S */
7228    /*
7229     * Jumbo 32-bit SPUT handler.
7230     *
7231     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
7232     *      sput-short/jumbo
7233     */
7234    /* exop vBBBB, field@AAAAAAAA */
7235    movl      rSELF,%ecx
7236    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7237    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7238    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7239    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7240    testl     %eax,%eax                          # resolved entry null?
7241    je        .LOP_SPUT_BYTE_JUMBO_resolve                # if not, make it so
7242.LOP_SPUT_BYTE_JUMBO_finish:     # field ptr in eax
7243    GET_VREG_R  %ecx rINST
7244    FETCH_INST_OPCODE 4 %edx
7245    ADVANCE_PC 4
7246    movl      %ecx,offStaticField_value(%eax)
7247    GOTO_NEXT_R %edx
7248
7249
7250/* ------------------------------ */
7251    .balign 64
7252.L_OP_SPUT_CHAR_JUMBO: /* 0x120 */
7253/* File: x86/OP_SPUT_CHAR_JUMBO.S */
7254/* File: x86/OP_SPUT_JUMBO.S */
7255    /*
7256     * Jumbo 32-bit SPUT handler.
7257     *
7258     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
7259     *      sput-short/jumbo
7260     */
7261    /* exop vBBBB, field@AAAAAAAA */
7262    movl      rSELF,%ecx
7263    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7264    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7265    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7266    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7267    testl     %eax,%eax                          # resolved entry null?
7268    je        .LOP_SPUT_CHAR_JUMBO_resolve                # if not, make it so
7269.LOP_SPUT_CHAR_JUMBO_finish:     # field ptr in eax
7270    GET_VREG_R  %ecx rINST
7271    FETCH_INST_OPCODE 4 %edx
7272    ADVANCE_PC 4
7273    movl      %ecx,offStaticField_value(%eax)
7274    GOTO_NEXT_R %edx
7275
7276
7277/* ------------------------------ */
7278    .balign 64
7279.L_OP_SPUT_SHORT_JUMBO: /* 0x121 */
7280/* File: x86/OP_SPUT_SHORT_JUMBO.S */
7281/* File: x86/OP_SPUT_JUMBO.S */
7282    /*
7283     * Jumbo 32-bit SPUT handler.
7284     *
7285     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
7286     *      sput-short/jumbo
7287     */
7288    /* exop vBBBB, field@AAAAAAAA */
7289    movl      rSELF,%ecx
7290    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7291    movl      2(rPC),%eax                        # eax<- field ref AAAAAAAA
7292    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7293    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7294    testl     %eax,%eax                          # resolved entry null?
7295    je        .LOP_SPUT_SHORT_JUMBO_resolve                # if not, make it so
7296.LOP_SPUT_SHORT_JUMBO_finish:     # field ptr in eax
7297    GET_VREG_R  %ecx rINST
7298    FETCH_INST_OPCODE 4 %edx
7299    ADVANCE_PC 4
7300    movl      %ecx,offStaticField_value(%eax)
7301    GOTO_NEXT_R %edx
7302
7303
7304/* ------------------------------ */
7305    .balign 64
7306.L_OP_INVOKE_VIRTUAL_JUMBO: /* 0x122 */
7307/* File: x86/OP_INVOKE_VIRTUAL_JUMBO.S */
7308    /*
7309     * Handle a jumbo virtual method call.
7310     */
7311    /* invoke-virtual/jumbo vBBBB, {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
7312    movl      rSELF,%eax
7313    movl      2(rPC),%ecx                 # ecx<- AAAAAAAA
7314    movl      offThread_methodClassDex(%eax),%eax  # eax<- pDvmDex
7315    EXPORT_PC
7316    movl      offDvmDex_pResMethods(%eax),%eax   # eax<- pDvmDex->pResMethods
7317    movl      (%eax,%ecx,4),%eax          # eax<- resolved baseMethod
7318    testl     %eax,%eax                   # already resolved?
7319    jne       .LOP_INVOKE_VIRTUAL_JUMBO_continue        # yes, continue
7320    movl      rSELF,%eax
7321    movl      %ecx,OUT_ARG1(%esp)         # arg1<- ref
7322    movl      offThread_method(%eax),%eax   # eax<- self->method
7323    jmp       .LOP_INVOKE_VIRTUAL_JUMBO_more
7324
7325/* ------------------------------ */
7326    .balign 64
7327.L_OP_INVOKE_SUPER_JUMBO: /* 0x123 */
7328/* File: x86/OP_INVOKE_SUPER_JUMBO.S */
7329    /*
7330     * Handle a jumbo "super" method call.
7331     */
7332    /* invoke-super/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
7333    movl      rSELF,rINST
7334    movl      2(rPC),%eax               # eax<- AAAAAAAA
7335    movl      offThread_methodClassDex(rINST),%ecx # ecx<- pDvmDex
7336    EXPORT_PC
7337    movl      offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods
7338    movl      (%ecx,%eax,4),%ecx        # ecx<- resolved baseMethod
7339    movl      offThread_method(rINST),%eax # eax<- method
7340    movzwl    8(rPC),rINST              # rINST<- CCCC
7341    GET_VREG_R  rINST rINST             # rINST<- "this" ptr
7342    testl     rINST,rINST               # null "this"?
7343    je        common_errNullObject      # yes, throw
7344    movl      offMethod_clazz(%eax),%eax # eax<- method->clazz
7345    testl     %ecx,%ecx                 # already resolved?
7346    jne       .LOP_INVOKE_SUPER_JUMBO_continue      # yes - go on
7347    jmp       .LOP_INVOKE_SUPER_JUMBO_resolve
7348
7349/* ------------------------------ */
7350    .balign 64
7351.L_OP_INVOKE_DIRECT_JUMBO: /* 0x124 */
7352/* File: x86/OP_INVOKE_DIRECT_JUMBO.S */
7353    /*
7354     * Handle a jumbo direct method call.
7355     *
7356     * (We could defer the "is 'this' pointer null" test to the common
7357     * method invocation code, and use a flag to indicate that static
7358     * calls don't count.  If we do this as part of copying the arguments
7359     * out we could avoiding loading the first arg twice.)
7360     */
7361    /* invoke-direct/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
7362    movl      rSELF,%ecx
7363    movl      2(rPC),%eax              # eax<- AAAAAAAA
7364    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
7365    EXPORT_PC
7366    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
7367    movzwl    8(rPC),%edx              # edx<- CCCC
7368    movl      (%ecx,%eax,4),%eax       # eax<- resolved methodToCall
7369    testl     %eax,%eax                # already resolved?
7370    GET_VREG_R  %ecx %edx              # ecx<- "this" ptr
7371    je        .LOP_INVOKE_DIRECT_JUMBO_resolve      # not resolved, do it now
7372.LOP_INVOKE_DIRECT_JUMBO_finish:
7373    testl     %ecx,%ecx                # null "this"?
7374    jne       common_invokeMethodJumbo # no, continue on
7375    jmp       common_errNullObject
7376
7377/* ------------------------------ */
7378    .balign 64
7379.L_OP_INVOKE_STATIC_JUMBO: /* 0x125 */
7380/* File: x86/OP_INVOKE_STATIC_JUMBO.S */
7381    /*
7382     * Handle a jumbo static method call.
7383     */
7384    /* invoke-static/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
7385    movl      rSELF,%ecx
7386    movl      2(rPC),%eax               # eax<- AAAAAAAA
7387    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
7388    EXPORT_PC
7389    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
7390    movl      (%ecx,%eax,4),%eax        # eax<- resolved methodToCall
7391    testl     %eax,%eax
7392    jne       common_invokeMethodJumbo
7393    movl      rSELF,%ecx
7394    movl      offThread_method(%ecx),%ecx # ecx<- self->method
7395    movl      2(rPC),%eax               # eax<- AAAAAAAA
7396    movl      offMethod_clazz(%ecx),%ecx# ecx<- method->clazz
7397    movl      %eax,OUT_ARG1(%esp)       # arg1<- AAAAAAAA
7398    movl      %ecx,OUT_ARG0(%esp)       # arg0<- clazz
7399    jmp       .LOP_INVOKE_STATIC_JUMBO_continue
7400
7401/* ------------------------------ */
7402    .balign 64
7403.L_OP_INVOKE_INTERFACE_JUMBO: /* 0x126 */
7404/* File: x86/OP_INVOKE_INTERFACE_JUMBO.S */
7405    /*
7406     * Handle a jumbo interface method call.
7407     */
7408    /* invoke-interface/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
7409    movzwl     8(rPC),%eax              # eax<- CCCC
7410    movl       rSELF,%ecx
7411    GET_VREG_R   %eax %eax              # eax<- "this"
7412    EXPORT_PC
7413    testl      %eax,%eax                # null this?
7414    je         common_errNullObject     # yes, fail
7415    movl       offObject_clazz(%eax),%eax# eax<- thisPtr->clazz
7416    movl       %eax,OUT_ARG0(%esp)                 # arg0<- class
7417    movl       offThread_methodClassDex(%ecx),%eax   # eax<- methodClassDex
7418    movl       offThread_method(%ecx),%ecx           # ecx<- method
7419    movl       %eax,OUT_ARG3(%esp)                 # arg3<- dex
7420    movl       2(rPC),%eax                         # eax<- AAAAAAAA
7421    movl       %ecx,OUT_ARG2(%esp)                 # arg2<- method
7422    movl       %eax,OUT_ARG1(%esp)                 # arg1<- AAAAAAAA
7423    jmp        .LOP_INVOKE_INTERFACE_JUMBO_continue
7424
7425/* ------------------------------ */
7426    .balign 64
7427.L_OP_UNUSED_27FF: /* 0x127 */
7428/* File: x86/OP_UNUSED_27FF.S */
7429/* File: x86/unused.S */
7430    jmp     common_abort
7431
7432
7433/* ------------------------------ */
7434    .balign 64
7435.L_OP_UNUSED_28FF: /* 0x128 */
7436/* File: x86/OP_UNUSED_28FF.S */
7437/* File: x86/unused.S */
7438    jmp     common_abort
7439
7440
7441/* ------------------------------ */
7442    .balign 64
7443.L_OP_UNUSED_29FF: /* 0x129 */
7444/* File: x86/OP_UNUSED_29FF.S */
7445/* File: x86/unused.S */
7446    jmp     common_abort
7447
7448
7449/* ------------------------------ */
7450    .balign 64
7451.L_OP_UNUSED_2AFF: /* 0x12a */
7452/* File: x86/OP_UNUSED_2AFF.S */
7453/* File: x86/unused.S */
7454    jmp     common_abort
7455
7456
7457/* ------------------------------ */
7458    .balign 64
7459.L_OP_UNUSED_2BFF: /* 0x12b */
7460/* File: x86/OP_UNUSED_2BFF.S */
7461/* File: x86/unused.S */
7462    jmp     common_abort
7463
7464
7465/* ------------------------------ */
7466    .balign 64
7467.L_OP_UNUSED_2CFF: /* 0x12c */
7468/* File: x86/OP_UNUSED_2CFF.S */
7469/* File: x86/unused.S */
7470    jmp     common_abort
7471
7472
7473/* ------------------------------ */
7474    .balign 64
7475.L_OP_UNUSED_2DFF: /* 0x12d */
7476/* File: x86/OP_UNUSED_2DFF.S */
7477/* File: x86/unused.S */
7478    jmp     common_abort
7479
7480
7481/* ------------------------------ */
7482    .balign 64
7483.L_OP_UNUSED_2EFF: /* 0x12e */
7484/* File: x86/OP_UNUSED_2EFF.S */
7485/* File: x86/unused.S */
7486    jmp     common_abort
7487
7488
7489/* ------------------------------ */
7490    .balign 64
7491.L_OP_UNUSED_2FFF: /* 0x12f */
7492/* File: x86/OP_UNUSED_2FFF.S */
7493/* File: x86/unused.S */
7494    jmp     common_abort
7495
7496
7497/* ------------------------------ */
7498    .balign 64
7499.L_OP_UNUSED_30FF: /* 0x130 */
7500/* File: x86/OP_UNUSED_30FF.S */
7501/* File: x86/unused.S */
7502    jmp     common_abort
7503
7504
7505/* ------------------------------ */
7506    .balign 64
7507.L_OP_UNUSED_31FF: /* 0x131 */
7508/* File: x86/OP_UNUSED_31FF.S */
7509/* File: x86/unused.S */
7510    jmp     common_abort
7511
7512
7513/* ------------------------------ */
7514    .balign 64
7515.L_OP_UNUSED_32FF: /* 0x132 */
7516/* File: x86/OP_UNUSED_32FF.S */
7517/* File: x86/unused.S */
7518    jmp     common_abort
7519
7520
7521/* ------------------------------ */
7522    .balign 64
7523.L_OP_UNUSED_33FF: /* 0x133 */
7524/* File: x86/OP_UNUSED_33FF.S */
7525/* File: x86/unused.S */
7526    jmp     common_abort
7527
7528
7529/* ------------------------------ */
7530    .balign 64
7531.L_OP_UNUSED_34FF: /* 0x134 */
7532/* File: x86/OP_UNUSED_34FF.S */
7533/* File: x86/unused.S */
7534    jmp     common_abort
7535
7536
7537/* ------------------------------ */
7538    .balign 64
7539.L_OP_UNUSED_35FF: /* 0x135 */
7540/* File: x86/OP_UNUSED_35FF.S */
7541/* File: x86/unused.S */
7542    jmp     common_abort
7543
7544
7545/* ------------------------------ */
7546    .balign 64
7547.L_OP_UNUSED_36FF: /* 0x136 */
7548/* File: x86/OP_UNUSED_36FF.S */
7549/* File: x86/unused.S */
7550    jmp     common_abort
7551
7552
7553/* ------------------------------ */
7554    .balign 64
7555.L_OP_UNUSED_37FF: /* 0x137 */
7556/* File: x86/OP_UNUSED_37FF.S */
7557/* File: x86/unused.S */
7558    jmp     common_abort
7559
7560
7561/* ------------------------------ */
7562    .balign 64
7563.L_OP_UNUSED_38FF: /* 0x138 */
7564/* File: x86/OP_UNUSED_38FF.S */
7565/* File: x86/unused.S */
7566    jmp     common_abort
7567
7568
7569/* ------------------------------ */
7570    .balign 64
7571.L_OP_UNUSED_39FF: /* 0x139 */
7572/* File: x86/OP_UNUSED_39FF.S */
7573/* File: x86/unused.S */
7574    jmp     common_abort
7575
7576
7577/* ------------------------------ */
7578    .balign 64
7579.L_OP_UNUSED_3AFF: /* 0x13a */
7580/* File: x86/OP_UNUSED_3AFF.S */
7581/* File: x86/unused.S */
7582    jmp     common_abort
7583
7584
7585/* ------------------------------ */
7586    .balign 64
7587.L_OP_UNUSED_3BFF: /* 0x13b */
7588/* File: x86/OP_UNUSED_3BFF.S */
7589/* File: x86/unused.S */
7590    jmp     common_abort
7591
7592
7593/* ------------------------------ */
7594    .balign 64
7595.L_OP_UNUSED_3CFF: /* 0x13c */
7596/* File: x86/OP_UNUSED_3CFF.S */
7597/* File: x86/unused.S */
7598    jmp     common_abort
7599
7600
7601/* ------------------------------ */
7602    .balign 64
7603.L_OP_UNUSED_3DFF: /* 0x13d */
7604/* File: x86/OP_UNUSED_3DFF.S */
7605/* File: x86/unused.S */
7606    jmp     common_abort
7607
7608
7609/* ------------------------------ */
7610    .balign 64
7611.L_OP_UNUSED_3EFF: /* 0x13e */
7612/* File: x86/OP_UNUSED_3EFF.S */
7613/* File: x86/unused.S */
7614    jmp     common_abort
7615
7616
7617/* ------------------------------ */
7618    .balign 64
7619.L_OP_UNUSED_3FFF: /* 0x13f */
7620/* File: x86/OP_UNUSED_3FFF.S */
7621/* File: x86/unused.S */
7622    jmp     common_abort
7623
7624
7625/* ------------------------------ */
7626    .balign 64
7627.L_OP_UNUSED_40FF: /* 0x140 */
7628/* File: x86/OP_UNUSED_40FF.S */
7629/* File: x86/unused.S */
7630    jmp     common_abort
7631
7632
7633/* ------------------------------ */
7634    .balign 64
7635.L_OP_UNUSED_41FF: /* 0x141 */
7636/* File: x86/OP_UNUSED_41FF.S */
7637/* File: x86/unused.S */
7638    jmp     common_abort
7639
7640
7641/* ------------------------------ */
7642    .balign 64
7643.L_OP_UNUSED_42FF: /* 0x142 */
7644/* File: x86/OP_UNUSED_42FF.S */
7645/* File: x86/unused.S */
7646    jmp     common_abort
7647
7648
7649/* ------------------------------ */
7650    .balign 64
7651.L_OP_UNUSED_43FF: /* 0x143 */
7652/* File: x86/OP_UNUSED_43FF.S */
7653/* File: x86/unused.S */
7654    jmp     common_abort
7655
7656
7657/* ------------------------------ */
7658    .balign 64
7659.L_OP_UNUSED_44FF: /* 0x144 */
7660/* File: x86/OP_UNUSED_44FF.S */
7661/* File: x86/unused.S */
7662    jmp     common_abort
7663
7664
7665/* ------------------------------ */
7666    .balign 64
7667.L_OP_UNUSED_45FF: /* 0x145 */
7668/* File: x86/OP_UNUSED_45FF.S */
7669/* File: x86/unused.S */
7670    jmp     common_abort
7671
7672
7673/* ------------------------------ */
7674    .balign 64
7675.L_OP_UNUSED_46FF: /* 0x146 */
7676/* File: x86/OP_UNUSED_46FF.S */
7677/* File: x86/unused.S */
7678    jmp     common_abort
7679
7680
7681/* ------------------------------ */
7682    .balign 64
7683.L_OP_UNUSED_47FF: /* 0x147 */
7684/* File: x86/OP_UNUSED_47FF.S */
7685/* File: x86/unused.S */
7686    jmp     common_abort
7687
7688
7689/* ------------------------------ */
7690    .balign 64
7691.L_OP_UNUSED_48FF: /* 0x148 */
7692/* File: x86/OP_UNUSED_48FF.S */
7693/* File: x86/unused.S */
7694    jmp     common_abort
7695
7696
7697/* ------------------------------ */
7698    .balign 64
7699.L_OP_UNUSED_49FF: /* 0x149 */
7700/* File: x86/OP_UNUSED_49FF.S */
7701/* File: x86/unused.S */
7702    jmp     common_abort
7703
7704
7705/* ------------------------------ */
7706    .balign 64
7707.L_OP_UNUSED_4AFF: /* 0x14a */
7708/* File: x86/OP_UNUSED_4AFF.S */
7709/* File: x86/unused.S */
7710    jmp     common_abort
7711
7712
7713/* ------------------------------ */
7714    .balign 64
7715.L_OP_UNUSED_4BFF: /* 0x14b */
7716/* File: x86/OP_UNUSED_4BFF.S */
7717/* File: x86/unused.S */
7718    jmp     common_abort
7719
7720
7721/* ------------------------------ */
7722    .balign 64
7723.L_OP_UNUSED_4CFF: /* 0x14c */
7724/* File: x86/OP_UNUSED_4CFF.S */
7725/* File: x86/unused.S */
7726    jmp     common_abort
7727
7728
7729/* ------------------------------ */
7730    .balign 64
7731.L_OP_UNUSED_4DFF: /* 0x14d */
7732/* File: x86/OP_UNUSED_4DFF.S */
7733/* File: x86/unused.S */
7734    jmp     common_abort
7735
7736
7737/* ------------------------------ */
7738    .balign 64
7739.L_OP_UNUSED_4EFF: /* 0x14e */
7740/* File: x86/OP_UNUSED_4EFF.S */
7741/* File: x86/unused.S */
7742    jmp     common_abort
7743
7744
7745/* ------------------------------ */
7746    .balign 64
7747.L_OP_UNUSED_4FFF: /* 0x14f */
7748/* File: x86/OP_UNUSED_4FFF.S */
7749/* File: x86/unused.S */
7750    jmp     common_abort
7751
7752
7753/* ------------------------------ */
7754    .balign 64
7755.L_OP_UNUSED_50FF: /* 0x150 */
7756/* File: x86/OP_UNUSED_50FF.S */
7757/* File: x86/unused.S */
7758    jmp     common_abort
7759
7760
7761/* ------------------------------ */
7762    .balign 64
7763.L_OP_UNUSED_51FF: /* 0x151 */
7764/* File: x86/OP_UNUSED_51FF.S */
7765/* File: x86/unused.S */
7766    jmp     common_abort
7767
7768
7769/* ------------------------------ */
7770    .balign 64
7771.L_OP_UNUSED_52FF: /* 0x152 */
7772/* File: x86/OP_UNUSED_52FF.S */
7773/* File: x86/unused.S */
7774    jmp     common_abort
7775
7776
7777/* ------------------------------ */
7778    .balign 64
7779.L_OP_UNUSED_53FF: /* 0x153 */
7780/* File: x86/OP_UNUSED_53FF.S */
7781/* File: x86/unused.S */
7782    jmp     common_abort
7783
7784
7785/* ------------------------------ */
7786    .balign 64
7787.L_OP_UNUSED_54FF: /* 0x154 */
7788/* File: x86/OP_UNUSED_54FF.S */
7789/* File: x86/unused.S */
7790    jmp     common_abort
7791
7792
7793/* ------------------------------ */
7794    .balign 64
7795.L_OP_UNUSED_55FF: /* 0x155 */
7796/* File: x86/OP_UNUSED_55FF.S */
7797/* File: x86/unused.S */
7798    jmp     common_abort
7799
7800
7801/* ------------------------------ */
7802    .balign 64
7803.L_OP_UNUSED_56FF: /* 0x156 */
7804/* File: x86/OP_UNUSED_56FF.S */
7805/* File: x86/unused.S */
7806    jmp     common_abort
7807
7808
7809/* ------------------------------ */
7810    .balign 64
7811.L_OP_UNUSED_57FF: /* 0x157 */
7812/* File: x86/OP_UNUSED_57FF.S */
7813/* File: x86/unused.S */
7814    jmp     common_abort
7815
7816
7817/* ------------------------------ */
7818    .balign 64
7819.L_OP_UNUSED_58FF: /* 0x158 */
7820/* File: x86/OP_UNUSED_58FF.S */
7821/* File: x86/unused.S */
7822    jmp     common_abort
7823
7824
7825/* ------------------------------ */
7826    .balign 64
7827.L_OP_UNUSED_59FF: /* 0x159 */
7828/* File: x86/OP_UNUSED_59FF.S */
7829/* File: x86/unused.S */
7830    jmp     common_abort
7831
7832
7833/* ------------------------------ */
7834    .balign 64
7835.L_OP_UNUSED_5AFF: /* 0x15a */
7836/* File: x86/OP_UNUSED_5AFF.S */
7837/* File: x86/unused.S */
7838    jmp     common_abort
7839
7840
7841/* ------------------------------ */
7842    .balign 64
7843.L_OP_UNUSED_5BFF: /* 0x15b */
7844/* File: x86/OP_UNUSED_5BFF.S */
7845/* File: x86/unused.S */
7846    jmp     common_abort
7847
7848
7849/* ------------------------------ */
7850    .balign 64
7851.L_OP_UNUSED_5CFF: /* 0x15c */
7852/* File: x86/OP_UNUSED_5CFF.S */
7853/* File: x86/unused.S */
7854    jmp     common_abort
7855
7856
7857/* ------------------------------ */
7858    .balign 64
7859.L_OP_UNUSED_5DFF: /* 0x15d */
7860/* File: x86/OP_UNUSED_5DFF.S */
7861/* File: x86/unused.S */
7862    jmp     common_abort
7863
7864
7865/* ------------------------------ */
7866    .balign 64
7867.L_OP_UNUSED_5EFF: /* 0x15e */
7868/* File: x86/OP_UNUSED_5EFF.S */
7869/* File: x86/unused.S */
7870    jmp     common_abort
7871
7872
7873/* ------------------------------ */
7874    .balign 64
7875.L_OP_UNUSED_5FFF: /* 0x15f */
7876/* File: x86/OP_UNUSED_5FFF.S */
7877/* File: x86/unused.S */
7878    jmp     common_abort
7879
7880
7881/* ------------------------------ */
7882    .balign 64
7883.L_OP_UNUSED_60FF: /* 0x160 */
7884/* File: x86/OP_UNUSED_60FF.S */
7885/* File: x86/unused.S */
7886    jmp     common_abort
7887
7888
7889/* ------------------------------ */
7890    .balign 64
7891.L_OP_UNUSED_61FF: /* 0x161 */
7892/* File: x86/OP_UNUSED_61FF.S */
7893/* File: x86/unused.S */
7894    jmp     common_abort
7895
7896
7897/* ------------------------------ */
7898    .balign 64
7899.L_OP_UNUSED_62FF: /* 0x162 */
7900/* File: x86/OP_UNUSED_62FF.S */
7901/* File: x86/unused.S */
7902    jmp     common_abort
7903
7904
7905/* ------------------------------ */
7906    .balign 64
7907.L_OP_UNUSED_63FF: /* 0x163 */
7908/* File: x86/OP_UNUSED_63FF.S */
7909/* File: x86/unused.S */
7910    jmp     common_abort
7911
7912
7913/* ------------------------------ */
7914    .balign 64
7915.L_OP_UNUSED_64FF: /* 0x164 */
7916/* File: x86/OP_UNUSED_64FF.S */
7917/* File: x86/unused.S */
7918    jmp     common_abort
7919
7920
7921/* ------------------------------ */
7922    .balign 64
7923.L_OP_UNUSED_65FF: /* 0x165 */
7924/* File: x86/OP_UNUSED_65FF.S */
7925/* File: x86/unused.S */
7926    jmp     common_abort
7927
7928
7929/* ------------------------------ */
7930    .balign 64
7931.L_OP_UNUSED_66FF: /* 0x166 */
7932/* File: x86/OP_UNUSED_66FF.S */
7933/* File: x86/unused.S */
7934    jmp     common_abort
7935
7936
7937/* ------------------------------ */
7938    .balign 64
7939.L_OP_UNUSED_67FF: /* 0x167 */
7940/* File: x86/OP_UNUSED_67FF.S */
7941/* File: x86/unused.S */
7942    jmp     common_abort
7943
7944
7945/* ------------------------------ */
7946    .balign 64
7947.L_OP_UNUSED_68FF: /* 0x168 */
7948/* File: x86/OP_UNUSED_68FF.S */
7949/* File: x86/unused.S */
7950    jmp     common_abort
7951
7952
7953/* ------------------------------ */
7954    .balign 64
7955.L_OP_UNUSED_69FF: /* 0x169 */
7956/* File: x86/OP_UNUSED_69FF.S */
7957/* File: x86/unused.S */
7958    jmp     common_abort
7959
7960
7961/* ------------------------------ */
7962    .balign 64
7963.L_OP_UNUSED_6AFF: /* 0x16a */
7964/* File: x86/OP_UNUSED_6AFF.S */
7965/* File: x86/unused.S */
7966    jmp     common_abort
7967
7968
7969/* ------------------------------ */
7970    .balign 64
7971.L_OP_UNUSED_6BFF: /* 0x16b */
7972/* File: x86/OP_UNUSED_6BFF.S */
7973/* File: x86/unused.S */
7974    jmp     common_abort
7975
7976
7977/* ------------------------------ */
7978    .balign 64
7979.L_OP_UNUSED_6CFF: /* 0x16c */
7980/* File: x86/OP_UNUSED_6CFF.S */
7981/* File: x86/unused.S */
7982    jmp     common_abort
7983
7984
7985/* ------------------------------ */
7986    .balign 64
7987.L_OP_UNUSED_6DFF: /* 0x16d */
7988/* File: x86/OP_UNUSED_6DFF.S */
7989/* File: x86/unused.S */
7990    jmp     common_abort
7991
7992
7993/* ------------------------------ */
7994    .balign 64
7995.L_OP_UNUSED_6EFF: /* 0x16e */
7996/* File: x86/OP_UNUSED_6EFF.S */
7997/* File: x86/unused.S */
7998    jmp     common_abort
7999
8000
8001/* ------------------------------ */
8002    .balign 64
8003.L_OP_UNUSED_6FFF: /* 0x16f */
8004/* File: x86/OP_UNUSED_6FFF.S */
8005/* File: x86/unused.S */
8006    jmp     common_abort
8007
8008
8009/* ------------------------------ */
8010    .balign 64
8011.L_OP_UNUSED_70FF: /* 0x170 */
8012/* File: x86/OP_UNUSED_70FF.S */
8013/* File: x86/unused.S */
8014    jmp     common_abort
8015
8016
8017/* ------------------------------ */
8018    .balign 64
8019.L_OP_UNUSED_71FF: /* 0x171 */
8020/* File: x86/OP_UNUSED_71FF.S */
8021/* File: x86/unused.S */
8022    jmp     common_abort
8023
8024
8025/* ------------------------------ */
8026    .balign 64
8027.L_OP_UNUSED_72FF: /* 0x172 */
8028/* File: x86/OP_UNUSED_72FF.S */
8029/* File: x86/unused.S */
8030    jmp     common_abort
8031
8032
8033/* ------------------------------ */
8034    .balign 64
8035.L_OP_UNUSED_73FF: /* 0x173 */
8036/* File: x86/OP_UNUSED_73FF.S */
8037/* File: x86/unused.S */
8038    jmp     common_abort
8039
8040
8041/* ------------------------------ */
8042    .balign 64
8043.L_OP_UNUSED_74FF: /* 0x174 */
8044/* File: x86/OP_UNUSED_74FF.S */
8045/* File: x86/unused.S */
8046    jmp     common_abort
8047
8048
8049/* ------------------------------ */
8050    .balign 64
8051.L_OP_UNUSED_75FF: /* 0x175 */
8052/* File: x86/OP_UNUSED_75FF.S */
8053/* File: x86/unused.S */
8054    jmp     common_abort
8055
8056
8057/* ------------------------------ */
8058    .balign 64
8059.L_OP_UNUSED_76FF: /* 0x176 */
8060/* File: x86/OP_UNUSED_76FF.S */
8061/* File: x86/unused.S */
8062    jmp     common_abort
8063
8064
8065/* ------------------------------ */
8066    .balign 64
8067.L_OP_UNUSED_77FF: /* 0x177 */
8068/* File: x86/OP_UNUSED_77FF.S */
8069/* File: x86/unused.S */
8070    jmp     common_abort
8071
8072
8073/* ------------------------------ */
8074    .balign 64
8075.L_OP_UNUSED_78FF: /* 0x178 */
8076/* File: x86/OP_UNUSED_78FF.S */
8077/* File: x86/unused.S */
8078    jmp     common_abort
8079
8080
8081/* ------------------------------ */
8082    .balign 64
8083.L_OP_UNUSED_79FF: /* 0x179 */
8084/* File: x86/OP_UNUSED_79FF.S */
8085/* File: x86/unused.S */
8086    jmp     common_abort
8087
8088
8089/* ------------------------------ */
8090    .balign 64
8091.L_OP_UNUSED_7AFF: /* 0x17a */
8092/* File: x86/OP_UNUSED_7AFF.S */
8093/* File: x86/unused.S */
8094    jmp     common_abort
8095
8096
8097/* ------------------------------ */
8098    .balign 64
8099.L_OP_UNUSED_7BFF: /* 0x17b */
8100/* File: x86/OP_UNUSED_7BFF.S */
8101/* File: x86/unused.S */
8102    jmp     common_abort
8103
8104
8105/* ------------------------------ */
8106    .balign 64
8107.L_OP_UNUSED_7CFF: /* 0x17c */
8108/* File: x86/OP_UNUSED_7CFF.S */
8109/* File: x86/unused.S */
8110    jmp     common_abort
8111
8112
8113/* ------------------------------ */
8114    .balign 64
8115.L_OP_UNUSED_7DFF: /* 0x17d */
8116/* File: x86/OP_UNUSED_7DFF.S */
8117/* File: x86/unused.S */
8118    jmp     common_abort
8119
8120
8121/* ------------------------------ */
8122    .balign 64
8123.L_OP_UNUSED_7EFF: /* 0x17e */
8124/* File: x86/OP_UNUSED_7EFF.S */
8125/* File: x86/unused.S */
8126    jmp     common_abort
8127
8128
8129/* ------------------------------ */
8130    .balign 64
8131.L_OP_UNUSED_7FFF: /* 0x17f */
8132/* File: x86/OP_UNUSED_7FFF.S */
8133/* File: x86/unused.S */
8134    jmp     common_abort
8135
8136
8137/* ------------------------------ */
8138    .balign 64
8139.L_OP_UNUSED_80FF: /* 0x180 */
8140/* File: x86/OP_UNUSED_80FF.S */
8141/* File: x86/unused.S */
8142    jmp     common_abort
8143
8144
8145/* ------------------------------ */
8146    .balign 64
8147.L_OP_UNUSED_81FF: /* 0x181 */
8148/* File: x86/OP_UNUSED_81FF.S */
8149/* File: x86/unused.S */
8150    jmp     common_abort
8151
8152
8153/* ------------------------------ */
8154    .balign 64
8155.L_OP_UNUSED_82FF: /* 0x182 */
8156/* File: x86/OP_UNUSED_82FF.S */
8157/* File: x86/unused.S */
8158    jmp     common_abort
8159
8160
8161/* ------------------------------ */
8162    .balign 64
8163.L_OP_UNUSED_83FF: /* 0x183 */
8164/* File: x86/OP_UNUSED_83FF.S */
8165/* File: x86/unused.S */
8166    jmp     common_abort
8167
8168
8169/* ------------------------------ */
8170    .balign 64
8171.L_OP_UNUSED_84FF: /* 0x184 */
8172/* File: x86/OP_UNUSED_84FF.S */
8173/* File: x86/unused.S */
8174    jmp     common_abort
8175
8176
8177/* ------------------------------ */
8178    .balign 64
8179.L_OP_UNUSED_85FF: /* 0x185 */
8180/* File: x86/OP_UNUSED_85FF.S */
8181/* File: x86/unused.S */
8182    jmp     common_abort
8183
8184
8185/* ------------------------------ */
8186    .balign 64
8187.L_OP_UNUSED_86FF: /* 0x186 */
8188/* File: x86/OP_UNUSED_86FF.S */
8189/* File: x86/unused.S */
8190    jmp     common_abort
8191
8192
8193/* ------------------------------ */
8194    .balign 64
8195.L_OP_UNUSED_87FF: /* 0x187 */
8196/* File: x86/OP_UNUSED_87FF.S */
8197/* File: x86/unused.S */
8198    jmp     common_abort
8199
8200
8201/* ------------------------------ */
8202    .balign 64
8203.L_OP_UNUSED_88FF: /* 0x188 */
8204/* File: x86/OP_UNUSED_88FF.S */
8205/* File: x86/unused.S */
8206    jmp     common_abort
8207
8208
8209/* ------------------------------ */
8210    .balign 64
8211.L_OP_UNUSED_89FF: /* 0x189 */
8212/* File: x86/OP_UNUSED_89FF.S */
8213/* File: x86/unused.S */
8214    jmp     common_abort
8215
8216
8217/* ------------------------------ */
8218    .balign 64
8219.L_OP_UNUSED_8AFF: /* 0x18a */
8220/* File: x86/OP_UNUSED_8AFF.S */
8221/* File: x86/unused.S */
8222    jmp     common_abort
8223
8224
8225/* ------------------------------ */
8226    .balign 64
8227.L_OP_UNUSED_8BFF: /* 0x18b */
8228/* File: x86/OP_UNUSED_8BFF.S */
8229/* File: x86/unused.S */
8230    jmp     common_abort
8231
8232
8233/* ------------------------------ */
8234    .balign 64
8235.L_OP_UNUSED_8CFF: /* 0x18c */
8236/* File: x86/OP_UNUSED_8CFF.S */
8237/* File: x86/unused.S */
8238    jmp     common_abort
8239
8240
8241/* ------------------------------ */
8242    .balign 64
8243.L_OP_UNUSED_8DFF: /* 0x18d */
8244/* File: x86/OP_UNUSED_8DFF.S */
8245/* File: x86/unused.S */
8246    jmp     common_abort
8247
8248
8249/* ------------------------------ */
8250    .balign 64
8251.L_OP_UNUSED_8EFF: /* 0x18e */
8252/* File: x86/OP_UNUSED_8EFF.S */
8253/* File: x86/unused.S */
8254    jmp     common_abort
8255
8256
8257/* ------------------------------ */
8258    .balign 64
8259.L_OP_UNUSED_8FFF: /* 0x18f */
8260/* File: x86/OP_UNUSED_8FFF.S */
8261/* File: x86/unused.S */
8262    jmp     common_abort
8263
8264
8265/* ------------------------------ */
8266    .balign 64
8267.L_OP_UNUSED_90FF: /* 0x190 */
8268/* File: x86/OP_UNUSED_90FF.S */
8269/* File: x86/unused.S */
8270    jmp     common_abort
8271
8272
8273/* ------------------------------ */
8274    .balign 64
8275.L_OP_UNUSED_91FF: /* 0x191 */
8276/* File: x86/OP_UNUSED_91FF.S */
8277/* File: x86/unused.S */
8278    jmp     common_abort
8279
8280
8281/* ------------------------------ */
8282    .balign 64
8283.L_OP_UNUSED_92FF: /* 0x192 */
8284/* File: x86/OP_UNUSED_92FF.S */
8285/* File: x86/unused.S */
8286    jmp     common_abort
8287
8288
8289/* ------------------------------ */
8290    .balign 64
8291.L_OP_UNUSED_93FF: /* 0x193 */
8292/* File: x86/OP_UNUSED_93FF.S */
8293/* File: x86/unused.S */
8294    jmp     common_abort
8295
8296
8297/* ------------------------------ */
8298    .balign 64
8299.L_OP_UNUSED_94FF: /* 0x194 */
8300/* File: x86/OP_UNUSED_94FF.S */
8301/* File: x86/unused.S */
8302    jmp     common_abort
8303
8304
8305/* ------------------------------ */
8306    .balign 64
8307.L_OP_UNUSED_95FF: /* 0x195 */
8308/* File: x86/OP_UNUSED_95FF.S */
8309/* File: x86/unused.S */
8310    jmp     common_abort
8311
8312
8313/* ------------------------------ */
8314    .balign 64
8315.L_OP_UNUSED_96FF: /* 0x196 */
8316/* File: x86/OP_UNUSED_96FF.S */
8317/* File: x86/unused.S */
8318    jmp     common_abort
8319
8320
8321/* ------------------------------ */
8322    .balign 64
8323.L_OP_UNUSED_97FF: /* 0x197 */
8324/* File: x86/OP_UNUSED_97FF.S */
8325/* File: x86/unused.S */
8326    jmp     common_abort
8327
8328
8329/* ------------------------------ */
8330    .balign 64
8331.L_OP_UNUSED_98FF: /* 0x198 */
8332/* File: x86/OP_UNUSED_98FF.S */
8333/* File: x86/unused.S */
8334    jmp     common_abort
8335
8336
8337/* ------------------------------ */
8338    .balign 64
8339.L_OP_UNUSED_99FF: /* 0x199 */
8340/* File: x86/OP_UNUSED_99FF.S */
8341/* File: x86/unused.S */
8342    jmp     common_abort
8343
8344
8345/* ------------------------------ */
8346    .balign 64
8347.L_OP_UNUSED_9AFF: /* 0x19a */
8348/* File: x86/OP_UNUSED_9AFF.S */
8349/* File: x86/unused.S */
8350    jmp     common_abort
8351
8352
8353/* ------------------------------ */
8354    .balign 64
8355.L_OP_UNUSED_9BFF: /* 0x19b */
8356/* File: x86/OP_UNUSED_9BFF.S */
8357/* File: x86/unused.S */
8358    jmp     common_abort
8359
8360
8361/* ------------------------------ */
8362    .balign 64
8363.L_OP_UNUSED_9CFF: /* 0x19c */
8364/* File: x86/OP_UNUSED_9CFF.S */
8365/* File: x86/unused.S */
8366    jmp     common_abort
8367
8368
8369/* ------------------------------ */
8370    .balign 64
8371.L_OP_UNUSED_9DFF: /* 0x19d */
8372/* File: x86/OP_UNUSED_9DFF.S */
8373/* File: x86/unused.S */
8374    jmp     common_abort
8375
8376
8377/* ------------------------------ */
8378    .balign 64
8379.L_OP_UNUSED_9EFF: /* 0x19e */
8380/* File: x86/OP_UNUSED_9EFF.S */
8381/* File: x86/unused.S */
8382    jmp     common_abort
8383
8384
8385/* ------------------------------ */
8386    .balign 64
8387.L_OP_UNUSED_9FFF: /* 0x19f */
8388/* File: x86/OP_UNUSED_9FFF.S */
8389/* File: x86/unused.S */
8390    jmp     common_abort
8391
8392
8393/* ------------------------------ */
8394    .balign 64
8395.L_OP_UNUSED_A0FF: /* 0x1a0 */
8396/* File: x86/OP_UNUSED_A0FF.S */
8397/* File: x86/unused.S */
8398    jmp     common_abort
8399
8400
8401/* ------------------------------ */
8402    .balign 64
8403.L_OP_UNUSED_A1FF: /* 0x1a1 */
8404/* File: x86/OP_UNUSED_A1FF.S */
8405/* File: x86/unused.S */
8406    jmp     common_abort
8407
8408
8409/* ------------------------------ */
8410    .balign 64
8411.L_OP_UNUSED_A2FF: /* 0x1a2 */
8412/* File: x86/OP_UNUSED_A2FF.S */
8413/* File: x86/unused.S */
8414    jmp     common_abort
8415
8416
8417/* ------------------------------ */
8418    .balign 64
8419.L_OP_UNUSED_A3FF: /* 0x1a3 */
8420/* File: x86/OP_UNUSED_A3FF.S */
8421/* File: x86/unused.S */
8422    jmp     common_abort
8423
8424
8425/* ------------------------------ */
8426    .balign 64
8427.L_OP_UNUSED_A4FF: /* 0x1a4 */
8428/* File: x86/OP_UNUSED_A4FF.S */
8429/* File: x86/unused.S */
8430    jmp     common_abort
8431
8432
8433/* ------------------------------ */
8434    .balign 64
8435.L_OP_UNUSED_A5FF: /* 0x1a5 */
8436/* File: x86/OP_UNUSED_A5FF.S */
8437/* File: x86/unused.S */
8438    jmp     common_abort
8439
8440
8441/* ------------------------------ */
8442    .balign 64
8443.L_OP_UNUSED_A6FF: /* 0x1a6 */
8444/* File: x86/OP_UNUSED_A6FF.S */
8445/* File: x86/unused.S */
8446    jmp     common_abort
8447
8448
8449/* ------------------------------ */
8450    .balign 64
8451.L_OP_UNUSED_A7FF: /* 0x1a7 */
8452/* File: x86/OP_UNUSED_A7FF.S */
8453/* File: x86/unused.S */
8454    jmp     common_abort
8455
8456
8457/* ------------------------------ */
8458    .balign 64
8459.L_OP_UNUSED_A8FF: /* 0x1a8 */
8460/* File: x86/OP_UNUSED_A8FF.S */
8461/* File: x86/unused.S */
8462    jmp     common_abort
8463
8464
8465/* ------------------------------ */
8466    .balign 64
8467.L_OP_UNUSED_A9FF: /* 0x1a9 */
8468/* File: x86/OP_UNUSED_A9FF.S */
8469/* File: x86/unused.S */
8470    jmp     common_abort
8471
8472
8473/* ------------------------------ */
8474    .balign 64
8475.L_OP_UNUSED_AAFF: /* 0x1aa */
8476/* File: x86/OP_UNUSED_AAFF.S */
8477/* File: x86/unused.S */
8478    jmp     common_abort
8479
8480
8481/* ------------------------------ */
8482    .balign 64
8483.L_OP_UNUSED_ABFF: /* 0x1ab */
8484/* File: x86/OP_UNUSED_ABFF.S */
8485/* File: x86/unused.S */
8486    jmp     common_abort
8487
8488
8489/* ------------------------------ */
8490    .balign 64
8491.L_OP_UNUSED_ACFF: /* 0x1ac */
8492/* File: x86/OP_UNUSED_ACFF.S */
8493/* File: x86/unused.S */
8494    jmp     common_abort
8495
8496
8497/* ------------------------------ */
8498    .balign 64
8499.L_OP_UNUSED_ADFF: /* 0x1ad */
8500/* File: x86/OP_UNUSED_ADFF.S */
8501/* File: x86/unused.S */
8502    jmp     common_abort
8503
8504
8505/* ------------------------------ */
8506    .balign 64
8507.L_OP_UNUSED_AEFF: /* 0x1ae */
8508/* File: x86/OP_UNUSED_AEFF.S */
8509/* File: x86/unused.S */
8510    jmp     common_abort
8511
8512
8513/* ------------------------------ */
8514    .balign 64
8515.L_OP_UNUSED_AFFF: /* 0x1af */
8516/* File: x86/OP_UNUSED_AFFF.S */
8517/* File: x86/unused.S */
8518    jmp     common_abort
8519
8520
8521/* ------------------------------ */
8522    .balign 64
8523.L_OP_UNUSED_B0FF: /* 0x1b0 */
8524/* File: x86/OP_UNUSED_B0FF.S */
8525/* File: x86/unused.S */
8526    jmp     common_abort
8527
8528
8529/* ------------------------------ */
8530    .balign 64
8531.L_OP_UNUSED_B1FF: /* 0x1b1 */
8532/* File: x86/OP_UNUSED_B1FF.S */
8533/* File: x86/unused.S */
8534    jmp     common_abort
8535
8536
8537/* ------------------------------ */
8538    .balign 64
8539.L_OP_UNUSED_B2FF: /* 0x1b2 */
8540/* File: x86/OP_UNUSED_B2FF.S */
8541/* File: x86/unused.S */
8542    jmp     common_abort
8543
8544
8545/* ------------------------------ */
8546    .balign 64
8547.L_OP_UNUSED_B3FF: /* 0x1b3 */
8548/* File: x86/OP_UNUSED_B3FF.S */
8549/* File: x86/unused.S */
8550    jmp     common_abort
8551
8552
8553/* ------------------------------ */
8554    .balign 64
8555.L_OP_UNUSED_B4FF: /* 0x1b4 */
8556/* File: x86/OP_UNUSED_B4FF.S */
8557/* File: x86/unused.S */
8558    jmp     common_abort
8559
8560
8561/* ------------------------------ */
8562    .balign 64
8563.L_OP_UNUSED_B5FF: /* 0x1b5 */
8564/* File: x86/OP_UNUSED_B5FF.S */
8565/* File: x86/unused.S */
8566    jmp     common_abort
8567
8568
8569/* ------------------------------ */
8570    .balign 64
8571.L_OP_UNUSED_B6FF: /* 0x1b6 */
8572/* File: x86/OP_UNUSED_B6FF.S */
8573/* File: x86/unused.S */
8574    jmp     common_abort
8575
8576
8577/* ------------------------------ */
8578    .balign 64
8579.L_OP_UNUSED_B7FF: /* 0x1b7 */
8580/* File: x86/OP_UNUSED_B7FF.S */
8581/* File: x86/unused.S */
8582    jmp     common_abort
8583
8584
8585/* ------------------------------ */
8586    .balign 64
8587.L_OP_UNUSED_B8FF: /* 0x1b8 */
8588/* File: x86/OP_UNUSED_B8FF.S */
8589/* File: x86/unused.S */
8590    jmp     common_abort
8591
8592
8593/* ------------------------------ */
8594    .balign 64
8595.L_OP_UNUSED_B9FF: /* 0x1b9 */
8596/* File: x86/OP_UNUSED_B9FF.S */
8597/* File: x86/unused.S */
8598    jmp     common_abort
8599
8600
8601/* ------------------------------ */
8602    .balign 64
8603.L_OP_UNUSED_BAFF: /* 0x1ba */
8604/* File: x86/OP_UNUSED_BAFF.S */
8605/* File: x86/unused.S */
8606    jmp     common_abort
8607
8608
8609/* ------------------------------ */
8610    .balign 64
8611.L_OP_UNUSED_BBFF: /* 0x1bb */
8612/* File: x86/OP_UNUSED_BBFF.S */
8613/* File: x86/unused.S */
8614    jmp     common_abort
8615
8616
8617/* ------------------------------ */
8618    .balign 64
8619.L_OP_UNUSED_BCFF: /* 0x1bc */
8620/* File: x86/OP_UNUSED_BCFF.S */
8621/* File: x86/unused.S */
8622    jmp     common_abort
8623
8624
8625/* ------------------------------ */
8626    .balign 64
8627.L_OP_UNUSED_BDFF: /* 0x1bd */
8628/* File: x86/OP_UNUSED_BDFF.S */
8629/* File: x86/unused.S */
8630    jmp     common_abort
8631
8632
8633/* ------------------------------ */
8634    .balign 64
8635.L_OP_UNUSED_BEFF: /* 0x1be */
8636/* File: x86/OP_UNUSED_BEFF.S */
8637/* File: x86/unused.S */
8638    jmp     common_abort
8639
8640
8641/* ------------------------------ */
8642    .balign 64
8643.L_OP_UNUSED_BFFF: /* 0x1bf */
8644/* File: x86/OP_UNUSED_BFFF.S */
8645/* File: x86/unused.S */
8646    jmp     common_abort
8647
8648
8649/* ------------------------------ */
8650    .balign 64
8651.L_OP_UNUSED_C0FF: /* 0x1c0 */
8652/* File: x86/OP_UNUSED_C0FF.S */
8653/* File: x86/unused.S */
8654    jmp     common_abort
8655
8656
8657/* ------------------------------ */
8658    .balign 64
8659.L_OP_UNUSED_C1FF: /* 0x1c1 */
8660/* File: x86/OP_UNUSED_C1FF.S */
8661/* File: x86/unused.S */
8662    jmp     common_abort
8663
8664
8665/* ------------------------------ */
8666    .balign 64
8667.L_OP_UNUSED_C2FF: /* 0x1c2 */
8668/* File: x86/OP_UNUSED_C2FF.S */
8669/* File: x86/unused.S */
8670    jmp     common_abort
8671
8672
8673/* ------------------------------ */
8674    .balign 64
8675.L_OP_UNUSED_C3FF: /* 0x1c3 */
8676/* File: x86/OP_UNUSED_C3FF.S */
8677/* File: x86/unused.S */
8678    jmp     common_abort
8679
8680
8681/* ------------------------------ */
8682    .balign 64
8683.L_OP_UNUSED_C4FF: /* 0x1c4 */
8684/* File: x86/OP_UNUSED_C4FF.S */
8685/* File: x86/unused.S */
8686    jmp     common_abort
8687
8688
8689/* ------------------------------ */
8690    .balign 64
8691.L_OP_UNUSED_C5FF: /* 0x1c5 */
8692/* File: x86/OP_UNUSED_C5FF.S */
8693/* File: x86/unused.S */
8694    jmp     common_abort
8695
8696
8697/* ------------------------------ */
8698    .balign 64
8699.L_OP_UNUSED_C6FF: /* 0x1c6 */
8700/* File: x86/OP_UNUSED_C6FF.S */
8701/* File: x86/unused.S */
8702    jmp     common_abort
8703
8704
8705/* ------------------------------ */
8706    .balign 64
8707.L_OP_UNUSED_C7FF: /* 0x1c7 */
8708/* File: x86/OP_UNUSED_C7FF.S */
8709/* File: x86/unused.S */
8710    jmp     common_abort
8711
8712
8713/* ------------------------------ */
8714    .balign 64
8715.L_OP_UNUSED_C8FF: /* 0x1c8 */
8716/* File: x86/OP_UNUSED_C8FF.S */
8717/* File: x86/unused.S */
8718    jmp     common_abort
8719
8720
8721/* ------------------------------ */
8722    .balign 64
8723.L_OP_UNUSED_C9FF: /* 0x1c9 */
8724/* File: x86/OP_UNUSED_C9FF.S */
8725/* File: x86/unused.S */
8726    jmp     common_abort
8727
8728
8729/* ------------------------------ */
8730    .balign 64
8731.L_OP_UNUSED_CAFF: /* 0x1ca */
8732/* File: x86/OP_UNUSED_CAFF.S */
8733/* File: x86/unused.S */
8734    jmp     common_abort
8735
8736
8737/* ------------------------------ */
8738    .balign 64
8739.L_OP_UNUSED_CBFF: /* 0x1cb */
8740/* File: x86/OP_UNUSED_CBFF.S */
8741/* File: x86/unused.S */
8742    jmp     common_abort
8743
8744
8745/* ------------------------------ */
8746    .balign 64
8747.L_OP_UNUSED_CCFF: /* 0x1cc */
8748/* File: x86/OP_UNUSED_CCFF.S */
8749/* File: x86/unused.S */
8750    jmp     common_abort
8751
8752
8753/* ------------------------------ */
8754    .balign 64
8755.L_OP_UNUSED_CDFF: /* 0x1cd */
8756/* File: x86/OP_UNUSED_CDFF.S */
8757/* File: x86/unused.S */
8758    jmp     common_abort
8759
8760
8761/* ------------------------------ */
8762    .balign 64
8763.L_OP_UNUSED_CEFF: /* 0x1ce */
8764/* File: x86/OP_UNUSED_CEFF.S */
8765/* File: x86/unused.S */
8766    jmp     common_abort
8767
8768
8769/* ------------------------------ */
8770    .balign 64
8771.L_OP_UNUSED_CFFF: /* 0x1cf */
8772/* File: x86/OP_UNUSED_CFFF.S */
8773/* File: x86/unused.S */
8774    jmp     common_abort
8775
8776
8777/* ------------------------------ */
8778    .balign 64
8779.L_OP_UNUSED_D0FF: /* 0x1d0 */
8780/* File: x86/OP_UNUSED_D0FF.S */
8781/* File: x86/unused.S */
8782    jmp     common_abort
8783
8784
8785/* ------------------------------ */
8786    .balign 64
8787.L_OP_UNUSED_D1FF: /* 0x1d1 */
8788/* File: x86/OP_UNUSED_D1FF.S */
8789/* File: x86/unused.S */
8790    jmp     common_abort
8791
8792
8793/* ------------------------------ */
8794    .balign 64
8795.L_OP_UNUSED_D2FF: /* 0x1d2 */
8796/* File: x86/OP_UNUSED_D2FF.S */
8797/* File: x86/unused.S */
8798    jmp     common_abort
8799
8800
8801/* ------------------------------ */
8802    .balign 64
8803.L_OP_UNUSED_D3FF: /* 0x1d3 */
8804/* File: x86/OP_UNUSED_D3FF.S */
8805/* File: x86/unused.S */
8806    jmp     common_abort
8807
8808
8809/* ------------------------------ */
8810    .balign 64
8811.L_OP_UNUSED_D4FF: /* 0x1d4 */
8812/* File: x86/OP_UNUSED_D4FF.S */
8813/* File: x86/unused.S */
8814    jmp     common_abort
8815
8816
8817/* ------------------------------ */
8818    .balign 64
8819.L_OP_UNUSED_D5FF: /* 0x1d5 */
8820/* File: x86/OP_UNUSED_D5FF.S */
8821/* File: x86/unused.S */
8822    jmp     common_abort
8823
8824
8825/* ------------------------------ */
8826    .balign 64
8827.L_OP_UNUSED_D6FF: /* 0x1d6 */
8828/* File: x86/OP_UNUSED_D6FF.S */
8829/* File: x86/unused.S */
8830    jmp     common_abort
8831
8832
8833/* ------------------------------ */
8834    .balign 64
8835.L_OP_UNUSED_D7FF: /* 0x1d7 */
8836/* File: x86/OP_UNUSED_D7FF.S */
8837/* File: x86/unused.S */
8838    jmp     common_abort
8839
8840
8841/* ------------------------------ */
8842    .balign 64
8843.L_OP_UNUSED_D8FF: /* 0x1d8 */
8844/* File: x86/OP_UNUSED_D8FF.S */
8845/* File: x86/unused.S */
8846    jmp     common_abort
8847
8848
8849/* ------------------------------ */
8850    .balign 64
8851.L_OP_UNUSED_D9FF: /* 0x1d9 */
8852/* File: x86/OP_UNUSED_D9FF.S */
8853/* File: x86/unused.S */
8854    jmp     common_abort
8855
8856
8857/* ------------------------------ */
8858    .balign 64
8859.L_OP_UNUSED_DAFF: /* 0x1da */
8860/* File: x86/OP_UNUSED_DAFF.S */
8861/* File: x86/unused.S */
8862    jmp     common_abort
8863
8864
8865/* ------------------------------ */
8866    .balign 64
8867.L_OP_UNUSED_DBFF: /* 0x1db */
8868/* File: x86/OP_UNUSED_DBFF.S */
8869/* File: x86/unused.S */
8870    jmp     common_abort
8871
8872
8873/* ------------------------------ */
8874    .balign 64
8875.L_OP_UNUSED_DCFF: /* 0x1dc */
8876/* File: x86/OP_UNUSED_DCFF.S */
8877/* File: x86/unused.S */
8878    jmp     common_abort
8879
8880
8881/* ------------------------------ */
8882    .balign 64
8883.L_OP_UNUSED_DDFF: /* 0x1dd */
8884/* File: x86/OP_UNUSED_DDFF.S */
8885/* File: x86/unused.S */
8886    jmp     common_abort
8887
8888
8889/* ------------------------------ */
8890    .balign 64
8891.L_OP_UNUSED_DEFF: /* 0x1de */
8892/* File: x86/OP_UNUSED_DEFF.S */
8893/* File: x86/unused.S */
8894    jmp     common_abort
8895
8896
8897/* ------------------------------ */
8898    .balign 64
8899.L_OP_UNUSED_DFFF: /* 0x1df */
8900/* File: x86/OP_UNUSED_DFFF.S */
8901/* File: x86/unused.S */
8902    jmp     common_abort
8903
8904
8905/* ------------------------------ */
8906    .balign 64
8907.L_OP_UNUSED_E0FF: /* 0x1e0 */
8908/* File: x86/OP_UNUSED_E0FF.S */
8909/* File: x86/unused.S */
8910    jmp     common_abort
8911
8912
8913/* ------------------------------ */
8914    .balign 64
8915.L_OP_UNUSED_E1FF: /* 0x1e1 */
8916/* File: x86/OP_UNUSED_E1FF.S */
8917/* File: x86/unused.S */
8918    jmp     common_abort
8919
8920
8921/* ------------------------------ */
8922    .balign 64
8923.L_OP_UNUSED_E2FF: /* 0x1e2 */
8924/* File: x86/OP_UNUSED_E2FF.S */
8925/* File: x86/unused.S */
8926    jmp     common_abort
8927
8928
8929/* ------------------------------ */
8930    .balign 64
8931.L_OP_UNUSED_E3FF: /* 0x1e3 */
8932/* File: x86/OP_UNUSED_E3FF.S */
8933/* File: x86/unused.S */
8934    jmp     common_abort
8935
8936
8937/* ------------------------------ */
8938    .balign 64
8939.L_OP_UNUSED_E4FF: /* 0x1e4 */
8940/* File: x86/OP_UNUSED_E4FF.S */
8941/* File: x86/unused.S */
8942    jmp     common_abort
8943
8944
8945/* ------------------------------ */
8946    .balign 64
8947.L_OP_UNUSED_E5FF: /* 0x1e5 */
8948/* File: x86/OP_UNUSED_E5FF.S */
8949/* File: x86/unused.S */
8950    jmp     common_abort
8951
8952
8953/* ------------------------------ */
8954    .balign 64
8955.L_OP_UNUSED_E6FF: /* 0x1e6 */
8956/* File: x86/OP_UNUSED_E6FF.S */
8957/* File: x86/unused.S */
8958    jmp     common_abort
8959
8960
8961/* ------------------------------ */
8962    .balign 64
8963.L_OP_UNUSED_E7FF: /* 0x1e7 */
8964/* File: x86/OP_UNUSED_E7FF.S */
8965/* File: x86/unused.S */
8966    jmp     common_abort
8967
8968
8969/* ------------------------------ */
8970    .balign 64
8971.L_OP_UNUSED_E8FF: /* 0x1e8 */
8972/* File: x86/OP_UNUSED_E8FF.S */
8973/* File: x86/unused.S */
8974    jmp     common_abort
8975
8976
8977/* ------------------------------ */
8978    .balign 64
8979.L_OP_UNUSED_E9FF: /* 0x1e9 */
8980/* File: x86/OP_UNUSED_E9FF.S */
8981/* File: x86/unused.S */
8982    jmp     common_abort
8983
8984
8985/* ------------------------------ */
8986    .balign 64
8987.L_OP_UNUSED_EAFF: /* 0x1ea */
8988/* File: x86/OP_UNUSED_EAFF.S */
8989/* File: x86/unused.S */
8990    jmp     common_abort
8991
8992
8993/* ------------------------------ */
8994    .balign 64
8995.L_OP_UNUSED_EBFF: /* 0x1eb */
8996/* File: x86/OP_UNUSED_EBFF.S */
8997/* File: x86/unused.S */
8998    jmp     common_abort
8999
9000
9001/* ------------------------------ */
9002    .balign 64
9003.L_OP_UNUSED_ECFF: /* 0x1ec */
9004/* File: x86/OP_UNUSED_ECFF.S */
9005/* File: x86/unused.S */
9006    jmp     common_abort
9007
9008
9009/* ------------------------------ */
9010    .balign 64
9011.L_OP_UNUSED_EDFF: /* 0x1ed */
9012/* File: x86/OP_UNUSED_EDFF.S */
9013/* File: x86/unused.S */
9014    jmp     common_abort
9015
9016
9017/* ------------------------------ */
9018    .balign 64
9019.L_OP_UNUSED_EEFF: /* 0x1ee */
9020/* File: x86/OP_UNUSED_EEFF.S */
9021/* File: x86/unused.S */
9022    jmp     common_abort
9023
9024
9025/* ------------------------------ */
9026    .balign 64
9027.L_OP_UNUSED_EFFF: /* 0x1ef */
9028/* File: x86/OP_UNUSED_EFFF.S */
9029/* File: x86/unused.S */
9030    jmp     common_abort
9031
9032
9033/* ------------------------------ */
9034    .balign 64
9035.L_OP_UNUSED_F0FF: /* 0x1f0 */
9036/* File: x86/OP_UNUSED_F0FF.S */
9037/* File: x86/unused.S */
9038    jmp     common_abort
9039
9040
9041/* ------------------------------ */
9042    .balign 64
9043.L_OP_UNUSED_F1FF: /* 0x1f1 */
9044/* File: x86/OP_UNUSED_F1FF.S */
9045/* File: x86/unused.S */
9046    jmp     common_abort
9047
9048
9049/* ------------------------------ */
9050    .balign 64
9051.L_OP_UNUSED_F2FF: /* 0x1f2 */
9052/* File: x86/OP_UNUSED_F2FF.S */
9053/* File: x86/unused.S */
9054    jmp     common_abort
9055
9056
9057/* ------------------------------ */
9058    .balign 64
9059.L_OP_UNUSED_F3FF: /* 0x1f3 */
9060/* File: x86/OP_UNUSED_F3FF.S */
9061/* File: x86/unused.S */
9062    jmp     common_abort
9063
9064
9065/* ------------------------------ */
9066    .balign 64
9067.L_OP_UNUSED_F4FF: /* 0x1f4 */
9068/* File: x86/OP_UNUSED_F4FF.S */
9069/* File: x86/unused.S */
9070    jmp     common_abort
9071
9072
9073/* ------------------------------ */
9074    .balign 64
9075.L_OP_UNUSED_F5FF: /* 0x1f5 */
9076/* File: x86/OP_UNUSED_F5FF.S */
9077/* File: x86/unused.S */
9078    jmp     common_abort
9079
9080
9081/* ------------------------------ */
9082    .balign 64
9083.L_OP_UNUSED_F6FF: /* 0x1f6 */
9084/* File: x86/OP_UNUSED_F6FF.S */
9085/* File: x86/unused.S */
9086    jmp     common_abort
9087
9088
9089/* ------------------------------ */
9090    .balign 64
9091.L_OP_UNUSED_F7FF: /* 0x1f7 */
9092/* File: x86/OP_UNUSED_F7FF.S */
9093/* File: x86/unused.S */
9094    jmp     common_abort
9095
9096
9097/* ------------------------------ */
9098    .balign 64
9099.L_OP_UNUSED_F8FF: /* 0x1f8 */
9100/* File: x86/OP_UNUSED_F8FF.S */
9101/* File: x86/unused.S */
9102    jmp     common_abort
9103
9104
9105/* ------------------------------ */
9106    .balign 64
9107.L_OP_UNUSED_F9FF: /* 0x1f9 */
9108/* File: x86/OP_UNUSED_F9FF.S */
9109/* File: x86/unused.S */
9110    jmp     common_abort
9111
9112
9113/* ------------------------------ */
9114    .balign 64
9115.L_OP_UNUSED_FAFF: /* 0x1fa */
9116/* File: x86/OP_UNUSED_FAFF.S */
9117/* File: x86/unused.S */
9118    jmp     common_abort
9119
9120
9121/* ------------------------------ */
9122    .balign 64
9123.L_OP_UNUSED_FBFF: /* 0x1fb */
9124/* File: x86/OP_UNUSED_FBFF.S */
9125/* File: x86/unused.S */
9126    jmp     common_abort
9127
9128
9129/* ------------------------------ */
9130    .balign 64
9131.L_OP_UNUSED_FCFF: /* 0x1fc */
9132/* File: x86/OP_UNUSED_FCFF.S */
9133/* File: x86/unused.S */
9134    jmp     common_abort
9135
9136
9137/* ------------------------------ */
9138    .balign 64
9139.L_OP_UNUSED_FDFF: /* 0x1fd */
9140/* File: x86/OP_UNUSED_FDFF.S */
9141/* File: x86/unused.S */
9142    jmp     common_abort
9143
9144
9145/* ------------------------------ */
9146    .balign 64
9147.L_OP_UNUSED_FEFF: /* 0x1fe */
9148/* File: x86/OP_UNUSED_FEFF.S */
9149/* File: x86/unused.S */
9150    jmp     common_abort
9151
9152
9153/* ------------------------------ */
9154    .balign 64
9155.L_OP_THROW_VERIFICATION_ERROR_JUMBO: /* 0x1ff */
9156/* File: x86/OP_THROW_VERIFICATION_ERROR_JUMBO.S */
9157    /*
9158     * Handle a jumbo throw-verification-error instruction.  This throws an
9159     * exception for an error discovered during verification.  The
9160     * exception is indicated by BBBB, with some detail provided by AAAAAAAA.
9161     */
9162    /* exop BBBB, ref@AAAAAAAA */
9163    movl     rSELF,%ecx
9164    movl     2(rPC),%eax                     # eax<- AAAAAAAA
9165    movl     offThread_method(%ecx),%ecx       # ecx<- self->method
9166    EXPORT_PC
9167    movl     %eax,OUT_ARG2(%esp)             # arg2<- AAAAAAAA
9168    movl     rINST,OUT_ARG1(%esp)            # arg1<- BBBB
9169    movl     %ecx,OUT_ARG0(%esp)             # arg0<- method
9170    call     dvmThrowVerificationError       # call(method, kind, ref)
9171    jmp      common_exceptionThrown          # handle exception
9172
9173
9174    .balign 64
9175    .size   .L_OP_NOP, .-.L_OP_NOP
9176    .global dvmAsmInstructionEnd
9177dvmAsmInstructionEnd:
9178
9179/*
9180 * ===========================================================================
9181 *  Sister implementations
9182 * ===========================================================================
9183 */
9184    .global dvmAsmSisterStart
9185    .type   dvmAsmSisterStart, %function
9186    .text
9187    .balign 4
9188dvmAsmSisterStart:
9189
9190/* continuation for OP_CONST_STRING */
9191
9192/* This is the less common path, so we'll redo some work
9193   here rather than force spills on the common path */
9194.LOP_CONST_STRING_resolve:
9195    movl     rSELF,%eax
9196    movl     %ecx,rINST                # rINST<- AA
9197    EXPORT_PC
9198    movl     offThread_method(%eax),%eax # eax<- self->method
9199    movzwl   2(rPC),%ecx               # ecx<- BBBB
9200    movl     offMethod_clazz(%eax),%eax
9201    movl     %ecx,OUT_ARG1(%esp)
9202    movl     %eax,OUT_ARG0(%esp)
9203    call     dvmResolveString          # go resolve
9204    testl    %eax,%eax                 # failed?
9205    je       common_exceptionThrown
9206    SET_VREG %eax rINST
9207    FETCH_INST_OPCODE 2 %edx
9208    ADVANCE_PC 2
9209    GOTO_NEXT_R %edx
9210
9211/* continuation for OP_CONST_STRING_JUMBO */
9212
9213/* This is the less common path, so we'll redo some work
9214   here rather than force spills on the common path */
9215.LOP_CONST_STRING_JUMBO_resolve:
9216    movl     rSELF,%eax
9217    movl     %ecx,rINST                # rINST<- AA
9218    EXPORT_PC
9219    movl     offThread_method(%eax),%eax # eax<- self->method
9220    movl     2(rPC),%ecx               # ecx<- BBBBBBBB
9221    movl     offMethod_clazz(%eax),%eax
9222    movl     %ecx,OUT_ARG1(%esp)
9223    movl     %eax,OUT_ARG0(%esp)
9224    call     dvmResolveString          # go resolve
9225    testl    %eax,%eax                 # failed?
9226    je       common_exceptionThrown
9227    SET_VREG %eax rINST
9228    FETCH_INST_OPCODE 3 %edx
9229    ADVANCE_PC 3
9230    GOTO_NEXT_R %edx
9231
9232/* continuation for OP_CONST_CLASS */
9233
9234/* This is the less common path, so we'll redo some work
9235   here rather than force spills on the common path */
9236.LOP_CONST_CLASS_resolve:
9237    movl     rSELF,%eax
9238    movl     %ecx,rINST                # rINST<- AA
9239    EXPORT_PC
9240    movl     offThread_method(%eax),%eax # eax<- self->method
9241    movl     $1,OUT_ARG2(%esp)        # true
9242    movzwl   2(rPC),%ecx               # ecx<- BBBB
9243    movl     offMethod_clazz(%eax),%eax
9244    movl     %ecx,OUT_ARG1(%esp)
9245    movl     %eax,OUT_ARG0(%esp)
9246    call     dvmResolveClass           # go resolve
9247    testl    %eax,%eax                 # failed?
9248    je       common_exceptionThrown
9249    SET_VREG %eax rINST
9250    FETCH_INST_OPCODE 2 %edx
9251    ADVANCE_PC 2
9252    GOTO_NEXT_R %edx
9253
9254/* continuation for OP_MONITOR_ENTER */
9255
9256.LOP_MONITOR_ENTER_continue:
9257    movl    %ecx,OUT_ARG0(%esp)
9258    movl    %eax,OUT_ARG1(%esp)
9259    call    dvmLockObject               # dvmLockObject(self,object)
9260    ADVANCE_PC 1
9261    GOTO_NEXT
9262
9263/* continuation for OP_MONITOR_EXIT */
9264
9265.LOP_MONITOR_EXIT_continue:
9266    call    dvmUnlockObject             # unlock(self,obj)
9267    FETCH_INST_OPCODE 1 %edx
9268    testl   %eax,%eax                   # success?
9269    ADVANCE_PC 1
9270    je      common_exceptionThrown      # no, exception pending
9271    GOTO_NEXT_R %edx
9272.LOP_MONITOR_EXIT_errNullObject:
9273    ADVANCE_PC 1                        # advance before throw
9274    jmp     common_errNullObject
9275
9276/* continuation for OP_CHECK_CAST */
9277
9278    /*
9279     * Trivial test failed, need to perform full check.  This is common.
9280     *  ecx holds obj->clazz
9281     *  eax holds class resolved from BBBB
9282     *  rINST holds object
9283     */
9284.LOP_CHECK_CAST_fullcheck:
9285    movl    %eax,sReg0                 # we'll need the desired class on failure
9286    movl    %eax,OUT_ARG1(%esp)
9287    movl    %ecx,OUT_ARG0(%esp)
9288    call    dvmInstanceofNonTrivial    # eax<- boolean result
9289    testl   %eax,%eax                  # failed?
9290    jne     .LOP_CHECK_CAST_okay           # no, success
9291
9292    # A cast has failed.  We need to throw a ClassCastException.
9293    EXPORT_PC
9294    movl    offObject_clazz(rINST),%eax
9295    movl    %eax,OUT_ARG0(%esp)                 # arg0<- obj->clazz
9296    movl    sReg0,%ecx
9297    movl    %ecx,OUT_ARG1(%esp)                 # arg1<- desired class
9298    call    dvmThrowClassCastException
9299    jmp     common_exceptionThrown
9300
9301    /*
9302     * Resolution required.  This is the least-likely path, and we're
9303     * going to have to recreate some data.
9304     *
9305     *  rINST holds object
9306     */
9307.LOP_CHECK_CAST_resolve:
9308    movl    rSELF,%ecx
9309    EXPORT_PC
9310    movzwl  2(rPC),%eax                # eax<- BBBB
9311    movl    offThread_method(%ecx),%ecx  # ecx<- self->method
9312    movl    %eax,OUT_ARG1(%esp)        # arg1<- BBBB
9313    movl    offMethod_clazz(%ecx),%ecx # ecx<- metho->clazz
9314    movl    $0,OUT_ARG2(%esp)         # arg2<- false
9315    movl    %ecx,OUT_ARG0(%esp)        # arg0<- method->clazz
9316    call    dvmResolveClass            # eax<- resolved ClassObject ptr
9317    testl   %eax,%eax                  # got null?
9318    je      common_exceptionThrown     # yes, handle exception
9319    movl    offObject_clazz(rINST),%ecx  # ecx<- obj->clazz
9320    jmp     .LOP_CHECK_CAST_resolved       # pick up where we left off
9321
9322/* continuation for OP_INSTANCE_OF */
9323
9324    /*
9325     * Trivial test failed, need to perform full check.  This is common.
9326     *  eax holds obj->clazz
9327     *  ecx holds class resolved from BBBB
9328     *  rINST has BA
9329     */
9330.LOP_INSTANCE_OF_fullcheck:
9331    movl    %eax,OUT_ARG0(%esp)
9332    movl    %ecx,OUT_ARG1(%esp)
9333    call    dvmInstanceofNonTrivial     # eax<- boolean result
9334    # fall through to OP_INSTANCE_OF_store
9335
9336    /*
9337     * eax holds boolean result
9338     * rINST holds BA
9339     */
9340.LOP_INSTANCE_OF_store:
9341    FETCH_INST_OPCODE 2 %edx
9342    andb    $0xf,rINSTbl               # <- A
9343    ADVANCE_PC 2
9344    SET_VREG %eax rINST                 # vA<- eax
9345    GOTO_NEXT_R %edx
9346
9347    /*
9348     * Trivial test succeeded, save and bail.
9349     *  r9 holds A
9350     */
9351.LOP_INSTANCE_OF_trivial:
9352    FETCH_INST_OPCODE 2 %edx
9353    andb    $0xf,rINSTbl               # <- A
9354    ADVANCE_PC 2
9355    movl    $1,%eax
9356    SET_VREG %eax rINST                 # vA<- true
9357    GOTO_NEXT_R %edx
9358
9359    /*
9360     * Resolution required.  This is the least-likely path.
9361     *
9362     *  edx holds BBBB
9363     *  rINST holds BA
9364     */
9365.LOP_INSTANCE_OF_resolve:
9366    movl    %edx,OUT_ARG1(%esp)         # arg1<- BBBB
9367    movl    rSELF,%ecx
9368    movl    offThread_method(%ecx),%ecx
9369    movl    $1,OUT_ARG2(%esp)          # arg2<- true
9370    movl    offMethod_clazz(%ecx),%ecx  # ecx<- method->clazz
9371    EXPORT_PC
9372    movl    %ecx,OUT_ARG0(%esp)         # arg0<- method->clazz
9373    call    dvmResolveClass             # eax<- resolved ClassObject ptr
9374    testl   %eax,%eax                   # success?
9375    je      common_exceptionThrown      # no, handle exception
9376/* Now, we need to sync up with fast path.  We need eax to
9377 * hold the obj->clazz, and ecx to hold the resolved class
9378 */
9379    movl    %eax,%ecx                   # ecx<- resolved class
9380    movl    rINST,%eax                # eax<- BA
9381    sarl    $4,%eax                    # eax<- B
9382    GET_VREG_R %eax %eax                # eax<- vB (obj)
9383    movl    offObject_clazz(%eax),%eax  # eax<- obj->clazz
9384    jmp     .LOP_INSTANCE_OF_resolved
9385
9386/* continuation for OP_NEW_INSTANCE */
9387
9388.LOP_NEW_INSTANCE_initialized:  # on entry, ecx<- class
9389    /* TODO: remove test for interface/abstract, now done in verifier */
9390    testl     $(ACC_INTERFACE|ACC_ABSTRACT),offClassObject_accessFlags(%ecx)
9391    movl      $ALLOC_DONT_TRACK,OUT_ARG1(%esp)
9392    jne       .LOP_NEW_INSTANCE_abstract
9393.LOP_NEW_INSTANCE_finish: # ecx=class
9394    movl     %ecx,OUT_ARG0(%esp)
9395    call     dvmAllocObject             # eax<- new object
9396    FETCH_INST_OPCODE 2 %edx
9397    testl    %eax,%eax                  # success?
9398    je       common_exceptionThrown     # no, bail out
9399    SET_VREG %eax rINST
9400    ADVANCE_PC 2
9401    GOTO_NEXT_R %edx
9402
9403    /*
9404     * Class initialization required.
9405     *
9406     *  ecx holds class object
9407     */
9408.LOP_NEW_INSTANCE_needinit:
9409    SPILL_TMP1(%ecx)                    # save object
9410    movl    %ecx,OUT_ARG0(%esp)
9411    call    dvmInitClass                # initialize class
9412    UNSPILL_TMP1(%ecx)                  # restore object
9413    testl   %eax,%eax                   # success?
9414    jne     .LOP_NEW_INSTANCE_initialized     # success, continue
9415    jmp     common_exceptionThrown      # go deal with init exception
9416
9417    /*
9418     * Resolution required.  This is the least-likely path.
9419     *
9420     */
9421.LOP_NEW_INSTANCE_resolve:
9422    movl    rSELF,%ecx
9423    movzwl  2(rPC),%eax
9424    movl    offThread_method(%ecx),%ecx   # ecx<- self->method
9425    movl    %eax,OUT_ARG1(%esp)
9426    movl    offMethod_clazz(%ecx),%ecx  # ecx<- method->clazz
9427    movl    $0,OUT_ARG2(%esp)
9428    movl    %ecx,OUT_ARG0(%esp)
9429    call    dvmResolveClass             # call(clazz,off,flags)
9430    movl    %eax,%ecx                   # ecx<- resolved ClassObject ptr
9431    testl   %ecx,%ecx                   # success?
9432    jne     .LOP_NEW_INSTANCE_resolved        # good to go
9433    jmp     common_exceptionThrown      # no, handle exception
9434
9435    /*
9436     * TODO: remove this
9437     * We can't instantiate an abstract class or interface, so throw an
9438     * InstantiationError with the class descriptor as the message.
9439     *
9440     *  ecx holds class object
9441     */
9442.LOP_NEW_INSTANCE_abstract:
9443    movl    offClassObject_descriptor(%ecx),%eax
9444    movl    $.LstrInstantiationError,OUT_ARG0(%esp)
9445    movl    %eax,OUT_ARG1(%esp)
9446    call    dvmThrowExceptionWithClassMessage
9447    jmp     common_exceptionThrown
9448
9449/* continuation for OP_NEW_ARRAY */
9450
9451    /*
9452     * Resolve class.  (This is an uncommon case.)
9453     *  ecx holds class (null here)
9454     *  eax holds array length (vB)
9455     */
9456.LOP_NEW_ARRAY_resolve:
9457    movl    rSELF,%ecx
9458    SPILL_TMP1(%eax)                   # save array length
9459    movl    offThread_method(%ecx),%ecx  # ecx<- self->method
9460    movzwl  2(rPC),%eax                # eax<- CCCC
9461    movl    offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
9462    movl    %eax,OUT_ARG1(%esp)
9463    movl    $0,OUT_ARG2(%esp)
9464    movl    %ecx,OUT_ARG0(%esp)
9465    call    dvmResolveClass            # eax<- call(clazz,ref,flag)
9466    movl    %eax,%ecx
9467    UNSPILL_TMP1(%eax)
9468    testl   %ecx,%ecx                  # successful resolution?
9469    je      common_exceptionThrown     # no, bail.
9470# fall through to OP_NEW_ARRAY_finish
9471
9472    /*
9473     * Finish allocation
9474     *
9475     * ecx holds class
9476     * eax holds array length (vB)
9477     */
9478.LOP_NEW_ARRAY_finish:
9479    movl    %ecx,OUT_ARG0(%esp)
9480    movl    %eax,OUT_ARG1(%esp)
9481    movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)
9482    call    dvmAllocArrayByClass    # eax<- call(clazz,length,flags)
9483    FETCH_INST_OPCODE 2 %edx
9484    testl   %eax,%eax               # failed?
9485    je      common_exceptionThrown  # yup - go handle
9486    SET_VREG %eax rINST
9487    ADVANCE_PC 2
9488    GOTO_NEXT_R %edx
9489
9490/* continuation for OP_FILLED_NEW_ARRAY */
9491
9492.LOP_FILLED_NEW_ARRAY_more:
9493    movl    offMethod_clazz(%eax),%eax        # eax<- method->clazz
9494    movl    %eax,OUT_ARG0(%esp)               # arg0<- clazz
9495    call    dvmResolveClass                   # eax<- call(clazz,ref,flag)
9496    testl   %eax,%eax                         # null?
9497    je      common_exceptionThrown            # yes, handle it
9498
9499       # note: fall through to .LOP_FILLED_NEW_ARRAY_continue
9500
9501    /*
9502     * On entry:
9503     *    eax holds array class [r0]
9504     *    rINST holds AA or BB [r10]
9505     *    ecx is scratch
9506     */
9507.LOP_FILLED_NEW_ARRAY_continue:
9508    movl    offClassObject_descriptor(%eax),%ecx  # ecx<- arrayClass->descriptor
9509    movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)     # arg2<- flags
9510    movzbl  1(%ecx),%ecx                          # ecx<- descriptor[1]
9511    movl    %eax,OUT_ARG0(%esp)                   # arg0<- arrayClass
9512    movl    rSELF,%eax
9513    cmpb    $'I',%cl                             # supported?
9514    je      1f
9515    cmpb    $'L',%cl
9516    je      1f
9517    cmpb    $'[',%cl
9518    jne      .LOP_FILLED_NEW_ARRAY_notimpl                  # no, not handled yet
95191:
9520    movl    %ecx,offThread_retval+4(%eax)           # save type
9521    .if      (!0)
9522    SPILL_TMP1(rINST)                              # save copy, need "B" later
9523    sarl    $4,rINST
9524    .endif
9525    movl    rINST,OUT_ARG1(%esp)                  # arg1<- A or AA (length)
9526    call    dvmAllocArrayByClass     # eax<- call(arrayClass, length, flags)
9527    movl    rSELF,%ecx
9528    testl   %eax,%eax                             # alloc successful?
9529    je      common_exceptionThrown                # no, handle exception
9530    movl    %eax,offThread_retval(%ecx)             # retval.l<- new array
9531    movzwl  4(rPC),%ecx                           # ecx<- FEDC or CCCC
9532    leal    offArrayObject_contents(%eax),%eax    # eax<- newArray->contents
9533
9534/* at this point:
9535 *     eax is pointer to tgt
9536 *     rINST is length
9537 *     ecx is FEDC or CCCC
9538 *     TMP_SPILL1 is BA
9539 *  We now need to copy values from registers into the array
9540 */
9541
9542    .if 0
9543    # set up src pointer
9544    SPILL_TMP2(%esi)
9545    SPILL_TMP3(%edi)
9546    leal    (rFP,%ecx,4),%esi # set up src ptr
9547    movl    %eax,%edi         # set up dst ptr
9548    movl    rINST,%ecx        # load count register
9549    rep
9550    movsd
9551    UNSPILL_TMP2(%esi)
9552    UNSPILL_TMP3(%edi)
9553    movl    rSELF,%ecx
9554    movl    offThread_retval+4(%ecx),%eax      # eax<- type
9555    FETCH_INST_OPCODE 3 %edx
9556    .else
9557    testl  rINST,rINST
9558    je     4f
9559    UNSPILL_TMP1(%edx)        # restore "BA"
9560    andl   $0x0f,%edx        # edx<- 0000000A
9561    sall   $16,%edx          # edx<- 000A0000
9562    orl    %ecx,%edx          # edx<- 000AFEDC
95633:
9564    movl   $0xf,%ecx
9565    andl   %edx,%ecx          # ecx<- next reg to load
9566    GET_VREG_R %ecx %ecx
9567    shrl   $4,%edx
9568    leal   4(%eax),%eax
9569    movl   %ecx,-4(%eax)
9570    sub    $1,rINST
9571    jne    3b
95724:
9573    movl   rSELF,%ecx
9574    movl    offThread_retval+4(%ecx),%eax      # eax<- type
9575    FETCH_INST_OPCODE 3 %edx
9576    .endif
9577
9578    cmpb    $'I',%al                        # Int array?
9579    je      5f                               # skip card mark if so
9580    movl    offThread_retval(%ecx),%eax        # eax<- object head
9581    movl    offThread_cardTable(%ecx),%ecx     # card table base
9582    shrl    $GC_CARD_SHIFT,%eax             # convert to card num
9583    movb    %cl,(%ecx,%eax)                  # mark card based on object head
95845:
9585    ADVANCE_PC 3
9586    GOTO_NEXT_R %edx
9587
9588
9589    /*
9590     * Throw an exception indicating that we have not implemented this
9591     * mode of filled-new-array.
9592     */
9593.LOP_FILLED_NEW_ARRAY_notimpl:
9594    movl    $.LstrInternalErrorA,%eax
9595    movl    %eax,OUT_ARG0(%esp)
9596    movl    $.LstrFilledNewArrayNotImplA,%eax
9597    movl    %eax,OUT_ARG1(%esp)
9598    call    dvmThrowException
9599    jmp     common_exceptionThrown
9600
9601/* continuation for OP_FILLED_NEW_ARRAY_RANGE */
9602
9603.LOP_FILLED_NEW_ARRAY_RANGE_more:
9604    movl    offMethod_clazz(%eax),%eax        # eax<- method->clazz
9605    movl    %eax,OUT_ARG0(%esp)               # arg0<- clazz
9606    call    dvmResolveClass                   # eax<- call(clazz,ref,flag)
9607    testl   %eax,%eax                         # null?
9608    je      common_exceptionThrown            # yes, handle it
9609
9610       # note: fall through to .LOP_FILLED_NEW_ARRAY_RANGE_continue
9611
9612    /*
9613     * On entry:
9614     *    eax holds array class [r0]
9615     *    rINST holds AA or BB [r10]
9616     *    ecx is scratch
9617     */
9618.LOP_FILLED_NEW_ARRAY_RANGE_continue:
9619    movl    offClassObject_descriptor(%eax),%ecx  # ecx<- arrayClass->descriptor
9620    movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)     # arg2<- flags
9621    movzbl  1(%ecx),%ecx                          # ecx<- descriptor[1]
9622    movl    %eax,OUT_ARG0(%esp)                   # arg0<- arrayClass
9623    movl    rSELF,%eax
9624    cmpb    $'I',%cl                             # supported?
9625    je      1f
9626    cmpb    $'L',%cl
9627    je      1f
9628    cmpb    $'[',%cl
9629    jne      .LOP_FILLED_NEW_ARRAY_RANGE_notimpl                  # no, not handled yet
96301:
9631    movl    %ecx,offThread_retval+4(%eax)           # save type
9632    .if      (!1)
9633    SPILL_TMP1(rINST)                              # save copy, need "B" later
9634    sarl    $4,rINST
9635    .endif
9636    movl    rINST,OUT_ARG1(%esp)                  # arg1<- A or AA (length)
9637    call    dvmAllocArrayByClass     # eax<- call(arrayClass, length, flags)
9638    movl    rSELF,%ecx
9639    testl   %eax,%eax                             # alloc successful?
9640    je      common_exceptionThrown                # no, handle exception
9641    movl    %eax,offThread_retval(%ecx)             # retval.l<- new array
9642    movzwl  4(rPC),%ecx                           # ecx<- FEDC or CCCC
9643    leal    offArrayObject_contents(%eax),%eax    # eax<- newArray->contents
9644
9645/* at this point:
9646 *     eax is pointer to tgt
9647 *     rINST is length
9648 *     ecx is FEDC or CCCC
9649 *     TMP_SPILL1 is BA
9650 *  We now need to copy values from registers into the array
9651 */
9652
9653    .if 1
9654    # set up src pointer
9655    SPILL_TMP2(%esi)
9656    SPILL_TMP3(%edi)
9657    leal    (rFP,%ecx,4),%esi # set up src ptr
9658    movl    %eax,%edi         # set up dst ptr
9659    movl    rINST,%ecx        # load count register
9660    rep
9661    movsd
9662    UNSPILL_TMP2(%esi)
9663    UNSPILL_TMP3(%edi)
9664    movl    rSELF,%ecx
9665    movl    offThread_retval+4(%ecx),%eax      # eax<- type
9666    FETCH_INST_OPCODE 3 %edx
9667    .else
9668    testl  rINST,rINST
9669    je     4f
9670    UNSPILL_TMP1(%edx)        # restore "BA"
9671    andl   $0x0f,%edx        # edx<- 0000000A
9672    sall   $16,%edx          # edx<- 000A0000
9673    orl    %ecx,%edx          # edx<- 000AFEDC
96743:
9675    movl   $0xf,%ecx
9676    andl   %edx,%ecx          # ecx<- next reg to load
9677    GET_VREG_R %ecx %ecx
9678    shrl   $4,%edx
9679    leal   4(%eax),%eax
9680    movl   %ecx,-4(%eax)
9681    sub    $1,rINST
9682    jne    3b
96834:
9684    movl   rSELF,%ecx
9685    movl    offThread_retval+4(%ecx),%eax      # eax<- type
9686    FETCH_INST_OPCODE 3 %edx
9687    .endif
9688
9689    cmpb    $'I',%al                        # Int array?
9690    je      5f                               # skip card mark if so
9691    movl    offThread_retval(%ecx),%eax        # eax<- object head
9692    movl    offThread_cardTable(%ecx),%ecx     # card table base
9693    shrl    $GC_CARD_SHIFT,%eax             # convert to card num
9694    movb    %cl,(%ecx,%eax)                  # mark card based on object head
96955:
9696    ADVANCE_PC 3
9697    GOTO_NEXT_R %edx
9698
9699
9700    /*
9701     * Throw an exception indicating that we have not implemented this
9702     * mode of filled-new-array.
9703     */
9704.LOP_FILLED_NEW_ARRAY_RANGE_notimpl:
9705    movl    $.LstrInternalErrorA,%eax
9706    movl    %eax,OUT_ARG0(%esp)
9707    movl    $.LstrFilledNewArrayNotImplA,%eax
9708    movl    %eax,OUT_ARG1(%esp)
9709    call    dvmThrowException
9710    jmp     common_exceptionThrown
9711
9712/* continuation for OP_CMPL_FLOAT */
9713
9714.LOP_CMPL_FLOAT_isNaN:
9715    movl      $-1,%ecx
9716    jmp       .LOP_CMPL_FLOAT_finish
9717
9718/* continuation for OP_CMPG_FLOAT */
9719
9720.LOP_CMPG_FLOAT_isNaN:
9721    movl      $1,%ecx
9722    jmp       .LOP_CMPG_FLOAT_finish
9723
9724/* continuation for OP_CMPL_DOUBLE */
9725
9726.LOP_CMPL_DOUBLE_isNaN:
9727    movl      $-1,%ecx
9728    jmp       .LOP_CMPL_DOUBLE_finish
9729
9730/* continuation for OP_CMPG_DOUBLE */
9731
9732.LOP_CMPG_DOUBLE_isNaN:
9733    movl      $1,%ecx
9734    jmp       .LOP_CMPG_DOUBLE_finish
9735
9736/* continuation for OP_CMP_LONG */
9737
9738.LOP_CMP_LONG_bigger:
9739    movl      $1,%ecx
9740    jmp       .LOP_CMP_LONG_finish
9741.LOP_CMP_LONG_smaller:
9742    movl      $-1,%ecx
9743.LOP_CMP_LONG_finish:
9744    SET_VREG %ecx rINST
9745    FETCH_INST_OPCODE 2 %edx
9746    ADVANCE_PC 2
9747    GOTO_NEXT_R %edx
9748
9749/* continuation for OP_AGET_WIDE */
9750
9751.LOP_AGET_WIDE_finish:
9752    leal      offArrayObject_contents(%eax,%ecx,8),%eax
9753    movl      (%eax),%ecx
9754    movl      4(%eax),%eax
9755    SET_VREG_WORD %ecx rINST 0
9756    SET_VREG_WORD %eax rINST 1
9757    FETCH_INST_OPCODE 2 %edx
9758    ADVANCE_PC 2
9759    GOTO_NEXT_R %edx
9760
9761/* continuation for OP_APUT_WIDE */
9762
9763.LOP_APUT_WIDE_finish:
9764    leal      offArrayObject_contents(%eax,%ecx,8),%eax
9765    GET_VREG_WORD %ecx rINST 0
9766    GET_VREG_WORD rINST rINST 1
9767    movl      rINST,4(%eax)
9768    FETCH_INST_OPCODE 2 %edx
9769    movl      %ecx,(%eax)
9770    ADVANCE_PC 2
9771    GOTO_NEXT_R %edx
9772
9773/* continuation for OP_APUT_OBJECT */
9774
9775    /* On entry:
9776     *   eax<- array object
9777     *   ecx<- index
9778     *   rINST<- vAA
9779     */
9780.LOP_APUT_OBJECT_continue:
9781    leal      offArrayObject_contents(%eax,%ecx,4),%ecx
9782    testl     rINST,rINST                    # storing null reference?
9783    je        .LOP_APUT_OBJECT_skip_check
9784    SPILL_TMP1(%ecx)                         # save target address
9785    SPILL_TMP2(%eax)                         # save object head
9786    movl      offObject_clazz(%eax),%eax     # eax<- arrayObj->clazz
9787    movl      offObject_clazz(rINST),%ecx    # ecx<- obj->clazz
9788    movl      %eax,OUT_ARG1(%esp)
9789    movl      %ecx,OUT_ARG0(%esp)
9790    movl      %ecx,sReg0                     # store the two classes for later
9791    movl      %eax,sReg1
9792    call      dvmCanPutArrayElement          # test object type vs. array type
9793    UNSPILL_TMP1(%ecx)                       # recover target address
9794    testl     %eax,%eax
9795    movl      rSELF,%eax
9796    jne       .LOP_APUT_OBJECT_types_okay
9797
9798    # The types don't match.  We need to throw an ArrayStoreException.
9799    EXPORT_PC
9800    movl      sReg0,%eax                     # restore the two classes...
9801    movl      %eax,OUT_ARG0(%esp)
9802    movl      sReg1,%ecx
9803    movl      %ecx,OUT_ARG1(%esp)
9804    call      dvmThrowArrayStoreException    # ...and throw
9805    jmp       common_exceptionThrown
9806
9807.LOP_APUT_OBJECT_types_okay:
9808    movl      offThread_cardTable(%eax),%eax   # get card table base
9809    movl      rINST,(%ecx)                   # store into array
9810    UNSPILL_TMP2(%ecx)                       # recover object head
9811    FETCH_INST_OPCODE 2 %edx
9812    shrl      $GC_CARD_SHIFT,%ecx           # object head to card number
9813    movb      %al,(%eax,%ecx)                # mark card using object head
9814    ADVANCE_PC 2
9815    GOTO_NEXT_R %edx
9816
9817.LOP_APUT_OBJECT_skip_check:
9818    movl      rINST,(%ecx)
9819    FETCH_INST_OPCODE 2 %edx
9820    ADVANCE_PC 2
9821    GOTO_NEXT_R %edx
9822
9823/* continuation for OP_IGET */
9824
9825
9826.LOP_IGET_resolve:
9827    EXPORT_PC
9828    movl    offThread_method(%edx),%edx           # edx<- current method
9829    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
9830    SPILL_TMP1(%ecx)                            # save obj pointer across call
9831    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
9832    call    dvmResolveInstField                 #  ... to dvmResolveInstField
9833    UNSPILL_TMP1(%ecx)
9834    testl   %eax,%eax                           #  returns InstrField ptr
9835    jne     .LOP_IGET_finish
9836    jmp     common_exceptionThrown
9837
9838.LOP_IGET_finish:
9839    /*
9840     * Currently:
9841     *   eax holds resolved field
9842     *   ecx holds object
9843     *   rINST holds A
9844     */
9845    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
9846    testl   %ecx,%ecx                           # object null?
9847    je      common_errNullObject                # object was null
9848    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
9849    movl    rINST,%eax                          # eax<- A
9850    FETCH_INST_OPCODE 2 %edx
9851    SET_VREG %ecx %eax
9852    ADVANCE_PC 2
9853    GOTO_NEXT_R %edx
9854
9855/* continuation for OP_IGET_WIDE */
9856
9857
9858.LOP_IGET_WIDE_resolve:
9859    EXPORT_PC
9860    movl    offThread_method(%edx),%edx           # edx<- current method
9861    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
9862    SPILL_TMP1(%ecx)                            # save objpointer across call
9863    movl    rPC,OUT_ARG0(%esp)                  # pass in method->clazz
9864    call    dvmResolveInstField                 #  ... to dvmResolveInstField
9865    UNSPILL_TMP1(%ecx)
9866    testl   %eax,%eax                           # returns InstrField ptr
9867    jne     .LOP_IGET_WIDE_finish
9868    jmp     common_exceptionThrown
9869
9870.LOP_IGET_WIDE_finish:
9871    /*
9872     * Currently:
9873     *   eax holds resolved field
9874     *   ecx holds object
9875     *   rINST holds A
9876     */
9877    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
9878    testl   %ecx,%ecx                           # object null?
9879    je      common_errNullObject                # object was null
9880    leal    (%ecx,%eax,1),%eax                  # eax<- address of field
9881    movl    (%eax),%ecx                         # ecx<- lsw
9882    movl    4(%eax),%eax                        # eax<- msw
9883    FETCH_INST_OPCODE 2 %edx
9884    SET_VREG_WORD %ecx rINST 0
9885    SET_VREG_WORD %eax rINST 1
9886    ADVANCE_PC 2
9887    GOTO_NEXT_R %edx
9888
9889/* continuation for OP_IGET_OBJECT */
9890
9891
9892.LOP_IGET_OBJECT_resolve:
9893    EXPORT_PC
9894    movl    offThread_method(%edx),%edx           # edx<- current method
9895    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
9896    SPILL_TMP1(%ecx)                            # save obj pointer across call
9897    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
9898    call    dvmResolveInstField                 #  ... to dvmResolveInstField
9899    UNSPILL_TMP1(%ecx)
9900    testl   %eax,%eax                           #  returns InstrField ptr
9901    jne     .LOP_IGET_OBJECT_finish
9902    jmp     common_exceptionThrown
9903
9904.LOP_IGET_OBJECT_finish:
9905    /*
9906     * Currently:
9907     *   eax holds resolved field
9908     *   ecx holds object
9909     *   rINST holds A
9910     */
9911    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
9912    testl   %ecx,%ecx                           # object null?
9913    je      common_errNullObject                # object was null
9914    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
9915    movl    rINST,%eax                          # eax<- A
9916    FETCH_INST_OPCODE 2 %edx
9917    SET_VREG %ecx %eax
9918    ADVANCE_PC 2
9919    GOTO_NEXT_R %edx
9920
9921/* continuation for OP_IGET_BOOLEAN */
9922
9923
9924.LOP_IGET_BOOLEAN_resolve:
9925    EXPORT_PC
9926    movl    offThread_method(%edx),%edx           # edx<- current method
9927    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
9928    SPILL_TMP1(%ecx)                            # save obj pointer across call
9929    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
9930    call    dvmResolveInstField                 #  ... to dvmResolveInstField
9931    UNSPILL_TMP1(%ecx)
9932    testl   %eax,%eax                           #  returns InstrField ptr
9933    jne     .LOP_IGET_BOOLEAN_finish
9934    jmp     common_exceptionThrown
9935
9936.LOP_IGET_BOOLEAN_finish:
9937    /*
9938     * Currently:
9939     *   eax holds resolved field
9940     *   ecx holds object
9941     *   rINST holds A
9942     */
9943    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
9944    testl   %ecx,%ecx                           # object null?
9945    je      common_errNullObject                # object was null
9946    movzbl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
9947    movl    rINST,%eax                          # eax<- A
9948    FETCH_INST_OPCODE 2 %edx
9949    SET_VREG %ecx %eax
9950    ADVANCE_PC 2
9951    GOTO_NEXT_R %edx
9952
9953/* continuation for OP_IGET_BYTE */
9954
9955
9956.LOP_IGET_BYTE_resolve:
9957    EXPORT_PC
9958    movl    offThread_method(%edx),%edx           # edx<- current method
9959    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
9960    SPILL_TMP1(%ecx)                            # save obj pointer across call
9961    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
9962    call    dvmResolveInstField                 #  ... to dvmResolveInstField
9963    UNSPILL_TMP1(%ecx)
9964    testl   %eax,%eax                           #  returns InstrField ptr
9965    jne     .LOP_IGET_BYTE_finish
9966    jmp     common_exceptionThrown
9967
9968.LOP_IGET_BYTE_finish:
9969    /*
9970     * Currently:
9971     *   eax holds resolved field
9972     *   ecx holds object
9973     *   rINST holds A
9974     */
9975    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
9976    testl   %ecx,%ecx                           # object null?
9977    je      common_errNullObject                # object was null
9978    movsbl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
9979    movl    rINST,%eax                          # eax<- A
9980    FETCH_INST_OPCODE 2 %edx
9981    SET_VREG %ecx %eax
9982    ADVANCE_PC 2
9983    GOTO_NEXT_R %edx
9984
9985/* continuation for OP_IGET_CHAR */
9986
9987
9988.LOP_IGET_CHAR_resolve:
9989    EXPORT_PC
9990    movl    offThread_method(%edx),%edx           # edx<- current method
9991    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
9992    SPILL_TMP1(%ecx)                            # save obj pointer across call
9993    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
9994    call    dvmResolveInstField                 #  ... to dvmResolveInstField
9995    UNSPILL_TMP1(%ecx)
9996    testl   %eax,%eax                           #  returns InstrField ptr
9997    jne     .LOP_IGET_CHAR_finish
9998    jmp     common_exceptionThrown
9999
10000.LOP_IGET_CHAR_finish:
10001    /*
10002     * Currently:
10003     *   eax holds resolved field
10004     *   ecx holds object
10005     *   rINST holds A
10006     */
10007    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
10008    testl   %ecx,%ecx                           # object null?
10009    je      common_errNullObject                # object was null
10010    movzwl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
10011    movl    rINST,%eax                          # eax<- A
10012    FETCH_INST_OPCODE 2 %edx
10013    SET_VREG %ecx %eax
10014    ADVANCE_PC 2
10015    GOTO_NEXT_R %edx
10016
10017/* continuation for OP_IGET_SHORT */
10018
10019
10020.LOP_IGET_SHORT_resolve:
10021    EXPORT_PC
10022    movl    offThread_method(%edx),%edx           # edx<- current method
10023    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
10024    SPILL_TMP1(%ecx)                            # save obj pointer across call
10025    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
10026    call    dvmResolveInstField                 #  ... to dvmResolveInstField
10027    UNSPILL_TMP1(%ecx)
10028    testl   %eax,%eax                           #  returns InstrField ptr
10029    jne     .LOP_IGET_SHORT_finish
10030    jmp     common_exceptionThrown
10031
10032.LOP_IGET_SHORT_finish:
10033    /*
10034     * Currently:
10035     *   eax holds resolved field
10036     *   ecx holds object
10037     *   rINST holds A
10038     */
10039    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
10040    testl   %ecx,%ecx                           # object null?
10041    je      common_errNullObject                # object was null
10042    movswl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
10043    movl    rINST,%eax                          # eax<- A
10044    FETCH_INST_OPCODE 2 %edx
10045    SET_VREG %ecx %eax
10046    ADVANCE_PC 2
10047    GOTO_NEXT_R %edx
10048
10049/* continuation for OP_IPUT */
10050
10051
10052.LOP_IPUT_resolve:
10053    EXPORT_PC
10054    movl    offThread_method(%edx),%edx           # edx<- current method
10055    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
10056    SPILL_TMP1(%ecx)                            # save obj pointer across call
10057    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
10058    call    dvmResolveInstField                 #  ... to dvmResolveInstField
10059    UNSPILL_TMP1(%ecx)
10060    testl   %eax,%eax                           # returns InstrField ptr
10061    jne     .LOP_IPUT_finish
10062    jmp     common_exceptionThrown
10063
10064.LOP_IPUT_finish:
10065    /*
10066     * Currently:
10067     *   eax holds resolved field
10068     *   ecx holds object
10069     *   rINST holds A
10070     */
10071    GET_VREG_R rINST rINST                       # rINST<- v[A]
10072    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
10073    testl   %ecx,%ecx                            # object null?
10074    je      common_errNullObject                 # object was null
10075    FETCH_INST_OPCODE 2 %edx
10076    movl   rINST,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
10077    ADVANCE_PC 2
10078    GOTO_NEXT_R %edx
10079
10080/* continuation for OP_IPUT_WIDE */
10081
10082
10083.LOP_IPUT_WIDE_resolve:
10084    EXPORT_PC
10085    movl    offThread_method(%edx),%edx           # edx<- current method
10086    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
10087    SPILL_TMP1(%ecx)                            # save obj pointer across call
10088    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
10089    call    dvmResolveInstField                 #  ... to dvmResolveInstField
10090    UNSPILL_TMP1(%ecx)
10091    testl   %eax,%eax                           #  ... which returns InstrField ptr
10092    jne     .LOP_IPUT_WIDE_finish
10093    jmp     common_exceptionThrown
10094
10095.LOP_IPUT_WIDE_finish:
10096    /*
10097     * Currently:
10098     *   eax holds resolved field
10099     *   ecx holds object
10100     *   %edx is scratch, but needs to be unspilled
10101     *   rINST holds A
10102     */
10103    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
10104    testl   %ecx,%ecx                           # object null?
10105    je      common_errNullObject                # object was null
10106    leal    (%ecx,%eax,1),%eax                  # eax<- address of field
10107    GET_VREG_WORD %ecx rINST 0                  # ecx<- lsw
10108    GET_VREG_WORD rINST rINST 1                 # rINST<- msw
10109    FETCH_INST_OPCODE 2 %edx
10110    movl    rINST,4(%eax)
10111    movl    %ecx,(%eax)
10112    ADVANCE_PC 2
10113    GOTO_NEXT_R %edx
10114
10115/* continuation for OP_IPUT_OBJECT */
10116
10117
10118.LOP_IPUT_OBJECT_resolve:
10119    EXPORT_PC
10120    movl    offThread_method(%edx),%edx           # edx<- current method
10121    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
10122    SPILL_TMP1(%ecx)                            # save obj pointer across call
10123    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
10124    call    dvmResolveInstField                 #  ... to dvmResolveInstField
10125    UNSPILL_TMP1(%ecx)
10126    testl   %eax,%eax                           # returns InstrField ptr
10127    jne     .LOP_IPUT_OBJECT_finish
10128    jmp     common_exceptionThrown
10129
10130.LOP_IPUT_OBJECT_finish:
10131    /*
10132     * Currently:
10133     *   eax holds resolved field
10134     *   ecx holds object
10135     *   %edx is scratch, but needs to be unspilled
10136     *   rINST holds A
10137     */
10138    GET_VREG_R rINST rINST                      # rINST<- v[A]
10139    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
10140    testl   %ecx,%ecx                           # object null?
10141    je      common_errNullObject                # object was null
10142    movl    rINST,(%ecx,%eax)      # obj.field <- v[A](8/16/32 bits)
10143    movl    rSELF,%eax
10144    testl   rINST,rINST                         # stored a NULL?
10145    movl    offThread_cardTable(%eax),%eax        # get card table base
10146    FETCH_INST_OPCODE 2 %edx
10147    je      1f                                  # skip card mark if null store
10148    shrl    $GC_CARD_SHIFT,%ecx                # object head to card number
10149    movb    %al,(%eax,%ecx)                     # mark card using object head
101501:
10151    ADVANCE_PC 2
10152    GOTO_NEXT_R %edx
10153
10154/* continuation for OP_IPUT_BOOLEAN */
10155
10156
10157.LOP_IPUT_BOOLEAN_resolve:
10158    EXPORT_PC
10159    movl    offThread_method(%edx),%edx           # edx<- current method
10160    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
10161    SPILL_TMP1(%ecx)                            # save obj pointer across call
10162    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
10163    call    dvmResolveInstField                 #  ... to dvmResolveInstField
10164    UNSPILL_TMP1(%ecx)
10165    testl   %eax,%eax                           # returns InstrField ptr
10166    jne     .LOP_IPUT_BOOLEAN_finish
10167    jmp     common_exceptionThrown
10168
10169.LOP_IPUT_BOOLEAN_finish:
10170    /*
10171     * Currently:
10172     *   eax holds resolved field
10173     *   ecx holds object
10174     *   rINST holds A
10175     */
10176    GET_VREG_R rINST rINST                       # rINST<- v[A]
10177    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
10178    testl   %ecx,%ecx                            # object null?
10179    je      common_errNullObject                 # object was null
10180    FETCH_INST_OPCODE 2 %edx
10181    movb   rINSTbl,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
10182    ADVANCE_PC 2
10183    GOTO_NEXT_R %edx
10184
10185/* continuation for OP_IPUT_BYTE */
10186
10187
10188.LOP_IPUT_BYTE_resolve:
10189    EXPORT_PC
10190    movl    offThread_method(%edx),%edx           # edx<- current method
10191    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
10192    SPILL_TMP1(%ecx)                            # save obj pointer across call
10193    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
10194    call    dvmResolveInstField                 #  ... to dvmResolveInstField
10195    UNSPILL_TMP1(%ecx)
10196    testl   %eax,%eax                           # returns InstrField ptr
10197    jne     .LOP_IPUT_BYTE_finish
10198    jmp     common_exceptionThrown
10199
10200.LOP_IPUT_BYTE_finish:
10201    /*
10202     * Currently:
10203     *   eax holds resolved field
10204     *   ecx holds object
10205     *   rINST holds A
10206     */
10207    GET_VREG_R rINST rINST                       # rINST<- v[A]
10208    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
10209    testl   %ecx,%ecx                            # object null?
10210    je      common_errNullObject                 # object was null
10211    FETCH_INST_OPCODE 2 %edx
10212    movb   rINSTbl,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
10213    ADVANCE_PC 2
10214    GOTO_NEXT_R %edx
10215
10216/* continuation for OP_IPUT_CHAR */
10217
10218
10219.LOP_IPUT_CHAR_resolve:
10220    EXPORT_PC
10221    movl    offThread_method(%edx),%edx           # edx<- current method
10222    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
10223    SPILL_TMP1(%ecx)                            # save obj pointer across call
10224    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
10225    call    dvmResolveInstField                 #  ... to dvmResolveInstField
10226    UNSPILL_TMP1(%ecx)
10227    testl   %eax,%eax                           # returns InstrField ptr
10228    jne     .LOP_IPUT_CHAR_finish
10229    jmp     common_exceptionThrown
10230
10231.LOP_IPUT_CHAR_finish:
10232    /*
10233     * Currently:
10234     *   eax holds resolved field
10235     *   ecx holds object
10236     *   rINST holds A
10237     */
10238    GET_VREG_R rINST rINST                       # rINST<- v[A]
10239    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
10240    testl   %ecx,%ecx                            # object null?
10241    je      common_errNullObject                 # object was null
10242    FETCH_INST_OPCODE 2 %edx
10243    movw   rINSTw,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
10244    ADVANCE_PC 2
10245    GOTO_NEXT_R %edx
10246
10247/* continuation for OP_IPUT_SHORT */
10248
10249
10250.LOP_IPUT_SHORT_resolve:
10251    EXPORT_PC
10252    movl    offThread_method(%edx),%edx           # edx<- current method
10253    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
10254    SPILL_TMP1(%ecx)                            # save obj pointer across call
10255    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
10256    call    dvmResolveInstField                 #  ... to dvmResolveInstField
10257    UNSPILL_TMP1(%ecx)
10258    testl   %eax,%eax                           # returns InstrField ptr
10259    jne     .LOP_IPUT_SHORT_finish
10260    jmp     common_exceptionThrown
10261
10262.LOP_IPUT_SHORT_finish:
10263    /*
10264     * Currently:
10265     *   eax holds resolved field
10266     *   ecx holds object
10267     *   rINST holds A
10268     */
10269    GET_VREG_R rINST rINST                       # rINST<- v[A]
10270    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
10271    testl   %ecx,%ecx                            # object null?
10272    je      common_errNullObject                 # object was null
10273    FETCH_INST_OPCODE 2 %edx
10274    movw   rINSTw,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
10275    ADVANCE_PC 2
10276    GOTO_NEXT_R %edx
10277
10278/* continuation for OP_SGET */
10279
10280    /*
10281     * Go resolve the field
10282     */
10283.LOP_SGET_resolve:
10284    movl     rSELF,%ecx
10285    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10286    movl     offThread_method(%ecx),%ecx          # ecx<- current method
10287    EXPORT_PC                                   # could throw, need to export
10288    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10289    movl     %eax,OUT_ARG1(%esp)
10290    movl     %ecx,OUT_ARG0(%esp)
10291    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10292    testl    %eax,%eax
10293    jne      .LOP_SGET_finish                 # success, continue
10294    jmp      common_exceptionThrown             # no, handle exception
10295
10296/* continuation for OP_SGET_WIDE */
10297
10298    /*
10299     * Go resolve the field
10300     */
10301.LOP_SGET_WIDE_resolve:
10302    movl     rSELF,%ecx
10303    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10304    movl     offThread_method(%ecx),%ecx          # ecx<- current method
10305    EXPORT_PC                                   # could throw, need to export
10306    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10307    movl     %eax,OUT_ARG1(%esp)
10308    movl     %ecx,OUT_ARG0(%esp)
10309    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10310    testl    %eax,%eax
10311    jne      .LOP_SGET_WIDE_finish                 # success, continue
10312    jmp      common_exceptionThrown             # no, handle exception
10313
10314/* continuation for OP_SGET_OBJECT */
10315
10316    /*
10317     * Go resolve the field
10318     */
10319.LOP_SGET_OBJECT_resolve:
10320    movl     rSELF,%ecx
10321    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10322    movl     offThread_method(%ecx),%ecx          # ecx<- current method
10323    EXPORT_PC                                   # could throw, need to export
10324    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10325    movl     %eax,OUT_ARG1(%esp)
10326    movl     %ecx,OUT_ARG0(%esp)
10327    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10328    testl    %eax,%eax
10329    jne      .LOP_SGET_OBJECT_finish                 # success, continue
10330    jmp      common_exceptionThrown             # no, handle exception
10331
10332/* continuation for OP_SGET_BOOLEAN */
10333
10334    /*
10335     * Go resolve the field
10336     */
10337.LOP_SGET_BOOLEAN_resolve:
10338    movl     rSELF,%ecx
10339    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10340    movl     offThread_method(%ecx),%ecx          # ecx<- current method
10341    EXPORT_PC                                   # could throw, need to export
10342    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10343    movl     %eax,OUT_ARG1(%esp)
10344    movl     %ecx,OUT_ARG0(%esp)
10345    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10346    testl    %eax,%eax
10347    jne      .LOP_SGET_BOOLEAN_finish                 # success, continue
10348    jmp      common_exceptionThrown             # no, handle exception
10349
10350/* continuation for OP_SGET_BYTE */
10351
10352    /*
10353     * Go resolve the field
10354     */
10355.LOP_SGET_BYTE_resolve:
10356    movl     rSELF,%ecx
10357    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10358    movl     offThread_method(%ecx),%ecx          # ecx<- current method
10359    EXPORT_PC                                   # could throw, need to export
10360    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10361    movl     %eax,OUT_ARG1(%esp)
10362    movl     %ecx,OUT_ARG0(%esp)
10363    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10364    testl    %eax,%eax
10365    jne      .LOP_SGET_BYTE_finish                 # success, continue
10366    jmp      common_exceptionThrown             # no, handle exception
10367
10368/* continuation for OP_SGET_CHAR */
10369
10370    /*
10371     * Go resolve the field
10372     */
10373.LOP_SGET_CHAR_resolve:
10374    movl     rSELF,%ecx
10375    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10376    movl     offThread_method(%ecx),%ecx          # ecx<- current method
10377    EXPORT_PC                                   # could throw, need to export
10378    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10379    movl     %eax,OUT_ARG1(%esp)
10380    movl     %ecx,OUT_ARG0(%esp)
10381    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10382    testl    %eax,%eax
10383    jne      .LOP_SGET_CHAR_finish                 # success, continue
10384    jmp      common_exceptionThrown             # no, handle exception
10385
10386/* continuation for OP_SGET_SHORT */
10387
10388    /*
10389     * Go resolve the field
10390     */
10391.LOP_SGET_SHORT_resolve:
10392    movl     rSELF,%ecx
10393    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10394    movl     offThread_method(%ecx),%ecx          # ecx<- current method
10395    EXPORT_PC                                   # could throw, need to export
10396    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10397    movl     %eax,OUT_ARG1(%esp)
10398    movl     %ecx,OUT_ARG0(%esp)
10399    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10400    testl    %eax,%eax
10401    jne      .LOP_SGET_SHORT_finish                 # success, continue
10402    jmp      common_exceptionThrown             # no, handle exception
10403
10404/* continuation for OP_SPUT */
10405
10406    /*
10407     * Go resolve the field
10408     */
10409.LOP_SPUT_resolve:
10410    movl     rSELF,%ecx
10411    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10412    movl     offThread_method(%ecx),%ecx          # ecx<- current method
10413    EXPORT_PC                                   # could throw, need to export
10414    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10415    movl     %eax,OUT_ARG1(%esp)
10416    movl     %ecx,OUT_ARG0(%esp)
10417    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10418    testl    %eax,%eax
10419    jne      .LOP_SPUT_finish                 # success, continue
10420    jmp      common_exceptionThrown             # no, handle exception
10421
10422/* continuation for OP_SPUT_WIDE */
10423
10424    /*
10425     * Go resolve the field
10426     */
10427.LOP_SPUT_WIDE_resolve:
10428    movl     rSELF,%ecx
10429    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10430    movl     offThread_method(%ecx),%ecx          # ecx<- current method
10431    EXPORT_PC                                   # could throw, need to export
10432    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10433    movl     %eax,OUT_ARG1(%esp)
10434    movl     %ecx,OUT_ARG0(%esp)
10435    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10436    testl    %eax,%eax
10437    jne      .LOP_SPUT_WIDE_finish                 # success, continue
10438    jmp      common_exceptionThrown             # no, handle exception
10439
10440/* continuation for OP_SPUT_OBJECT */
10441
10442
10443.LOP_SPUT_OBJECT_continue:
10444    movl      %ecx,offStaticField_value(%eax)    # do the store
10445    testl     %ecx,%ecx                          # stored null object ptr?
10446    FETCH_INST_OPCODE 2 %edx
10447    je        1f                                 # skip card mark if null
10448    movl      rSELF,%ecx
10449    movl      offField_clazz(%eax),%eax          # eax<- method->clazz
10450    movl      offThread_cardTable(%ecx),%ecx       # get card table base
10451    shrl      $GC_CARD_SHIFT,%eax               # head to card number
10452    movb      %cl,(%ecx,%eax)                    # mark card
104531:
10454    ADVANCE_PC 2
10455    GOTO_NEXT_R %edx
10456
10457.LOP_SPUT_OBJECT_resolve:
10458    movl     rSELF,%ecx
10459    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10460    movl     offThread_method(%ecx),%ecx          # ecx<- current method
10461    EXPORT_PC                                   # could throw, need to export
10462    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10463    movl     %eax,OUT_ARG1(%esp)
10464    movl     %ecx,OUT_ARG0(%esp)
10465    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10466    testl    %eax,%eax
10467    jne      .LOP_SPUT_OBJECT_finish                 # success, continue
10468    jmp      common_exceptionThrown             # no, handle exception
10469
10470/* continuation for OP_SPUT_BOOLEAN */
10471
10472    /*
10473     * Go resolve the field
10474     */
10475.LOP_SPUT_BOOLEAN_resolve:
10476    movl     rSELF,%ecx
10477    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10478    movl     offThread_method(%ecx),%ecx          # ecx<- current method
10479    EXPORT_PC                                   # could throw, need to export
10480    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10481    movl     %eax,OUT_ARG1(%esp)
10482    movl     %ecx,OUT_ARG0(%esp)
10483    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10484    testl    %eax,%eax
10485    jne      .LOP_SPUT_BOOLEAN_finish                 # success, continue
10486    jmp      common_exceptionThrown             # no, handle exception
10487
10488/* continuation for OP_SPUT_BYTE */
10489
10490    /*
10491     * Go resolve the field
10492     */
10493.LOP_SPUT_BYTE_resolve:
10494    movl     rSELF,%ecx
10495    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10496    movl     offThread_method(%ecx),%ecx          # ecx<- current method
10497    EXPORT_PC                                   # could throw, need to export
10498    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10499    movl     %eax,OUT_ARG1(%esp)
10500    movl     %ecx,OUT_ARG0(%esp)
10501    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10502    testl    %eax,%eax
10503    jne      .LOP_SPUT_BYTE_finish                 # success, continue
10504    jmp      common_exceptionThrown             # no, handle exception
10505
10506/* continuation for OP_SPUT_CHAR */
10507
10508    /*
10509     * Go resolve the field
10510     */
10511.LOP_SPUT_CHAR_resolve:
10512    movl     rSELF,%ecx
10513    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10514    movl     offThread_method(%ecx),%ecx          # ecx<- current method
10515    EXPORT_PC                                   # could throw, need to export
10516    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10517    movl     %eax,OUT_ARG1(%esp)
10518    movl     %ecx,OUT_ARG0(%esp)
10519    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10520    testl    %eax,%eax
10521    jne      .LOP_SPUT_CHAR_finish                 # success, continue
10522    jmp      common_exceptionThrown             # no, handle exception
10523
10524/* continuation for OP_SPUT_SHORT */
10525
10526    /*
10527     * Go resolve the field
10528     */
10529.LOP_SPUT_SHORT_resolve:
10530    movl     rSELF,%ecx
10531    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
10532    movl     offThread_method(%ecx),%ecx          # ecx<- current method
10533    EXPORT_PC                                   # could throw, need to export
10534    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
10535    movl     %eax,OUT_ARG1(%esp)
10536    movl     %ecx,OUT_ARG0(%esp)
10537    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
10538    testl    %eax,%eax
10539    jne      .LOP_SPUT_SHORT_finish                 # success, continue
10540    jmp      common_exceptionThrown             # no, handle exception
10541
10542/* continuation for OP_INVOKE_VIRTUAL */
10543
10544
10545.LOP_INVOKE_VIRTUAL_more:
10546    movl      offMethod_clazz(%eax),%eax  # ecx<- method->clazz
10547    movl      %eax,OUT_ARG0(%esp)         # arg0<- clazz
10548    movl      $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags
10549    call      dvmResolveMethod            # eax<- call(clazz, ref, flags)
10550    testl     %eax,%eax                   # got null?
10551    jne       .LOP_INVOKE_VIRTUAL_continue        # no, continue
10552    jmp       common_exceptionThrown      # yes, handle exception
10553
10554    /* At this point:
10555     *   eax = resolved base method
10556     *   ecx = scratch
10557     */
10558.LOP_INVOKE_VIRTUAL_continue:
10559    movzwl    4(rPC),%ecx               # ecx<- GFED or CCCC
10560    .if       (!0)
10561    andl      $0xf,%ecx                # ecx<- D (or stays CCCC)
10562    .endif
10563    GET_VREG_R  %ecx %ecx               # ecx<- "this"
10564    movzwl    offMethod_methodIndex(%eax),%eax  # eax<- baseMethod->methodIndex
10565    testl     %ecx,%ecx                 # null this?
10566    je        common_errNullObject      # go if so
10567    movl      offObject_clazz(%ecx),%ecx  # ecx<- thisPtr->clazz
10568    movl      offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable
10569    movl      (%ecx,%eax,4),%eax        # eax<- vtable[methodIndex]
10570    jmp       common_invokeMethodNoRange
10571
10572/* continuation for OP_INVOKE_SUPER */
10573
10574    /*
10575     * At this point:
10576     *  ecx = resolved base method [r0]
10577     *  eax = method->clazz [r9]
10578     */
10579.LOP_INVOKE_SUPER_continue:
10580    movl    offClassObject_super(%eax),%eax   # eax<- method->clazz->super
10581    movzwl  offMethod_methodIndex(%ecx),%ecx  # ecx<- baseMthod->methodIndex
10582    cmpl    offClassObject_vtableCount(%eax),%ecx # compare(methodIndex,vtableCount)
10583    jae     .LOP_INVOKE_SUPER_nsm           # method not present in superclass
10584    movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
10585    movl    (%eax,%ecx,4),%eax        # eax<- vtable[methodIndex]
10586    jmp     common_invokeMethodNoRange
10587
10588
10589    /* At this point:
10590     * ecx = null (needs to be resolved base method)
10591     * eax = method->clazz
10592    */
10593.LOP_INVOKE_SUPER_resolve:
10594    SPILL_TMP1(%eax)                    # method->clazz
10595    movl    %eax,OUT_ARG0(%esp)         # arg0<- method->clazz
10596    movzwl  2(rPC),%ecx                 # ecx<- BBBB
10597    movl    $METHOD_VIRTUAL,OUT_ARG2(%esp)  # arg2<- resolver method type
10598    movl    %ecx,OUT_ARG1(%esp)         # arg1<- ref
10599    call    dvmResolveMethod            # eax<- call(clazz, ref, flags)
10600    testl   %eax,%eax                   # got null?
10601    movl    %eax,%ecx                   # ecx<- resolved base method
10602    UNSPILL_TMP1(%eax)                  # restore method->clazz
10603    jne     .LOP_INVOKE_SUPER_continue        # good to go - continue
10604    jmp     common_exceptionThrown      # handle exception
10605
10606    /*
10607     * Throw a NoSuchMethodError with the method name as the message.
10608     *  ecx = resolved base method
10609     */
10610.LOP_INVOKE_SUPER_nsm:
10611    movl    offMethod_name(%ecx),%eax
10612    mov     %eax,OUT_ARG1(%esp)
10613    jmp     common_errNoSuchMethod
10614
10615/* continuation for OP_INVOKE_DIRECT */
10616
10617    /*
10618     * On entry:
10619     *   TMP_SPILL  <- "this" register
10620     * Things a bit ugly on this path, but it's the less
10621     * frequent one.  We'll have to do some reloading.
10622     */
10623.LOP_INVOKE_DIRECT_resolve:
10624     SPILL_TMP1(%ecx)
10625     movl     rSELF,%ecx
10626     movl     offThread_method(%ecx),%ecx  # ecx<- self->method
10627     movzwl   2(rPC),%eax      # reference (BBBB or CCCC)
10628     movl     offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
10629     movl     $METHOD_DIRECT,OUT_ARG2(%esp)
10630     movl     %eax,OUT_ARG1(%esp)
10631     movl     %ecx,OUT_ARG0(%esp)
10632     call     dvmResolveMethod # eax<- call(clazz, ref, flags)
10633     UNSPILL_TMP1(%ecx)
10634     testl    %eax,%eax
10635     jne      .LOP_INVOKE_DIRECT_finish
10636     jmp      common_exceptionThrown
10637
10638/* continuation for OP_INVOKE_STATIC */
10639
10640.LOP_INVOKE_STATIC_continue:
10641    movl      $METHOD_STATIC,%eax
10642    movl      %eax,OUT_ARG2(%esp)       # arg2<- flags
10643    call      dvmResolveMethod          # call(clazz,ref,flags)
10644    testl     %eax,%eax                 # got null?
10645    jne       common_invokeMethodNoRange
10646    jmp       common_exceptionThrown
10647
10648/* continuation for OP_INVOKE_INTERFACE */
10649
10650.LOP_INVOKE_INTERFACE_continue:
10651    call       dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex)
10652    testl      %eax,%eax
10653    je         common_exceptionThrown
10654    jmp        common_invokeMethodNoRange
10655
10656/* continuation for OP_INVOKE_VIRTUAL_RANGE */
10657
10658
10659.LOP_INVOKE_VIRTUAL_RANGE_more:
10660    movl      offMethod_clazz(%eax),%eax  # ecx<- method->clazz
10661    movl      %eax,OUT_ARG0(%esp)         # arg0<- clazz
10662    movl      $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags
10663    call      dvmResolveMethod            # eax<- call(clazz, ref, flags)
10664    testl     %eax,%eax                   # got null?
10665    jne       .LOP_INVOKE_VIRTUAL_RANGE_continue        # no, continue
10666    jmp       common_exceptionThrown      # yes, handle exception
10667
10668    /* At this point:
10669     *   eax = resolved base method
10670     *   ecx = scratch
10671     */
10672.LOP_INVOKE_VIRTUAL_RANGE_continue:
10673    movzwl    4(rPC),%ecx               # ecx<- GFED or CCCC
10674    .if       (!1)
10675    andl      $0xf,%ecx                # ecx<- D (or stays CCCC)
10676    .endif
10677    GET_VREG_R  %ecx %ecx               # ecx<- "this"
10678    movzwl    offMethod_methodIndex(%eax),%eax  # eax<- baseMethod->methodIndex
10679    testl     %ecx,%ecx                 # null this?
10680    je        common_errNullObject      # go if so
10681    movl      offObject_clazz(%ecx),%ecx  # ecx<- thisPtr->clazz
10682    movl      offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable
10683    movl      (%ecx,%eax,4),%eax        # eax<- vtable[methodIndex]
10684    jmp       common_invokeMethodRange
10685
10686/* continuation for OP_INVOKE_SUPER_RANGE */
10687
10688    /*
10689     * At this point:
10690     *  ecx = resolved base method [r0]
10691     *  eax = method->clazz [r9]
10692     */
10693.LOP_INVOKE_SUPER_RANGE_continue:
10694    movl    offClassObject_super(%eax),%eax   # eax<- method->clazz->super
10695    movzwl  offMethod_methodIndex(%ecx),%ecx  # ecx<- baseMthod->methodIndex
10696    cmpl    offClassObject_vtableCount(%eax),%ecx # compare(methodIndex,vtableCount)
10697    jae     .LOP_INVOKE_SUPER_RANGE_nsm           # method not present in superclass
10698    movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
10699    movl    (%eax,%ecx,4),%eax        # eax<- vtable[methodIndex]
10700    jmp     common_invokeMethodRange
10701
10702
10703    /* At this point:
10704     * ecx = null (needs to be resolved base method)
10705     * eax = method->clazz
10706    */
10707.LOP_INVOKE_SUPER_RANGE_resolve:
10708    SPILL_TMP1(%eax)                    # method->clazz
10709    movl    %eax,OUT_ARG0(%esp)         # arg0<- method->clazz
10710    movzwl  2(rPC),%ecx                 # ecx<- BBBB
10711    movl    $METHOD_VIRTUAL,OUT_ARG2(%esp)  # arg2<- resolver method type
10712    movl    %ecx,OUT_ARG1(%esp)         # arg1<- ref
10713    call    dvmResolveMethod            # eax<- call(clazz, ref, flags)
10714    testl   %eax,%eax                   # got null?
10715    movl    %eax,%ecx                   # ecx<- resolved base method
10716    UNSPILL_TMP1(%eax)                  # restore method->clazz
10717    jne     .LOP_INVOKE_SUPER_RANGE_continue        # good to go - continue
10718    jmp     common_exceptionThrown      # handle exception
10719
10720    /*
10721     * Throw a NoSuchMethodError with the method name as the message.
10722     *  ecx = resolved base method
10723     */
10724.LOP_INVOKE_SUPER_RANGE_nsm:
10725    movl    offMethod_name(%ecx),%eax
10726    mov     %eax,OUT_ARG1(%esp)
10727    jmp     common_errNoSuchMethod
10728
10729/* continuation for OP_INVOKE_DIRECT_RANGE */
10730
10731    /*
10732     * On entry:
10733     *   TMP_SPILL  <- "this" register
10734     * Things a bit ugly on this path, but it's the less
10735     * frequent one.  We'll have to do some reloading.
10736     */
10737.LOP_INVOKE_DIRECT_RANGE_resolve:
10738     SPILL_TMP1(%ecx)
10739     movl     rSELF,%ecx
10740     movl     offThread_method(%ecx),%ecx  # ecx<- self->method
10741     movzwl   2(rPC),%eax      # reference (BBBB or CCCC)
10742     movl     offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
10743     movl     $METHOD_DIRECT,OUT_ARG2(%esp)
10744     movl     %eax,OUT_ARG1(%esp)
10745     movl     %ecx,OUT_ARG0(%esp)
10746     call     dvmResolveMethod # eax<- call(clazz, ref, flags)
10747     UNSPILL_TMP1(%ecx)
10748     testl    %eax,%eax
10749     jne      .LOP_INVOKE_DIRECT_RANGE_finish
10750     jmp      common_exceptionThrown
10751
10752/* continuation for OP_INVOKE_STATIC_RANGE */
10753
10754.LOP_INVOKE_STATIC_RANGE_continue:
10755    movl      $METHOD_STATIC,%eax
10756    movl      %eax,OUT_ARG2(%esp)       # arg2<- flags
10757    call      dvmResolveMethod          # call(clazz,ref,flags)
10758    testl     %eax,%eax                 # got null?
10759    jne       common_invokeMethodRange
10760    jmp       common_exceptionThrown
10761
10762/* continuation for OP_INVOKE_INTERFACE_RANGE */
10763
10764.LOP_INVOKE_INTERFACE_RANGE_continue:
10765    call       dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex)
10766    testl      %eax,%eax
10767    je         common_exceptionThrown
10768    jmp        common_invokeMethodRange
10769
10770/* continuation for OP_FLOAT_TO_INT */
10771
10772
10773.LOP_FLOAT_TO_INT_continue:
10774    .if 0
10775    movl     $0x80000000,%eax
10776    xorl     4(rFP,%ecx,4),%eax
10777    orl      (rFP,%ecx,4),%eax
10778    .else
10779    cmpl     $0x80000000,(rFP,%ecx,4)
10780    .endif
10781    je       .LOP_FLOAT_TO_INT_special_case # fix up result
10782
10783.LOP_FLOAT_TO_INT_finish:
10784    ADVANCE_PC 1
10785    GOTO_NEXT_R %edx
10786
10787.LOP_FLOAT_TO_INT_special_case:
10788    fnstsw   %ax
10789    sahf
10790    jp       .LOP_FLOAT_TO_INT_isNaN
10791    adcl     $-1,(rFP,%ecx,4)
10792    .if 0
10793    adcl     $-1,4(rFP,%ecx,4)
10794    .endif
10795   jmp       .LOP_FLOAT_TO_INT_finish
10796.LOP_FLOAT_TO_INT_isNaN:
10797    movl      $0,(rFP,%ecx,4)
10798    .if 0
10799    movl      $0,4(rFP,%ecx,4)
10800    .endif
10801    jmp       .LOP_FLOAT_TO_INT_finish
10802
10803/* continuation for OP_FLOAT_TO_LONG */
10804
10805
10806.LOP_FLOAT_TO_LONG_continue:
10807    .if 1
10808    movl     $0x80000000,%eax
10809    xorl     4(rFP,%ecx,4),%eax
10810    orl      (rFP,%ecx,4),%eax
10811    .else
10812    cmpl     $0x80000000,(rFP,%ecx,4)
10813    .endif
10814    je       .LOP_FLOAT_TO_LONG_special_case # fix up result
10815
10816.LOP_FLOAT_TO_LONG_finish:
10817    ADVANCE_PC 1
10818    GOTO_NEXT_R %edx
10819
10820.LOP_FLOAT_TO_LONG_special_case:
10821    fnstsw   %ax
10822    sahf
10823    jp       .LOP_FLOAT_TO_LONG_isNaN
10824    adcl     $-1,(rFP,%ecx,4)
10825    .if 1
10826    adcl     $-1,4(rFP,%ecx,4)
10827    .endif
10828   jmp       .LOP_FLOAT_TO_LONG_finish
10829.LOP_FLOAT_TO_LONG_isNaN:
10830    movl      $0,(rFP,%ecx,4)
10831    .if 1
10832    movl      $0,4(rFP,%ecx,4)
10833    .endif
10834    jmp       .LOP_FLOAT_TO_LONG_finish
10835
10836/* continuation for OP_DOUBLE_TO_INT */
10837
10838
10839.LOP_DOUBLE_TO_INT_continue:
10840    .if 0
10841    movl     $0x80000000,%eax
10842    xorl     4(rFP,%ecx,4),%eax
10843    orl      (rFP,%ecx,4),%eax
10844    .else
10845    cmpl     $0x80000000,(rFP,%ecx,4)
10846    .endif
10847    je       .LOP_DOUBLE_TO_INT_special_case # fix up result
10848
10849.LOP_DOUBLE_TO_INT_finish:
10850    ADVANCE_PC 1
10851    GOTO_NEXT_R %edx
10852
10853.LOP_DOUBLE_TO_INT_special_case:
10854    fnstsw   %ax
10855    sahf
10856    jp       .LOP_DOUBLE_TO_INT_isNaN
10857    adcl     $-1,(rFP,%ecx,4)
10858    .if 0
10859    adcl     $-1,4(rFP,%ecx,4)
10860    .endif
10861   jmp       .LOP_DOUBLE_TO_INT_finish
10862.LOP_DOUBLE_TO_INT_isNaN:
10863    movl      $0,(rFP,%ecx,4)
10864    .if 0
10865    movl      $0,4(rFP,%ecx,4)
10866    .endif
10867    jmp       .LOP_DOUBLE_TO_INT_finish
10868
10869/* continuation for OP_DOUBLE_TO_LONG */
10870
10871
10872.LOP_DOUBLE_TO_LONG_continue:
10873    .if 1
10874    movl     $0x80000000,%eax
10875    xorl     4(rFP,%ecx,4),%eax
10876    orl      (rFP,%ecx,4),%eax
10877    .else
10878    cmpl     $0x80000000,(rFP,%ecx,4)
10879    .endif
10880    je       .LOP_DOUBLE_TO_LONG_special_case # fix up result
10881
10882.LOP_DOUBLE_TO_LONG_finish:
10883    ADVANCE_PC 1
10884    GOTO_NEXT_R %edx
10885
10886.LOP_DOUBLE_TO_LONG_special_case:
10887    fnstsw   %ax
10888    sahf
10889    jp       .LOP_DOUBLE_TO_LONG_isNaN
10890    adcl     $-1,(rFP,%ecx,4)
10891    .if 1
10892    adcl     $-1,4(rFP,%ecx,4)
10893    .endif
10894   jmp       .LOP_DOUBLE_TO_LONG_finish
10895.LOP_DOUBLE_TO_LONG_isNaN:
10896    movl      $0,(rFP,%ecx,4)
10897    .if 1
10898    movl      $0,4(rFP,%ecx,4)
10899    .endif
10900    jmp       .LOP_DOUBLE_TO_LONG_finish
10901
10902/* continuation for OP_DIV_INT */
10903.LOP_DIV_INT_continue_div:
10904    cltd
10905    idivl   %ecx
10906.LOP_DIV_INT_finish_div:
10907    SET_VREG %eax rINST
10908    FETCH_INST_OPCODE 2 %edx
10909    ADVANCE_PC 2
10910    GOTO_NEXT_R %edx
10911
10912/* continuation for OP_REM_INT */
10913.LOP_REM_INT_continue_div:
10914    cltd
10915    idivl   %ecx
10916.LOP_REM_INT_finish_div:
10917    SET_VREG %edx rINST
10918    FETCH_INST_OPCODE 2 %edx
10919    ADVANCE_PC 2
10920    GOTO_NEXT_R %edx
10921
10922/* continuation for OP_MUL_LONG */
10923
10924.LOP_MUL_LONG_continue:
10925    leal      (%ecx,%edx),%edx     # full result now in %edx:%eax
10926    UNSPILL_TMP2(%esi)             # Restore Dalvik PC
10927    FETCH_INST_OPCODE 2 %ecx       # Fetch next instruction
10928    movl      %edx,4(rFP,rINST,4)  # v[B+1]<- %edx
10929    movl      %eax,(rFP,rINST,4)   # v[B]<- %eax
10930    ADVANCE_PC 2
10931    GOTO_NEXT_R %ecx
10932
10933/* continuation for OP_DIV_LONG */
10934
10935.LOP_DIV_LONG_continue:
10936    call     __divdi3
10937.LOP_DIV_LONG_finish:
10938    SET_VREG_WORD %edx rINST 1
10939    SET_VREG_WORD %eax rINST 0
10940    FETCH_INST_OPCODE 2 %edx
10941    ADVANCE_PC 2
10942    GOTO_NEXT_R %edx
10943
10944.LOP_DIV_LONG_check_zero:
10945    testl   %edx,%edx
10946    jne     .LOP_DIV_LONG_notSpecial
10947    jmp     common_errDivideByZero
10948.LOP_DIV_LONG_check_neg1:
10949    testl   %edx,%eax
10950    jne     .LOP_DIV_LONG_notSpecial
10951    GET_VREG_WORD %edx %ecx 0
10952    GET_VREG_WORD %ecx %ecx 1
10953    testl    %edx,%edx
10954    jne      .LOP_DIV_LONG_notSpecial1
10955    cmpl     $0x80000000,%ecx
10956    jne      .LOP_DIV_LONG_notSpecial1
10957    /* minint / -1, return minint on div, 0 on rem */
10958    xorl     %eax,%eax
10959    movl     $0x80000000,%edx
10960    jmp      .LOP_DIV_LONG_finish
10961
10962/* continuation for OP_REM_LONG */
10963
10964.LOP_REM_LONG_continue:
10965    call     __moddi3
10966.LOP_REM_LONG_finish:
10967    SET_VREG_WORD %edx rINST 1
10968    SET_VREG_WORD %eax rINST 0
10969    FETCH_INST_OPCODE 2 %edx
10970    ADVANCE_PC 2
10971    GOTO_NEXT_R %edx
10972
10973.LOP_REM_LONG_check_zero:
10974    testl   %edx,%edx
10975    jne     .LOP_REM_LONG_notSpecial
10976    jmp     common_errDivideByZero
10977.LOP_REM_LONG_check_neg1:
10978    testl   %edx,%eax
10979    jne     .LOP_REM_LONG_notSpecial
10980    GET_VREG_WORD %edx %ecx 0
10981    GET_VREG_WORD %ecx %ecx 1
10982    testl    %edx,%edx
10983    jne      .LOP_REM_LONG_notSpecial1
10984    cmpl     $0x80000000,%ecx
10985    jne      .LOP_REM_LONG_notSpecial1
10986    /* minint / -1, return minint on div, 0 on rem */
10987    xorl     %eax,%eax
10988    movl     $0,%edx
10989    jmp      .LOP_REM_LONG_finish
10990
10991/* continuation for OP_SHL_LONG */
10992
10993.LOP_SHL_LONG_finish:
10994    SET_VREG_WORD %eax rINST 0          # v[AA+0]<- %eax
10995    ADVANCE_PC 2
10996    GOTO_NEXT_R %edx
10997
10998/* continuation for OP_SHR_LONG */
10999
11000
11001.LOP_SHR_LONG_finish:
11002    SET_VREG_WORD %eax rINST 0          # v[AA+0]<- eax
11003    ADVANCE_PC 2
11004    GOTO_NEXT_R %edx
11005
11006/* continuation for OP_USHR_LONG */
11007
11008
11009.LOP_USHR_LONG_finish:
11010    SET_VREG_WORD %eax rINST 0         # v[BB+0]<- eax
11011    ADVANCE_PC 2
11012    GOTO_NEXT_R %edx
11013
11014/* continuation for OP_DIV_INT_2ADDR */
11015.LOP_DIV_INT_2ADDR_continue_div2addr:
11016    cltd
11017    idivl   %ecx
11018.LOP_DIV_INT_2ADDR_finish_div2addr:
11019    SET_VREG %eax rINST
11020    FETCH_INST_OPCODE 1 %edx
11021    ADVANCE_PC 1
11022    GOTO_NEXT_R %edx
11023
11024/* continuation for OP_REM_INT_2ADDR */
11025.LOP_REM_INT_2ADDR_continue_div2addr:
11026    cltd
11027    idivl   %ecx
11028.LOP_REM_INT_2ADDR_finish_div2addr:
11029    SET_VREG %edx rINST
11030    FETCH_INST_OPCODE 1 %edx
11031    ADVANCE_PC 1
11032    GOTO_NEXT_R %edx
11033
11034/* continuation for OP_MUL_LONG_2ADDR */
11035
11036.LOP_MUL_LONG_2ADDR_continue:
11037    leal      (%ecx,%edx),%edx         # full result now in %edx:%eax
11038    movl      %edx,4(%esi)             # v[A+1]<- %edx
11039    movl      %eax,(%esi)              # v[A]<- %eax
11040    UNSPILL_TMP2(%esi)
11041    FETCH_INST_OPCODE 1 %ecx
11042    UNSPILL(rFP)
11043    ADVANCE_PC 1
11044    GOTO_NEXT_R %ecx
11045
11046/* continuation for OP_DIV_LONG_2ADDR */
11047
11048.LOP_DIV_LONG_2ADDR_continue:
11049    movl     %eax,OUT_ARG3(%esp)
11050    movl     %edx,OUT_ARG0(%esp)
11051    movl     %ecx,OUT_ARG1(%esp)
11052    call     __divdi3
11053.LOP_DIV_LONG_2ADDR_finish:
11054    SET_VREG_WORD %edx rINST 1
11055    SET_VREG_WORD %eax rINST 0
11056    FETCH_INST_OPCODE 1 %edx
11057    ADVANCE_PC 1
11058    GOTO_NEXT_R %edx
11059
11060.LOP_DIV_LONG_2ADDR_check_zero:
11061    testl   %edx,%edx
11062    jne     .LOP_DIV_LONG_2ADDR_notSpecial
11063    jmp     common_errDivideByZero
11064.LOP_DIV_LONG_2ADDR_check_neg1:
11065    testl   %edx,%eax
11066    jne     .LOP_DIV_LONG_2ADDR_notSpecial
11067    GET_VREG_WORD %edx rINST 0
11068    GET_VREG_WORD %ecx rINST 1
11069    testl    %edx,%edx
11070    jne      .LOP_DIV_LONG_2ADDR_notSpecial1
11071    cmpl     $0x80000000,%ecx
11072    jne      .LOP_DIV_LONG_2ADDR_notSpecial1
11073    /* minint / -1, return minint on div, 0 on rem */
11074    xorl     %eax,%eax
11075    movl     $0x80000000,%edx
11076    jmp      .LOP_DIV_LONG_2ADDR_finish
11077
11078/* continuation for OP_REM_LONG_2ADDR */
11079
11080.LOP_REM_LONG_2ADDR_continue:
11081    movl     %eax,OUT_ARG3(%esp)
11082    movl     %edx,OUT_ARG0(%esp)
11083    movl     %ecx,OUT_ARG1(%esp)
11084    call     __moddi3
11085.LOP_REM_LONG_2ADDR_finish:
11086    SET_VREG_WORD %edx rINST 1
11087    SET_VREG_WORD %eax rINST 0
11088    FETCH_INST_OPCODE 1 %edx
11089    ADVANCE_PC 1
11090    GOTO_NEXT_R %edx
11091
11092.LOP_REM_LONG_2ADDR_check_zero:
11093    testl   %edx,%edx
11094    jne     .LOP_REM_LONG_2ADDR_notSpecial
11095    jmp     common_errDivideByZero
11096.LOP_REM_LONG_2ADDR_check_neg1:
11097    testl   %edx,%eax
11098    jne     .LOP_REM_LONG_2ADDR_notSpecial
11099    GET_VREG_WORD %edx rINST 0
11100    GET_VREG_WORD %ecx rINST 1
11101    testl    %edx,%edx
11102    jne      .LOP_REM_LONG_2ADDR_notSpecial1
11103    cmpl     $0x80000000,%ecx
11104    jne      .LOP_REM_LONG_2ADDR_notSpecial1
11105    /* minint / -1, return minint on div, 0 on rem */
11106    xorl     %eax,%eax
11107    movl     $0,%edx
11108    jmp      .LOP_REM_LONG_2ADDR_finish
11109
11110/* continuation for OP_SHL_LONG_2ADDR */
11111
11112
11113.LOP_SHL_LONG_2ADDR_finish:
11114    FETCH_INST_OPCODE 1 %edx
11115    SET_VREG_WORD %eax rINST 0         # v[AA+0]<- eax
11116    ADVANCE_PC 1
11117    GOTO_NEXT_R %edx
11118
11119/* continuation for OP_SHR_LONG_2ADDR */
11120
11121
11122.LOP_SHR_LONG_2ADDR_finish:
11123    FETCH_INST_OPCODE 1 %edx
11124    SET_VREG_WORD %eax rINST 0    # v[AA+0]<- eax
11125    ADVANCE_PC 1
11126    GOTO_NEXT_R %edx
11127
11128/* continuation for OP_USHR_LONG_2ADDR */
11129
11130
11131.LOP_USHR_LONG_2ADDR_finish:
11132    FETCH_INST_OPCODE 1 %edx
11133    SET_VREG_WORD %eax rINST 0         # v[AA+0]<- eax
11134    ADVANCE_PC 1
11135    GOTO_NEXT_R %edx
11136
11137/* continuation for OP_DIV_INT_LIT16 */
11138.LOP_DIV_INT_LIT16_continue_div:
11139    cltd
11140    idivl   %ecx
11141.LOP_DIV_INT_LIT16_finish_div:
11142    SET_VREG %eax rINST
11143    FETCH_INST_OPCODE 2 %edx
11144    ADVANCE_PC 2
11145    GOTO_NEXT_R %edx
11146
11147/* continuation for OP_REM_INT_LIT16 */
11148.LOP_REM_INT_LIT16_continue_div:
11149    cltd
11150    idivl   %ecx
11151.LOP_REM_INT_LIT16_finish_div:
11152    SET_VREG %edx rINST
11153    FETCH_INST_OPCODE 2 %edx
11154    ADVANCE_PC 2
11155    GOTO_NEXT_R %edx
11156
11157/* continuation for OP_DIV_INT_LIT8 */
11158.LOP_DIV_INT_LIT8_continue_div:
11159    cltd
11160    idivl   %ecx
11161.LOP_DIV_INT_LIT8_finish_div:
11162    SET_VREG %eax rINST
11163    FETCH_INST_OPCODE 2 %edx
11164    ADVANCE_PC 2
11165    GOTO_NEXT_R %edx
11166
11167/* continuation for OP_REM_INT_LIT8 */
11168.LOP_REM_INT_LIT8_continue_div:
11169    cltd
11170    idivl   %ecx
11171.LOP_REM_INT_LIT8_finish_div:
11172    SET_VREG %edx rINST
11173    FETCH_INST_OPCODE 2 %edx
11174    ADVANCE_PC 2
11175    GOTO_NEXT_R %edx
11176
11177/* continuation for OP_IGET_VOLATILE */
11178
11179
11180.LOP_IGET_VOLATILE_resolve:
11181    EXPORT_PC
11182    movl    offThread_method(%edx),%edx           # edx<- current method
11183    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11184    SPILL_TMP1(%ecx)                            # save obj pointer across call
11185    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
11186    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11187    UNSPILL_TMP1(%ecx)
11188    testl   %eax,%eax                           #  returns InstrField ptr
11189    jne     .LOP_IGET_VOLATILE_finish
11190    jmp     common_exceptionThrown
11191
11192.LOP_IGET_VOLATILE_finish:
11193    /*
11194     * Currently:
11195     *   eax holds resolved field
11196     *   ecx holds object
11197     *   rINST holds A
11198     */
11199    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11200    testl   %ecx,%ecx                           # object null?
11201    je      common_errNullObject                # object was null
11202    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
11203    movl    rINST,%eax                          # eax<- A
11204    FETCH_INST_OPCODE 2 %edx
11205    SET_VREG %ecx %eax
11206    ADVANCE_PC 2
11207    GOTO_NEXT_R %edx
11208
11209/* continuation for OP_IPUT_VOLATILE */
11210
11211
11212.LOP_IPUT_VOLATILE_resolve:
11213    EXPORT_PC
11214    movl    offThread_method(%edx),%edx           # edx<- current method
11215    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11216    SPILL_TMP1(%ecx)                            # save obj pointer across call
11217    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
11218    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11219    UNSPILL_TMP1(%ecx)
11220    testl   %eax,%eax                           # returns InstrField ptr
11221    jne     .LOP_IPUT_VOLATILE_finish
11222    jmp     common_exceptionThrown
11223
11224.LOP_IPUT_VOLATILE_finish:
11225    /*
11226     * Currently:
11227     *   eax holds resolved field
11228     *   ecx holds object
11229     *   rINST holds A
11230     */
11231    GET_VREG_R rINST rINST                       # rINST<- v[A]
11232    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
11233    testl   %ecx,%ecx                            # object null?
11234    je      common_errNullObject                 # object was null
11235    FETCH_INST_OPCODE 2 %edx
11236    movl   rINST,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
11237    ADVANCE_PC 2
11238    GOTO_NEXT_R %edx
11239
11240/* continuation for OP_SGET_VOLATILE */
11241
11242    /*
11243     * Go resolve the field
11244     */
11245.LOP_SGET_VOLATILE_resolve:
11246    movl     rSELF,%ecx
11247    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
11248    movl     offThread_method(%ecx),%ecx          # ecx<- current method
11249    EXPORT_PC                                   # could throw, need to export
11250    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
11251    movl     %eax,OUT_ARG1(%esp)
11252    movl     %ecx,OUT_ARG0(%esp)
11253    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
11254    testl    %eax,%eax
11255    jne      .LOP_SGET_VOLATILE_finish                 # success, continue
11256    jmp      common_exceptionThrown             # no, handle exception
11257
11258/* continuation for OP_SPUT_VOLATILE */
11259
11260    /*
11261     * Go resolve the field
11262     */
11263.LOP_SPUT_VOLATILE_resolve:
11264    movl     rSELF,%ecx
11265    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
11266    movl     offThread_method(%ecx),%ecx          # ecx<- current method
11267    EXPORT_PC                                   # could throw, need to export
11268    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
11269    movl     %eax,OUT_ARG1(%esp)
11270    movl     %ecx,OUT_ARG0(%esp)
11271    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
11272    testl    %eax,%eax
11273    jne      .LOP_SPUT_VOLATILE_finish                 # success, continue
11274    jmp      common_exceptionThrown             # no, handle exception
11275
11276/* continuation for OP_IGET_OBJECT_VOLATILE */
11277
11278
11279.LOP_IGET_OBJECT_VOLATILE_resolve:
11280    EXPORT_PC
11281    movl    offThread_method(%edx),%edx           # edx<- current method
11282    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11283    SPILL_TMP1(%ecx)                            # save obj pointer across call
11284    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
11285    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11286    UNSPILL_TMP1(%ecx)
11287    testl   %eax,%eax                           #  returns InstrField ptr
11288    jne     .LOP_IGET_OBJECT_VOLATILE_finish
11289    jmp     common_exceptionThrown
11290
11291.LOP_IGET_OBJECT_VOLATILE_finish:
11292    /*
11293     * Currently:
11294     *   eax holds resolved field
11295     *   ecx holds object
11296     *   rINST holds A
11297     */
11298    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11299    testl   %ecx,%ecx                           # object null?
11300    je      common_errNullObject                # object was null
11301    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
11302    movl    rINST,%eax                          # eax<- A
11303    FETCH_INST_OPCODE 2 %edx
11304    SET_VREG %ecx %eax
11305    ADVANCE_PC 2
11306    GOTO_NEXT_R %edx
11307
11308/* continuation for OP_EXECUTE_INLINE */
11309
11310.LOP_EXECUTE_INLINE_continue:
11311    /*
11312     * Extract args, call function.
11313     *  ecx = #of args (0-4)
11314     *  eax = call index
11315     *  @esp = return addr
11316     *  esp is -4 from normal
11317     *
11318     *  Go ahead and load all 4 args, even if not used.
11319     */
11320    movzwl    4(rPC),%edx
11321
11322    movl      $0xf,%ecx
11323    andl      %edx,%ecx
11324    GET_VREG_R  %ecx %ecx
11325    sarl      $4,%edx
11326    movl      %ecx,4+OUT_ARG0(%esp)
11327
11328    movl      $0xf,%ecx
11329    andl      %edx,%ecx
11330    GET_VREG_R  %ecx %ecx
11331    sarl      $4,%edx
11332    movl      %ecx,4+OUT_ARG1(%esp)
11333
11334    movl      $0xf,%ecx
11335    andl      %edx,%ecx
11336    GET_VREG_R  %ecx %ecx
11337    sarl      $4,%edx
11338    movl      %ecx,4+OUT_ARG2(%esp)
11339
11340    movl      $0xf,%ecx
11341    andl      %edx,%ecx
11342    GET_VREG_R  %ecx %ecx
11343    sarl      $4,%edx
11344    movl      %ecx,4+OUT_ARG3(%esp)
11345
11346    sall      $4,%eax      # index *= sizeof(table entry)
11347    jmp       *gDvmInlineOpsTable(%eax)
11348    # will return to caller of .LOP_EXECUTE_INLINE_continue
11349
11350/* continuation for OP_IPUT_OBJECT_QUICK */
11351
11352.LOP_IPUT_OBJECT_QUICK_finish:
11353    testl     rINST,rINST               # did we store null?
11354    FETCH_INST_OPCODE 2 %edx
11355    movl      offThread_cardTable(%eax),%eax  # get card table base
11356    je        1f                            # skip card mark if null store
11357    shrl      $GC_CARD_SHIFT,%ecx          # object head to card number
11358    movb      %al,(%eax,%ecx)               # mark card based on object head
113591:
11360    ADVANCE_PC 2
11361    GOTO_NEXT_R %edx
11362
11363/* continuation for OP_IPUT_OBJECT_VOLATILE */
11364
11365
11366.LOP_IPUT_OBJECT_VOLATILE_resolve:
11367    EXPORT_PC
11368    movl    offThread_method(%edx),%edx           # edx<- current method
11369    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11370    SPILL_TMP1(%ecx)                            # save obj pointer across call
11371    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
11372    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11373    UNSPILL_TMP1(%ecx)
11374    testl   %eax,%eax                           # returns InstrField ptr
11375    jne     .LOP_IPUT_OBJECT_VOLATILE_finish
11376    jmp     common_exceptionThrown
11377
11378.LOP_IPUT_OBJECT_VOLATILE_finish:
11379    /*
11380     * Currently:
11381     *   eax holds resolved field
11382     *   ecx holds object
11383     *   %edx is scratch, but needs to be unspilled
11384     *   rINST holds A
11385     */
11386    GET_VREG_R rINST rINST                      # rINST<- v[A]
11387    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11388    testl   %ecx,%ecx                           # object null?
11389    je      common_errNullObject                # object was null
11390    movl    rINST,(%ecx,%eax)      # obj.field <- v[A](8/16/32 bits)
11391    movl    rSELF,%eax
11392    testl   rINST,rINST                         # stored a NULL?
11393    movl    offThread_cardTable(%eax),%eax        # get card table base
11394    FETCH_INST_OPCODE 2 %edx
11395    je      1f                                  # skip card mark if null store
11396    shrl    $GC_CARD_SHIFT,%ecx                # object head to card number
11397    movb    %al,(%eax,%ecx)                     # mark card using object head
113981:
11399    ADVANCE_PC 2
11400    GOTO_NEXT_R %edx
11401
11402/* continuation for OP_SGET_OBJECT_VOLATILE */
11403
11404    /*
11405     * Go resolve the field
11406     */
11407.LOP_SGET_OBJECT_VOLATILE_resolve:
11408    movl     rSELF,%ecx
11409    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
11410    movl     offThread_method(%ecx),%ecx          # ecx<- current method
11411    EXPORT_PC                                   # could throw, need to export
11412    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
11413    movl     %eax,OUT_ARG1(%esp)
11414    movl     %ecx,OUT_ARG0(%esp)
11415    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
11416    testl    %eax,%eax
11417    jne      .LOP_SGET_OBJECT_VOLATILE_finish                 # success, continue
11418    jmp      common_exceptionThrown             # no, handle exception
11419
11420/* continuation for OP_SPUT_OBJECT_VOLATILE */
11421
11422
11423.LOP_SPUT_OBJECT_VOLATILE_continue:
11424    movl      %ecx,offStaticField_value(%eax)    # do the store
11425    testl     %ecx,%ecx                          # stored null object ptr?
11426    FETCH_INST_OPCODE 2 %edx
11427    je        1f                                 # skip card mark if null
11428    movl      rSELF,%ecx
11429    movl      offField_clazz(%eax),%eax          # eax<- method->clazz
11430    movl      offThread_cardTable(%ecx),%ecx       # get card table base
11431    shrl      $GC_CARD_SHIFT,%eax               # head to card number
11432    movb      %cl,(%ecx,%eax)                    # mark card
114331:
11434    ADVANCE_PC 2
11435    GOTO_NEXT_R %edx
11436
11437.LOP_SPUT_OBJECT_VOLATILE_resolve:
11438    movl     rSELF,%ecx
11439    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
11440    movl     offThread_method(%ecx),%ecx          # ecx<- current method
11441    EXPORT_PC                                   # could throw, need to export
11442    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
11443    movl     %eax,OUT_ARG1(%esp)
11444    movl     %ecx,OUT_ARG0(%esp)
11445    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
11446    testl    %eax,%eax
11447    jne      .LOP_SPUT_OBJECT_VOLATILE_finish                 # success, continue
11448    jmp      common_exceptionThrown             # no, handle exception
11449
11450/* continuation for OP_CONST_CLASS_JUMBO */
11451
11452/* This is the less common path, so we'll redo some work
11453   here rather than force spills on the common path */
11454.LOP_CONST_CLASS_JUMBO_resolve:
11455    movl     rSELF,%eax
11456    EXPORT_PC
11457    movl     offThread_method(%eax),%eax # eax<- self->method
11458    movl     $1,OUT_ARG2(%esp)        # true
11459    movl     2(rPC),%ecx               # ecx<- AAAAAAAA
11460    movl     offMethod_clazz(%eax),%eax
11461    movl     %ecx,OUT_ARG1(%esp)
11462    movl     %eax,OUT_ARG0(%esp)
11463    call     dvmResolveClass           # go resolve
11464    testl    %eax,%eax                 # failed?
11465    je       common_exceptionThrown
11466    SET_VREG %eax rINST
11467    FETCH_INST_OPCODE 4 %edx
11468    ADVANCE_PC 4
11469    GOTO_NEXT_R %edx
11470
11471/* continuation for OP_CHECK_CAST_JUMBO */
11472
11473    /*
11474     * Trivial test failed, need to perform full check.  This is common.
11475     *  ecx holds obj->clazz
11476     *  eax holds class resolved from AAAAAAAA
11477     *  rINST holds object
11478     */
11479.LOP_CHECK_CAST_JUMBO_fullcheck:
11480    movl    %eax,sReg0                 # we'll need the desired class on failure
11481    movl    %eax,OUT_ARG1(%esp)
11482    movl    %ecx,OUT_ARG0(%esp)
11483    call    dvmInstanceofNonTrivial    # eax<- boolean result
11484    testl   %eax,%eax                  # failed?
11485    jne     .LOP_CHECK_CAST_JUMBO_okay           # no, success
11486
11487    # A cast has failed.  We need to throw a ClassCastException.
11488    EXPORT_PC
11489    movl    offObject_clazz(rINST),%eax
11490    movl    %eax,OUT_ARG0(%esp)                 # arg0<- obj->clazz
11491    movl    sReg0,%ecx
11492    movl    %ecx,OUT_ARG1(%esp)                 # arg1<- desired class
11493    call    dvmThrowClassCastException
11494    jmp     common_exceptionThrown
11495
11496    /*
11497     * Resolution required.  This is the least-likely path, and we're
11498     * going to have to recreate some data.
11499     *
11500     *  rINST holds object
11501     */
11502.LOP_CHECK_CAST_JUMBO_resolve:
11503    movl    rSELF,%ecx
11504    EXPORT_PC
11505    movl    2(rPC),%eax                # eax<- AAAAAAAA
11506    movl    offThread_method(%ecx),%ecx  # ecx<- self->method
11507    movl    %eax,OUT_ARG1(%esp)        # arg1<- AAAAAAAA
11508    movl    offMethod_clazz(%ecx),%ecx # ecx<- metho->clazz
11509    movl    $0,OUT_ARG2(%esp)         # arg2<- false
11510    movl    %ecx,OUT_ARG0(%esp)        # arg0<- method->clazz
11511    call    dvmResolveClass            # eax<- resolved ClassObject ptr
11512    testl   %eax,%eax                  # got null?
11513    je      common_exceptionThrown     # yes, handle exception
11514    movl    offObject_clazz(rINST),%ecx  # ecx<- obj->clazz
11515    jmp     .LOP_CHECK_CAST_JUMBO_resolved       # pick up where we left off
11516
11517/* continuation for OP_INSTANCE_OF_JUMBO */
11518
11519    /*
11520     * Trivial test failed, need to perform full check.  This is common.
11521     *  eax holds obj->clazz
11522     *  ecx holds class resolved from BBBB
11523     *  rINST has BA
11524     */
11525.LOP_INSTANCE_OF_JUMBO_fullcheck:
11526    movl    %eax,OUT_ARG0(%esp)
11527    movl    %ecx,OUT_ARG1(%esp)
11528    call    dvmInstanceofNonTrivial     # eax<- boolean result
11529    # fall through to OP_INSTANCE_OF_JUMBO_store
11530
11531    /*
11532     * eax holds boolean result
11533     * rINST holds BBBB
11534     */
11535.LOP_INSTANCE_OF_JUMBO_store:
11536    FETCH_INST_OPCODE 5 %edx
11537    ADVANCE_PC 5
11538    SET_VREG %eax rINST                 # vBBBB<- eax
11539    GOTO_NEXT_R %edx
11540
11541    /*
11542     * Trivial test succeeded, save and bail.
11543     *  r9 holds BBBB
11544     */
11545.LOP_INSTANCE_OF_JUMBO_trivial:
11546    FETCH_INST_OPCODE 5 %edx
11547    ADVANCE_PC 5
11548    movl    $1,%eax
11549    SET_VREG %eax rINST                 # vBBBB<- true
11550    GOTO_NEXT_R %edx
11551
11552    /*
11553     * Resolution required.  This is the least-likely path.
11554     *
11555     *  edx holds AAAAAAAA
11556     */
11557.LOP_INSTANCE_OF_JUMBO_resolve:
11558    movl    %edx,OUT_ARG1(%esp)         # arg1<- AAAAAAAA
11559    movl    rSELF,%ecx
11560    movl    offThread_method(%ecx),%ecx
11561    movl    $1,OUT_ARG2(%esp)          # arg2<- true
11562    movl    offMethod_clazz(%ecx),%ecx  # ecx<- method->clazz
11563    EXPORT_PC
11564    movl    %ecx,OUT_ARG0(%esp)         # arg0<- method->clazz
11565    call    dvmResolveClass             # eax<- resolved ClassObject ptr
11566    testl   %eax,%eax                   # success?
11567    je      common_exceptionThrown      # no, handle exception
11568/* Now, we need to sync up with fast path.  We need eax to
11569 * hold the obj->clazz, and ecx to hold the resolved class
11570 */
11571    movl    %eax,%ecx                   # ecx<- resolved class
11572    movzwl  8(rPC),%eax                 # eax<- CCCC
11573    GET_VREG_R %eax %eax                # eax<- vCCCC (obj)
11574    movl    offObject_clazz(%eax),%eax  # eax<- obj->clazz
11575    jmp     .LOP_INSTANCE_OF_JUMBO_resolved
11576
11577/* continuation for OP_NEW_INSTANCE_JUMBO */
11578
11579.LOP_NEW_INSTANCE_JUMBO_initialized:  # on entry, ecx<- class
11580    /* TODO: remove test for interface/abstract, now done in verifier */
11581    testl     $(ACC_INTERFACE|ACC_ABSTRACT),offClassObject_accessFlags(%ecx)
11582    movl      $ALLOC_DONT_TRACK,OUT_ARG1(%esp)
11583    jne       .LOP_NEW_INSTANCE_JUMBO_abstract
11584.LOP_NEW_INSTANCE_JUMBO_finish: # ecx=class
11585    movl     %ecx,OUT_ARG0(%esp)
11586    call     dvmAllocObject             # eax<- new object
11587    FETCH_INST_OPCODE 4 %edx
11588    testl    %eax,%eax                  # success?
11589    je       common_exceptionThrown     # no, bail out
11590    SET_VREG %eax rINST
11591    ADVANCE_PC 4
11592    GOTO_NEXT_R %edx
11593
11594    /*
11595     * Class initialization required.
11596     *
11597     *  ecx holds class object
11598     */
11599.LOP_NEW_INSTANCE_JUMBO_needinit:
11600    SPILL_TMP1(%ecx)                    # save object
11601    movl    %ecx,OUT_ARG0(%esp)
11602    call    dvmInitClass                # initialize class
11603    UNSPILL_TMP1(%ecx)                  # restore object
11604    testl   %eax,%eax                   # success?
11605    jne     .LOP_NEW_INSTANCE_JUMBO_initialized     # success, continue
11606    jmp     common_exceptionThrown      # go deal with init exception
11607
11608    /*
11609     * Resolution required.  This is the least-likely path.
11610     *
11611     */
11612.LOP_NEW_INSTANCE_JUMBO_resolve:
11613    movl    rSELF,%ecx
11614    movl    2(rPC),%eax                 # eax<- AAAAAAAA
11615    movl    offThread_method(%ecx),%ecx   # ecx<- self->method
11616    movl    %eax,OUT_ARG1(%esp)
11617    movl    offMethod_clazz(%ecx),%ecx  # ecx<- method->clazz
11618    movl    $0,OUT_ARG2(%esp)
11619    movl    %ecx,OUT_ARG0(%esp)
11620    call    dvmResolveClass             # call(clazz,off,flags)
11621    movl    %eax,%ecx                   # ecx<- resolved ClassObject ptr
11622    testl   %ecx,%ecx                   # success?
11623    jne     .LOP_NEW_INSTANCE_JUMBO_resolved        # good to go
11624    jmp     common_exceptionThrown      # no, handle exception
11625
11626    /*
11627     * TODO: remove this
11628     * We can't instantiate an abstract class or interface, so throw an
11629     * InstantiationError with the class descriptor as the message.
11630     *
11631     *  ecx holds class object
11632     */
11633.LOP_NEW_INSTANCE_JUMBO_abstract:
11634    movl    offClassObject_descriptor(%ecx),%eax
11635    movl    $.LstrInstantiationError,OUT_ARG0(%esp)
11636    movl    %eax,OUT_ARG1(%esp)
11637    call    dvmThrowExceptionWithClassMessage
11638    jmp     common_exceptionThrown
11639
11640/* continuation for OP_NEW_ARRAY_JUMBO */
11641
11642    /*
11643     * Resolve class.  (This is an uncommon case.)
11644     *  ecx holds class (null here)
11645     *  eax holds array length (vCCCC)
11646     */
11647.LOP_NEW_ARRAY_JUMBO_resolve:
11648    movl    rSELF,%ecx
11649    SPILL_TMP1(%eax)                   # save array length
11650    movl    offThread_method(%ecx),%ecx  # ecx<- self->method
11651    movl    2(rPC),%eax                # eax<- AAAAAAAA
11652    movl    offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
11653    movl    %eax,OUT_ARG1(%esp)
11654    movl    $0,OUT_ARG2(%esp)
11655    movl    %ecx,OUT_ARG0(%esp)
11656    call    dvmResolveClass            # eax<- call(clazz,ref,flag)
11657    movl    %eax,%ecx
11658    UNSPILL_TMP1(%eax)
11659    testl   %ecx,%ecx                  # successful resolution?
11660    je      common_exceptionThrown     # no, bail.
11661# fall through to OP_NEW_ARRAY_JUMBO_finish
11662
11663    /*
11664     * Finish allocation
11665     *
11666     * ecx holds class
11667     * eax holds array length (vCCCC)
11668     */
11669.LOP_NEW_ARRAY_JUMBO_finish:
11670    movl    %ecx,OUT_ARG0(%esp)
11671    movl    %eax,OUT_ARG1(%esp)
11672    movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)
11673    call    dvmAllocArrayByClass    # eax<- call(clazz,length,flags)
11674    FETCH_INST_OPCODE 5 %edx
11675    testl   %eax,%eax               # failed?
11676    je      common_exceptionThrown  # yup - go handle
11677    SET_VREG %eax rINST
11678    ADVANCE_PC 5
11679    GOTO_NEXT_R %edx
11680
11681/* continuation for OP_FILLED_NEW_ARRAY_JUMBO */
11682
11683.LOP_FILLED_NEW_ARRAY_JUMBO_more:
11684    movl    offMethod_clazz(%eax),%eax        # eax<- method->clazz
11685    movl    %eax,OUT_ARG0(%esp)               # arg0<- clazz
11686    call    dvmResolveClass                   # eax<- call(clazz,ref,flag)
11687    testl   %eax,%eax                         # null?
11688    je      common_exceptionThrown            # yes, handle it
11689
11690       # note: fall through to .LOP_FILLED_NEW_ARRAY_JUMBO_continue
11691
11692    /*
11693     * On entry:
11694     *    eax holds array class [r0]
11695     *    ecx is scratch
11696     */
11697.LOP_FILLED_NEW_ARRAY_JUMBO_continue:
11698    movl    offClassObject_descriptor(%eax),%ecx  # ecx<- arrayClass->descriptor
11699    movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)     # arg2<- flags
11700    movzbl  1(%ecx),%ecx                          # ecx<- descriptor[1]
11701    movl    %eax,OUT_ARG0(%esp)                   # arg0<- arrayClass
11702    movl    rSELF,%eax
11703    cmpb    $'I',%cl                             # supported?
11704    je      1f
11705    cmpb    $'L',%cl
11706    je      1f
11707    cmpb    $'[',%cl
11708    jne      .LOP_FILLED_NEW_ARRAY_JUMBO_notimpl                  # no, not handled yet
117091:
11710    movl    %ecx,offThread_retval+4(%eax)           # save type
11711    movl    rINST,OUT_ARG1(%esp)                  # arg1<- BBBB (length)
11712    call    dvmAllocArrayByClass     # eax<- call(arrayClass, length, flags)
11713    movl    rSELF,%ecx
11714    testl   %eax,%eax                             # alloc successful?
11715    je      common_exceptionThrown                # no, handle exception
11716    movl    %eax,offThread_retval(%ecx)             # retval.l<- new array
11717    movzwl  8(rPC),%ecx                           # ecx<- CCCC
11718    leal    offArrayObject_contents(%eax),%eax    # eax<- newArray->contents
11719
11720/* at this point:
11721 *     eax is pointer to tgt
11722 *     rINST is length
11723 *     ecx is CCCC
11724 *  We now need to copy values from registers into the array
11725 */
11726
11727    # set up src pointer
11728    SPILL_TMP2(%esi)
11729    SPILL_TMP3(%edi)
11730    leal    (rFP,%ecx,4),%esi # set up src ptr
11731    movl    %eax,%edi         # set up dst ptr
11732    movl    rINST,%ecx        # load count register
11733    rep
11734    movsd
11735    UNSPILL_TMP2(%esi)
11736    UNSPILL_TMP3(%edi)
11737    movl    rSELF,%ecx
11738    movl    offThread_retval+4(%ecx),%eax      # eax<- type
11739    FETCH_INST_OPCODE 5 %edx
11740
11741    cmpb    $'I',%al                        # Int array?
11742    je      5f                               # skip card mark if so
11743    movl    offThread_retval(%ecx),%eax        # eax<- object head
11744    movl    offThread_cardTable(%ecx),%ecx     # card table base
11745    shrl    $GC_CARD_SHIFT,%eax             # convert to card num
11746    movb    %cl,(%ecx,%eax)                  # mark card based on object head
117475:
11748    ADVANCE_PC 5
11749    GOTO_NEXT_R %edx
11750
11751
11752    /*
11753     * Throw an exception indicating that we have not implemented this
11754     * mode of filled-new-array.
11755     */
11756.LOP_FILLED_NEW_ARRAY_JUMBO_notimpl:
11757    movl    $.LstrInternalErrorA,%eax
11758    movl    %eax,OUT_ARG0(%esp)
11759    movl    $.LstrFilledNewArrayNotImplA,%eax
11760    movl    %eax,OUT_ARG1(%esp)
11761    call    dvmThrowException
11762    jmp     common_exceptionThrown
11763
11764/* continuation for OP_IGET_JUMBO */
11765
11766
11767.LOP_IGET_JUMBO_resolve:
11768    EXPORT_PC
11769    movl    offThread_method(%edx),%edx           # edx<- current method
11770    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11771    SPILL_TMP1(%ecx)                            # save obj pointer across call
11772    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
11773    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11774    UNSPILL_TMP1(%ecx)
11775    testl   %eax,%eax                           #  returns InstrField ptr
11776    jne     .LOP_IGET_JUMBO_finish
11777    jmp     common_exceptionThrown
11778
11779.LOP_IGET_JUMBO_finish:
11780    /*
11781     * Currently:
11782     *   eax holds resolved field
11783     *   ecx holds object
11784     *   rINST holds BBBB
11785     */
11786    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11787    testl   %ecx,%ecx                           # object null?
11788    je      common_errNullObject                # object was null
11789    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
11790    movl    rINST,%eax                          # eax<- BBBB
11791    FETCH_INST_OPCODE 5 %edx
11792    SET_VREG %ecx %eax
11793    ADVANCE_PC 5
11794    GOTO_NEXT_R %edx
11795
11796/* continuation for OP_IGET_WIDE_JUMBO */
11797
11798
11799.LOP_IGET_WIDE_JUMBO_resolve:
11800    EXPORT_PC
11801    movl    offThread_method(%edx),%edx           # edx<- current method
11802    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11803    SPILL_TMP1(%ecx)                            # save objpointer across call
11804    movl    rPC,OUT_ARG0(%esp)                  # pass in method->clazz
11805    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11806    UNSPILL_TMP1(%ecx)
11807    testl   %eax,%eax                           # returns InstrField ptr
11808    jne     .LOP_IGET_WIDE_JUMBO_finish
11809    jmp     common_exceptionThrown
11810
11811.LOP_IGET_WIDE_JUMBO_finish:
11812    /*
11813     * Currently:
11814     *   eax holds resolved field
11815     *   ecx holds object
11816     *   rINST holds BBBB
11817     */
11818    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11819    testl   %ecx,%ecx                           # object null?
11820    je      common_errNullObject                # object was null
11821    leal    (%ecx,%eax,1),%eax                  # eax<- address of field
11822    movl    (%eax),%ecx                         # ecx<- lsw
11823    movl    4(%eax),%eax                        # eax<- msw
11824    FETCH_INST_OPCODE 5 %edx
11825    SET_VREG_WORD %ecx rINST 0
11826    SET_VREG_WORD %eax rINST 1
11827    ADVANCE_PC 5
11828    GOTO_NEXT_R %edx
11829
11830/* continuation for OP_IGET_OBJECT_JUMBO */
11831
11832
11833.LOP_IGET_OBJECT_JUMBO_resolve:
11834    EXPORT_PC
11835    movl    offThread_method(%edx),%edx           # edx<- current method
11836    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11837    SPILL_TMP1(%ecx)                            # save obj pointer across call
11838    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
11839    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11840    UNSPILL_TMP1(%ecx)
11841    testl   %eax,%eax                           #  returns InstrField ptr
11842    jne     .LOP_IGET_OBJECT_JUMBO_finish
11843    jmp     common_exceptionThrown
11844
11845.LOP_IGET_OBJECT_JUMBO_finish:
11846    /*
11847     * Currently:
11848     *   eax holds resolved field
11849     *   ecx holds object
11850     *   rINST holds BBBB
11851     */
11852    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11853    testl   %ecx,%ecx                           # object null?
11854    je      common_errNullObject                # object was null
11855    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
11856    movl    rINST,%eax                          # eax<- BBBB
11857    FETCH_INST_OPCODE 5 %edx
11858    SET_VREG %ecx %eax
11859    ADVANCE_PC 5
11860    GOTO_NEXT_R %edx
11861
11862/* continuation for OP_IGET_BOOLEAN_JUMBO */
11863
11864
11865.LOP_IGET_BOOLEAN_JUMBO_resolve:
11866    EXPORT_PC
11867    movl    offThread_method(%edx),%edx           # edx<- current method
11868    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11869    SPILL_TMP1(%ecx)                            # save obj pointer across call
11870    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
11871    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11872    UNSPILL_TMP1(%ecx)
11873    testl   %eax,%eax                           #  returns InstrField ptr
11874    jne     .LOP_IGET_BOOLEAN_JUMBO_finish
11875    jmp     common_exceptionThrown
11876
11877.LOP_IGET_BOOLEAN_JUMBO_finish:
11878    /*
11879     * Currently:
11880     *   eax holds resolved field
11881     *   ecx holds object
11882     *   rINST holds BBBB
11883     */
11884    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11885    testl   %ecx,%ecx                           # object null?
11886    je      common_errNullObject                # object was null
11887    movzbl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
11888    movl    rINST,%eax                          # eax<- BBBB
11889    FETCH_INST_OPCODE 5 %edx
11890    SET_VREG %ecx %eax
11891    ADVANCE_PC 5
11892    GOTO_NEXT_R %edx
11893
11894/* continuation for OP_IGET_BYTE_JUMBO */
11895
11896
11897.LOP_IGET_BYTE_JUMBO_resolve:
11898    EXPORT_PC
11899    movl    offThread_method(%edx),%edx           # edx<- current method
11900    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11901    SPILL_TMP1(%ecx)                            # save obj pointer across call
11902    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
11903    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11904    UNSPILL_TMP1(%ecx)
11905    testl   %eax,%eax                           #  returns InstrField ptr
11906    jne     .LOP_IGET_BYTE_JUMBO_finish
11907    jmp     common_exceptionThrown
11908
11909.LOP_IGET_BYTE_JUMBO_finish:
11910    /*
11911     * Currently:
11912     *   eax holds resolved field
11913     *   ecx holds object
11914     *   rINST holds BBBB
11915     */
11916    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11917    testl   %ecx,%ecx                           # object null?
11918    je      common_errNullObject                # object was null
11919    movsbl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
11920    movl    rINST,%eax                          # eax<- BBBB
11921    FETCH_INST_OPCODE 5 %edx
11922    SET_VREG %ecx %eax
11923    ADVANCE_PC 5
11924    GOTO_NEXT_R %edx
11925
11926/* continuation for OP_IGET_CHAR_JUMBO */
11927
11928
11929.LOP_IGET_CHAR_JUMBO_resolve:
11930    EXPORT_PC
11931    movl    offThread_method(%edx),%edx           # edx<- current method
11932    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11933    SPILL_TMP1(%ecx)                            # save obj pointer across call
11934    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
11935    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11936    UNSPILL_TMP1(%ecx)
11937    testl   %eax,%eax                           #  returns InstrField ptr
11938    jne     .LOP_IGET_CHAR_JUMBO_finish
11939    jmp     common_exceptionThrown
11940
11941.LOP_IGET_CHAR_JUMBO_finish:
11942    /*
11943     * Currently:
11944     *   eax holds resolved field
11945     *   ecx holds object
11946     *   rINST holds BBBB
11947     */
11948    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11949    testl   %ecx,%ecx                           # object null?
11950    je      common_errNullObject                # object was null
11951    movzwl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
11952    movl    rINST,%eax                          # eax<- BBBB
11953    FETCH_INST_OPCODE 5 %edx
11954    SET_VREG %ecx %eax
11955    ADVANCE_PC 5
11956    GOTO_NEXT_R %edx
11957
11958/* continuation for OP_IGET_SHORT_JUMBO */
11959
11960
11961.LOP_IGET_SHORT_JUMBO_resolve:
11962    EXPORT_PC
11963    movl    offThread_method(%edx),%edx           # edx<- current method
11964    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11965    SPILL_TMP1(%ecx)                            # save obj pointer across call
11966    movl    %edx,OUT_ARG0(%esp)                  # pass in method->clazz
11967    call    dvmResolveInstField                 #  ... to dvmResolveInstField
11968    UNSPILL_TMP1(%ecx)
11969    testl   %eax,%eax                           #  returns InstrField ptr
11970    jne     .LOP_IGET_SHORT_JUMBO_finish
11971    jmp     common_exceptionThrown
11972
11973.LOP_IGET_SHORT_JUMBO_finish:
11974    /*
11975     * Currently:
11976     *   eax holds resolved field
11977     *   ecx holds object
11978     *   rINST holds BBBB
11979     */
11980    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
11981    testl   %ecx,%ecx                           # object null?
11982    je      common_errNullObject                # object was null
11983    movswl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
11984    movl    rINST,%eax                          # eax<- BBBB
11985    FETCH_INST_OPCODE 5 %edx
11986    SET_VREG %ecx %eax
11987    ADVANCE_PC 5
11988    GOTO_NEXT_R %edx
11989
11990/* continuation for OP_IPUT_JUMBO */
11991
11992
11993.LOP_IPUT_JUMBO_resolve:
11994    EXPORT_PC
11995    movl    offThread_method(%edx),%edx           # edx<- current method
11996    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
11997    SPILL_TMP1(%ecx)                            # save obj pointer across call
11998    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
11999    call    dvmResolveInstField                 #  ... to dvmResolveInstField
12000    UNSPILL_TMP1(%ecx)
12001    testl   %eax,%eax                           # returns InstrField ptr
12002    jne     .LOP_IPUT_JUMBO_finish
12003    jmp     common_exceptionThrown
12004
12005.LOP_IPUT_JUMBO_finish:
12006    /*
12007     * Currently:
12008     *   eax holds resolved field
12009     *   ecx holds object
12010     *   rINST holds BBBB
12011     */
12012    GET_VREG_R rINST rINST                       # rINST<- v[BBBB]
12013    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
12014    testl   %ecx,%ecx                            # object null?
12015    je      common_errNullObject                 # object was null
12016    FETCH_INST_OPCODE 5 %edx
12017    movl   rINST,(%ecx,%eax,1)            # obj.field <- v[BBBB](8/16/32 bits)
12018    ADVANCE_PC 5
12019    GOTO_NEXT_R %edx
12020
12021/* continuation for OP_IPUT_WIDE_JUMBO */
12022
12023
12024.LOP_IPUT_WIDE_JUMBO_resolve:
12025    EXPORT_PC
12026    movl    offThread_method(%edx),%edx           # edx<- current method
12027    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
12028    SPILL_TMP1(%ecx)                            # save obj pointer across call
12029    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
12030    call    dvmResolveInstField                 #  ... to dvmResolveInstField
12031    UNSPILL_TMP1(%ecx)
12032    testl   %eax,%eax                           #  ... which returns InstrField ptr
12033    jne     .LOP_IPUT_WIDE_JUMBO_finish
12034    jmp     common_exceptionThrown
12035
12036.LOP_IPUT_WIDE_JUMBO_finish:
12037    /*
12038     * Currently:
12039     *   eax holds resolved field
12040     *   ecx holds object
12041     *   %edx is scratch, but needs to be unspilled
12042     *   rINST holds BBBB
12043     */
12044    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
12045    testl   %ecx,%ecx                           # object null?
12046    je      common_errNullObject                # object was null
12047    leal    (%ecx,%eax,1),%eax                  # eax<- address of field
12048    GET_VREG_WORD %ecx rINST 0                  # ecx<- lsw
12049    GET_VREG_WORD rINST rINST 1                 # rINST<- msw
12050    FETCH_INST_OPCODE 5 %edx
12051    movl    rINST,4(%eax)
12052    movl    %ecx,(%eax)
12053    ADVANCE_PC 5
12054    GOTO_NEXT_R %edx
12055
12056/* continuation for OP_IPUT_OBJECT_JUMBO */
12057
12058
12059.LOP_IPUT_OBJECT_JUMBO_resolve:
12060    EXPORT_PC
12061    movl    offThread_method(%edx),%edx           # edx<- current method
12062    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
12063    SPILL_TMP1(%ecx)                            # save obj pointer across call
12064    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
12065    call    dvmResolveInstField                 #  ... to dvmResolveInstField
12066    UNSPILL_TMP1(%ecx)
12067    testl   %eax,%eax                           # returns InstrField ptr
12068    jne     .LOP_IPUT_OBJECT_JUMBO_finish
12069    jmp     common_exceptionThrown
12070
12071.LOP_IPUT_OBJECT_JUMBO_finish:
12072    /*
12073     * Currently:
12074     *   eax holds resolved field
12075     *   ecx holds object
12076     *   %edx is scratch, but needs to be unspilled
12077     *   rINST holds BBBB
12078     */
12079    GET_VREG_R rINST rINST                      # rINST<- v[BBBB]
12080    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
12081    testl   %ecx,%ecx                           # object null?
12082    je      common_errNullObject                # object was null
12083    movl    rINST,(%ecx,%eax)      # obj.field <- v[BBBB](8/16/32 bits)
12084    movl    rSELF,%eax
12085    testl   rINST,rINST                         # stored a NULL?
12086    movl    offThread_cardTable(%eax),%eax        # get card table base
12087    FETCH_INST_OPCODE 5 %edx
12088    je      1f                                  # skip card mark if null store
12089    shrl    $GC_CARD_SHIFT,%ecx                # object head to card number
12090    movb    %al,(%eax,%ecx)                     # mark card using object head
120911:
12092    ADVANCE_PC 5
12093    GOTO_NEXT_R %edx
12094
12095/* continuation for OP_IPUT_BOOLEAN_JUMBO */
12096
12097
12098.LOP_IPUT_BOOLEAN_JUMBO_resolve:
12099    EXPORT_PC
12100    movl    offThread_method(%edx),%edx           # edx<- current method
12101    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
12102    SPILL_TMP1(%ecx)                            # save obj pointer across call
12103    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
12104    call    dvmResolveInstField                 #  ... to dvmResolveInstField
12105    UNSPILL_TMP1(%ecx)
12106    testl   %eax,%eax                           # returns InstrField ptr
12107    jne     .LOP_IPUT_BOOLEAN_JUMBO_finish
12108    jmp     common_exceptionThrown
12109
12110.LOP_IPUT_BOOLEAN_JUMBO_finish:
12111    /*
12112     * Currently:
12113     *   eax holds resolved field
12114     *   ecx holds object
12115     *   rINST holds BBBB
12116     */
12117    GET_VREG_R rINST rINST                       # rINST<- v[BBBB]
12118    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
12119    testl   %ecx,%ecx                            # object null?
12120    je      common_errNullObject                 # object was null
12121    FETCH_INST_OPCODE 5 %edx
12122    movb   rINSTbl,(%ecx,%eax,1)            # obj.field <- v[BBBB](8/16/32 bits)
12123    ADVANCE_PC 5
12124    GOTO_NEXT_R %edx
12125
12126/* continuation for OP_IPUT_BYTE_JUMBO */
12127
12128
12129.LOP_IPUT_BYTE_JUMBO_resolve:
12130    EXPORT_PC
12131    movl    offThread_method(%edx),%edx           # edx<- current method
12132    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
12133    SPILL_TMP1(%ecx)                            # save obj pointer across call
12134    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
12135    call    dvmResolveInstField                 #  ... to dvmResolveInstField
12136    UNSPILL_TMP1(%ecx)
12137    testl   %eax,%eax                           # returns InstrField ptr
12138    jne     .LOP_IPUT_BYTE_JUMBO_finish
12139    jmp     common_exceptionThrown
12140
12141.LOP_IPUT_BYTE_JUMBO_finish:
12142    /*
12143     * Currently:
12144     *   eax holds resolved field
12145     *   ecx holds object
12146     *   rINST holds BBBB
12147     */
12148    GET_VREG_R rINST rINST                       # rINST<- v[BBBB]
12149    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
12150    testl   %ecx,%ecx                            # object null?
12151    je      common_errNullObject                 # object was null
12152    FETCH_INST_OPCODE 5 %edx
12153    movb   rINSTbl,(%ecx,%eax,1)            # obj.field <- v[BBBB](8/16/32 bits)
12154    ADVANCE_PC 5
12155    GOTO_NEXT_R %edx
12156
12157/* continuation for OP_IPUT_CHAR_JUMBO */
12158
12159
12160.LOP_IPUT_CHAR_JUMBO_resolve:
12161    EXPORT_PC
12162    movl    offThread_method(%edx),%edx           # edx<- current method
12163    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
12164    SPILL_TMP1(%ecx)                            # save obj pointer across call
12165    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
12166    call    dvmResolveInstField                 #  ... to dvmResolveInstField
12167    UNSPILL_TMP1(%ecx)
12168    testl   %eax,%eax                           # returns InstrField ptr
12169    jne     .LOP_IPUT_CHAR_JUMBO_finish
12170    jmp     common_exceptionThrown
12171
12172.LOP_IPUT_CHAR_JUMBO_finish:
12173    /*
12174     * Currently:
12175     *   eax holds resolved field
12176     *   ecx holds object
12177     *   rINST holds BBBB
12178     */
12179    GET_VREG_R rINST rINST                       # rINST<- v[BBBB]
12180    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
12181    testl   %ecx,%ecx                            # object null?
12182    je      common_errNullObject                 # object was null
12183    FETCH_INST_OPCODE 5 %edx
12184    movw   rINSTw,(%ecx,%eax,1)            # obj.field <- v[BBBB](8/16/32 bits)
12185    ADVANCE_PC 5
12186    GOTO_NEXT_R %edx
12187
12188/* continuation for OP_IPUT_SHORT_JUMBO */
12189
12190
12191.LOP_IPUT_SHORT_JUMBO_resolve:
12192    EXPORT_PC
12193    movl    offThread_method(%edx),%edx           # edx<- current method
12194    movl    offMethod_clazz(%edx),%edx          # edx<- method->clazz
12195    SPILL_TMP1(%ecx)                            # save obj pointer across call
12196    movl    %edx,OUT_ARG0(%esp)                 # pass in method->clazz
12197    call    dvmResolveInstField                 #  ... to dvmResolveInstField
12198    UNSPILL_TMP1(%ecx)
12199    testl   %eax,%eax                           # returns InstrField ptr
12200    jne     .LOP_IPUT_SHORT_JUMBO_finish
12201    jmp     common_exceptionThrown
12202
12203.LOP_IPUT_SHORT_JUMBO_finish:
12204    /*
12205     * Currently:
12206     *   eax holds resolved field
12207     *   ecx holds object
12208     *   rINST holds BBBB
12209     */
12210    GET_VREG_R rINST rINST                       # rINST<- v[BBBB]
12211    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
12212    testl   %ecx,%ecx                            # object null?
12213    je      common_errNullObject                 # object was null
12214    FETCH_INST_OPCODE 5 %edx
12215    movw   rINSTw,(%ecx,%eax,1)            # obj.field <- v[BBBB](8/16/32 bits)
12216    ADVANCE_PC 5
12217    GOTO_NEXT_R %edx
12218
12219/* continuation for OP_SGET_JUMBO */
12220
12221    /*
12222     * Go resolve the field
12223     */
12224.LOP_SGET_JUMBO_resolve:
12225    movl     rSELF,%ecx
12226    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12227    movl     offThread_method(%ecx),%ecx          # ecx<- current method
12228    EXPORT_PC                                   # could throw, need to export
12229    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12230    movl     %eax,OUT_ARG1(%esp)
12231    movl     %ecx,OUT_ARG0(%esp)
12232    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12233    testl    %eax,%eax
12234    jne      .LOP_SGET_JUMBO_finish                 # success, continue
12235    jmp      common_exceptionThrown             # no, handle exception
12236
12237/* continuation for OP_SGET_WIDE_JUMBO */
12238
12239    /*
12240     * Go resolve the field
12241     */
12242.LOP_SGET_WIDE_JUMBO_resolve:
12243    movl     rSELF,%ecx
12244    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12245    movl     offThread_method(%ecx),%ecx          # ecx<- current method
12246    EXPORT_PC                                   # could throw, need to export
12247    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12248    movl     %eax,OUT_ARG1(%esp)
12249    movl     %ecx,OUT_ARG0(%esp)
12250    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12251    testl    %eax,%eax
12252    jne      .LOP_SGET_WIDE_JUMBO_finish                 # success, continue
12253    jmp      common_exceptionThrown             # no, handle exception
12254
12255/* continuation for OP_SGET_OBJECT_JUMBO */
12256
12257    /*
12258     * Go resolve the field
12259     */
12260.LOP_SGET_OBJECT_JUMBO_resolve:
12261    movl     rSELF,%ecx
12262    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12263    movl     offThread_method(%ecx),%ecx          # ecx<- current method
12264    EXPORT_PC                                   # could throw, need to export
12265    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12266    movl     %eax,OUT_ARG1(%esp)
12267    movl     %ecx,OUT_ARG0(%esp)
12268    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12269    testl    %eax,%eax
12270    jne      .LOP_SGET_OBJECT_JUMBO_finish                 # success, continue
12271    jmp      common_exceptionThrown             # no, handle exception
12272
12273/* continuation for OP_SGET_BOOLEAN_JUMBO */
12274
12275    /*
12276     * Go resolve the field
12277     */
12278.LOP_SGET_BOOLEAN_JUMBO_resolve:
12279    movl     rSELF,%ecx
12280    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12281    movl     offThread_method(%ecx),%ecx          # ecx<- current method
12282    EXPORT_PC                                   # could throw, need to export
12283    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12284    movl     %eax,OUT_ARG1(%esp)
12285    movl     %ecx,OUT_ARG0(%esp)
12286    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12287    testl    %eax,%eax
12288    jne      .LOP_SGET_BOOLEAN_JUMBO_finish                 # success, continue
12289    jmp      common_exceptionThrown             # no, handle exception
12290
12291/* continuation for OP_SGET_BYTE_JUMBO */
12292
12293    /*
12294     * Go resolve the field
12295     */
12296.LOP_SGET_BYTE_JUMBO_resolve:
12297    movl     rSELF,%ecx
12298    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12299    movl     offThread_method(%ecx),%ecx          # ecx<- current method
12300    EXPORT_PC                                   # could throw, need to export
12301    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12302    movl     %eax,OUT_ARG1(%esp)
12303    movl     %ecx,OUT_ARG0(%esp)
12304    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12305    testl    %eax,%eax
12306    jne      .LOP_SGET_BYTE_JUMBO_finish                 # success, continue
12307    jmp      common_exceptionThrown             # no, handle exception
12308
12309/* continuation for OP_SGET_CHAR_JUMBO */
12310
12311    /*
12312     * Go resolve the field
12313     */
12314.LOP_SGET_CHAR_JUMBO_resolve:
12315    movl     rSELF,%ecx
12316    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12317    movl     offThread_method(%ecx),%ecx          # ecx<- current method
12318    EXPORT_PC                                   # could throw, need to export
12319    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12320    movl     %eax,OUT_ARG1(%esp)
12321    movl     %ecx,OUT_ARG0(%esp)
12322    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12323    testl    %eax,%eax
12324    jne      .LOP_SGET_CHAR_JUMBO_finish                 # success, continue
12325    jmp      common_exceptionThrown             # no, handle exception
12326
12327/* continuation for OP_SGET_SHORT_JUMBO */
12328
12329    /*
12330     * Go resolve the field
12331     */
12332.LOP_SGET_SHORT_JUMBO_resolve:
12333    movl     rSELF,%ecx
12334    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12335    movl     offThread_method(%ecx),%ecx          # ecx<- current method
12336    EXPORT_PC                                   # could throw, need to export
12337    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12338    movl     %eax,OUT_ARG1(%esp)
12339    movl     %ecx,OUT_ARG0(%esp)
12340    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12341    testl    %eax,%eax
12342    jne      .LOP_SGET_SHORT_JUMBO_finish                 # success, continue
12343    jmp      common_exceptionThrown             # no, handle exception
12344
12345/* continuation for OP_SPUT_JUMBO */
12346
12347    /*
12348     * Go resolve the field
12349     */
12350.LOP_SPUT_JUMBO_resolve:
12351    movl     rSELF,%ecx
12352    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12353    movl     offThread_method(%ecx),%ecx          # ecx<- current method
12354    EXPORT_PC                                   # could throw, need to export
12355    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12356    movl     %eax,OUT_ARG1(%esp)
12357    movl     %ecx,OUT_ARG0(%esp)
12358    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12359    testl    %eax,%eax
12360    jne      .LOP_SPUT_JUMBO_finish                 # success, continue
12361    jmp      common_exceptionThrown             # no, handle exception
12362
12363/* continuation for OP_SPUT_WIDE_JUMBO */
12364
12365    /*
12366     * Go resolve the field
12367     */
12368.LOP_SPUT_WIDE_JUMBO_resolve:
12369    movl     rSELF,%ecx
12370    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12371    movl     offThread_method(%ecx),%ecx          # ecx<- current method
12372    EXPORT_PC                                   # could throw, need to export
12373    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12374    movl     %eax,OUT_ARG1(%esp)
12375    movl     %ecx,OUT_ARG0(%esp)
12376    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12377    testl    %eax,%eax
12378    jne      .LOP_SPUT_WIDE_JUMBO_finish                 # success, continue
12379    jmp      common_exceptionThrown             # no, handle exception
12380
12381/* continuation for OP_SPUT_OBJECT_JUMBO */
12382
12383
12384.LOP_SPUT_OBJECT_JUMBO_continue:
12385    movl      %ecx,offStaticField_value(%eax)    # do the store
12386    testl     %ecx,%ecx                          # stored null object ptr?
12387    FETCH_INST_OPCODE 4 %edx
12388    je        1f                                 # skip card mark if null
12389    movl      rSELF,%ecx
12390    movl      offField_clazz(%eax),%eax          # eax<- method->clazz
12391    movl      offThread_cardTable(%ecx),%ecx       # get card table base
12392    shrl      $GC_CARD_SHIFT,%eax               # head to card number
12393    movb      %cl,(%ecx,%eax)                    # mark card
123941:
12395    ADVANCE_PC 4
12396    GOTO_NEXT_R %edx
12397
12398.LOP_SPUT_OBJECT_JUMBO_resolve:
12399    movl     rSELF,%ecx
12400    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12401    movl     offThread_method(%ecx),%ecx          # ecx<- current method
12402    EXPORT_PC                                   # could throw, need to export
12403    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12404    movl     %eax,OUT_ARG1(%esp)
12405    movl     %ecx,OUT_ARG0(%esp)
12406    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12407    testl    %eax,%eax
12408    jne      .LOP_SPUT_OBJECT_JUMBO_finish                 # success, continue
12409    jmp      common_exceptionThrown             # no, handle exception
12410
12411/* continuation for OP_SPUT_BOOLEAN_JUMBO */
12412
12413    /*
12414     * Go resolve the field
12415     */
12416.LOP_SPUT_BOOLEAN_JUMBO_resolve:
12417    movl     rSELF,%ecx
12418    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12419    movl     offThread_method(%ecx),%ecx          # ecx<- current method
12420    EXPORT_PC                                   # could throw, need to export
12421    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12422    movl     %eax,OUT_ARG1(%esp)
12423    movl     %ecx,OUT_ARG0(%esp)
12424    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12425    testl    %eax,%eax
12426    jne      .LOP_SPUT_BOOLEAN_JUMBO_finish                 # success, continue
12427    jmp      common_exceptionThrown             # no, handle exception
12428
12429/* continuation for OP_SPUT_BYTE_JUMBO */
12430
12431    /*
12432     * Go resolve the field
12433     */
12434.LOP_SPUT_BYTE_JUMBO_resolve:
12435    movl     rSELF,%ecx
12436    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12437    movl     offThread_method(%ecx),%ecx          # ecx<- current method
12438    EXPORT_PC                                   # could throw, need to export
12439    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12440    movl     %eax,OUT_ARG1(%esp)
12441    movl     %ecx,OUT_ARG0(%esp)
12442    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12443    testl    %eax,%eax
12444    jne      .LOP_SPUT_BYTE_JUMBO_finish                 # success, continue
12445    jmp      common_exceptionThrown             # no, handle exception
12446
12447/* continuation for OP_SPUT_CHAR_JUMBO */
12448
12449    /*
12450     * Go resolve the field
12451     */
12452.LOP_SPUT_CHAR_JUMBO_resolve:
12453    movl     rSELF,%ecx
12454    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12455    movl     offThread_method(%ecx),%ecx          # ecx<- current method
12456    EXPORT_PC                                   # could throw, need to export
12457    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12458    movl     %eax,OUT_ARG1(%esp)
12459    movl     %ecx,OUT_ARG0(%esp)
12460    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12461    testl    %eax,%eax
12462    jne      .LOP_SPUT_CHAR_JUMBO_finish                 # success, continue
12463    jmp      common_exceptionThrown             # no, handle exception
12464
12465/* continuation for OP_SPUT_SHORT_JUMBO */
12466
12467    /*
12468     * Go resolve the field
12469     */
12470.LOP_SPUT_SHORT_JUMBO_resolve:
12471    movl     rSELF,%ecx
12472    movl     2(rPC),%eax                        # eax<- field ref AAAAAAAA
12473    movl     offThread_method(%ecx),%ecx          # ecx<- current method
12474    EXPORT_PC                                   # could throw, need to export
12475    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
12476    movl     %eax,OUT_ARG1(%esp)
12477    movl     %ecx,OUT_ARG0(%esp)
12478    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
12479    testl    %eax,%eax
12480    jne      .LOP_SPUT_SHORT_JUMBO_finish                 # success, continue
12481    jmp      common_exceptionThrown             # no, handle exception
12482
12483/* continuation for OP_INVOKE_VIRTUAL_JUMBO */
12484
12485
12486.LOP_INVOKE_VIRTUAL_JUMBO_more:
12487    movl      offMethod_clazz(%eax),%eax  # ecx<- method->clazz
12488    movl      %eax,OUT_ARG0(%esp)         # arg0<- clazz
12489    movl      $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags
12490    call      dvmResolveMethod            # eax<- call(clazz, ref, flags)
12491    testl     %eax,%eax                   # got null?
12492    jne       .LOP_INVOKE_VIRTUAL_JUMBO_continue        # no, continue
12493    jmp       common_exceptionThrown      # yes, handle exception
12494
12495    /* At this point:
12496     *   eax = resolved base method
12497     *   ecx = scratch
12498     */
12499.LOP_INVOKE_VIRTUAL_JUMBO_continue:
12500    movzwl    8(rPC),%ecx               # ecx<- CCCC
12501    GET_VREG_R  %ecx %ecx               # ecx<- "this"
12502    movzwl    offMethod_methodIndex(%eax),%eax  # eax<- baseMethod->methodIndex
12503    testl     %ecx,%ecx                 # null this?
12504    je        common_errNullObject      # go if so
12505    movl      offObject_clazz(%ecx),%ecx  # ecx<- thisPtr->clazz
12506    movl      offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable
12507    movl      (%ecx,%eax,4),%eax        # eax<- vtable[methodIndex]
12508    jmp       common_invokeMethodJumbo
12509
12510/* continuation for OP_INVOKE_SUPER_JUMBO */
12511
12512    /*
12513     * At this point:
12514     *  ecx = resolved base method [r0]
12515     *  eax = method->clazz [r9]
12516     */
12517.LOP_INVOKE_SUPER_JUMBO_continue:
12518    movl    offClassObject_super(%eax),%eax   # eax<- method->clazz->super
12519    movzwl  offMethod_methodIndex(%ecx),%ecx  # ecx<- baseMthod->methodIndex
12520    cmpl    offClassObject_vtableCount(%eax),%ecx # compare(methodIndex,vtableCount)
12521    jae     .LOP_INVOKE_SUPER_JUMBO_nsm           # method not present in superclass
12522    movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
12523    movl    (%eax,%ecx,4),%eax        # eax<- vtable[methodIndex]
12524    jmp     common_invokeMethodJumbo
12525
12526
12527    /* At this point:
12528     * ecx = null (needs to be resolved base method)
12529     * eax = method->clazz
12530    */
12531.LOP_INVOKE_SUPER_JUMBO_resolve:
12532    SPILL_TMP1(%eax)                    # method->clazz
12533    movl    %eax,OUT_ARG0(%esp)         # arg0<- method->clazz
12534    movl    2(rPC),%ecx                 # ecx<- AAAAAAAA
12535    movl    $METHOD_VIRTUAL,OUT_ARG2(%esp)  # arg2<- resolver method type
12536    movl    %ecx,OUT_ARG1(%esp)         # arg1<- ref
12537    call    dvmResolveMethod            # eax<- call(clazz, ref, flags)
12538    testl   %eax,%eax                   # got null?
12539    movl    %eax,%ecx                   # ecx<- resolved base method
12540    UNSPILL_TMP1(%eax)                  # restore method->clazz
12541    jne     .LOP_INVOKE_SUPER_JUMBO_continue        # good to go - continue
12542    jmp     common_exceptionThrown      # handle exception
12543
12544    /*
12545     * Throw a NoSuchMethodError with the method name as the message.
12546     *  ecx = resolved base method
12547     */
12548.LOP_INVOKE_SUPER_JUMBO_nsm:
12549    movl    offMethod_name(%ecx),%eax
12550    mov     %eax,OUT_ARG1(%esp)
12551    jmp     common_errNoSuchMethod
12552
12553/* continuation for OP_INVOKE_DIRECT_JUMBO */
12554
12555    /*
12556     * On entry:
12557     *   TMP_SPILL  <- "this" register
12558     * Things a bit ugly on this path, but it's the less
12559     * frequent one.  We'll have to do some reloading.
12560     */
12561.LOP_INVOKE_DIRECT_JUMBO_resolve:
12562     SPILL_TMP1(%ecx)
12563     movl     rSELF,%ecx
12564     movl     offThread_method(%ecx),%ecx  # ecx<- self->method
12565     movl     2(rPC),%eax      # reference AAAAAAAA
12566     movl     offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
12567     movl     $METHOD_DIRECT,OUT_ARG2(%esp)
12568     movl     %eax,OUT_ARG1(%esp)
12569     movl     %ecx,OUT_ARG0(%esp)
12570     call     dvmResolveMethod # eax<- call(clazz, ref, flags)
12571     UNSPILL_TMP1(%ecx)
12572     testl    %eax,%eax
12573     jne      .LOP_INVOKE_DIRECT_JUMBO_finish
12574     jmp      common_exceptionThrown
12575
12576/* continuation for OP_INVOKE_STATIC_JUMBO */
12577
12578.LOP_INVOKE_STATIC_JUMBO_continue:
12579    movl      $METHOD_STATIC,%eax
12580    movl      %eax,OUT_ARG2(%esp)       # arg2<- flags
12581    call      dvmResolveMethod          # call(clazz,ref,flags)
12582    testl     %eax,%eax                 # got null?
12583    jne       common_invokeMethodJumbo
12584    jmp       common_exceptionThrown
12585
12586/* continuation for OP_INVOKE_INTERFACE_JUMBO */
12587
12588.LOP_INVOKE_INTERFACE_JUMBO_continue:
12589    call       dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex)
12590    testl      %eax,%eax
12591    je         common_exceptionThrown
12592    jmp        common_invokeMethodJumbo
12593
12594    .size   dvmAsmSisterStart, .-dvmAsmSisterStart
12595    .global dvmAsmSisterEnd
12596dvmAsmSisterEnd:
12597
12598/* File: x86/entry.S */
12599/*
12600 * Copyright (C) 2008 The Android Open Source Project
12601 *
12602 * Licensed under the Apache License, Version 2.0 (the "License");
12603 * you may not use this file except in compliance with the License.
12604 * You may obtain a copy of the License at
12605 *
12606 *      http://www.apache.org/licenses/LICENSE-2.0
12607 *
12608 * Unless required by applicable law or agreed to in writing, software
12609 * distributed under the License is distributed on an "AS IS" BASIS,
12610 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12611 * See the License for the specific language governing permissions and
12612 * limitations under the License.
12613 */
12614
12615
12616    .text
12617    .global dvmMterpStdRun
12618    .type   dvmMterpStdRun, %function
12619/*
12620 * bool dvmMterpStdRun(Thread* self)
12621 *
12622 * Interpreter entry point.  Returns changeInterp.
12623 *
12624 */
12625dvmMterpStdRun:
12626    movl    4(%esp), %ecx        # get incoming rSELF
12627    push    %ebp                 # save caller base pointer
12628    push    %ecx                 # save rSELF at (%ebp)
12629    movl    %esp, %ebp           # set our %ebp
12630/*
12631 * At this point we've allocated two slots on the stack
12632 * via push and stack is 8-byte aligned.  Allocate space
12633 * for 8 spill slots, 3 local slots, 5 arg slots + 2 slots for
12634 * padding to bring us to 16-byte alignment
12635 */
12636    subl    $(FRAME_SIZE-8), %esp
12637
12638/* Spill callee save regs */
12639    movl    %edi,EDI_SPILL(%ebp)
12640    movl    %esi,ESI_SPILL(%ebp)
12641    movl    %ebx,EBX_SPILL(%ebp)
12642
12643/* Set up "named" registers */
12644    movl    offThread_pc(%ecx),rPC
12645    movl    offThread_fp(%ecx),rFP
12646
12647/* Remember %esp for future "longjmp" */
12648    movl    %esp,offThread_bailPtr(%ecx)
12649
12650/* How to start? */
12651    movb    offThread_entryPoint(%ecx),%al
12652
12653/* Normal start? */
12654    cmpb    $kInterpEntryInstr,%al
12655    jne     .Lnot_instr
12656
12657   /* Normal case: start executing the instruction at rPC */
12658    FETCH_INST
12659    GOTO_NEXT
12660
12661.Lnot_instr:
12662    /* Reset to normal case */
12663    movb   $kInterpEntryInstr,offThread_entryPoint(%ecx)
12664    cmpb   $kInterpEntryReturn,%al
12665    je     common_returnFromMethod
12666    cmpb   $kInterpEntryThrow,%al
12667    je     common_exceptionThrown
12668    movzx  %al,%eax
12669    movl   %eax,OUT_ARG1(%esp)
12670    movl   $.LstrBadEntryPoint,OUT_ARG0(%esp)
12671    call   printf
12672    call   dvmAbort
12673    /* Not reached */
12674
12675
12676    .global dvmMterpStdBail
12677    .type   dvmMterpStdBail, %function
12678/*
12679 * void dvmMterpStdBail(Thread* self, bool changeInterp)
12680 *
12681 * Restore the stack pointer and PC from the save point established on entry.
12682 * This is essentially the same as a longjmp, but should be cheaper.  The
12683 * last instruction causes us to return to whoever called dvmMterpStdRun.
12684 *
12685 * We're not going to build a standard frame here, so the arg accesses will
12686 * look a little strange.
12687 *
12688 * On entry:
12689 *  esp+4 (arg0)  Thread* self
12690 *  esp+8 (arg1)  bool changeInterp
12691 */
12692dvmMterpStdBail:
12693    movl    4(%esp),%ecx                 # grab self
12694    movl    8(%esp),%eax                 # changeInterp to return reg
12695    movl    offThread_bailPtr(%ecx),%esp   # Restore "setjmp" esp
12696    movl    %esp,%ebp
12697    addl    $(FRAME_SIZE-8), %ebp       # Restore %ebp at point of setjmp
12698    movl    EDI_SPILL(%ebp),%edi
12699    movl    ESI_SPILL(%ebp),%esi
12700    movl    EBX_SPILL(%ebp),%ebx
12701    movl    PREV_FP(%ebp),%ebp           # restore caller's ebp
12702    addl    $FRAME_SIZE,%esp                    # strip frame
12703    ret                                  # return to dvmMterpStdRun's caller
12704
12705
12706/*
12707 * Strings
12708 */
12709    .section    .rodata
12710.LstrBadEntryPoint:
12711    .asciz  "Bad entry point %d\n"
12712
12713
12714/*
12715 * FIXME: Should have the config/rebuild mechanism generate this
12716 * for targets that need it.
12717 */
12718
12719/* Jump table */
12720dvmAsmInstructionJmpTable = .LdvmAsmInstructionJmpTable
12721.LdvmAsmInstructionJmpTable:
12722.long .L_OP_NOP
12723.long .L_OP_MOVE
12724.long .L_OP_MOVE_FROM16
12725.long .L_OP_MOVE_16
12726.long .L_OP_MOVE_WIDE
12727.long .L_OP_MOVE_WIDE_FROM16
12728.long .L_OP_MOVE_WIDE_16
12729.long .L_OP_MOVE_OBJECT
12730.long .L_OP_MOVE_OBJECT_FROM16
12731.long .L_OP_MOVE_OBJECT_16
12732.long .L_OP_MOVE_RESULT
12733.long .L_OP_MOVE_RESULT_WIDE
12734.long .L_OP_MOVE_RESULT_OBJECT
12735.long .L_OP_MOVE_EXCEPTION
12736.long .L_OP_RETURN_VOID
12737.long .L_OP_RETURN
12738.long .L_OP_RETURN_WIDE
12739.long .L_OP_RETURN_OBJECT
12740.long .L_OP_CONST_4
12741.long .L_OP_CONST_16
12742.long .L_OP_CONST
12743.long .L_OP_CONST_HIGH16
12744.long .L_OP_CONST_WIDE_16
12745.long .L_OP_CONST_WIDE_32
12746.long .L_OP_CONST_WIDE
12747.long .L_OP_CONST_WIDE_HIGH16
12748.long .L_OP_CONST_STRING
12749.long .L_OP_CONST_STRING_JUMBO
12750.long .L_OP_CONST_CLASS
12751.long .L_OP_MONITOR_ENTER
12752.long .L_OP_MONITOR_EXIT
12753.long .L_OP_CHECK_CAST
12754.long .L_OP_INSTANCE_OF
12755.long .L_OP_ARRAY_LENGTH
12756.long .L_OP_NEW_INSTANCE
12757.long .L_OP_NEW_ARRAY
12758.long .L_OP_FILLED_NEW_ARRAY
12759.long .L_OP_FILLED_NEW_ARRAY_RANGE
12760.long .L_OP_FILL_ARRAY_DATA
12761.long .L_OP_THROW
12762.long .L_OP_GOTO
12763.long .L_OP_GOTO_16
12764.long .L_OP_GOTO_32
12765.long .L_OP_PACKED_SWITCH
12766.long .L_OP_SPARSE_SWITCH
12767.long .L_OP_CMPL_FLOAT
12768.long .L_OP_CMPG_FLOAT
12769.long .L_OP_CMPL_DOUBLE
12770.long .L_OP_CMPG_DOUBLE
12771.long .L_OP_CMP_LONG
12772.long .L_OP_IF_EQ
12773.long .L_OP_IF_NE
12774.long .L_OP_IF_LT
12775.long .L_OP_IF_GE
12776.long .L_OP_IF_GT
12777.long .L_OP_IF_LE
12778.long .L_OP_IF_EQZ
12779.long .L_OP_IF_NEZ
12780.long .L_OP_IF_LTZ
12781.long .L_OP_IF_GEZ
12782.long .L_OP_IF_GTZ
12783.long .L_OP_IF_LEZ
12784.long .L_OP_UNUSED_3E
12785.long .L_OP_UNUSED_3F
12786.long .L_OP_UNUSED_40
12787.long .L_OP_UNUSED_41
12788.long .L_OP_UNUSED_42
12789.long .L_OP_UNUSED_43
12790.long .L_OP_AGET
12791.long .L_OP_AGET_WIDE
12792.long .L_OP_AGET_OBJECT
12793.long .L_OP_AGET_BOOLEAN
12794.long .L_OP_AGET_BYTE
12795.long .L_OP_AGET_CHAR
12796.long .L_OP_AGET_SHORT
12797.long .L_OP_APUT
12798.long .L_OP_APUT_WIDE
12799.long .L_OP_APUT_OBJECT
12800.long .L_OP_APUT_BOOLEAN
12801.long .L_OP_APUT_BYTE
12802.long .L_OP_APUT_CHAR
12803.long .L_OP_APUT_SHORT
12804.long .L_OP_IGET
12805.long .L_OP_IGET_WIDE
12806.long .L_OP_IGET_OBJECT
12807.long .L_OP_IGET_BOOLEAN
12808.long .L_OP_IGET_BYTE
12809.long .L_OP_IGET_CHAR
12810.long .L_OP_IGET_SHORT
12811.long .L_OP_IPUT
12812.long .L_OP_IPUT_WIDE
12813.long .L_OP_IPUT_OBJECT
12814.long .L_OP_IPUT_BOOLEAN
12815.long .L_OP_IPUT_BYTE
12816.long .L_OP_IPUT_CHAR
12817.long .L_OP_IPUT_SHORT
12818.long .L_OP_SGET
12819.long .L_OP_SGET_WIDE
12820.long .L_OP_SGET_OBJECT
12821.long .L_OP_SGET_BOOLEAN
12822.long .L_OP_SGET_BYTE
12823.long .L_OP_SGET_CHAR
12824.long .L_OP_SGET_SHORT
12825.long .L_OP_SPUT
12826.long .L_OP_SPUT_WIDE
12827.long .L_OP_SPUT_OBJECT
12828.long .L_OP_SPUT_BOOLEAN
12829.long .L_OP_SPUT_BYTE
12830.long .L_OP_SPUT_CHAR
12831.long .L_OP_SPUT_SHORT
12832.long .L_OP_INVOKE_VIRTUAL
12833.long .L_OP_INVOKE_SUPER
12834.long .L_OP_INVOKE_DIRECT
12835.long .L_OP_INVOKE_STATIC
12836.long .L_OP_INVOKE_INTERFACE
12837.long .L_OP_UNUSED_73
12838.long .L_OP_INVOKE_VIRTUAL_RANGE
12839.long .L_OP_INVOKE_SUPER_RANGE
12840.long .L_OP_INVOKE_DIRECT_RANGE
12841.long .L_OP_INVOKE_STATIC_RANGE
12842.long .L_OP_INVOKE_INTERFACE_RANGE
12843.long .L_OP_UNUSED_79
12844.long .L_OP_UNUSED_7A
12845.long .L_OP_NEG_INT
12846.long .L_OP_NOT_INT
12847.long .L_OP_NEG_LONG
12848.long .L_OP_NOT_LONG
12849.long .L_OP_NEG_FLOAT
12850.long .L_OP_NEG_DOUBLE
12851.long .L_OP_INT_TO_LONG
12852.long .L_OP_INT_TO_FLOAT
12853.long .L_OP_INT_TO_DOUBLE
12854.long .L_OP_LONG_TO_INT
12855.long .L_OP_LONG_TO_FLOAT
12856.long .L_OP_LONG_TO_DOUBLE
12857.long .L_OP_FLOAT_TO_INT
12858.long .L_OP_FLOAT_TO_LONG
12859.long .L_OP_FLOAT_TO_DOUBLE
12860.long .L_OP_DOUBLE_TO_INT
12861.long .L_OP_DOUBLE_TO_LONG
12862.long .L_OP_DOUBLE_TO_FLOAT
12863.long .L_OP_INT_TO_BYTE
12864.long .L_OP_INT_TO_CHAR
12865.long .L_OP_INT_TO_SHORT
12866.long .L_OP_ADD_INT
12867.long .L_OP_SUB_INT
12868.long .L_OP_MUL_INT
12869.long .L_OP_DIV_INT
12870.long .L_OP_REM_INT
12871.long .L_OP_AND_INT
12872.long .L_OP_OR_INT
12873.long .L_OP_XOR_INT
12874.long .L_OP_SHL_INT
12875.long .L_OP_SHR_INT
12876.long .L_OP_USHR_INT
12877.long .L_OP_ADD_LONG
12878.long .L_OP_SUB_LONG
12879.long .L_OP_MUL_LONG
12880.long .L_OP_DIV_LONG
12881.long .L_OP_REM_LONG
12882.long .L_OP_AND_LONG
12883.long .L_OP_OR_LONG
12884.long .L_OP_XOR_LONG
12885.long .L_OP_SHL_LONG
12886.long .L_OP_SHR_LONG
12887.long .L_OP_USHR_LONG
12888.long .L_OP_ADD_FLOAT
12889.long .L_OP_SUB_FLOAT
12890.long .L_OP_MUL_FLOAT
12891.long .L_OP_DIV_FLOAT
12892.long .L_OP_REM_FLOAT
12893.long .L_OP_ADD_DOUBLE
12894.long .L_OP_SUB_DOUBLE
12895.long .L_OP_MUL_DOUBLE
12896.long .L_OP_DIV_DOUBLE
12897.long .L_OP_REM_DOUBLE
12898.long .L_OP_ADD_INT_2ADDR
12899.long .L_OP_SUB_INT_2ADDR
12900.long .L_OP_MUL_INT_2ADDR
12901.long .L_OP_DIV_INT_2ADDR
12902.long .L_OP_REM_INT_2ADDR
12903.long .L_OP_AND_INT_2ADDR
12904.long .L_OP_OR_INT_2ADDR
12905.long .L_OP_XOR_INT_2ADDR
12906.long .L_OP_SHL_INT_2ADDR
12907.long .L_OP_SHR_INT_2ADDR
12908.long .L_OP_USHR_INT_2ADDR
12909.long .L_OP_ADD_LONG_2ADDR
12910.long .L_OP_SUB_LONG_2ADDR
12911.long .L_OP_MUL_LONG_2ADDR
12912.long .L_OP_DIV_LONG_2ADDR
12913.long .L_OP_REM_LONG_2ADDR
12914.long .L_OP_AND_LONG_2ADDR
12915.long .L_OP_OR_LONG_2ADDR
12916.long .L_OP_XOR_LONG_2ADDR
12917.long .L_OP_SHL_LONG_2ADDR
12918.long .L_OP_SHR_LONG_2ADDR
12919.long .L_OP_USHR_LONG_2ADDR
12920.long .L_OP_ADD_FLOAT_2ADDR
12921.long .L_OP_SUB_FLOAT_2ADDR
12922.long .L_OP_MUL_FLOAT_2ADDR
12923.long .L_OP_DIV_FLOAT_2ADDR
12924.long .L_OP_REM_FLOAT_2ADDR
12925.long .L_OP_ADD_DOUBLE_2ADDR
12926.long .L_OP_SUB_DOUBLE_2ADDR
12927.long .L_OP_MUL_DOUBLE_2ADDR
12928.long .L_OP_DIV_DOUBLE_2ADDR
12929.long .L_OP_REM_DOUBLE_2ADDR
12930.long .L_OP_ADD_INT_LIT16
12931.long .L_OP_RSUB_INT
12932.long .L_OP_MUL_INT_LIT16
12933.long .L_OP_DIV_INT_LIT16
12934.long .L_OP_REM_INT_LIT16
12935.long .L_OP_AND_INT_LIT16
12936.long .L_OP_OR_INT_LIT16
12937.long .L_OP_XOR_INT_LIT16
12938.long .L_OP_ADD_INT_LIT8
12939.long .L_OP_RSUB_INT_LIT8
12940.long .L_OP_MUL_INT_LIT8
12941.long .L_OP_DIV_INT_LIT8
12942.long .L_OP_REM_INT_LIT8
12943.long .L_OP_AND_INT_LIT8
12944.long .L_OP_OR_INT_LIT8
12945.long .L_OP_XOR_INT_LIT8
12946.long .L_OP_SHL_INT_LIT8
12947.long .L_OP_SHR_INT_LIT8
12948.long .L_OP_USHR_INT_LIT8
12949.long .L_OP_IGET_VOLATILE
12950.long .L_OP_IPUT_VOLATILE
12951.long .L_OP_SGET_VOLATILE
12952.long .L_OP_SPUT_VOLATILE
12953.long .L_OP_IGET_OBJECT_VOLATILE
12954.long .L_OP_IGET_WIDE_VOLATILE
12955.long .L_OP_IPUT_WIDE_VOLATILE
12956.long .L_OP_SGET_WIDE_VOLATILE
12957.long .L_OP_SPUT_WIDE_VOLATILE
12958.long .L_OP_BREAKPOINT
12959.long .L_OP_THROW_VERIFICATION_ERROR
12960.long .L_OP_EXECUTE_INLINE
12961.long .L_OP_EXECUTE_INLINE_RANGE
12962.long .L_OP_INVOKE_OBJECT_INIT
12963.long .L_OP_RETURN_VOID_BARRIER
12964.long .L_OP_IGET_QUICK
12965.long .L_OP_IGET_WIDE_QUICK
12966.long .L_OP_IGET_OBJECT_QUICK
12967.long .L_OP_IPUT_QUICK
12968.long .L_OP_IPUT_WIDE_QUICK
12969.long .L_OP_IPUT_OBJECT_QUICK
12970.long .L_OP_INVOKE_VIRTUAL_QUICK
12971.long .L_OP_INVOKE_VIRTUAL_QUICK_RANGE
12972.long .L_OP_INVOKE_SUPER_QUICK
12973.long .L_OP_INVOKE_SUPER_QUICK_RANGE
12974.long .L_OP_IPUT_OBJECT_VOLATILE
12975.long .L_OP_SGET_OBJECT_VOLATILE
12976.long .L_OP_SPUT_OBJECT_VOLATILE
12977.long .L_OP_DISPATCH_FF
12978.long .L_OP_CONST_CLASS_JUMBO
12979.long .L_OP_CHECK_CAST_JUMBO
12980.long .L_OP_INSTANCE_OF_JUMBO
12981.long .L_OP_NEW_INSTANCE_JUMBO
12982.long .L_OP_NEW_ARRAY_JUMBO
12983.long .L_OP_FILLED_NEW_ARRAY_JUMBO
12984.long .L_OP_IGET_JUMBO
12985.long .L_OP_IGET_WIDE_JUMBO
12986.long .L_OP_IGET_OBJECT_JUMBO
12987.long .L_OP_IGET_BOOLEAN_JUMBO
12988.long .L_OP_IGET_BYTE_JUMBO
12989.long .L_OP_IGET_CHAR_JUMBO
12990.long .L_OP_IGET_SHORT_JUMBO
12991.long .L_OP_IPUT_JUMBO
12992.long .L_OP_IPUT_WIDE_JUMBO
12993.long .L_OP_IPUT_OBJECT_JUMBO
12994.long .L_OP_IPUT_BOOLEAN_JUMBO
12995.long .L_OP_IPUT_BYTE_JUMBO
12996.long .L_OP_IPUT_CHAR_JUMBO
12997.long .L_OP_IPUT_SHORT_JUMBO
12998.long .L_OP_SGET_JUMBO
12999.long .L_OP_SGET_WIDE_JUMBO
13000.long .L_OP_SGET_OBJECT_JUMBO
13001.long .L_OP_SGET_BOOLEAN_JUMBO
13002.long .L_OP_SGET_BYTE_JUMBO
13003.long .L_OP_SGET_CHAR_JUMBO
13004.long .L_OP_SGET_SHORT_JUMBO
13005.long .L_OP_SPUT_JUMBO
13006.long .L_OP_SPUT_WIDE_JUMBO
13007.long .L_OP_SPUT_OBJECT_JUMBO
13008.long .L_OP_SPUT_BOOLEAN_JUMBO
13009.long .L_OP_SPUT_BYTE_JUMBO
13010.long .L_OP_SPUT_CHAR_JUMBO
13011.long .L_OP_SPUT_SHORT_JUMBO
13012.long .L_OP_INVOKE_VIRTUAL_JUMBO
13013.long .L_OP_INVOKE_SUPER_JUMBO
13014.long .L_OP_INVOKE_DIRECT_JUMBO
13015.long .L_OP_INVOKE_STATIC_JUMBO
13016.long .L_OP_INVOKE_INTERFACE_JUMBO
13017.long .L_OP_UNUSED_27FF
13018.long .L_OP_UNUSED_28FF
13019.long .L_OP_UNUSED_29FF
13020.long .L_OP_UNUSED_2AFF
13021.long .L_OP_UNUSED_2BFF
13022.long .L_OP_UNUSED_2CFF
13023.long .L_OP_UNUSED_2DFF
13024.long .L_OP_UNUSED_2EFF
13025.long .L_OP_UNUSED_2FFF
13026.long .L_OP_UNUSED_30FF
13027.long .L_OP_UNUSED_31FF
13028.long .L_OP_UNUSED_32FF
13029.long .L_OP_UNUSED_33FF
13030.long .L_OP_UNUSED_34FF
13031.long .L_OP_UNUSED_35FF
13032.long .L_OP_UNUSED_36FF
13033.long .L_OP_UNUSED_37FF
13034.long .L_OP_UNUSED_38FF
13035.long .L_OP_UNUSED_39FF
13036.long .L_OP_UNUSED_3AFF
13037.long .L_OP_UNUSED_3BFF
13038.long .L_OP_UNUSED_3CFF
13039.long .L_OP_UNUSED_3DFF
13040.long .L_OP_UNUSED_3EFF
13041.long .L_OP_UNUSED_3FFF
13042.long .L_OP_UNUSED_40FF
13043.long .L_OP_UNUSED_41FF
13044.long .L_OP_UNUSED_42FF
13045.long .L_OP_UNUSED_43FF
13046.long .L_OP_UNUSED_44FF
13047.long .L_OP_UNUSED_45FF
13048.long .L_OP_UNUSED_46FF
13049.long .L_OP_UNUSED_47FF
13050.long .L_OP_UNUSED_48FF
13051.long .L_OP_UNUSED_49FF
13052.long .L_OP_UNUSED_4AFF
13053.long .L_OP_UNUSED_4BFF
13054.long .L_OP_UNUSED_4CFF
13055.long .L_OP_UNUSED_4DFF
13056.long .L_OP_UNUSED_4EFF
13057.long .L_OP_UNUSED_4FFF
13058.long .L_OP_UNUSED_50FF
13059.long .L_OP_UNUSED_51FF
13060.long .L_OP_UNUSED_52FF
13061.long .L_OP_UNUSED_53FF
13062.long .L_OP_UNUSED_54FF
13063.long .L_OP_UNUSED_55FF
13064.long .L_OP_UNUSED_56FF
13065.long .L_OP_UNUSED_57FF
13066.long .L_OP_UNUSED_58FF
13067.long .L_OP_UNUSED_59FF
13068.long .L_OP_UNUSED_5AFF
13069.long .L_OP_UNUSED_5BFF
13070.long .L_OP_UNUSED_5CFF
13071.long .L_OP_UNUSED_5DFF
13072.long .L_OP_UNUSED_5EFF
13073.long .L_OP_UNUSED_5FFF
13074.long .L_OP_UNUSED_60FF
13075.long .L_OP_UNUSED_61FF
13076.long .L_OP_UNUSED_62FF
13077.long .L_OP_UNUSED_63FF
13078.long .L_OP_UNUSED_64FF
13079.long .L_OP_UNUSED_65FF
13080.long .L_OP_UNUSED_66FF
13081.long .L_OP_UNUSED_67FF
13082.long .L_OP_UNUSED_68FF
13083.long .L_OP_UNUSED_69FF
13084.long .L_OP_UNUSED_6AFF
13085.long .L_OP_UNUSED_6BFF
13086.long .L_OP_UNUSED_6CFF
13087.long .L_OP_UNUSED_6DFF
13088.long .L_OP_UNUSED_6EFF
13089.long .L_OP_UNUSED_6FFF
13090.long .L_OP_UNUSED_70FF
13091.long .L_OP_UNUSED_71FF
13092.long .L_OP_UNUSED_72FF
13093.long .L_OP_UNUSED_73FF
13094.long .L_OP_UNUSED_74FF
13095.long .L_OP_UNUSED_75FF
13096.long .L_OP_UNUSED_76FF
13097.long .L_OP_UNUSED_77FF
13098.long .L_OP_UNUSED_78FF
13099.long .L_OP_UNUSED_79FF
13100.long .L_OP_UNUSED_7AFF
13101.long .L_OP_UNUSED_7BFF
13102.long .L_OP_UNUSED_7CFF
13103.long .L_OP_UNUSED_7DFF
13104.long .L_OP_UNUSED_7EFF
13105.long .L_OP_UNUSED_7FFF
13106.long .L_OP_UNUSED_80FF
13107.long .L_OP_UNUSED_81FF
13108.long .L_OP_UNUSED_82FF
13109.long .L_OP_UNUSED_83FF
13110.long .L_OP_UNUSED_84FF
13111.long .L_OP_UNUSED_85FF
13112.long .L_OP_UNUSED_86FF
13113.long .L_OP_UNUSED_87FF
13114.long .L_OP_UNUSED_88FF
13115.long .L_OP_UNUSED_89FF
13116.long .L_OP_UNUSED_8AFF
13117.long .L_OP_UNUSED_8BFF
13118.long .L_OP_UNUSED_8CFF
13119.long .L_OP_UNUSED_8DFF
13120.long .L_OP_UNUSED_8EFF
13121.long .L_OP_UNUSED_8FFF
13122.long .L_OP_UNUSED_90FF
13123.long .L_OP_UNUSED_91FF
13124.long .L_OP_UNUSED_92FF
13125.long .L_OP_UNUSED_93FF
13126.long .L_OP_UNUSED_94FF
13127.long .L_OP_UNUSED_95FF
13128.long .L_OP_UNUSED_96FF
13129.long .L_OP_UNUSED_97FF
13130.long .L_OP_UNUSED_98FF
13131.long .L_OP_UNUSED_99FF
13132.long .L_OP_UNUSED_9AFF
13133.long .L_OP_UNUSED_9BFF
13134.long .L_OP_UNUSED_9CFF
13135.long .L_OP_UNUSED_9DFF
13136.long .L_OP_UNUSED_9EFF
13137.long .L_OP_UNUSED_9FFF
13138.long .L_OP_UNUSED_A0FF
13139.long .L_OP_UNUSED_A1FF
13140.long .L_OP_UNUSED_A2FF
13141.long .L_OP_UNUSED_A3FF
13142.long .L_OP_UNUSED_A4FF
13143.long .L_OP_UNUSED_A5FF
13144.long .L_OP_UNUSED_A6FF
13145.long .L_OP_UNUSED_A7FF
13146.long .L_OP_UNUSED_A8FF
13147.long .L_OP_UNUSED_A9FF
13148.long .L_OP_UNUSED_AAFF
13149.long .L_OP_UNUSED_ABFF
13150.long .L_OP_UNUSED_ACFF
13151.long .L_OP_UNUSED_ADFF
13152.long .L_OP_UNUSED_AEFF
13153.long .L_OP_UNUSED_AFFF
13154.long .L_OP_UNUSED_B0FF
13155.long .L_OP_UNUSED_B1FF
13156.long .L_OP_UNUSED_B2FF
13157.long .L_OP_UNUSED_B3FF
13158.long .L_OP_UNUSED_B4FF
13159.long .L_OP_UNUSED_B5FF
13160.long .L_OP_UNUSED_B6FF
13161.long .L_OP_UNUSED_B7FF
13162.long .L_OP_UNUSED_B8FF
13163.long .L_OP_UNUSED_B9FF
13164.long .L_OP_UNUSED_BAFF
13165.long .L_OP_UNUSED_BBFF
13166.long .L_OP_UNUSED_BCFF
13167.long .L_OP_UNUSED_BDFF
13168.long .L_OP_UNUSED_BEFF
13169.long .L_OP_UNUSED_BFFF
13170.long .L_OP_UNUSED_C0FF
13171.long .L_OP_UNUSED_C1FF
13172.long .L_OP_UNUSED_C2FF
13173.long .L_OP_UNUSED_C3FF
13174.long .L_OP_UNUSED_C4FF
13175.long .L_OP_UNUSED_C5FF
13176.long .L_OP_UNUSED_C6FF
13177.long .L_OP_UNUSED_C7FF
13178.long .L_OP_UNUSED_C8FF
13179.long .L_OP_UNUSED_C9FF
13180.long .L_OP_UNUSED_CAFF
13181.long .L_OP_UNUSED_CBFF
13182.long .L_OP_UNUSED_CCFF
13183.long .L_OP_UNUSED_CDFF
13184.long .L_OP_UNUSED_CEFF
13185.long .L_OP_UNUSED_CFFF
13186.long .L_OP_UNUSED_D0FF
13187.long .L_OP_UNUSED_D1FF
13188.long .L_OP_UNUSED_D2FF
13189.long .L_OP_UNUSED_D3FF
13190.long .L_OP_UNUSED_D4FF
13191.long .L_OP_UNUSED_D5FF
13192.long .L_OP_UNUSED_D6FF
13193.long .L_OP_UNUSED_D7FF
13194.long .L_OP_UNUSED_D8FF
13195.long .L_OP_UNUSED_D9FF
13196.long .L_OP_UNUSED_DAFF
13197.long .L_OP_UNUSED_DBFF
13198.long .L_OP_UNUSED_DCFF
13199.long .L_OP_UNUSED_DDFF
13200.long .L_OP_UNUSED_DEFF
13201.long .L_OP_UNUSED_DFFF
13202.long .L_OP_UNUSED_E0FF
13203.long .L_OP_UNUSED_E1FF
13204.long .L_OP_UNUSED_E2FF
13205.long .L_OP_UNUSED_E3FF
13206.long .L_OP_UNUSED_E4FF
13207.long .L_OP_UNUSED_E5FF
13208.long .L_OP_UNUSED_E6FF
13209.long .L_OP_UNUSED_E7FF
13210.long .L_OP_UNUSED_E8FF
13211.long .L_OP_UNUSED_E9FF
13212.long .L_OP_UNUSED_EAFF
13213.long .L_OP_UNUSED_EBFF
13214.long .L_OP_UNUSED_ECFF
13215.long .L_OP_UNUSED_EDFF
13216.long .L_OP_UNUSED_EEFF
13217.long .L_OP_UNUSED_EFFF
13218.long .L_OP_UNUSED_F0FF
13219.long .L_OP_UNUSED_F1FF
13220.long .L_OP_UNUSED_F2FF
13221.long .L_OP_UNUSED_F3FF
13222.long .L_OP_UNUSED_F4FF
13223.long .L_OP_UNUSED_F5FF
13224.long .L_OP_UNUSED_F6FF
13225.long .L_OP_UNUSED_F7FF
13226.long .L_OP_UNUSED_F8FF
13227.long .L_OP_UNUSED_F9FF
13228.long .L_OP_UNUSED_FAFF
13229.long .L_OP_UNUSED_FBFF
13230.long .L_OP_UNUSED_FCFF
13231.long .L_OP_UNUSED_FDFF
13232.long .L_OP_UNUSED_FEFF
13233.long .L_OP_THROW_VERIFICATION_ERROR_JUMBO
13234
13235/* File: x86/footer.S */
13236/*
13237 * Copyright (C) 2008 The Android Open Source Project
13238 *
13239 * Licensed under the Apache License, Version 2.0 (the "License");
13240 * you may not use this file except in compliance with the License.
13241 * You may obtain a copy of the License at
13242 *
13243 *      http://www.apache.org/licenses/LICENSE-2.0
13244 *
13245 * Unless required by applicable law or agreed to in writing, software
13246 * distributed under the License is distributed on an "AS IS" BASIS,
13247 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13248 * See the License for the specific language governing permissions and
13249 * limitations under the License.
13250 */
13251/*
13252 * Common subroutines and data.
13253 */
13254
13255#if defined(WITH_JIT)
13256/*
13257 * JIT-related re-entries into the interpreter.  In general, if the
13258 * exit from a translation can at some point be chained, the entry
13259 * here requires that control arrived via a call, and that the "rp"
13260 * on TOS is actually a pointer to a 32-bit cell containing the Dalvik PC
13261 * of the next insn to handle.  If no chaining will happen, the entry
13262 * should be reached via a direct jump and rPC set beforehand.
13263 */
13264
13265    .global dvmJitToInterpPunt
13266/*
13267 * The compiler will generate a jump to this entry point when it is
13268 * having difficulty translating a Dalvik instruction.  We must skip
13269 * the code cache lookup & prevent chaining to avoid bouncing between
13270 * the interpreter and code cache. rPC must be set on entry.
13271 */
13272dvmJitToInterpPunt:
13273#if defined(WITH_JIT_TUNING)
13274    movl   rPC, OUT_ARG0(%esp)
13275    call   dvmBumpPunt
13276#endif
13277    FETCH_INST_R %edx
13278    GOTO_NEXT_R %edx
13279
13280    .global dvmJitToInterpSingleStep
13281/*
13282 * Return to the interpreter to handle a single instruction.
13283 * Should be reached via a call.
13284 * On entry:
13285 *   0(%esp)          <= native return address within trace
13286 *   rPC              <= Dalvik PC of this instruction
13287 *   OUT_ARG0+4(%esp) <= Dalvik PC of next instruction
13288 */
13289dvmJitToInterpSingleStep:
13290    pop    %eax
13291    movl   rSELF, %ecx
13292    movl   OUT_ARG0(%esp), %edx
13293    movl   %eax,offThread_jitResumeNPC(%ecx)
13294    movl   %edx,offThread_jitResumeDPC(%ecx)
13295    movl   $kInterpEntryInstr,offThread_entryPoint(%ecx)
13296    movl   $1,rINST     # changeInterp <= true
13297    jmp    common_gotoBail
13298
13299    .global dvmJitToInterpNoChainNoProfile
13300/*
13301 * Return from the translation cache to the interpreter to do method
13302 * invocation.  Check if the translation exists for the callee, but don't
13303 * chain to it. rPC must be set on entry.
13304 */
13305dvmJitToInterpNoChainNoProfile:
13306#if defined(WITH_JIT_TUNING)
13307    call   dvmBumpNoChain
13308#endif
13309    movl   rPC,OUT_ARG0(%esp)
13310    call   dvmJitGetTraceAddr        # is there a translation?
13311    movl   rSELF,%ecx                # ecx <- self
13312    movl   %eax,offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
13313    cmpl   $0, %eax
13314    jz     1f
13315    call   *%eax                     # exec translation if we've got one
13316    # won't return
133171:
13318    FETCH_INST_R %edx
13319    GOTO_NEXT_R %edx
13320
13321/*
13322 * Return from the translation cache and immediately request a
13323 * translation fro the exit target, but don't attempt to chain.
13324 * rPC set on entry.
13325 */
13326    .global dvmJitToInterpTraceSelectNoChain
13327dvmJitToInterpTraceSelectNoChain:
13328#if defined(WITH_JIT_TUNING)
13329    call   dvmBumpNoChain
13330#endif
13331    movl   rPC,OUT_ARG0(%esp)
13332    call   dvmJitGetTraceAddr # is there a translation?
13333    movl   rSELF,%ecx
13334    cmpl   $0,%eax
13335    movl   %eax,offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
13336    jz     1f
13337    call   *%eax              # jump to tranlation
13338    # won't return
13339
13340/* No Translation - request one */
133411:
13342    GET_JIT_PROF_TABLE %ecx %eax
13343    cmpl   $0, %eax          # JIT enabled?
13344    jnz    2f                 # Request one if so
13345    FETCH_INST_R %edx         # Continue interpreting if not
13346    GOTO_NEXT_R %edx
133472:
13348    movl   $kJitTSelectRequestHot,rINST  # ask for trace select
13349    jmp    common_selectTrace
13350
13351/*
13352 * Return from the translation cache and immediately request a
13353 * translation for the exit target.  Reached via a call, and
13354 * (TOS)->rPC.
13355 */
13356    .global dvmJitToInterpTraceSelect
13357dvmJitToInterpTraceSelect:
13358    pop    rINST           # save chain cell address in callee save reg
13359    movl   (rINST),rPC
13360    movl   rPC,OUT_ARG0(%esp)
13361    call   dvmJitGetTraceAddr # is there a translation?
13362    cmpl   $0,%eax
13363    jz     1b                 # no - ask for one
13364    movl   %eax,OUT_ARG0(%esp)
13365# FIXME - need to adjust rINST to beginning of sequence
13366    movl   rINST,OUT_ARG1(%esp)
13367    call   dvmJitChain        # Attempt dvmJitChain(codeAddr,chainAddr)
13368    cmpl   $0,%eax           # Success?
13369    jz     toInterpreter      # didn't chain - interpret
13370    call   *%eax
13371    # won't return
13372
13373/*
13374 * Placeholder entries for x86 JIT
13375 */
13376    .global dvmJitToInterpBackwardBranch
13377dvmJitToInterpBackwardBranch:
13378    .global dvmJitToInterpNormal
13379dvmJitToInterpNormal:
13380    .global dvmJitToInterpNoChain
13381dvmJitToInterpNoChain:
13382toInterpreter:
13383    jmp  common_abort
13384#endif
13385
13386/*
13387 * Common code when a backwards branch is taken
13388 *
13389 * On entry:
13390 *   ebx (a.k.a. rINST) -> PC adjustment in 16-bit words
13391 */
13392common_backwardBranch:
13393    movl    rSELF,%ecx
13394    call   common_periodicChecks  # rPC and ecx/rSELF preserved
13395#if defined(WITH_JIT)
13396    GET_JIT_PROF_TABLE %ecx %edx
13397    ADVANCE_PC_INDEXED rINST
13398    cmpl   $0,%edx
13399    FETCH_INST
13400    jz    1f                    # Profiling off - continue
13401    .global updateProfile
13402updateProfile:
13403common_updateProfile:
13404    # quick & dirty hash
13405    movl   rPC, %eax
13406    shrl   $12, %eax
13407    xorl   rPC, %eax
13408    andl   $((1<<JIT_PROF_SIZE_LOG_2)-1),%eax
13409    decb   (%edx,%eax)
13410    jz     2f
134111:
13412    GOTO_NEXT
134132:
13414/*
13415 * Here, we switch to the debug interpreter to request
13416 * trace selection.  First, though, check to see if there
13417 * is already a native translation in place (and, if so,
13418 * jump to it now.
13419 */
13420    GET_JIT_THRESHOLD %ecx rINST  # leaves rSELF in %ecx
13421    EXPORT_PC
13422    movb   rINSTbl,(%edx,%eax)   # reset counter
13423    movl   %ecx,rINST            # preserve rSELF
13424    movl   rPC,OUT_ARG0(%esp)
13425    call   dvmJitGetTraceAddr  # already have one?
13426    movl   %eax,offThread_inJitCodeCache(rINST)   # set the inJitCodeCache flag
13427    cmpl   $0,%eax
13428    jz     1f
13429    call   *%eax        # FIXME: decide call vs/ jmp!.  No return either way
134301:
13431    movl   $kJitTSelectRequest,%eax
13432    # On entry, eax<- jitState, rPC valid
13433common_selectTrace:
13434
13435    movl   rSELF,%ecx
13436    movl   %eax,offThread_jitState(%ecx)
13437    movl   $kInterpEntryInstr,offThread_entryPoint(%ecx)
13438    movl   $1,rINST
13439    jmp    common_gotoBail
13440#else
13441    ADVANCE_PC_INDEXED rINST
13442    FETCH_INST
13443    GOTO_NEXT
13444#endif
13445
13446
13447
13448/*
13449 * Common code for jumbo method invocation.
13450 *
13451 * On entry:
13452 *   eax = Method* methodToCall
13453 *   rINSTw trashed, must reload
13454 */
13455
13456common_invokeMethodJumbo:
13457.LinvokeNewJumbo:
13458
13459   /*
13460    * prepare to copy args to "outs" area of current frame
13461    */
13462    movzwl      6(rPC),rINST            # rINST<- BBBB
13463    movzwl      8(rPC), %ecx            # %ecx<- CCCC
13464    ADVANCE_PC 2                        # adjust pc to make return similar
13465    SAVEAREA_FROM_FP %edx               # %edx<- &StackSaveArea
13466    test        rINST, rINST
13467    movl        rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- BBBB
13468    jz          .LinvokeArgsDone        # no args; jump to args done
13469    jmp         .LinvokeRangeArgs       # handle args like invoke range
13470
13471/*
13472 * Common code for method invocation with range.
13473 *
13474 * On entry:
13475 *   eax = Method* methodToCall
13476 *   rINSTw trashed, must reload
13477 */
13478
13479common_invokeMethodRange:
13480.LinvokeNewRange:
13481
13482   /*
13483    * prepare to copy args to "outs" area of current frame
13484    */
13485
13486    movzbl      1(rPC),rINST       # rINST<- AA
13487    movzwl      4(rPC), %ecx            # %ecx<- CCCC
13488    SAVEAREA_FROM_FP %edx               # %edx<- &StackSaveArea
13489    test        rINST, rINST
13490    movl        rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- AA
13491    jz          .LinvokeArgsDone        # no args; jump to args done
13492
13493
13494   /*
13495    * %eax=methodToCall, %ecx=CCCC, LOCAL0_OFFSET(%ebp)=count, %edx=&outs (&stackSaveArea)
13496    * (very few methods have > 10 args; could unroll for common cases)
13497    */
13498
13499.LinvokeRangeArgs:
13500    movl        %ebx, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- save %ebx
13501    lea         (rFP, %ecx, 4), %ecx    # %ecx<- &vCCCC
13502    shll        $2, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- offset
13503    subl        LOCAL0_OFFSET(%ebp), %edx       # %edx<- update &outs
13504    shrl        $2, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- offset
135051:
13506    movl        (%ecx), %ebx            # %ebx<- vCCCC
13507    lea         4(%ecx), %ecx           # %ecx<- &vCCCC++
13508    subl        $1, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET<- LOCAL0_OFFSET--
13509    movl        %ebx, (%edx)            # *outs<- vCCCC
13510    lea         4(%edx), %edx           # outs++
13511    jne         1b                      # loop if count (LOCAL0_OFFSET(%ebp)) not zero
13512    movl        LOCAL1_OFFSET(%ebp), %ebx       # %ebx<- restore %ebx
13513    jmp         .LinvokeArgsDone        # continue
13514
13515   /*
13516    * %eax is "Method* methodToCall", the method we're trying to call
13517    * prepare to copy args to "outs" area of current frame
13518    */
13519
13520common_invokeMethodNoRange:
13521.LinvokeNewNoRange:
13522    movzbl      1(rPC),rINST       # rINST<- BA
13523    movl        rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- BA
13524    shrl        $4, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- B
13525    je          .LinvokeArgsDone        # no args; jump to args done
13526    movzwl      4(rPC), %ecx            # %ecx<- GFED
13527    SAVEAREA_FROM_FP %edx               # %edx<- &StackSaveArea
13528
13529   /*
13530    * %eax=methodToCall, %ecx=GFED, LOCAL0_OFFSET(%ebp)=count, %edx=outs
13531    */
13532
13533.LinvokeNonRange:
13534    cmp         $2, LOCAL0_OFFSET(%ebp)        # compare LOCAL0_OFFSET(%ebp) to 2
13535    movl        %ecx, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- GFED
13536    jl          1f                      # handle 1 arg
13537    je          2f                      # handle 2 args
13538    cmp         $4, LOCAL0_OFFSET(%ebp)        # compare LOCAL0_OFFSET(%ebp) to 4
13539    jl          3f                      # handle 3 args
13540    je          4f                      # handle 4 args
135415:
13542    andl        $15, rINST             # rINSTw<- A
13543    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
13544    movl        (rFP, rINST, 4), %ecx   # %ecx<- vA
13545    movl        %ecx, (%edx)            # *outs<- vA
13546    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
135474:
13548    shr         $12, %ecx              # %ecx<- G
13549    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
13550    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vG
13551    movl        %ecx, (%edx)            # *outs<- vG
13552    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
135533:
13554    and         $0x0f00, %ecx          # %ecx<- 0F00
13555    shr         $8, %ecx               # %ecx<- F
13556    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
13557    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vF
13558    movl        %ecx, (%edx)            # *outs<- vF
13559    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
135602:
13561    and         $0x00f0, %ecx          # %ecx<- 00E0
13562    shr         $4, %ecx               # %ecx<- E
13563    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
13564    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vE
13565    movl        %ecx, (%edx)            # *outs<- vE
13566    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
135671:
13568    and         $0x000f, %ecx          # %ecx<- 000D
13569    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vD
13570    movl        %ecx, -4(%edx)          # *--outs<- vD
135710:
13572
13573   /*
13574    * %eax is "Method* methodToCall", the method we're trying to call
13575    * find space for the new stack frame, check for overflow
13576    */
13577
13578.LinvokeArgsDone:
13579    movzwl      offMethod_registersSize(%eax), %edx # %edx<- methodToCall->regsSize
13580    movzwl      offMethod_outsSize(%eax), %ecx # %ecx<- methodToCall->outsSize
13581    movl        %eax, LOCAL0_OFFSET(%ebp)       # LOCAL0_OFFSET<- methodToCall
13582    shl         $2, %edx               # %edx<- update offset
13583    SAVEAREA_FROM_FP %eax               # %eax<- &StackSaveArea
13584    subl        %edx, %eax              # %eax<- newFP; (old savearea - regsSize)
13585    movl        rSELF,%edx              # %edx<- pthread
13586    movl        %eax, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- &outs
13587    subl        $sizeofStackSaveArea, %eax # %eax<- newSaveArea (stack save area using newFP)
13588    movl        offThread_interpStackEnd(%edx), %edx # %edx<- self->interpStackEnd
13589    movl        %edx, LOCAL2_OFFSET(%ebp)       # LOCAL2_OFFSET<- self->interpStackEnd
13590    shl         $2, %ecx               # %ecx<- update offset for outsSize
13591    movl        %eax, %edx              # %edx<- newSaveArea
13592    sub         %ecx, %eax              # %eax<- bottom; (newSaveArea - outsSize)
13593    cmp         LOCAL2_OFFSET(%ebp), %eax       # compare interpStackEnd and bottom
13594    movl        LOCAL0_OFFSET(%ebp), %eax       # %eax<- restore methodToCall
13595    jl          .LstackOverflow         # handle frame overflow
13596
13597   /*
13598    * set up newSaveArea
13599    */
13600
13601#ifdef EASY_GDB
13602    SAVEAREA_FROM_FP %ecx               # %ecx<- &StackSaveArea
13603    movl        %ecx, offStackSaveArea_prevSave(%edx) # newSaveArea->prevSave<- &outs
13604#endif
13605    movl        rFP, offStackSaveArea_prevFrame(%edx) # newSaveArea->prevFrame<- rFP
13606    movl        rPC, offStackSaveArea_savedPc(%edx) # newSaveArea->savedPc<- rPC
13607    testl       $ACC_NATIVE, offMethod_accessFlags(%eax) # check for native call
13608    movl        %eax, offStackSaveArea_method(%edx) # newSaveArea->method<- method to call
13609    jne         .LinvokeNative          # handle native call
13610
13611   /*
13612    * Update "self" values for the new method
13613    * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFp
13614    */
13615
13616    movl        offMethod_clazz(%eax), %edx # %edx<- method->clazz
13617    movl        rSELF,%ecx                  # %ecx<- pthread
13618    movl        offClassObject_pDvmDex(%edx), %edx # %edx<- method->clazz->pDvmDex
13619    movl        %eax, offThread_method(%ecx) # self->method<- methodToCall
13620    movl        %edx, offThread_methodClassDex(%ecx) # self->methodClassDex<- method->clazz->pDvmDex
13621    movl        offMethod_insns(%eax), rPC # rPC<- methodToCall->insns
13622    movl        LOCAL1_OFFSET(%ebp), rFP # rFP<- newFP
13623    movl        rFP, offThread_curFrame(%ecx) # self->curFrame<- newFP
13624    FETCH_INST
13625    GOTO_NEXT                           # jump to methodToCall->insns
13626
13627   /*
13628    * Prep for the native call
13629    * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFP, %edx=newSaveArea
13630    */
13631
13632.LinvokeNative:
13633    movl        rSELF,%ecx              # %ecx<- pthread
13634    movl        %eax, OUT_ARG1(%esp)    # push parameter methodToCall
13635    movl        offThread_jniLocal_topCookie(%ecx), %eax # %eax<- self->localRef->...
13636    movl        %eax, offStackSaveArea_localRefCookie(%edx) # newSaveArea->localRefCookie<- top
13637    movl        %edx, OUT_ARG4(%esp)    # save newSaveArea
13638    movl        LOCAL1_OFFSET(%ebp), %edx # %edx<- newFP
13639    movl        %edx, offThread_curFrame(%ecx)  # self->self->curFrame<- newFP
13640    movl        %ecx, OUT_ARG3(%esp)    # save self->self
13641    movl        %ecx, OUT_ARG2(%esp)    # push parameter self->self
13642    movl        rSELF,%ecx              # %ecx<- pthread
13643    movl        OUT_ARG1(%esp), %eax    # %eax<- methodToCall
13644    lea         offThread_retval(%ecx), %ecx # %ecx<- &retval
13645    movl        %ecx, OUT_ARG0(%esp)    # push parameter pthread
13646    push        %edx                    # push parameter newFP
13647
13648    call        *offMethod_nativeFunc(%eax) # call methodToCall->nativeFunc
13649    lea         4(%esp), %esp
13650    movl        OUT_ARG4(%esp), %ecx    # %ecx<- newSaveArea
13651    movl        OUT_ARG3(%esp), %eax    # %eax<- self->self
13652    movl        offStackSaveArea_localRefCookie(%ecx), %edx # %edx<- old top
13653    cmp         $0, offThread_exception(%eax) # check for exception
13654    movl        rFP, offThread_curFrame(%eax) # self->self->curFrame<- rFP
13655    movl        %edx, offThread_jniLocal_topCookie(%eax) # new top <- old top
13656    jne         common_exceptionThrown  # handle exception
13657    FETCH_INST_OPCODE 3 %edx
13658    ADVANCE_PC 3
13659    GOTO_NEXT_R %edx                    # jump to next instruction
13660
13661.LstackOverflow:    # eax=methodToCall
13662    movl        %eax, OUT_ARG1(%esp)    # push parameter methodToCall
13663    movl        rSELF,%eax              # %eax<- self
13664    movl        %eax, OUT_ARG0(%esp)    # push parameter self
13665    call        dvmHandleStackOverflow  # call: (Thread* self, Method* meth)
13666    jmp         common_exceptionThrown  # handle exception
13667
13668
13669/*
13670 * Do we need the thread to be suspended or have debugger/profiling activity?
13671 *
13672 * On entry:
13673 *   ebx  -> PC adjustment in 16-bit words (must be preserved)
13674 *   ecx  -> SELF pointer
13675 *   reentry type, e.g. kInterpEntryInstr stored in rSELF->entryPoint
13676 *
13677 * Note: A call will normally kill %eax and %ecx.  To
13678 *       streamline the normal case, this routine will preserve
13679 *       %ecx in addition to the normal caller save regs.  The save/restore
13680 *       is a bit ugly, but will happen in the relatively uncommon path.
13681 * TODO: Basic-block style Jit will need a hook here as well.  Fold it into
13682 *       the suspendCount check so we can get both in 1 shot.
13683 * TUNING: Improve scheduling here & do initial single test for all.
13684 */
13685common_periodicChecks:
13686    cmpl    $0,offThread_suspendCount(%ecx)     # non-zero suspendCount?
13687    jne     1f
13688
136896:
13690    movl   offThread_pInterpBreak(%ecx),%eax    # eax <- &interpBreak
13691    cmpl   $0,(%eax)              # something interesting happening?
13692    jne    3f                      # yes - switch interpreters
13693    ret
13694
13695    /* Check for suspend */
136961:
13697    /*  At this point, the return pointer to the caller of
13698     *  common_periodicChecks is on the top of stack.  We need to preserve
13699     *  SELF(ecx).
13700     *  The outgoing profile is:
13701     *      bool dvmCheckSuspendPending(Thread* self)
13702     *  Because we reached here via a call, go ahead and build a new frame.
13703     */
13704    EXPORT_PC                         # need for precise GC
13705    movl    %ecx,%eax                 # eax<- self
13706    push    %ebp
13707    movl    %esp,%ebp
13708    subl    $24,%esp
13709    movl    %eax,OUT_ARG0(%esp)
13710    call    dvmCheckSuspendPending
13711    addl    $24,%esp
13712    pop     %ebp
13713    movl    rSELF,%ecx
13714
13715    /*
13716     * Need to check to see if debugger or profiler flags got set
13717     * while we were suspended.
13718     */
13719    jmp    6b
13720
13721    /* Switch interpreters */
13722    /* Note: %ebx contains the 16-bit word offset to be applied to rPC to
13723     * "complete" the interpretation of backwards branches.  In effect, we
13724     * are completing the interpretation of the branch instruction here,
13725     * and the new interpreter will resume interpretation at the branch
13726     * target. However, a switch request recognized during the handling
13727     * of a return from method instruction results in an immediate abort,
13728     * and the new interpreter will resume by re-interpreting the return
13729     * instruction.
13730     */
137313:
13732    leal    (rPC,%ebx,2),rPC       # adjust pc to show target
13733    movl    rSELF,%ecx             # bail expect SELF already loaded
13734    movl    $1,rINST              # set changeInterp to true
13735    jmp     common_gotoBail
13736
13737
13738/*
13739 * Common code for handling a return instruction
13740 */
13741common_returnFromMethod:
13742    movl    rSELF,%ecx
13743    /* Set entry mode in case we bail */
13744    movb    $kInterpEntryReturn,offThread_entryPoint(%ecx)
13745    xorl    rINST,rINST   # zero offset in case we switch interps
13746    call    common_periodicChecks   # Note: expects %ecx to be preserved
13747
13748    SAVEAREA_FROM_FP %eax                         # eax<- saveArea (old)
13749    movl    offStackSaveArea_prevFrame(%eax),rFP  # rFP<- prevFrame
13750    movl    (offStackSaveArea_method-sizeofStackSaveArea)(rFP),rINST
13751    cmpl    $0,rINST                             # break?
13752    je      common_gotoBail    # break frame, bail out completely
13753
13754    movl    offStackSaveArea_savedPc(%eax),rPC    # pc<- saveArea->savedPC
13755    movl    rINST,offThread_method(%ecx)  # self->method = newSave->meethod
13756    movl    rFP,offThread_curFrame(%ecx)     # self->curFrame = fp
13757    movl    offMethod_clazz(rINST),%eax      # eax<- method->clazz
13758    FETCH_INST_OPCODE 3 %edx
13759    movl    offClassObject_pDvmDex(%eax),%eax # eax<- method->clazz->pDvmDex
13760    ADVANCE_PC 3
13761    movl    %eax,offThread_methodClassDex(%ecx)
13762    /* not bailing - restore entry mode to default */
13763    movb    $kInterpEntryInstr,offThread_entryPoint(%ecx)
13764    GOTO_NEXT_R %edx
13765
13766/*
13767 * Prepare to strip the current frame and "longjump" back to caller of
13768 * dvmMterpStdRun.
13769 *
13770 * on entry:
13771 *    rINST holds changeInterp
13772 *    ecx holds self pointer
13773 *
13774 * expected profile: dvmMterpStdBail(Thread *self, bool changeInterp)
13775 */
13776common_gotoBail:
13777    movl   rPC,offThread_pc(%ecx)     # export state to self
13778    movl   rFP,offThread_fp(%ecx)
13779    movl   %ecx,OUT_ARG0(%esp)      # self in arg0
13780    movl   rINST,OUT_ARG1(%esp)     # changeInterp in arg1
13781    call   dvmMterpStdBail          # bail out....
13782
13783
13784/*
13785 * After returning from a "selfd" function, pull out the updated values
13786 * and start executing at the next instruction.
13787 */
13788 common_resumeAfterGlueCall:
13789     LOAD_PC_FP_FROM_SELF
13790     FETCH_INST
13791     GOTO_NEXT
13792
13793/*
13794 * Integer divide or mod by zero
13795 */
13796common_errDivideByZero:
13797    EXPORT_PC
13798    movl    $.LstrArithmeticException,%eax
13799    movl    %eax,OUT_ARG0(%esp)
13800    movl    $.LstrDivideByZero,%eax
13801    movl    %eax,OUT_ARG1(%esp)
13802    call    dvmThrowException
13803    jmp     common_exceptionThrown
13804
13805/*
13806 * Attempt to allocate an array with a negative size.
13807 */
13808common_errNegativeArraySize:
13809    EXPORT_PC
13810    movl    $.LstrNegativeArraySizeException,%eax
13811    movl    %eax,OUT_ARG0(%esp)
13812    xorl    %eax,%eax
13813    movl    %eax,OUT_ARG1(%esp)
13814    call    dvmThrowException
13815    jmp     common_exceptionThrown
13816
13817/*
13818 * Attempt to allocate an array with a negative size.
13819 */
13820common_errNoSuchMethod:
13821
13822    EXPORT_PC
13823    movl    $.LstrNoSuchMethodError,%eax
13824    movl    %eax,OUT_ARG0(%esp)
13825    xorl    %eax,%eax
13826    movl    %eax,OUT_ARG1(%esp)
13827    call    dvmThrowException
13828    jmp     common_exceptionThrown
13829
13830/*
13831 * Hit a null object when we weren't expecting one.  Export the PC, throw a
13832 * NullPointerException and goto the exception processing code.
13833 */
13834common_errNullObject:
13835    EXPORT_PC
13836    movl    $.LstrNullPointerException,%eax
13837    movl    %eax,OUT_ARG0(%esp)
13838    xorl    %eax,%eax
13839    movl    %eax,OUT_ARG1(%esp)
13840    call    dvmThrowException
13841    jmp     common_exceptionThrown
13842
13843/*
13844 * Array index exceeds max.
13845 * On entry:
13846 *    eax <- array object
13847 *    ecx <- index
13848 */
13849common_errArrayIndex:
13850    EXPORT_PC
13851    movl    offArrayObject_length(%eax), %eax
13852    movl    %ecx,OUT_ARG0(%esp)
13853    movl    %eax,OUT_ARG1(%esp)
13854    call    dvmThrowAIOOBE        # dvmThrowAIOO(index, length)
13855    jmp     common_exceptionThrown
13856
13857/*
13858 * Somebody has thrown an exception.  Handle it.
13859 *
13860 * If the exception processing code returns to us (instead of falling
13861 * out of the interpreter), continue with whatever the next instruction
13862 * now happens to be.
13863 *
13864 * This does not return.
13865 */
13866common_exceptionThrown:
13867    movl    rSELF,%ecx
13868    movl    rPC,offThread_pc(%ecx)
13869    movl    rFP,offThread_fp(%ecx)
13870    movl    %ecx,OUT_ARG0(%esp)
13871    call    dvmMterp_exceptionThrown
13872    jmp     common_resumeAfterGlueCall
13873
13874common_abort:
13875    movl    $0xdeadf00d,%eax
13876    call     *%eax
13877
13878
13879/*
13880 * Strings
13881 */
13882
13883    .section     .rodata
13884.LstrNullPointerException:
13885    .asciz    "Ljava/lang/NullPointerException;"
13886.LstrArithmeticException:
13887    .asciz  "Ljava/lang/ArithmeticException;"
13888.LstrDivideByZero:
13889    .asciz  "divide by zero"
13890.LstrNegativeArraySizeException:
13891    .asciz  "Ljava/lang/NegativeArraySizeException;"
13892.LstrInstantiationError:
13893    .asciz  "Ljava/lang/InstantiationError;"
13894.LstrNoSuchMethodError:
13895    .asciz  "Ljava/lang/NoSuchMethodError;"
13896.LstrInternalErrorA:
13897    .asciz  "Ljava/lang/InternalError;"
13898.LstrFilledNewArrayNotImplA:
13899    .asciz  "filled-new-array only implemented for 'int'"
13900
13901