InterpAsm-x86.S revision 3185a41fe8b3223003a07685c1acdf44bfe148d0
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
49Stack must be 16-byte aligned to support SSE in native code.
50
51If we're not doing variable stack allocation (alloca), the frame pointer can be
52eliminated and all arg references adjusted to be esp relative.
53
54Mterp notes:
55
56Some key interpreter variables will be assigned to registers.  Note that each
57will also have an associated spill location (mostly useful for those assigned
58to callee save registers).
59
60  nick     reg   purpose
61  rPC      edi   interpreted program counter, used for fetching instructions
62  rFP      esi   interpreted frame pointer, used for accessing locals and args
63  rINSTw   bx    first 16-bit code of current instruction
64  rINSTbl  bl    opcode portion of instruction word
65  rINSTbh  bh    high byte of inst word, usually contains src/tgt reg names
66  rIBASE   edx   base of instruction handler table
67
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 and ecx are scratch, rINSTw/ebx sometimes scratch
72
73*/
74
75#define rSELF    8(%ebp)
76#define rPC      %esi
77#define rFP      %edi
78#define rINST    %ebx
79#define rINSTw   %bx
80#define rINSTbh  %bh
81#define rINSTbl  %bl
82#define rIBASE   %edx
83
84
85/* Frame diagram while executing dvmMterpStdRun, high to low addresses */
86#define IN_ARG0        (  8)
87#define CALLER_RP      (  4)
88#define PREV_FP        (  0)
89/* Spill offsets relative to %ebp */
90#define EDI_SPILL      ( -4)
91#define ESI_SPILL      ( -8)
92#define EBX_SPILL      (-12)
93#define rPC_SPILL      (-16)
94#define rFP_SPILL      (-20)
95#define rINST_SPILL    (-24)
96#define rIBASE_SPILL   (-28)
97#define TMP_SPILL1     (-32)
98#define TMP_SPILL2     (-36)
99#define TMP_SPILL3     (-20)
100#define LOCAL0_OFFSET  (-44)
101#define LOCAL1_OFFSET  (-48)
102#define LOCAL2_OFFSET  (-52)
103/* Out Arg offsets, relative to %esp */
104#define OUT_ARG4       ( 16)
105#define OUT_ARG3       ( 12)
106#define OUT_ARG2       (  8)
107#define OUT_ARG1       (  4)
108#define OUT_ARG0       (  0)  /* <- dvmMterpStdRun esp */
109#define FRAME_SIZE     76
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_curFrame(\_reg)
134.endm
135
136.macro LOAD_PC_FP_FROM_SELF
137    movl    rSELF,rFP
138    movl    offThread_pc(rFP),rPC
139    movl    offThread_curFrame(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 throws.
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     *(rIBASE,%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     *(rIBASE,\_reg,4)
234.endm
235
236/*
237 * Get/set the 32-bit value from a Dalvik register.
238 */
239.macro GET_VREG_R _reg _vreg
240    movl     (rFP,\_vreg,4),\_reg
241.endm
242
243.macro SET_VREG _reg _vreg
244    movl     \_reg,(rFP,\_vreg,4)
245.endm
246
247.macro GET_VREG_WORD _reg _vreg _offset
248    movl     4*(\_offset)(rFP,\_vreg,4),\_reg
249.endm
250
251.macro SET_VREG_WORD _reg _vreg _offset
252    movl     \_reg,4*(\_offset)(rFP,\_vreg,4)
253.endm
254
255#define sReg0 LOCAL0_OFFSET(%ebp)
256#define sReg1 LOCAL1_OFFSET(%ebp)
257#define sReg2 LOCAL2_OFFSET(%ebp)
258
259   /*
260    * Hard coded helper values.
261    */
262
263.balign 16
264
265.LdoubNeg:
266    .quad       0x8000000000000000
267
268.L64bits:
269    .quad       0xFFFFFFFFFFFFFFFF
270
271.LshiftMask2:
272    .quad       0x0000000000000000
273.LshiftMask:
274    .quad       0x000000000000003F
275
276.Lvalue64:
277    .quad       0x0000000000000040
278
279.LvaluePosInfLong:
280    .quad       0x7FFFFFFFFFFFFFFF
281
282.LvalueNegInfLong:
283    .quad       0x8000000000000000
284
285.LvalueNanLong:
286    .quad       0x0000000000000000
287
288.LintMin:
289.long   0x80000000
290
291.LintMax:
292.long   0x7FFFFFFF
293
294
295/*
296 * This is a #include, not a %include, because we want the C pre-processor
297 * to expand the macros into assembler assignment statements.
298 */
299#include "../common/asm-constants.h"
300
301#if defined(WITH_JIT)
302#include "../common/jit-config.h"
303#endif
304
305
306    .global dvmAsmInstructionStartCode
307    .type   dvmAsmInstructionStartCode, %function
308dvmAsmInstructionStartCode = .L_OP_NOP
309    .text
310
311/* ------------------------------ */
312.L_OP_NOP: /* 0x00 */
313/* File: x86/OP_NOP.S */
314    FETCH_INST_OPCODE 1 %ecx
315    ADVANCE_PC 1
316    GOTO_NEXT_R %ecx
317
318/* ------------------------------ */
319.L_OP_MOVE: /* 0x01 */
320/* File: x86/OP_MOVE.S */
321    /* for move, move-object, long-to-int */
322    /* op vA, vB */
323    movzbl rINSTbl,%eax          # eax<- BA
324    andb   $0xf,%al             # eax<- A
325    shrl   $4,rINST            # rINST<- B
326    GET_VREG_R rINST rINST
327    FETCH_INST_OPCODE 1 %ecx
328    ADVANCE_PC 1
329    SET_VREG rINST %eax           # fp[A]<-fp[B]
330    GOTO_NEXT_R %ecx
331
332/* ------------------------------ */
333.L_OP_MOVE_FROM16: /* 0x02 */
334/* File: x86/OP_MOVE_FROM16.S */
335    /* for: move/from16, move-object/from16 */
336    /* op vAA, vBBBB */
337    movzx    rINSTbl,%eax              # eax <= AA
338    movw     2(rPC),rINSTw             # rINSTw <= BBBB
339    GET_VREG_R rINST rINST             # rINST- fp[BBBB]
340    FETCH_INST_OPCODE 2 %ecx
341    ADVANCE_PC 2
342    SET_VREG rINST %eax                # fp[AA]<- ecx]
343    GOTO_NEXT_R %ecx
344
345/* ------------------------------ */
346.L_OP_MOVE_16: /* 0x03 */
347/* File: x86/OP_MOVE_16.S */
348    /* for: move/16, move-object/16 */
349    /* op vAAAA, vBBBB */
350    movzwl    4(rPC),%ecx              # ecx<- BBBB
351    movzwl    2(rPC),%eax              # eax<- AAAA
352    GET_VREG_R  rINST %ecx
353    FETCH_INST_OPCODE 3 %ecx
354    ADVANCE_PC 3
355    SET_VREG  rINST %eax
356    GOTO_NEXT_R %ecx
357
358/* ------------------------------ */
359.L_OP_MOVE_WIDE: /* 0x04 */
360/* File: x86/OP_MOVE_WIDE.S */
361    /* move-wide vA, vB */
362    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
363    movzbl    rINSTbl,%ecx                # ecx <- BA
364    sarl      $4,rINST                   # rINST<- B
365    GET_VREG_WORD %eax rINST 0            # eax<- v[B+0]
366    GET_VREG_WORD rINST rINST 1           # rINST<- v[B+1]
367    andb      $0xf,%cl                   # ecx <- A
368    SET_VREG_WORD rINST %ecx 1            # v[A+1]<- rINST
369    SET_VREG_WORD %eax %ecx 0             # v[A+0]<- eax
370    FETCH_INST_OPCODE 1 %ecx
371    ADVANCE_PC 1
372    GOTO_NEXT_R %ecx
373
374/* ------------------------------ */
375.L_OP_MOVE_WIDE_FROM16: /* 0x05 */
376/* File: x86/OP_MOVE_WIDE_FROM16.S */
377    /* move-wide/from16 vAA, vBBBB */
378    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
379    movzwl    2(rPC),%ecx              # ecx<- BBBB
380    movzbl    rINSTbl,%eax             # eax<- AAAA
381    GET_VREG_WORD rINST %ecx 0         # rINST<- v[BBBB+0]
382    GET_VREG_WORD %ecx %ecx 1          # ecx<- v[BBBB+1]
383    SET_VREG_WORD rINST %eax 0         # v[AAAA+0]<- rINST
384    SET_VREG_WORD %ecx %eax 1          # v[AAAA+1]<- eax
385    FETCH_INST_OPCODE 2 %ecx
386    ADVANCE_PC 2
387    GOTO_NEXT_R %ecx
388
389/* ------------------------------ */
390.L_OP_MOVE_WIDE_16: /* 0x06 */
391/* File: x86/OP_MOVE_WIDE_16.S */
392    /* move-wide/16 vAAAA, vBBBB */
393    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
394    movzwl    4(rPC),%ecx            # ecx<- BBBB
395    movzwl    2(rPC),%eax            # eax<- AAAA
396    GET_VREG_WORD rINST %ecx 0       # rINSTw_WORD<- v[BBBB+0]
397    GET_VREG_WORD %ecx %ecx 1        # ecx<- v[BBBB+1]
398    SET_VREG_WORD rINST %eax 0       # v[AAAA+0]<- rINST
399    SET_VREG_WORD %ecx %eax 1        # v[AAAA+1]<- ecx
400    FETCH_INST_OPCODE 3 %ecx
401    ADVANCE_PC 3
402    GOTO_NEXT_R %ecx
403
404/* ------------------------------ */
405.L_OP_MOVE_OBJECT: /* 0x07 */
406/* File: x86/OP_MOVE_OBJECT.S */
407/* File: x86/OP_MOVE.S */
408    /* for move, move-object, long-to-int */
409    /* op vA, vB */
410    movzbl rINSTbl,%eax          # eax<- BA
411    andb   $0xf,%al             # eax<- A
412    shrl   $4,rINST            # rINST<- B
413    GET_VREG_R rINST rINST
414    FETCH_INST_OPCODE 1 %ecx
415    ADVANCE_PC 1
416    SET_VREG rINST %eax           # fp[A]<-fp[B]
417    GOTO_NEXT_R %ecx
418
419
420/* ------------------------------ */
421.L_OP_MOVE_OBJECT_FROM16: /* 0x08 */
422/* File: x86/OP_MOVE_OBJECT_FROM16.S */
423/* File: x86/OP_MOVE_FROM16.S */
424    /* for: move/from16, move-object/from16 */
425    /* op vAA, vBBBB */
426    movzx    rINSTbl,%eax              # eax <= AA
427    movw     2(rPC),rINSTw             # rINSTw <= BBBB
428    GET_VREG_R rINST rINST             # rINST- fp[BBBB]
429    FETCH_INST_OPCODE 2 %ecx
430    ADVANCE_PC 2
431    SET_VREG rINST %eax                # fp[AA]<- ecx]
432    GOTO_NEXT_R %ecx
433
434
435/* ------------------------------ */
436.L_OP_MOVE_OBJECT_16: /* 0x09 */
437/* File: x86/OP_MOVE_OBJECT_16.S */
438/* File: x86/OP_MOVE_16.S */
439    /* for: move/16, move-object/16 */
440    /* op vAAAA, vBBBB */
441    movzwl    4(rPC),%ecx              # ecx<- BBBB
442    movzwl    2(rPC),%eax              # eax<- AAAA
443    GET_VREG_R  rINST %ecx
444    FETCH_INST_OPCODE 3 %ecx
445    ADVANCE_PC 3
446    SET_VREG  rINST %eax
447    GOTO_NEXT_R %ecx
448
449
450/* ------------------------------ */
451.L_OP_MOVE_RESULT: /* 0x0a */
452/* File: x86/OP_MOVE_RESULT.S */
453    /* for: move-result, move-result-object */
454    /* op vAA */
455    movl     rSELF,%eax                    # eax<- rSELF
456    movl     offThread_retval(%eax),%eax   # eax<- self->retval.l
457    FETCH_INST_OPCODE 1 %ecx
458    ADVANCE_PC 1
459    SET_VREG  %eax rINST                   # fp[AA]<- retval.l
460    GOTO_NEXT_R %ecx
461
462/* ------------------------------ */
463.L_OP_MOVE_RESULT_WIDE: /* 0x0b */
464/* File: x86/OP_MOVE_RESULT_WIDE.S */
465    /* move-result-wide vAA */
466    movl    rSELF,%ecx
467    movl    offThread_retval(%ecx),%eax
468    movl    4+offThread_retval(%ecx),%ecx
469    SET_VREG_WORD %eax rINST 0     # v[AA+0] <- eax
470    SET_VREG_WORD %ecx rINST 1     # v[AA+1] <- ecx
471    FETCH_INST_OPCODE 1 %ecx
472    ADVANCE_PC 1
473    GOTO_NEXT_R %ecx
474
475/* ------------------------------ */
476.L_OP_MOVE_RESULT_OBJECT: /* 0x0c */
477/* File: x86/OP_MOVE_RESULT_OBJECT.S */
478/* File: x86/OP_MOVE_RESULT.S */
479    /* for: move-result, move-result-object */
480    /* op vAA */
481    movl     rSELF,%eax                    # eax<- rSELF
482    movl     offThread_retval(%eax),%eax   # eax<- self->retval.l
483    FETCH_INST_OPCODE 1 %ecx
484    ADVANCE_PC 1
485    SET_VREG  %eax rINST                   # fp[AA]<- retval.l
486    GOTO_NEXT_R %ecx
487
488
489/* ------------------------------ */
490.L_OP_MOVE_EXCEPTION: /* 0x0d */
491/* File: x86/OP_MOVE_EXCEPTION.S */
492    /* move-exception vAA */
493    movl    rSELF,%ecx
494    movl    offThread_exception(%ecx),%eax # eax<- dvmGetException bypass
495    SET_VREG %eax rINST                # fp[AA]<- exception object
496    FETCH_INST_OPCODE 1 %eax
497    ADVANCE_PC 1
498    movl    $0,offThread_exception(%ecx) # dvmClearException bypass
499    GOTO_NEXT_R %eax
500
501/* ------------------------------ */
502.L_OP_RETURN_VOID: /* 0x0e */
503/* File: x86/OP_RETURN_VOID.S */
504    jmp       common_returnFromMethod
505
506/* ------------------------------ */
507.L_OP_RETURN: /* 0x0f */
508/* File: x86/OP_RETURN.S */
509    /*
510     * Return a 32-bit value.  Copies the return value into the "self"
511     * structure, then jumps to the return handler.
512     *
513     * for: return, return-object
514     */
515    /* op vAA */
516    movl    rSELF,%ecx
517    GET_VREG_R %eax rINST               # eax<- vAA
518    movl    %eax,offThread_retval(%ecx)   # retval.i <- AA
519    jmp     common_returnFromMethod
520
521/* ------------------------------ */
522.L_OP_RETURN_WIDE: /* 0x10 */
523/* File: x86/OP_RETURN_WIDE.S */
524    /*
525     * Return a 64-bit value.  Copies the return value into the "self"
526     * structure, then jumps to the return handler.
527     */
528    /* return-wide vAA */
529    movl    rSELF,%ecx
530    GET_VREG_WORD %eax rINST 0       # eax<- v[AA+0]
531    GET_VREG_WORD rINST rINST 1      # rINST<- v[AA+1]
532    movl    %eax,offThread_retval(%ecx)
533    movl    rINST,4+offThread_retval(%ecx)
534    jmp     common_returnFromMethod
535
536/* ------------------------------ */
537.L_OP_RETURN_OBJECT: /* 0x11 */
538/* File: x86/OP_RETURN_OBJECT.S */
539/* File: x86/OP_RETURN.S */
540    /*
541     * Return a 32-bit value.  Copies the return value into the "self"
542     * structure, then jumps to the return handler.
543     *
544     * for: return, return-object
545     */
546    /* op vAA */
547    movl    rSELF,%ecx
548    GET_VREG_R %eax rINST               # eax<- vAA
549    movl    %eax,offThread_retval(%ecx)   # retval.i <- AA
550    jmp     common_returnFromMethod
551
552
553/* ------------------------------ */
554.L_OP_CONST_4: /* 0x12 */
555/* File: x86/OP_CONST_4.S */
556    /* const/4 vA, #+B */
557    movsx   rINSTbl,%eax              # eax<-ssssssBx
558    movl    $0xf,rINST
559    andl    %eax,rINST                # rINST<- A
560    FETCH_INST_OPCODE 1 %ecx
561    ADVANCE_PC 1
562    sarl    $4,%eax
563    SET_VREG %eax rINST
564    GOTO_NEXT_R %ecx
565
566/* ------------------------------ */
567.L_OP_CONST_16: /* 0x13 */
568/* File: x86/OP_CONST_16.S */
569    /* const/16 vAA, #+BBBB */
570    movswl  2(rPC),%ecx                # ecx<- ssssBBBB
571    FETCH_INST_OPCODE 2 %eax
572    ADVANCE_PC 2
573    SET_VREG %ecx rINST                # vAA<- ssssBBBB
574    GOTO_NEXT_R %eax
575
576/* ------------------------------ */
577.L_OP_CONST: /* 0x14 */
578/* File: x86/OP_CONST.S */
579    /* const vAA, #+BBBBbbbb */
580    movl      2(rPC),%eax             # grab all 32 bits at once
581    movl      rINST,rINST             # rINST<- AA
582    FETCH_INST_OPCODE 3 %ecx
583    ADVANCE_PC 3
584    SET_VREG %eax rINST               # vAA<- eax
585    GOTO_NEXT_R %ecx
586
587/* ------------------------------ */
588.L_OP_CONST_HIGH16: /* 0x15 */
589/* File: x86/OP_CONST_HIGH16.S */
590    /* const/high16 vAA, #+BBBB0000 */
591    movzwl     2(rPC),%eax                # eax<- 0000BBBB
592    FETCH_INST_OPCODE 2 %ecx
593    ADVANCE_PC 2
594    sall       $16,%eax                  # eax<- BBBB0000
595    SET_VREG %eax rINST                   # vAA<- eax
596    GOTO_NEXT_R %ecx
597
598/* ------------------------------ */
599.L_OP_CONST_WIDE_16: /* 0x16 */
600/* File: x86/OP_CONST_WIDE_16.S */
601    /* const-wide/16 vAA, #+BBBB */
602    movswl    2(rPC),%eax               # eax<- ssssBBBB
603    SPILL(rIBASE)                       # preserve rIBASE (cltd trashes it)
604    cltd                                # rIBASE:eax<- ssssssssssssBBBB
605    SET_VREG_WORD rIBASE rINST 1        # store msw
606    FETCH_INST_OPCODE 2 %ecx
607    UNSPILL(rIBASE)                     # restore rIBASE
608    SET_VREG_WORD %eax rINST 0          # store lsw
609    ADVANCE_PC 2
610    GOTO_NEXT_R %ecx
611
612/* ------------------------------ */
613.L_OP_CONST_WIDE_32: /* 0x17 */
614/* File: x86/OP_CONST_WIDE_32.S */
615    /* const-wide/32 vAA, #+BBBBbbbb */
616    movl     2(rPC),%eax                # eax<- BBBBbbbb
617    SPILL(rIBASE)                       # save rIBASE (cltd trashes it)
618    cltd                                # rIBASE:eax<- ssssssssssssBBBB
619    SET_VREG_WORD rIBASE rINST,1        # store msw
620    FETCH_INST_OPCODE 3 %ecx
621    UNSPILL(rIBASE)                     # restore rIBASE
622    SET_VREG_WORD %eax rINST 0          # store lsw
623    ADVANCE_PC 3
624    GOTO_NEXT_R %ecx
625
626/* ------------------------------ */
627.L_OP_CONST_WIDE: /* 0x18 */
628/* File: x86/OP_CONST_WIDE.S */
629    /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
630    movl      2(rPC),%eax         # eax<- lsw
631    movzbl    rINSTbl,%ecx        # ecx<- AA
632    movl      6(rPC),rINST        # rINST<- msw
633    leal      (rFP,%ecx,4),%ecx   # dst addr
634    movl      rINST,4(%ecx)
635    movl      %eax,(%ecx)
636    FETCH_INST_OPCODE 5 %ecx
637    ADVANCE_PC 5
638    GOTO_NEXT_R %ecx
639
640/* ------------------------------ */
641.L_OP_CONST_WIDE_HIGH16: /* 0x19 */
642/* File: x86/OP_CONST_WIDE_HIGH16.S */
643    /* const-wide/high16 vAA, #+BBBB000000000000 */
644    movzwl     2(rPC),%eax                # eax<- 0000BBBB
645    FETCH_INST_OPCODE 2 %ecx
646    ADVANCE_PC 2
647    sall       $16,%eax                  # eax<- BBBB0000
648    SET_VREG_WORD %eax rINST 1            # v[AA+1]<- eax
649    xorl       %eax,%eax
650    SET_VREG_WORD %eax rINST 0            # v[AA+0]<- eax
651    GOTO_NEXT_R %ecx
652
653/* ------------------------------ */
654.L_OP_CONST_STRING: /* 0x1a */
655/* File: x86/OP_CONST_STRING.S */
656
657    /* const/string vAA, String@BBBB */
658    movl      rSELF,%ecx
659    movzwl    2(rPC),%eax              # eax<- BBBB
660    movl      offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex
661    movl      offDvmDex_pResStrings(%ecx),%ecx # ecx<- dvmDex->pResStrings
662    movl      (%ecx,%eax,4),%eax       # eax<- rResString[BBBB]
663    FETCH_INST_OPCODE 2 %ecx
664    testl     %eax,%eax                # resolved yet?
665    je        .LOP_CONST_STRING_resolve
666    SET_VREG  %eax rINST               # vAA<- rResString[BBBB]
667    ADVANCE_PC 2
668    GOTO_NEXT_R %ecx
669
670/* This is the less common path, so we'll redo some work
671   here rather than force spills on the common path */
672.LOP_CONST_STRING_resolve:
673    movl     rSELF,%eax
674    EXPORT_PC
675    movl     offThread_method(%eax),%eax # eax<- self->method
676    movzwl   2(rPC),%ecx               # ecx<- BBBB
677    movl     offMethod_clazz(%eax),%eax
678    movl     %ecx,OUT_ARG1(%esp)
679    movl     %eax,OUT_ARG0(%esp)
680    SPILL(rIBASE)
681    call     dvmResolveString          # go resolve
682    UNSPILL(rIBASE)
683    testl    %eax,%eax                 # failed?
684    je       common_exceptionThrown
685    FETCH_INST_OPCODE 2 %ecx
686    SET_VREG %eax rINST
687    ADVANCE_PC 2
688    GOTO_NEXT_R %ecx
689
690/* ------------------------------ */
691.L_OP_CONST_STRING_JUMBO: /* 0x1b */
692/* File: x86/OP_CONST_STRING_JUMBO.S */
693
694    /* const/string vAA, String@BBBBBBBB */
695    movl      rSELF,%ecx
696    movl      2(rPC),%eax              # eax<- BBBBBBBB
697    movl      offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex
698    movl      offDvmDex_pResStrings(%ecx),%ecx # ecx<- dvmDex->pResStrings
699    movl      (%ecx,%eax,4),%eax       # eax<- rResString[BBBB]
700    FETCH_INST_OPCODE 3 %ecx
701    testl     %eax,%eax                # resolved yet?
702    je        .LOP_CONST_STRING_JUMBO_resolve
703    SET_VREG  %eax rINST               # vAA<- rResString[BBBB]
704    ADVANCE_PC 3
705    GOTO_NEXT_R %ecx
706
707/* This is the less common path, so we'll redo some work
708   here rather than force spills on the common path */
709.LOP_CONST_STRING_JUMBO_resolve:
710    movl     rSELF,%eax
711    EXPORT_PC
712    movl     offThread_method(%eax),%eax # eax<- self->method
713    movl     2(rPC),%ecx               # ecx<- BBBBBBBB
714    movl     offMethod_clazz(%eax),%eax
715    movl     %ecx,OUT_ARG1(%esp)
716    movl     %eax,OUT_ARG0(%esp)
717    SPILL(rIBASE)
718    call     dvmResolveString          # go resolve
719    UNSPILL(rIBASE)
720    testl    %eax,%eax                 # failed?
721    je       common_exceptionThrown
722    FETCH_INST_OPCODE 3 %ecx
723    SET_VREG %eax rINST
724    ADVANCE_PC 3
725    GOTO_NEXT_R %ecx
726
727/* ------------------------------ */
728.L_OP_CONST_CLASS: /* 0x1c */
729/* File: x86/OP_CONST_CLASS.S */
730
731    /* const/class vAA, Class@BBBB */
732    movl      rSELF,%ecx
733    movzwl    2(rPC),%eax              # eax<- BBBB
734    movl      offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex
735    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- dvmDex->pResClasses
736    movl      (%ecx,%eax,4),%eax       # eax<- rResClasses[BBBB]
737    testl     %eax,%eax                # resolved yet?
738    je        .LOP_CONST_CLASS_resolve
739    FETCH_INST_OPCODE 2 %ecx
740    SET_VREG  %eax rINST               # vAA<- rResClasses[BBBB]
741    ADVANCE_PC 2
742    GOTO_NEXT_R %ecx
743
744/* This is the less common path, so we'll redo some work
745   here rather than force spills on the common path */
746.LOP_CONST_CLASS_resolve:
747    movl     rSELF,%eax
748    EXPORT_PC
749    movl     offThread_method(%eax),%eax # eax<- self->method
750    movl     $1,OUT_ARG2(%esp)        # true
751    movzwl   2(rPC),%ecx               # ecx<- BBBB
752    movl     offMethod_clazz(%eax),%eax
753    movl     %ecx,OUT_ARG1(%esp)
754    movl     %eax,OUT_ARG0(%esp)
755    SPILL(rIBASE)
756    call     dvmResolveClass           # go resolve
757    UNSPILL(rIBASE)
758    testl    %eax,%eax                 # failed?
759    je       common_exceptionThrown
760    FETCH_INST_OPCODE 2 %ecx
761    SET_VREG %eax rINST
762    ADVANCE_PC 2
763    GOTO_NEXT_R %ecx
764
765/* ------------------------------ */
766.L_OP_MONITOR_ENTER: /* 0x1d */
767/* File: x86/OP_MONITOR_ENTER.S */
768    /*
769     * Synchronize on an object.
770     */
771    /* monitor-enter vAA */
772    movl    rSELF,%ecx
773    GET_VREG_R %eax rINST               # eax<- vAA
774    FETCH_INST_WORD 1
775    testl   %eax,%eax                   # null object?
776    EXPORT_PC                           # need for precise GC
777    je     common_errNullObject
778    movl    %ecx,OUT_ARG0(%esp)
779    movl    %eax,OUT_ARG1(%esp)
780    SPILL(rIBASE)
781    call    dvmLockObject               # dvmLockObject(self,object)
782    UNSPILL(rIBASE)
783    FETCH_INST_OPCODE 1 %ecx
784    ADVANCE_PC 1
785    GOTO_NEXT_R %ecx
786
787/* ------------------------------ */
788.L_OP_MONITOR_EXIT: /* 0x1e */
789/* File: x86/OP_MONITOR_EXIT.S */
790    /*
791     * Unlock an object.
792     *
793     * Exceptions that occur when unlocking a monitor need to appear as
794     * if they happened at the following instruction.  See the Dalvik
795     * instruction spec.
796     */
797    /* monitor-exit vAA */
798    GET_VREG_R %eax rINST
799    movl    rSELF,%ecx
800    EXPORT_PC
801    testl   %eax,%eax                   # null object?
802    je      .LOP_MONITOR_EXIT_errNullObject   # go if so
803    movl    %eax,OUT_ARG1(%esp)
804    movl    %ecx,OUT_ARG0(%esp)
805    SPILL(rIBASE)
806    call    dvmUnlockObject             # unlock(self,obj)
807    UNSPILL(rIBASE)
808    FETCH_INST_OPCODE 1 %ecx
809    testl   %eax,%eax                   # success?
810    ADVANCE_PC 1
811    je      common_exceptionThrown      # no, exception pending
812    GOTO_NEXT_R %ecx
813.LOP_MONITOR_EXIT_errNullObject:
814    ADVANCE_PC 1                        # advance before throw
815    jmp     common_errNullObject
816
817/* ------------------------------ */
818.L_OP_CHECK_CAST: /* 0x1f */
819/* File: x86/OP_CHECK_CAST.S */
820    /*
821     * Check to see if a cast from one class to another is allowed.
822     */
823    /* check-cast vAA, class@BBBB */
824    movl      rSELF,%ecx
825    GET_VREG_R  rINST,rINST             # rINST<- vAA (object)
826    movzwl    2(rPC),%eax               # eax<- BBBB
827    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
828    testl     rINST,rINST               # is oject null?
829    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
830    je        .LOP_CHECK_CAST_okay          # null obj, cast always succeeds
831    movl      (%ecx,%eax,4),%eax        # eax<- resolved class
832    movl      offObject_clazz(rINST),%ecx # ecx<- obj->clazz
833    testl     %eax,%eax                 # have we resolved this before?
834    je        .LOP_CHECK_CAST_resolve       # no, go do it now
835.LOP_CHECK_CAST_resolved:
836    cmpl      %eax,%ecx                 # same class (trivial success)?
837    jne       .LOP_CHECK_CAST_fullcheck     # no, do full check
838.LOP_CHECK_CAST_okay:
839    FETCH_INST_OPCODE 2 %ecx
840    ADVANCE_PC 2
841    GOTO_NEXT_R %ecx
842
843    /*
844     * Trivial test failed, need to perform full check.  This is common.
845     *  ecx holds obj->clazz
846     *  eax holds class resolved from BBBB
847     *  rINST holds object
848     */
849.LOP_CHECK_CAST_fullcheck:
850    movl    %eax,sReg0                 # we'll need the desired class on failure
851    movl    %eax,OUT_ARG1(%esp)
852    movl    %ecx,OUT_ARG0(%esp)
853    SPILL(rIBASE)
854    call    dvmInstanceofNonTrivial    # eax<- boolean result
855    UNSPILL(rIBASE)
856    testl   %eax,%eax                  # failed?
857    jne     .LOP_CHECK_CAST_okay           # no, success
858
859    # A cast has failed.  We need to throw a ClassCastException.
860    EXPORT_PC
861    movl    offObject_clazz(rINST),%eax
862    movl    %eax,OUT_ARG0(%esp)                 # arg0<- obj->clazz
863    movl    sReg0,%ecx
864    movl    %ecx,OUT_ARG1(%esp)                 # arg1<- desired class
865    call    dvmThrowClassCastException
866    jmp     common_exceptionThrown
867
868    /*
869     * Resolution required.  This is the least-likely path, and we're
870     * going to have to recreate some data.
871     *
872     *  rINST holds object
873     */
874.LOP_CHECK_CAST_resolve:
875    movl    rSELF,%ecx
876    EXPORT_PC
877    movzwl  2(rPC),%eax                # eax<- BBBB
878    movl    offThread_method(%ecx),%ecx  # ecx<- self->method
879    movl    %eax,OUT_ARG1(%esp)        # arg1<- BBBB
880    movl    offMethod_clazz(%ecx),%ecx # ecx<- metho->clazz
881    movl    $0,OUT_ARG2(%esp)         # arg2<- false
882    movl    %ecx,OUT_ARG0(%esp)        # arg0<- method->clazz
883    SPILL(rIBASE)
884    call    dvmResolveClass            # eax<- resolved ClassObject ptr
885    UNSPILL(rIBASE)
886    testl   %eax,%eax                  # got null?
887    je      common_exceptionThrown     # yes, handle exception
888    movl    offObject_clazz(rINST),%ecx  # ecx<- obj->clazz
889    jmp     .LOP_CHECK_CAST_resolved       # pick up where we left off
890
891/* ------------------------------ */
892.L_OP_INSTANCE_OF: /* 0x20 */
893/* File: x86/OP_INSTANCE_OF.S */
894    /*
895     * Check to see if an object reference is an instance of a class.
896     *
897     * Most common situation is a non-null object, being compared against
898     * an already-resolved class.
899     */
900    /* instance-of vA, vB, class@CCCC */
901    movl    rINST,%eax                  # eax<- BA
902    sarl    $4,%eax                    # eax<- B
903    GET_VREG_R %eax %eax                # eax<- vB (obj)
904    movl    rSELF,%ecx
905    testl   %eax,%eax                   # object null?
906    movl    offThread_methodClassDex(%ecx),%ecx  # ecx<- pDvmDex
907    SPILL(rIBASE)                       # preserve rIBASE
908    je      .LOP_INSTANCE_OF_store           # null obj, not instance, store it
909    movzwl  2(rPC),rIBASE               # rIBASE<- CCCC
910    movl    offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
911    movl    (%ecx,rIBASE,4),%ecx        # ecx<- resolved class
912    movl    offObject_clazz(%eax),%eax  # eax<- obj->clazz
913    testl   %ecx,%ecx                   # have we resolved this before?
914    je      .LOP_INSTANCE_OF_resolve         # not resolved, do it now
915.LOP_INSTANCE_OF_resolved:  # eax<- obj->clazz, ecx<- resolved class
916    cmpl    %eax,%ecx                   # same class (trivial success)?
917    je      .LOP_INSTANCE_OF_trivial         # yes, trivial finish
918    /*
919     * Trivial test failed, need to perform full check.  This is common.
920     *  eax holds obj->clazz
921     *  ecx holds class resolved from BBBB
922     *  rINST has BA
923     */
924    movl    %eax,OUT_ARG0(%esp)
925    movl    %ecx,OUT_ARG1(%esp)
926    call    dvmInstanceofNonTrivial     # eax<- boolean result
927    # fall through to OP_INSTANCE_OF_store
928
929    /*
930     * eax holds boolean result
931     * rINST holds BA
932     */
933.LOP_INSTANCE_OF_store:
934    FETCH_INST_OPCODE 2 %ecx
935    UNSPILL(rIBASE)
936    andb    $0xf,rINSTbl               # <- A
937    ADVANCE_PC 2
938    SET_VREG %eax rINST                 # vA<- eax
939    GOTO_NEXT_R %ecx
940
941    /*
942     * Trivial test succeeded, save and bail.
943     *  r9 holds A
944     */
945.LOP_INSTANCE_OF_trivial:
946    FETCH_INST_OPCODE 2 %ecx
947    UNSPILL(rIBASE)
948    andb    $0xf,rINSTbl               # <- A
949    ADVANCE_PC 2
950    movl    $1,%eax
951    SET_VREG %eax rINST                 # vA<- true
952    GOTO_NEXT_R %ecx
953
954    /*
955     * Resolution required.  This is the least-likely path.
956     *
957     *  rIBASE holds BBBB
958     *  rINST holds BA
959     */
960.LOP_INSTANCE_OF_resolve:
961    movl    rIBASE,OUT_ARG1(%esp)         # arg1<- BBBB
962    movl    rSELF,%ecx
963    movl    offThread_method(%ecx),%ecx
964    movl    $1,OUT_ARG2(%esp)          # arg2<- true
965    movl    offMethod_clazz(%ecx),%ecx  # ecx<- method->clazz
966    EXPORT_PC
967    movl    %ecx,OUT_ARG0(%esp)         # arg0<- method->clazz
968    call    dvmResolveClass             # eax<- resolved ClassObject ptr
969    testl   %eax,%eax                   # success?
970    je      common_exceptionThrown      # no, handle exception
971/* Now, we need to sync up with fast path.  We need eax to
972 * hold the obj->clazz, and ecx to hold the resolved class
973 */
974    movl    %eax,%ecx                   # ecx<- resolved class
975    movl    rINST,%eax                  # eax<- BA
976    sarl    $4,%eax                    # eax<- B
977    GET_VREG_R %eax %eax                # eax<- vB (obj)
978    movl    offObject_clazz(%eax),%eax  # eax<- obj->clazz
979    jmp     .LOP_INSTANCE_OF_resolved
980
981/* ------------------------------ */
982.L_OP_ARRAY_LENGTH: /* 0x21 */
983/* File: x86/OP_ARRAY_LENGTH.S */
984    /*
985     * Return the length of an array.
986     */
987   mov      rINST,%eax                # eax<- BA
988   sarl     $4,rINST                 # rINST<- B
989   GET_VREG_R %ecx rINST              # ecx<- vB (object ref)
990   andb     $0xf,%al                 # eax<- A
991   testl    %ecx,%ecx                 # is null?
992   je       common_errNullObject
993   movl     offArrayObject_length(%ecx),rINST
994   FETCH_INST_OPCODE 1 %ecx
995   ADVANCE_PC 1
996   SET_VREG rINST %eax
997   GOTO_NEXT_R %ecx
998
999/* ------------------------------ */
1000.L_OP_NEW_INSTANCE: /* 0x22 */
1001/* File: x86/OP_NEW_INSTANCE.S */
1002    /*
1003     * Create a new instance of a class.
1004     */
1005    /* new-instance vAA, class@BBBB */
1006    movl      rSELF,%ecx
1007    movzwl    2(rPC),%eax               # eax<- BBBB
1008    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- pDvmDex
1009    SPILL(rIBASE)
1010    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
1011    EXPORT_PC
1012    movl      (%ecx,%eax,4),%ecx        # ecx<- resolved class
1013    testl     %ecx,%ecx                 # resolved?
1014    je        .LOP_NEW_INSTANCE_resolve       # no, go do it
1015.LOP_NEW_INSTANCE_resolved:  # on entry, ecx<- class
1016    cmpb      $CLASS_INITIALIZED,offClassObject_status(%ecx)
1017    jne       .LOP_NEW_INSTANCE_needinit
1018.LOP_NEW_INSTANCE_initialized:  # on entry, ecx<- class
1019    movl      $ALLOC_DONT_TRACK,OUT_ARG1(%esp)
1020    movl     %ecx,OUT_ARG0(%esp)
1021    call     dvmAllocObject             # eax<- new object
1022    FETCH_INST_OPCODE 2 %ecx
1023    UNSPILL(rIBASE)
1024    testl    %eax,%eax                  # success?
1025    je       common_exceptionThrown     # no, bail out
1026    SET_VREG %eax rINST
1027    ADVANCE_PC 2
1028    GOTO_NEXT_R %ecx
1029
1030    /*
1031     * Class initialization required.
1032     *
1033     *  ecx holds class object
1034     */
1035.LOP_NEW_INSTANCE_needinit:
1036    SPILL_TMP1(%ecx)                    # save object
1037    movl    %ecx,OUT_ARG0(%esp)
1038    call    dvmInitClass                # initialize class
1039    UNSPILL_TMP1(%ecx)                  # restore object
1040    testl   %eax,%eax                   # success?
1041    jne     .LOP_NEW_INSTANCE_initialized     # success, continue
1042    jmp     common_exceptionThrown      # go deal with init exception
1043
1044    /*
1045     * Resolution required.  This is the least-likely path.
1046     *
1047     */
1048.LOP_NEW_INSTANCE_resolve:
1049    movl    rSELF,%ecx
1050    movzwl  2(rPC),%eax
1051    movl    offThread_method(%ecx),%ecx   # ecx<- self->method
1052    movl    %eax,OUT_ARG1(%esp)
1053    movl    offMethod_clazz(%ecx),%ecx  # ecx<- method->clazz
1054    movl    $0,OUT_ARG2(%esp)
1055    movl    %ecx,OUT_ARG0(%esp)
1056    call    dvmResolveClass             # call(clazz,off,flags)
1057    movl    %eax,%ecx                   # ecx<- resolved ClassObject ptr
1058    testl   %ecx,%ecx                   # success?
1059    jne     .LOP_NEW_INSTANCE_resolved        # good to go
1060    jmp     common_exceptionThrown      # no, handle exception
1061
1062/* ------------------------------ */
1063.L_OP_NEW_ARRAY: /* 0x23 */
1064/* File: x86/OP_NEW_ARRAY.S */
1065    /*
1066     * Allocate an array of objects, specified with the array class
1067     * and a count.
1068     *
1069     * The verifier guarantees that this is an array class, so we don't
1070     * check for it here.
1071     */
1072    /* new-array vA, vB, class@CCCC */
1073    movl    rSELF,%ecx
1074    EXPORT_PC
1075    movl    offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
1076    movzwl  2(rPC),%eax                       # eax<- CCCC
1077    movl    offDvmDex_pResClasses(%ecx),%ecx  # ecx<- pDvmDex->pResClasses
1078    SPILL(rIBASE)
1079    movl    (%ecx,%eax,4),%ecx                # ecx<- resolved class
1080    movzbl  rINSTbl,%eax
1081    sarl    $4,%eax                          # eax<- B
1082    GET_VREG_R %eax %eax                      # eax<- vB (array length)
1083    andb    $0xf,rINSTbl                     # rINST<- A
1084    testl   %eax,%eax
1085    js      common_errNegativeArraySize       # bail, passing len in eax
1086    testl   %ecx,%ecx                         # already resolved?
1087    jne     .LOP_NEW_ARRAY_finish                # yes, fast path
1088    /*
1089     * Resolve class.  (This is an uncommon case.)
1090     *  ecx holds class (null here)
1091     *  eax holds array length (vB)
1092     */
1093    movl    rSELF,%ecx
1094    SPILL_TMP1(%eax)                   # save array length
1095    movl    offThread_method(%ecx),%ecx  # ecx<- self->method
1096    movzwl  2(rPC),%eax                # eax<- CCCC
1097    movl    offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
1098    movl    %eax,OUT_ARG1(%esp)
1099    movl    $0,OUT_ARG2(%esp)
1100    movl    %ecx,OUT_ARG0(%esp)
1101    call    dvmResolveClass            # eax<- call(clazz,ref,flag)
1102    movl    %eax,%ecx
1103    UNSPILL_TMP1(%eax)
1104    testl   %ecx,%ecx                  # successful resolution?
1105    je      common_exceptionThrown     # no, bail.
1106# fall through to OP_NEW_ARRAY_finish
1107
1108    /*
1109     * Finish allocation
1110     *
1111     * ecx holds class
1112     * eax holds array length (vB)
1113     */
1114.LOP_NEW_ARRAY_finish:
1115    movl    %ecx,OUT_ARG0(%esp)
1116    movl    %eax,OUT_ARG1(%esp)
1117    movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)
1118    call    dvmAllocArrayByClass    # eax<- call(clazz,length,flags)
1119    FETCH_INST_OPCODE 2 %ecx
1120    UNSPILL(rIBASE)
1121    testl   %eax,%eax               # failed?
1122    je      common_exceptionThrown  # yup - go handle
1123    SET_VREG %eax rINST
1124    ADVANCE_PC 2
1125    GOTO_NEXT_R %ecx
1126
1127/* ------------------------------ */
1128.L_OP_FILLED_NEW_ARRAY: /* 0x24 */
1129/* File: x86/OP_FILLED_NEW_ARRAY.S */
1130    /*
1131     * Create a new array with elements filled from registers.
1132     *
1133     * for: filled-new-array, filled-new-array/range
1134     */
1135    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1136    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1137    movl    rSELF,%eax
1138    movl    offThread_methodClassDex(%eax),%eax # eax<- pDvmDex
1139    movzwl  2(rPC),%ecx                       # ecx<- BBBB
1140    movl    offDvmDex_pResClasses(%eax),%eax  # eax<- pDvmDex->pResClasses
1141    SPILL(rIBASE)                             # preserve rIBASE
1142    movl    (%eax,%ecx,4),%eax                # eax<- resolved class
1143    EXPORT_PC
1144    testl   %eax,%eax                         # already resolved?
1145    jne     .LOP_FILLED_NEW_ARRAY_continue              # yes, continue
1146    # less frequent path, so we'll redo some work
1147    movl    rSELF,%eax
1148    movl    $0,OUT_ARG2(%esp)                # arg2<- false
1149    movl    %ecx,OUT_ARG1(%esp)               # arg1<- BBBB
1150    movl    offThread_method(%eax),%eax         # eax<- self->method
1151    movl    offMethod_clazz(%eax),%eax        # eax<- method->clazz
1152    movl    %eax,OUT_ARG0(%esp)               # arg0<- clazz
1153    call    dvmResolveClass                   # eax<- call(clazz,ref,flag)
1154    testl   %eax,%eax                         # null?
1155    je      common_exceptionThrown            # yes, handle it
1156
1157       # note: fall through to .LOP_FILLED_NEW_ARRAY_continue
1158
1159    /*
1160     * On entry:
1161     *    eax holds array class [r0]
1162     *    rINST holds AA or BB [r10]
1163     *    ecx is scratch
1164     */
1165.LOP_FILLED_NEW_ARRAY_continue:
1166    movl    offClassObject_descriptor(%eax),%ecx  # ecx<- arrayClass->descriptor
1167    movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)     # arg2<- flags
1168    movzbl  1(%ecx),%ecx                          # ecx<- descriptor[1]
1169    movl    %eax,OUT_ARG0(%esp)                   # arg0<- arrayClass
1170    movl    rSELF,%eax
1171    cmpb    $'I',%cl                             # supported?
1172    je      1f
1173    cmpb    $'L',%cl
1174    je      1f
1175    cmpb    $'[',%cl
1176    jne      .LOP_FILLED_NEW_ARRAY_notimpl                  # no, not handled yet
11771:
1178    movl    %ecx,offThread_retval+4(%eax)           # save type
1179    .if      (!0)
1180    SPILL_TMP1(rINST)                              # save copy, need "B" later
1181    sarl    $4,rINST
1182    .endif
1183    movl    rINST,OUT_ARG1(%esp)                  # arg1<- A or AA (length)
1184    call    dvmAllocArrayByClass     # eax<- call(arrayClass, length, flags)
1185    movl    rSELF,%ecx
1186    testl   %eax,%eax                             # alloc successful?
1187    je      common_exceptionThrown                # no, handle exception
1188    movl    %eax,offThread_retval(%ecx)             # retval.l<- new array
1189    movzwl  4(rPC),%ecx                           # ecx<- FEDC or CCCC
1190    leal    offArrayObject_contents(%eax),%eax    # eax<- newArray->contents
1191
1192/* at this point:
1193 *     eax is pointer to tgt
1194 *     rINST is length
1195 *     ecx is FEDC or CCCC
1196 *     TMP_SPILL1 is BA
1197 *  We now need to copy values from registers into the array
1198 */
1199
1200    .if 0
1201    # set up src pointer
1202    SPILL_TMP2(%esi)
1203    SPILL_TMP3(%edi)
1204    leal    (rFP,%ecx,4),%esi # set up src ptr
1205    movl    %eax,%edi         # set up dst ptr
1206    movl    rINST,%ecx        # load count register
1207    rep
1208    movsd
1209    UNSPILL_TMP2(%esi)
1210    UNSPILL_TMP3(%edi)
1211    movl    rSELF,%ecx
1212    movl    offThread_retval+4(%ecx),%eax      # eax<- type
1213    .else
1214    testl  rINST,rINST
1215    je     4f
1216    UNSPILL_TMP1(rIBASE)      # restore "BA"
1217    andl   $0x0f,rIBASE      # rIBASE<- 0000000A
1218    sall   $16,rIBASE        # rIBASE<- 000A0000
1219    orl    %ecx,rIBASE        # rIBASE<- 000AFEDC
12203:
1221    movl   $0xf,%ecx
1222    andl   rIBASE,%ecx        # ecx<- next reg to load
1223    GET_VREG_R %ecx %ecx
1224    shrl   $4,rIBASE
1225    leal   4(%eax),%eax
1226    movl   %ecx,-4(%eax)
1227    sub    $1,rINST
1228    jne    3b
12294:
1230    movl   rSELF,%ecx
1231    movl    offThread_retval+4(%ecx),%eax      # eax<- type
1232    .endif
1233
1234    cmpb    $'I',%al                        # Int array?
1235    je      5f                               # skip card mark if so
1236    movl    offThread_retval(%ecx),%eax        # eax<- object head
1237    movl    offThread_cardTable(%ecx),%ecx     # card table base
1238    shrl    $GC_CARD_SHIFT,%eax             # convert to card num
1239    movb    %cl,(%ecx,%eax)                  # mark card based on object head
12405:
1241    UNSPILL(rIBASE)                          # restore rIBASE
1242    FETCH_INST_OPCODE 3 %ecx
1243    ADVANCE_PC 3
1244    GOTO_NEXT_R %ecx
1245
1246
1247    /*
1248     * Throw an exception indicating that we have not implemented this
1249     * mode of filled-new-array.
1250     */
1251.LOP_FILLED_NEW_ARRAY_notimpl:
1252    movl    $.LstrFilledNewArrayNotImplA,%eax
1253    movl    %eax,OUT_ARG0(%esp)
1254    call    dvmThrowInternalError
1255    jmp     common_exceptionThrown
1256
1257/* ------------------------------ */
1258.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
1259/* File: x86/OP_FILLED_NEW_ARRAY_RANGE.S */
1260/* File: x86/OP_FILLED_NEW_ARRAY.S */
1261    /*
1262     * Create a new array with elements filled from registers.
1263     *
1264     * for: filled-new-array, filled-new-array/range
1265     */
1266    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1267    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1268    movl    rSELF,%eax
1269    movl    offThread_methodClassDex(%eax),%eax # eax<- pDvmDex
1270    movzwl  2(rPC),%ecx                       # ecx<- BBBB
1271    movl    offDvmDex_pResClasses(%eax),%eax  # eax<- pDvmDex->pResClasses
1272    SPILL(rIBASE)                             # preserve rIBASE
1273    movl    (%eax,%ecx,4),%eax                # eax<- resolved class
1274    EXPORT_PC
1275    testl   %eax,%eax                         # already resolved?
1276    jne     .LOP_FILLED_NEW_ARRAY_RANGE_continue              # yes, continue
1277    # less frequent path, so we'll redo some work
1278    movl    rSELF,%eax
1279    movl    $0,OUT_ARG2(%esp)                # arg2<- false
1280    movl    %ecx,OUT_ARG1(%esp)               # arg1<- BBBB
1281    movl    offThread_method(%eax),%eax         # eax<- self->method
1282    movl    offMethod_clazz(%eax),%eax        # eax<- method->clazz
1283    movl    %eax,OUT_ARG0(%esp)               # arg0<- clazz
1284    call    dvmResolveClass                   # eax<- call(clazz,ref,flag)
1285    testl   %eax,%eax                         # null?
1286    je      common_exceptionThrown            # yes, handle it
1287
1288       # note: fall through to .LOP_FILLED_NEW_ARRAY_RANGE_continue
1289
1290    /*
1291     * On entry:
1292     *    eax holds array class [r0]
1293     *    rINST holds AA or BB [r10]
1294     *    ecx is scratch
1295     */
1296.LOP_FILLED_NEW_ARRAY_RANGE_continue:
1297    movl    offClassObject_descriptor(%eax),%ecx  # ecx<- arrayClass->descriptor
1298    movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)     # arg2<- flags
1299    movzbl  1(%ecx),%ecx                          # ecx<- descriptor[1]
1300    movl    %eax,OUT_ARG0(%esp)                   # arg0<- arrayClass
1301    movl    rSELF,%eax
1302    cmpb    $'I',%cl                             # supported?
1303    je      1f
1304    cmpb    $'L',%cl
1305    je      1f
1306    cmpb    $'[',%cl
1307    jne      .LOP_FILLED_NEW_ARRAY_RANGE_notimpl                  # no, not handled yet
13081:
1309    movl    %ecx,offThread_retval+4(%eax)           # save type
1310    .if      (!1)
1311    SPILL_TMP1(rINST)                              # save copy, need "B" later
1312    sarl    $4,rINST
1313    .endif
1314    movl    rINST,OUT_ARG1(%esp)                  # arg1<- A or AA (length)
1315    call    dvmAllocArrayByClass     # eax<- call(arrayClass, length, flags)
1316    movl    rSELF,%ecx
1317    testl   %eax,%eax                             # alloc successful?
1318    je      common_exceptionThrown                # no, handle exception
1319    movl    %eax,offThread_retval(%ecx)             # retval.l<- new array
1320    movzwl  4(rPC),%ecx                           # ecx<- FEDC or CCCC
1321    leal    offArrayObject_contents(%eax),%eax    # eax<- newArray->contents
1322
1323/* at this point:
1324 *     eax is pointer to tgt
1325 *     rINST is length
1326 *     ecx is FEDC or CCCC
1327 *     TMP_SPILL1 is BA
1328 *  We now need to copy values from registers into the array
1329 */
1330
1331    .if 1
1332    # set up src pointer
1333    SPILL_TMP2(%esi)
1334    SPILL_TMP3(%edi)
1335    leal    (rFP,%ecx,4),%esi # set up src ptr
1336    movl    %eax,%edi         # set up dst ptr
1337    movl    rINST,%ecx        # load count register
1338    rep
1339    movsd
1340    UNSPILL_TMP2(%esi)
1341    UNSPILL_TMP3(%edi)
1342    movl    rSELF,%ecx
1343    movl    offThread_retval+4(%ecx),%eax      # eax<- type
1344    .else
1345    testl  rINST,rINST
1346    je     4f
1347    UNSPILL_TMP1(rIBASE)      # restore "BA"
1348    andl   $0x0f,rIBASE      # rIBASE<- 0000000A
1349    sall   $16,rIBASE        # rIBASE<- 000A0000
1350    orl    %ecx,rIBASE        # rIBASE<- 000AFEDC
13513:
1352    movl   $0xf,%ecx
1353    andl   rIBASE,%ecx        # ecx<- next reg to load
1354    GET_VREG_R %ecx %ecx
1355    shrl   $4,rIBASE
1356    leal   4(%eax),%eax
1357    movl   %ecx,-4(%eax)
1358    sub    $1,rINST
1359    jne    3b
13604:
1361    movl   rSELF,%ecx
1362    movl    offThread_retval+4(%ecx),%eax      # eax<- type
1363    .endif
1364
1365    cmpb    $'I',%al                        # Int array?
1366    je      5f                               # skip card mark if so
1367    movl    offThread_retval(%ecx),%eax        # eax<- object head
1368    movl    offThread_cardTable(%ecx),%ecx     # card table base
1369    shrl    $GC_CARD_SHIFT,%eax             # convert to card num
1370    movb    %cl,(%ecx,%eax)                  # mark card based on object head
13715:
1372    UNSPILL(rIBASE)                          # restore rIBASE
1373    FETCH_INST_OPCODE 3 %ecx
1374    ADVANCE_PC 3
1375    GOTO_NEXT_R %ecx
1376
1377
1378    /*
1379     * Throw an exception indicating that we have not implemented this
1380     * mode of filled-new-array.
1381     */
1382.LOP_FILLED_NEW_ARRAY_RANGE_notimpl:
1383    movl    $.LstrFilledNewArrayNotImplA,%eax
1384    movl    %eax,OUT_ARG0(%esp)
1385    call    dvmThrowInternalError
1386    jmp     common_exceptionThrown
1387
1388
1389/* ------------------------------ */
1390.L_OP_FILL_ARRAY_DATA: /* 0x26 */
1391/* File: x86/OP_FILL_ARRAY_DATA.S */
1392    /* fill-array-data vAA, +BBBBBBBB */
1393    movl    2(rPC),%ecx                # ecx<- BBBBbbbb
1394    leal    (rPC,%ecx,2),%ecx          # ecx<- PC + BBBBbbbb*2
1395    GET_VREG_R %eax rINST
1396    EXPORT_PC
1397    movl    %eax,OUT_ARG0(%esp)
1398    movl    %ecx,OUT_ARG1(%esp)
1399    SPILL(rIBASE)
1400    call    dvmInterpHandleFillArrayData
1401    UNSPILL(rIBASE)
1402    FETCH_INST_OPCODE 3 %ecx
1403    testl   %eax,%eax                   # exception thrown?
1404    je      common_exceptionThrown
1405    ADVANCE_PC 3
1406    GOTO_NEXT_R %ecx
1407
1408/* ------------------------------ */
1409.L_OP_THROW: /* 0x27 */
1410/* File: x86/OP_THROW.S */
1411    /*
1412     * Throw an exception object in the current thread.
1413     */
1414    /* throw vAA */
1415    EXPORT_PC
1416    GET_VREG_R %eax rINST              # eax<- exception object
1417    movl     rSELF,%ecx                # ecx<- self
1418    testl    %eax,%eax                 # null object?
1419    je       common_errNullObject
1420    movl     %eax,offThread_exception(%ecx) # thread->exception<- obj
1421    jmp      common_exceptionThrown
1422
1423/* ------------------------------ */
1424.L_OP_GOTO: /* 0x28 */
1425/* File: x86/OP_GOTO.S */
1426    /*
1427     * Unconditional branch, 8-bit offset.
1428     *
1429     * The branch distance is a signed code-unit offset, which we need to
1430     * double to get a byte offset.
1431     */
1432    /* goto +AA */
1433    movl    rSELF,%ecx
1434    movsbl  rINSTbl,%eax          # eax<- ssssssAA
1435    movl    offThread_curHandlerTable(%ecx),rIBASE
1436    FETCH_INST_INDEXED %eax
1437    ADVANCE_PC_INDEXED %eax
1438    GOTO_NEXT
1439
1440/* ------------------------------ */
1441.L_OP_GOTO_16: /* 0x29 */
1442/* File: x86/OP_GOTO_16.S */
1443    /*
1444     * Unconditional branch, 16-bit offset.
1445     *
1446     * The branch distance is a signed code-unit offset
1447     */
1448    /* goto/16 +AAAA */
1449    movl    rSELF,%ecx
1450    movswl  2(rPC),%eax            # eax<- ssssAAAA
1451    movl    offThread_curHandlerTable(%ecx),rIBASE
1452    FETCH_INST_INDEXED %eax
1453    ADVANCE_PC_INDEXED %eax
1454    GOTO_NEXT
1455
1456/* ------------------------------ */
1457.L_OP_GOTO_32: /* 0x2a */
1458/* File: x86/OP_GOTO_32.S */
1459    /*
1460     * Unconditional branch, 32-bit offset.
1461     *
1462     * The branch distance is a signed code-unit offset.
1463     */
1464    /* goto/32 AAAAAAAA */
1465    movl    rSELF,%ecx
1466    movl    2(rPC),%eax            # eax<- AAAAAAAA
1467    movl    offThread_curHandlerTable(%ecx),rIBASE
1468    FETCH_INST_INDEXED %eax
1469    ADVANCE_PC_INDEXED %eax
1470    GOTO_NEXT
1471
1472/* ------------------------------ */
1473.L_OP_PACKED_SWITCH: /* 0x2b */
1474/* File: x86/OP_PACKED_SWITCH.S */
1475    /*
1476     * Handle a packed-switch or sparse-switch instruction.  In both cases
1477     * we decode it and hand it off to a helper function.
1478     *
1479     * We don't really expect backward branches in a switch statement, but
1480     * they're perfectly legal, so we check for them here.
1481     *
1482     * for: packed-switch, sparse-switch
1483     */
1484    /* op vAA, +BBBB */
1485    movl    2(rPC),%ecx           # ecx<- BBBBbbbb
1486    GET_VREG_R %eax rINST         # eax<- vAA
1487    leal    (rPC,%ecx,2),%ecx     # ecx<- PC + BBBBbbbb*2
1488    movl    %eax,OUT_ARG1(%esp)   # ARG1<- vAA
1489    movl    %ecx,OUT_ARG0(%esp)   # ARG0<- switchData
1490    call    dvmInterpHandlePackedSwitch
1491    movl    rSELF,%ecx
1492    ADVANCE_PC_INDEXED %eax
1493    movl    offThread_curHandlerTable(%ecx),rIBASE
1494    FETCH_INST
1495    GOTO_NEXT
1496
1497/* ------------------------------ */
1498.L_OP_SPARSE_SWITCH: /* 0x2c */
1499/* File: x86/OP_SPARSE_SWITCH.S */
1500/* File: x86/OP_PACKED_SWITCH.S */
1501    /*
1502     * Handle a packed-switch or sparse-switch instruction.  In both cases
1503     * we decode it and hand it off to a helper function.
1504     *
1505     * We don't really expect backward branches in a switch statement, but
1506     * they're perfectly legal, so we check for them here.
1507     *
1508     * for: packed-switch, sparse-switch
1509     */
1510    /* op vAA, +BBBB */
1511    movl    2(rPC),%ecx           # ecx<- BBBBbbbb
1512    GET_VREG_R %eax rINST         # eax<- vAA
1513    leal    (rPC,%ecx,2),%ecx     # ecx<- PC + BBBBbbbb*2
1514    movl    %eax,OUT_ARG1(%esp)   # ARG1<- vAA
1515    movl    %ecx,OUT_ARG0(%esp)   # ARG0<- switchData
1516    call    dvmInterpHandleSparseSwitch
1517    movl    rSELF,%ecx
1518    ADVANCE_PC_INDEXED %eax
1519    movl    offThread_curHandlerTable(%ecx),rIBASE
1520    FETCH_INST
1521    GOTO_NEXT
1522
1523
1524/* ------------------------------ */
1525.L_OP_CMPL_FLOAT: /* 0x2d */
1526/* File: x86/OP_CMPL_FLOAT.S */
1527/* File: x86/OP_CMPG_DOUBLE.S */
1528    /* float/double_cmp[gl] vAA, vBB, vCC */
1529    movzbl    3(rPC),%eax             # eax<- CC
1530    movzbl    2(rPC),%ecx             # ecx<- BB
1531    .if 0
1532    fldl     (rFP,%eax,4)
1533    fldl     (rFP,%ecx,4)
1534    .else
1535    flds     (rFP,%eax,4)
1536    flds     (rFP,%ecx,4)
1537    .endif
1538    xorl     %ecx,%ecx
1539    fucompp     # z if equal, p set if NaN, c set if st0 < st1
1540    fnstsw   %ax
1541    sahf
1542    FETCH_INST_OPCODE 2 %eax
1543    jp       .LOP_CMPL_FLOAT_isNaN
1544    je       .LOP_CMPL_FLOAT_finish
1545    sbbl     %ecx,%ecx
1546    jb       .LOP_CMPL_FLOAT_finish
1547    incl     %ecx
1548.LOP_CMPL_FLOAT_finish:
1549    SET_VREG %ecx rINST
1550    ADVANCE_PC 2
1551    GOTO_NEXT_R %eax
1552
1553.LOP_CMPL_FLOAT_isNaN:
1554    movl      $-1,%ecx
1555    jmp       .LOP_CMPL_FLOAT_finish
1556
1557
1558/* ------------------------------ */
1559.L_OP_CMPG_FLOAT: /* 0x2e */
1560/* File: x86/OP_CMPG_FLOAT.S */
1561/* File: x86/OP_CMPG_DOUBLE.S */
1562    /* float/double_cmp[gl] vAA, vBB, vCC */
1563    movzbl    3(rPC),%eax             # eax<- CC
1564    movzbl    2(rPC),%ecx             # ecx<- BB
1565    .if 0
1566    fldl     (rFP,%eax,4)
1567    fldl     (rFP,%ecx,4)
1568    .else
1569    flds     (rFP,%eax,4)
1570    flds     (rFP,%ecx,4)
1571    .endif
1572    xorl     %ecx,%ecx
1573    fucompp     # z if equal, p set if NaN, c set if st0 < st1
1574    fnstsw   %ax
1575    sahf
1576    FETCH_INST_OPCODE 2 %eax
1577    jp       .LOP_CMPG_FLOAT_isNaN
1578    je       .LOP_CMPG_FLOAT_finish
1579    sbbl     %ecx,%ecx
1580    jb       .LOP_CMPG_FLOAT_finish
1581    incl     %ecx
1582.LOP_CMPG_FLOAT_finish:
1583    SET_VREG %ecx rINST
1584    ADVANCE_PC 2
1585    GOTO_NEXT_R %eax
1586
1587.LOP_CMPG_FLOAT_isNaN:
1588    movl      $1,%ecx
1589    jmp       .LOP_CMPG_FLOAT_finish
1590
1591
1592/* ------------------------------ */
1593.L_OP_CMPL_DOUBLE: /* 0x2f */
1594/* File: x86/OP_CMPL_DOUBLE.S */
1595/* File: x86/OP_CMPG_DOUBLE.S */
1596    /* float/double_cmp[gl] vAA, vBB, vCC */
1597    movzbl    3(rPC),%eax             # eax<- CC
1598    movzbl    2(rPC),%ecx             # ecx<- BB
1599    .if 1
1600    fldl     (rFP,%eax,4)
1601    fldl     (rFP,%ecx,4)
1602    .else
1603    flds     (rFP,%eax,4)
1604    flds     (rFP,%ecx,4)
1605    .endif
1606    xorl     %ecx,%ecx
1607    fucompp     # z if equal, p set if NaN, c set if st0 < st1
1608    fnstsw   %ax
1609    sahf
1610    FETCH_INST_OPCODE 2 %eax
1611    jp       .LOP_CMPL_DOUBLE_isNaN
1612    je       .LOP_CMPL_DOUBLE_finish
1613    sbbl     %ecx,%ecx
1614    jb       .LOP_CMPL_DOUBLE_finish
1615    incl     %ecx
1616.LOP_CMPL_DOUBLE_finish:
1617    SET_VREG %ecx rINST
1618    ADVANCE_PC 2
1619    GOTO_NEXT_R %eax
1620
1621.LOP_CMPL_DOUBLE_isNaN:
1622    movl      $-1,%ecx
1623    jmp       .LOP_CMPL_DOUBLE_finish
1624
1625
1626/* ------------------------------ */
1627.L_OP_CMPG_DOUBLE: /* 0x30 */
1628/* File: x86/OP_CMPG_DOUBLE.S */
1629    /* float/double_cmp[gl] vAA, vBB, vCC */
1630    movzbl    3(rPC),%eax             # eax<- CC
1631    movzbl    2(rPC),%ecx             # ecx<- BB
1632    .if 1
1633    fldl     (rFP,%eax,4)
1634    fldl     (rFP,%ecx,4)
1635    .else
1636    flds     (rFP,%eax,4)
1637    flds     (rFP,%ecx,4)
1638    .endif
1639    xorl     %ecx,%ecx
1640    fucompp     # z if equal, p set if NaN, c set if st0 < st1
1641    fnstsw   %ax
1642    sahf
1643    FETCH_INST_OPCODE 2 %eax
1644    jp       .LOP_CMPG_DOUBLE_isNaN
1645    je       .LOP_CMPG_DOUBLE_finish
1646    sbbl     %ecx,%ecx
1647    jb       .LOP_CMPG_DOUBLE_finish
1648    incl     %ecx
1649.LOP_CMPG_DOUBLE_finish:
1650    SET_VREG %ecx rINST
1651    ADVANCE_PC 2
1652    GOTO_NEXT_R %eax
1653
1654.LOP_CMPG_DOUBLE_isNaN:
1655    movl      $1,%ecx
1656    jmp       .LOP_CMPG_DOUBLE_finish
1657
1658/* ------------------------------ */
1659.L_OP_CMP_LONG: /* 0x31 */
1660/* File: x86/OP_CMP_LONG.S */
1661    /*
1662     * Compare two 64-bit values.  Puts 0, 1, or -1 into the destination
1663     * register based on the results of the comparison.
1664     */
1665    // TUNING: rework to avoid rIBASE spill
1666    /* cmp-long vAA, vBB, vCC */
1667    movzbl    2(rPC),%ecx              # ecx<- BB
1668    SPILL(rIBASE)
1669    movzbl    3(rPC),rIBASE            # rIBASE- CC
1670    GET_VREG_WORD %eax %ecx,1          # eax<- v[BB+1]
1671    GET_VREG_WORD %ecx %ecx 0          # ecx<- v[BB+0]
1672    cmpl      4(rFP,rIBASE,4),%eax
1673    jl        .LOP_CMP_LONG_smaller
1674    jg        .LOP_CMP_LONG_bigger
1675    sub       (rFP,rIBASE,4),%ecx
1676    ja        .LOP_CMP_LONG_bigger
1677    jb        .LOP_CMP_LONG_smaller
1678    SET_VREG %ecx rINST
1679    FETCH_INST_OPCODE 2 %ecx
1680    UNSPILL(rIBASE)
1681    ADVANCE_PC 2
1682    GOTO_NEXT_R %ecx
1683
1684.LOP_CMP_LONG_bigger:
1685    movl      $1,%ecx
1686    SET_VREG %ecx rINST
1687    FETCH_INST_OPCODE 2 %ecx
1688    UNSPILL(rIBASE)
1689    ADVANCE_PC 2
1690    GOTO_NEXT_R %ecx
1691
1692.LOP_CMP_LONG_smaller:
1693    movl      $-1,%ecx
1694    SET_VREG %ecx rINST
1695    FETCH_INST_OPCODE 2 %ecx
1696    UNSPILL(rIBASE)
1697    ADVANCE_PC 2
1698    GOTO_NEXT_R %ecx
1699
1700/* ------------------------------ */
1701.L_OP_IF_EQ: /* 0x32 */
1702/* File: x86/OP_IF_EQ.S */
1703/* File: x86/bincmp.S */
1704    /*
1705     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1706     * fragment that specifies the *reverse* comparison to perform, e.g.
1707     * for "if-le" you would use "gt".
1708     *
1709     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1710     */
1711    /* if-cmp vA, vB, +CCCC */
1712    movzx    rINSTbl,%ecx          # ecx <- A+
1713    andb     $0xf,%cl             # ecx <- A
1714    GET_VREG_R %eax %ecx           # eax <- vA
1715    sarl     $4,rINST             # rINST<- B
1716    movl     rSELF,%ecx
1717    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1718    movl     $2,%eax              # assume not taken
1719    jne   1f
1720    movswl   2(rPC),%eax           # Get signed branch offset
17211:
1722    movl     offThread_curHandlerTable(%ecx),rIBASE
1723    FETCH_INST_INDEXED %eax
1724    ADVANCE_PC_INDEXED %eax
1725    GOTO_NEXT
1726
1727
1728/* ------------------------------ */
1729.L_OP_IF_NE: /* 0x33 */
1730/* File: x86/OP_IF_NE.S */
1731/* File: x86/bincmp.S */
1732    /*
1733     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1734     * fragment that specifies the *reverse* comparison to perform, e.g.
1735     * for "if-le" you would use "gt".
1736     *
1737     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1738     */
1739    /* if-cmp vA, vB, +CCCC */
1740    movzx    rINSTbl,%ecx          # ecx <- A+
1741    andb     $0xf,%cl             # ecx <- A
1742    GET_VREG_R %eax %ecx           # eax <- vA
1743    sarl     $4,rINST             # rINST<- B
1744    movl     rSELF,%ecx
1745    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1746    movl     $2,%eax              # assume not taken
1747    je   1f
1748    movswl   2(rPC),%eax           # Get signed branch offset
17491:
1750    movl     offThread_curHandlerTable(%ecx),rIBASE
1751    FETCH_INST_INDEXED %eax
1752    ADVANCE_PC_INDEXED %eax
1753    GOTO_NEXT
1754
1755
1756/* ------------------------------ */
1757.L_OP_IF_LT: /* 0x34 */
1758/* File: x86/OP_IF_LT.S */
1759/* File: x86/bincmp.S */
1760    /*
1761     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1762     * fragment that specifies the *reverse* comparison to perform, e.g.
1763     * for "if-le" you would use "gt".
1764     *
1765     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1766     */
1767    /* if-cmp vA, vB, +CCCC */
1768    movzx    rINSTbl,%ecx          # ecx <- A+
1769    andb     $0xf,%cl             # ecx <- A
1770    GET_VREG_R %eax %ecx           # eax <- vA
1771    sarl     $4,rINST             # rINST<- B
1772    movl     rSELF,%ecx
1773    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1774    movl     $2,%eax              # assume not taken
1775    jge   1f
1776    movswl   2(rPC),%eax           # Get signed branch offset
17771:
1778    movl     offThread_curHandlerTable(%ecx),rIBASE
1779    FETCH_INST_INDEXED %eax
1780    ADVANCE_PC_INDEXED %eax
1781    GOTO_NEXT
1782
1783
1784/* ------------------------------ */
1785.L_OP_IF_GE: /* 0x35 */
1786/* File: x86/OP_IF_GE.S */
1787/* File: x86/bincmp.S */
1788    /*
1789     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1790     * fragment that specifies the *reverse* comparison to perform, e.g.
1791     * for "if-le" you would use "gt".
1792     *
1793     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1794     */
1795    /* if-cmp vA, vB, +CCCC */
1796    movzx    rINSTbl,%ecx          # ecx <- A+
1797    andb     $0xf,%cl             # ecx <- A
1798    GET_VREG_R %eax %ecx           # eax <- vA
1799    sarl     $4,rINST             # rINST<- B
1800    movl     rSELF,%ecx
1801    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1802    movl     $2,%eax              # assume not taken
1803    jl   1f
1804    movswl   2(rPC),%eax           # Get signed branch offset
18051:
1806    movl     offThread_curHandlerTable(%ecx),rIBASE
1807    FETCH_INST_INDEXED %eax
1808    ADVANCE_PC_INDEXED %eax
1809    GOTO_NEXT
1810
1811
1812/* ------------------------------ */
1813.L_OP_IF_GT: /* 0x36 */
1814/* File: x86/OP_IF_GT.S */
1815/* File: x86/bincmp.S */
1816    /*
1817     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1818     * fragment that specifies the *reverse* comparison to perform, e.g.
1819     * for "if-le" you would use "gt".
1820     *
1821     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1822     */
1823    /* if-cmp vA, vB, +CCCC */
1824    movzx    rINSTbl,%ecx          # ecx <- A+
1825    andb     $0xf,%cl             # ecx <- A
1826    GET_VREG_R %eax %ecx           # eax <- vA
1827    sarl     $4,rINST             # rINST<- B
1828    movl     rSELF,%ecx
1829    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1830    movl     $2,%eax              # assume not taken
1831    jle   1f
1832    movswl   2(rPC),%eax           # Get signed branch offset
18331:
1834    movl     offThread_curHandlerTable(%ecx),rIBASE
1835    FETCH_INST_INDEXED %eax
1836    ADVANCE_PC_INDEXED %eax
1837    GOTO_NEXT
1838
1839
1840/* ------------------------------ */
1841.L_OP_IF_LE: /* 0x37 */
1842/* File: x86/OP_IF_LE.S */
1843/* File: x86/bincmp.S */
1844    /*
1845     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1846     * fragment that specifies the *reverse* comparison to perform, e.g.
1847     * for "if-le" you would use "gt".
1848     *
1849     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1850     */
1851    /* if-cmp vA, vB, +CCCC */
1852    movzx    rINSTbl,%ecx          # ecx <- A+
1853    andb     $0xf,%cl             # ecx <- A
1854    GET_VREG_R %eax %ecx           # eax <- vA
1855    sarl     $4,rINST             # rINST<- B
1856    movl     rSELF,%ecx
1857    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1858    movl     $2,%eax              # assume not taken
1859    jg   1f
1860    movswl   2(rPC),%eax           # Get signed branch offset
18611:
1862    movl     offThread_curHandlerTable(%ecx),rIBASE
1863    FETCH_INST_INDEXED %eax
1864    ADVANCE_PC_INDEXED %eax
1865    GOTO_NEXT
1866
1867
1868/* ------------------------------ */
1869.L_OP_IF_EQZ: /* 0x38 */
1870/* File: x86/OP_IF_EQZ.S */
1871/* File: x86/zcmp.S */
1872    /*
1873     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1874     * fragment that specifies the *reverse* comparison to perform, e.g.
1875     * for "if-le" you would use "gt".
1876     *
1877     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1878     */
1879    /* if-cmp vAA, +BBBB */
1880    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
1881    movl     $2,%eax              # assume branch not taken
1882    jne   1f
1883    movl     rSELF,%ecx
1884    movswl   2(rPC),%eax           # fetch signed displacement
1885    movl     offThread_curHandlerTable(%ecx),rIBASE
18861:
1887    FETCH_INST_INDEXED %eax
1888    ADVANCE_PC_INDEXED %eax
1889    GOTO_NEXT
1890
1891
1892/* ------------------------------ */
1893.L_OP_IF_NEZ: /* 0x39 */
1894/* File: x86/OP_IF_NEZ.S */
1895/* File: x86/zcmp.S */
1896    /*
1897     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1898     * fragment that specifies the *reverse* comparison to perform, e.g.
1899     * for "if-le" you would use "gt".
1900     *
1901     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1902     */
1903    /* if-cmp vAA, +BBBB */
1904    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
1905    movl     $2,%eax              # assume branch not taken
1906    je   1f
1907    movl     rSELF,%ecx
1908    movswl   2(rPC),%eax           # fetch signed displacement
1909    movl     offThread_curHandlerTable(%ecx),rIBASE
19101:
1911    FETCH_INST_INDEXED %eax
1912    ADVANCE_PC_INDEXED %eax
1913    GOTO_NEXT
1914
1915
1916/* ------------------------------ */
1917.L_OP_IF_LTZ: /* 0x3a */
1918/* File: x86/OP_IF_LTZ.S */
1919/* File: x86/zcmp.S */
1920    /*
1921     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1922     * fragment that specifies the *reverse* comparison to perform, e.g.
1923     * for "if-le" you would use "gt".
1924     *
1925     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1926     */
1927    /* if-cmp vAA, +BBBB */
1928    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
1929    movl     $2,%eax              # assume branch not taken
1930    jge   1f
1931    movl     rSELF,%ecx
1932    movswl   2(rPC),%eax           # fetch signed displacement
1933    movl     offThread_curHandlerTable(%ecx),rIBASE
19341:
1935    FETCH_INST_INDEXED %eax
1936    ADVANCE_PC_INDEXED %eax
1937    GOTO_NEXT
1938
1939
1940/* ------------------------------ */
1941.L_OP_IF_GEZ: /* 0x3b */
1942/* File: x86/OP_IF_GEZ.S */
1943/* File: x86/zcmp.S */
1944    /*
1945     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1946     * fragment that specifies the *reverse* comparison to perform, e.g.
1947     * for "if-le" you would use "gt".
1948     *
1949     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1950     */
1951    /* if-cmp vAA, +BBBB */
1952    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
1953    movl     $2,%eax              # assume branch not taken
1954    jl   1f
1955    movl     rSELF,%ecx
1956    movswl   2(rPC),%eax           # fetch signed displacement
1957    movl     offThread_curHandlerTable(%ecx),rIBASE
19581:
1959    FETCH_INST_INDEXED %eax
1960    ADVANCE_PC_INDEXED %eax
1961    GOTO_NEXT
1962
1963
1964/* ------------------------------ */
1965.L_OP_IF_GTZ: /* 0x3c */
1966/* File: x86/OP_IF_GTZ.S */
1967/* File: x86/zcmp.S */
1968    /*
1969     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1970     * fragment that specifies the *reverse* comparison to perform, e.g.
1971     * for "if-le" you would use "gt".
1972     *
1973     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1974     */
1975    /* if-cmp vAA, +BBBB */
1976    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
1977    movl     $2,%eax              # assume branch not taken
1978    jle   1f
1979    movl     rSELF,%ecx
1980    movswl   2(rPC),%eax           # fetch signed displacement
1981    movl     offThread_curHandlerTable(%ecx),rIBASE
19821:
1983    FETCH_INST_INDEXED %eax
1984    ADVANCE_PC_INDEXED %eax
1985    GOTO_NEXT
1986
1987
1988/* ------------------------------ */
1989.L_OP_IF_LEZ: /* 0x3d */
1990/* File: x86/OP_IF_LEZ.S */
1991/* File: x86/zcmp.S */
1992    /*
1993     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1994     * fragment that specifies the *reverse* comparison to perform, e.g.
1995     * for "if-le" you would use "gt".
1996     *
1997     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1998     */
1999    /* if-cmp vAA, +BBBB */
2000    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
2001    movl     $2,%eax              # assume branch not taken
2002    jg   1f
2003    movl     rSELF,%ecx
2004    movswl   2(rPC),%eax           # fetch signed displacement
2005    movl     offThread_curHandlerTable(%ecx),rIBASE
20061:
2007    FETCH_INST_INDEXED %eax
2008    ADVANCE_PC_INDEXED %eax
2009    GOTO_NEXT
2010
2011
2012/* ------------------------------ */
2013.L_OP_UNUSED_3E: /* 0x3e */
2014/* File: x86/OP_UNUSED_3E.S */
2015/* File: x86/unused.S */
2016    jmp     common_abort
2017
2018
2019/* ------------------------------ */
2020.L_OP_UNUSED_3F: /* 0x3f */
2021/* File: x86/OP_UNUSED_3F.S */
2022/* File: x86/unused.S */
2023    jmp     common_abort
2024
2025
2026/* ------------------------------ */
2027.L_OP_UNUSED_40: /* 0x40 */
2028/* File: x86/OP_UNUSED_40.S */
2029/* File: x86/unused.S */
2030    jmp     common_abort
2031
2032
2033/* ------------------------------ */
2034.L_OP_UNUSED_41: /* 0x41 */
2035/* File: x86/OP_UNUSED_41.S */
2036/* File: x86/unused.S */
2037    jmp     common_abort
2038
2039
2040/* ------------------------------ */
2041.L_OP_UNUSED_42: /* 0x42 */
2042/* File: x86/OP_UNUSED_42.S */
2043/* File: x86/unused.S */
2044    jmp     common_abort
2045
2046
2047/* ------------------------------ */
2048.L_OP_UNUSED_43: /* 0x43 */
2049/* File: x86/OP_UNUSED_43.S */
2050/* File: x86/unused.S */
2051    jmp     common_abort
2052
2053
2054/* ------------------------------ */
2055.L_OP_AGET: /* 0x44 */
2056/* File: x86/OP_AGET.S */
2057    /*
2058     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2059     *
2060     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2061     */
2062    /* op vAA, vBB, vCC */
2063    movzbl    2(rPC),%eax               # eax<- BB
2064    movzbl    3(rPC),%ecx               # ecx<- CC
2065    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2066    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2067    testl     %eax,%eax                 # null array object?
2068    je        common_errNullObject      # bail if so
2069    cmpl      offArrayObject_length(%eax),%ecx
2070    jae       common_errArrayIndex      # index >= length, bail.  Expects
2071                                        #    arrayObj in eax
2072                                        #    index in ecx
2073    movl     offArrayObject_contents(%eax,%ecx,4),%eax
2074.LOP_AGET_finish:
2075    FETCH_INST_OPCODE 2 %ecx
2076    SET_VREG  %eax rINST
2077    ADVANCE_PC 2
2078    GOTO_NEXT_R %ecx
2079
2080/* ------------------------------ */
2081.L_OP_AGET_WIDE: /* 0x45 */
2082/* File: x86/OP_AGET_WIDE.S */
2083    /*
2084     * Array get, 64 bits.  vAA <- vBB[vCC].
2085     *
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    leal      offArrayObject_contents(%eax,%ecx,8),%eax
2099    movl      (%eax),%ecx
2100    movl      4(%eax),%eax
2101    SET_VREG_WORD %ecx rINST 0
2102    SET_VREG_WORD %eax rINST 1
2103    FETCH_INST_OPCODE 2 %ecx
2104    ADVANCE_PC 2
2105    GOTO_NEXT_R %ecx
2106
2107/* ------------------------------ */
2108.L_OP_AGET_OBJECT: /* 0x46 */
2109/* File: x86/OP_AGET_OBJECT.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    movl     offArrayObject_contents(%eax,%ecx,4),%eax
2128.LOP_AGET_OBJECT_finish:
2129    FETCH_INST_OPCODE 2 %ecx
2130    SET_VREG  %eax rINST
2131    ADVANCE_PC 2
2132    GOTO_NEXT_R %ecx
2133
2134
2135/* ------------------------------ */
2136.L_OP_AGET_BOOLEAN: /* 0x47 */
2137/* File: x86/OP_AGET_BOOLEAN.S */
2138/* File: x86/OP_AGET.S */
2139    /*
2140     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2141     *
2142     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-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    movzbl     offArrayObject_contents(%eax,%ecx,1),%eax
2156.LOP_AGET_BOOLEAN_finish:
2157    FETCH_INST_OPCODE 2 %ecx
2158    SET_VREG  %eax rINST
2159    ADVANCE_PC 2
2160    GOTO_NEXT_R %ecx
2161
2162
2163/* ------------------------------ */
2164.L_OP_AGET_BYTE: /* 0x48 */
2165/* File: x86/OP_AGET_BYTE.S */
2166/* File: x86/OP_AGET.S */
2167    /*
2168     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2169     *
2170     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2171     */
2172    /* op vAA, vBB, vCC */
2173    movzbl    2(rPC),%eax               # eax<- BB
2174    movzbl    3(rPC),%ecx               # ecx<- CC
2175    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2176    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2177    testl     %eax,%eax                 # null array object?
2178    je        common_errNullObject      # bail if so
2179    cmpl      offArrayObject_length(%eax),%ecx
2180    jae       common_errArrayIndex      # index >= length, bail.  Expects
2181                                        #    arrayObj in eax
2182                                        #    index in ecx
2183    movsbl     offArrayObject_contents(%eax,%ecx,1),%eax
2184.LOP_AGET_BYTE_finish:
2185    FETCH_INST_OPCODE 2 %ecx
2186    SET_VREG  %eax rINST
2187    ADVANCE_PC 2
2188    GOTO_NEXT_R %ecx
2189
2190
2191/* ------------------------------ */
2192.L_OP_AGET_CHAR: /* 0x49 */
2193/* File: x86/OP_AGET_CHAR.S */
2194/* File: x86/OP_AGET.S */
2195    /*
2196     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2197     *
2198     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2199     */
2200    /* op vAA, vBB, vCC */
2201    movzbl    2(rPC),%eax               # eax<- BB
2202    movzbl    3(rPC),%ecx               # ecx<- CC
2203    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2204    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2205    testl     %eax,%eax                 # null array object?
2206    je        common_errNullObject      # bail if so
2207    cmpl      offArrayObject_length(%eax),%ecx
2208    jae       common_errArrayIndex      # index >= length, bail.  Expects
2209                                        #    arrayObj in eax
2210                                        #    index in ecx
2211    movzwl     offArrayObject_contents(%eax,%ecx,2),%eax
2212.LOP_AGET_CHAR_finish:
2213    FETCH_INST_OPCODE 2 %ecx
2214    SET_VREG  %eax rINST
2215    ADVANCE_PC 2
2216    GOTO_NEXT_R %ecx
2217
2218
2219/* ------------------------------ */
2220.L_OP_AGET_SHORT: /* 0x4a */
2221/* File: x86/OP_AGET_SHORT.S */
2222/* File: x86/OP_AGET.S */
2223    /*
2224     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2225     *
2226     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2227     */
2228    /* op vAA, vBB, vCC */
2229    movzbl    2(rPC),%eax               # eax<- BB
2230    movzbl    3(rPC),%ecx               # ecx<- CC
2231    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2232    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2233    testl     %eax,%eax                 # null array object?
2234    je        common_errNullObject      # bail if so
2235    cmpl      offArrayObject_length(%eax),%ecx
2236    jae       common_errArrayIndex      # index >= length, bail.  Expects
2237                                        #    arrayObj in eax
2238                                        #    index in ecx
2239    movswl     offArrayObject_contents(%eax,%ecx,2),%eax
2240.LOP_AGET_SHORT_finish:
2241    FETCH_INST_OPCODE 2 %ecx
2242    SET_VREG  %eax rINST
2243    ADVANCE_PC 2
2244    GOTO_NEXT_R %ecx
2245
2246
2247/* ------------------------------ */
2248.L_OP_APUT: /* 0x4b */
2249/* File: x86/OP_APUT.S */
2250    /*
2251     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2252     *
2253     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2254     */
2255    /* op vAA, vBB, vCC */
2256    movzbl    2(rPC),%eax               # eax<- BB
2257    movzbl    3(rPC),%ecx               # ecx<- CC
2258    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2259    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2260    testl     %eax,%eax                 # null array object?
2261    je        common_errNullObject      # bail if so
2262    cmpl      offArrayObject_length(%eax),%ecx
2263    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2264                                        #   arrayObj in eax
2265                                        #   index in ecx
2266    leal      offArrayObject_contents(%eax,%ecx,4),%eax
2267.LOP_APUT_finish:
2268    GET_VREG_R  rINST rINST
2269    FETCH_INST_OPCODE 2 %ecx
2270    movl     rINST,(%eax)
2271    ADVANCE_PC 2
2272    GOTO_NEXT_R %ecx
2273
2274/* ------------------------------ */
2275.L_OP_APUT_WIDE: /* 0x4c */
2276/* File: x86/OP_APUT_WIDE.S */
2277    /*
2278     * Array put, 64 bits.  vBB[vCC]<-vAA.
2279     *
2280     */
2281    /* op vAA, vBB, vCC */
2282    movzbl    2(rPC),%eax               # eax<- BB
2283    movzbl    3(rPC),%ecx               # ecx<- CC
2284    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2285    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2286    testl     %eax,%eax                 # null array object?
2287    je        common_errNullObject      # bail if so
2288    cmpl      offArrayObject_length(%eax),%ecx
2289    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2290                                        #   arrayObj in eax
2291                                        #   index in ecx
2292    leal      offArrayObject_contents(%eax,%ecx,8),%eax
2293    GET_VREG_WORD %ecx rINST 0
2294    GET_VREG_WORD rINST rINST 1
2295    movl      %ecx,(%eax)
2296    FETCH_INST_OPCODE 2 %ecx
2297    movl      rINST,4(%eax)
2298    ADVANCE_PC 2
2299    GOTO_NEXT_R %ecx
2300
2301/* ------------------------------ */
2302.L_OP_APUT_OBJECT: /* 0x4d */
2303/* File: x86/OP_APUT_OBJECT.S */
2304    /*
2305     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2306     *
2307     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2308     */
2309    /* op vAA, vBB, vCC */
2310    movzbl    2(rPC),%eax               # eax<- BB
2311    movzbl    3(rPC),%ecx               # ecx<- CC
2312    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2313    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2314    GET_VREG_R  rINST rINST             # rINST<- vAA
2315    testl     %eax,%eax                 # null array object?
2316    je        common_errNullObject      # bail if so
2317    cmpl      offArrayObject_length(%eax),%ecx
2318    jae       common_errArrayIndex      # index >= length, bail.  Expects
2319                                        #    arrayObj in eax
2320                                        #    index in ecx
2321    /* On entry:
2322     *   eax<- array object
2323     *   ecx<- index
2324     *   rINST<- vAA
2325     */
2326    leal      offArrayObject_contents(%eax,%ecx,4),%ecx
2327    testl     rINST,rINST                    # storing null reference?
2328    je        .LOP_APUT_OBJECT_skip_check
2329    SPILL_TMP1(%ecx)                         # save target address
2330    SPILL_TMP2(%eax)                         # save object head
2331    movl      offObject_clazz(%eax),%eax     # eax<- arrayObj->clazz
2332    movl      offObject_clazz(rINST),%ecx    # ecx<- obj->clazz
2333    movl      %eax,OUT_ARG1(%esp)
2334    movl      %ecx,OUT_ARG0(%esp)
2335    movl      %ecx,sReg0                     # store the two classes for later
2336    movl      %eax,sReg1
2337    SPILL(rIBASE)
2338    call      dvmCanPutArrayElement          # test object type vs. array type
2339    UNSPILL(rIBASE)
2340    UNSPILL_TMP1(%ecx)                       # recover target address
2341    testl     %eax,%eax
2342    movl      rSELF,%eax
2343    jne       .LOP_APUT_OBJECT_types_okay
2344
2345    # The types don't match.  We need to throw an ArrayStoreException.
2346    EXPORT_PC
2347    movl      sReg0,%eax                     # restore the two classes...
2348    movl      %eax,OUT_ARG0(%esp)
2349    movl      sReg1,%ecx
2350    movl      %ecx,OUT_ARG1(%esp)
2351    call      dvmThrowArrayStoreExceptionIncompatibleElement # ...and throw
2352    jmp       common_exceptionThrown
2353
2354.LOP_APUT_OBJECT_types_okay:
2355    movl      offThread_cardTable(%eax),%eax   # get card table base
2356    movl      rINST,(%ecx)                   # store into array
2357    UNSPILL_TMP2(rINST)                      # recover object head
2358    FETCH_INST_OPCODE 2 %ecx
2359    shrl      $GC_CARD_SHIFT,rINST          # object head to card number
2360    movb      %al,(%eax,rINST)               # mark card using object head
2361    ADVANCE_PC 2
2362    GOTO_NEXT_R %ecx
2363
2364.LOP_APUT_OBJECT_skip_check:
2365    movl      rINST,(%ecx)
2366    FETCH_INST_OPCODE 2 %ecx
2367    ADVANCE_PC 2
2368    GOTO_NEXT_R %ecx
2369
2370/* ------------------------------ */
2371.L_OP_APUT_BOOLEAN: /* 0x4e */
2372/* File: x86/OP_APUT_BOOLEAN.S */
2373/* File: x86/OP_APUT.S */
2374    /*
2375     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2376     *
2377     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2378     */
2379    /* op vAA, vBB, vCC */
2380    movzbl    2(rPC),%eax               # eax<- BB
2381    movzbl    3(rPC),%ecx               # ecx<- CC
2382    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2383    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2384    testl     %eax,%eax                 # null array object?
2385    je        common_errNullObject      # bail if so
2386    cmpl      offArrayObject_length(%eax),%ecx
2387    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2388                                        #   arrayObj in eax
2389                                        #   index in ecx
2390    leal      offArrayObject_contents(%eax,%ecx,1),%eax
2391.LOP_APUT_BOOLEAN_finish:
2392    GET_VREG_R  rINST rINST
2393    FETCH_INST_OPCODE 2 %ecx
2394    movb     rINSTbl,(%eax)
2395    ADVANCE_PC 2
2396    GOTO_NEXT_R %ecx
2397
2398
2399/* ------------------------------ */
2400.L_OP_APUT_BYTE: /* 0x4f */
2401/* File: x86/OP_APUT_BYTE.S */
2402/* File: x86/OP_APUT.S */
2403    /*
2404     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2405     *
2406     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2407     */
2408    /* op vAA, vBB, vCC */
2409    movzbl    2(rPC),%eax               # eax<- BB
2410    movzbl    3(rPC),%ecx               # ecx<- CC
2411    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2412    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2413    testl     %eax,%eax                 # null array object?
2414    je        common_errNullObject      # bail if so
2415    cmpl      offArrayObject_length(%eax),%ecx
2416    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2417                                        #   arrayObj in eax
2418                                        #   index in ecx
2419    leal      offArrayObject_contents(%eax,%ecx,1),%eax
2420.LOP_APUT_BYTE_finish:
2421    GET_VREG_R  rINST rINST
2422    FETCH_INST_OPCODE 2 %ecx
2423    movb     rINSTbl,(%eax)
2424    ADVANCE_PC 2
2425    GOTO_NEXT_R %ecx
2426
2427
2428/* ------------------------------ */
2429.L_OP_APUT_CHAR: /* 0x50 */
2430/* File: x86/OP_APUT_CHAR.S */
2431/* File: x86/OP_APUT.S */
2432    /*
2433     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2434     *
2435     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2436     */
2437    /* op vAA, vBB, vCC */
2438    movzbl    2(rPC),%eax               # eax<- BB
2439    movzbl    3(rPC),%ecx               # ecx<- CC
2440    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2441    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2442    testl     %eax,%eax                 # null array object?
2443    je        common_errNullObject      # bail if so
2444    cmpl      offArrayObject_length(%eax),%ecx
2445    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2446                                        #   arrayObj in eax
2447                                        #   index in ecx
2448    leal      offArrayObject_contents(%eax,%ecx,2),%eax
2449.LOP_APUT_CHAR_finish:
2450    GET_VREG_R  rINST rINST
2451    FETCH_INST_OPCODE 2 %ecx
2452    movw     rINSTw,(%eax)
2453    ADVANCE_PC 2
2454    GOTO_NEXT_R %ecx
2455
2456
2457/* ------------------------------ */
2458.L_OP_APUT_SHORT: /* 0x51 */
2459/* File: x86/OP_APUT_SHORT.S */
2460/* File: x86/OP_APUT.S */
2461    /*
2462     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2463     *
2464     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2465     */
2466    /* op vAA, vBB, vCC */
2467    movzbl    2(rPC),%eax               # eax<- BB
2468    movzbl    3(rPC),%ecx               # ecx<- CC
2469    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2470    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2471    testl     %eax,%eax                 # null array object?
2472    je        common_errNullObject      # bail if so
2473    cmpl      offArrayObject_length(%eax),%ecx
2474    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2475                                        #   arrayObj in eax
2476                                        #   index in ecx
2477    leal      offArrayObject_contents(%eax,%ecx,2),%eax
2478.LOP_APUT_SHORT_finish:
2479    GET_VREG_R  rINST rINST
2480    FETCH_INST_OPCODE 2 %ecx
2481    movw     rINSTw,(%eax)
2482    ADVANCE_PC 2
2483    GOTO_NEXT_R %ecx
2484
2485
2486/* ------------------------------ */
2487.L_OP_IGET: /* 0x52 */
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    SPILL(rIBASE)                               # preserve rIBASE
2497    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
2498    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
2499    movzbl  rINSTbl,%ecx                        # ecx<- BA
2500    sarl    $4,%ecx                            # ecx<- B
2501    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2502    andb    $0xf,rINSTbl                       # rINST<- A
2503    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2504    movl    (%eax,rIBASE,4),%eax                # resolved entry
2505    testl   %eax,%eax                           # is resolved entry null?
2506    jne     .LOP_IGET_finish                  # no, already resolved
2507    movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
2508    movl    rSELF,rIBASE
2509    EXPORT_PC
2510    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
2511    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
2512    SPILL_TMP1(%ecx)                            # save obj pointer across call
2513    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
2514    call    dvmResolveInstField                 #  ... to dvmResolveInstField
2515    UNSPILL_TMP1(%ecx)
2516    testl   %eax,%eax                           #  returns InstrField ptr
2517    jne     .LOP_IGET_finish
2518    jmp     common_exceptionThrown
2519
2520.LOP_IGET_finish:
2521    /*
2522     * Currently:
2523     *   eax holds resolved field
2524     *   ecx holds object
2525     *   rINST holds A
2526     */
2527    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
2528    testl   %ecx,%ecx                           # object null?
2529    je      common_errNullObject                # object was null
2530    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
2531    FETCH_INST_OPCODE 2 %eax
2532    UNSPILL(rIBASE)
2533    SET_VREG %ecx rINST
2534    ADVANCE_PC 2
2535    GOTO_NEXT_R %eax
2536
2537/* ------------------------------ */
2538.L_OP_IGET_WIDE: /* 0x53 */
2539/* File: x86/OP_IGET_WIDE.S */
2540    /*
2541     * 64-bit instance field get.
2542     *
2543     */
2544    /* op vA, vB, field@CCCC */
2545    movl    rSELF,%ecx
2546    SPILL(rIBASE)                               # preserve rIBASE
2547    movzwl  2(rPC),rIBASE                       # rIBASE<- 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,rIBASE,4),%eax                # resolved entry
2555    testl   %eax,%eax                           # is resolved entry null?
2556    jne     .LOP_IGET_WIDE_finish                  # no, already resolved
2557    movl    rIBASE,OUT_ARG1(%esp)               # for dvmResolveInstField
2558    movl    rSELF,rIBASE
2559    EXPORT_PC
2560    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
2561    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
2562    SPILL_TMP1(%ecx)                            # save objpointer across call
2563    movl    rPC,OUT_ARG0(%esp)                  # pass in method->clazz
2564    call    dvmResolveInstField                 #  ... to dvmResolveInstField
2565    UNSPILL_TMP1(%ecx)
2566    testl   %eax,%eax                           # returns InstrField ptr
2567    jne     .LOP_IGET_WIDE_finish
2568    jmp     common_exceptionThrown
2569
2570.LOP_IGET_WIDE_finish:
2571    /*
2572     * Currently:
2573     *   eax holds resolved field
2574     *   ecx holds object
2575     *   rINST holds A
2576     */
2577    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
2578    testl   %ecx,%ecx                           # object null?
2579    je      common_errNullObject                # object was null
2580    leal    (%ecx,%eax,1),%eax                  # eax<- address of field
2581    movl    (%eax),%ecx                         # ecx<- lsw
2582    movl    4(%eax),%eax                        # eax<- msw
2583    SET_VREG_WORD %ecx rINST 0
2584    FETCH_INST_OPCODE 2 %ecx
2585    UNSPILL(rIBASE)                             # restore rIBASE
2586    SET_VREG_WORD %eax rINST 1
2587    ADVANCE_PC 2
2588    GOTO_NEXT_R %ecx
2589
2590/* ------------------------------ */
2591.L_OP_IGET_OBJECT: /* 0x54 */
2592/* File: x86/OP_IGET_OBJECT.S */
2593/* File: x86/OP_IGET.S */
2594    /*
2595     * General 32-bit instance field get.
2596     *
2597     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2598     */
2599    /* op vA, vB, field@CCCC */
2600    movl    rSELF,%ecx
2601    SPILL(rIBASE)                               # preserve rIBASE
2602    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
2603    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
2604    movzbl  rINSTbl,%ecx                        # ecx<- BA
2605    sarl    $4,%ecx                            # ecx<- B
2606    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2607    andb    $0xf,rINSTbl                       # rINST<- A
2608    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2609    movl    (%eax,rIBASE,4),%eax                # resolved entry
2610    testl   %eax,%eax                           # is resolved entry null?
2611    jne     .LOP_IGET_OBJECT_finish                  # no, already resolved
2612    movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
2613    movl    rSELF,rIBASE
2614    EXPORT_PC
2615    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
2616    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
2617    SPILL_TMP1(%ecx)                            # save obj pointer across call
2618    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
2619    call    dvmResolveInstField                 #  ... to dvmResolveInstField
2620    UNSPILL_TMP1(%ecx)
2621    testl   %eax,%eax                           #  returns InstrField ptr
2622    jne     .LOP_IGET_OBJECT_finish
2623    jmp     common_exceptionThrown
2624
2625.LOP_IGET_OBJECT_finish:
2626    /*
2627     * Currently:
2628     *   eax holds resolved field
2629     *   ecx holds object
2630     *   rINST holds A
2631     */
2632    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
2633    testl   %ecx,%ecx                           # object null?
2634    je      common_errNullObject                # object was null
2635    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
2636    FETCH_INST_OPCODE 2 %eax
2637    UNSPILL(rIBASE)
2638    SET_VREG %ecx rINST
2639    ADVANCE_PC 2
2640    GOTO_NEXT_R %eax
2641
2642
2643/* ------------------------------ */
2644.L_OP_IGET_BOOLEAN: /* 0x55 */
2645/* File: x86/OP_IGET_BOOLEAN.S */
2646/* File: x86/OP_IGET.S */
2647    /*
2648     * General 32-bit instance field get.
2649     *
2650     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2651     */
2652    /* op vA, vB, field@CCCC */
2653    movl    rSELF,%ecx
2654    SPILL(rIBASE)                               # preserve rIBASE
2655    movzwl  2(rPC),rIBASE                       # rIBASE<- 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,rIBASE,4),%eax                # resolved entry
2663    testl   %eax,%eax                           # is resolved entry null?
2664    jne     .LOP_IGET_BOOLEAN_finish                  # no, already resolved
2665    movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
2666    movl    rSELF,rIBASE
2667    EXPORT_PC
2668    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
2669    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
2670    SPILL_TMP1(%ecx)                            # save obj pointer across call
2671    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
2672    call    dvmResolveInstField                 #  ... to dvmResolveInstField
2673    UNSPILL_TMP1(%ecx)
2674    testl   %eax,%eax                           #  returns InstrField ptr
2675    jne     .LOP_IGET_BOOLEAN_finish
2676    jmp     common_exceptionThrown
2677
2678.LOP_IGET_BOOLEAN_finish:
2679    /*
2680     * Currently:
2681     *   eax holds resolved field
2682     *   ecx holds object
2683     *   rINST holds A
2684     */
2685    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
2686    testl   %ecx,%ecx                           # object null?
2687    je      common_errNullObject                # object was null
2688    movzbl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
2689    FETCH_INST_OPCODE 2 %eax
2690    UNSPILL(rIBASE)
2691    SET_VREG %ecx rINST
2692    ADVANCE_PC 2
2693    GOTO_NEXT_R %eax
2694
2695
2696/* ------------------------------ */
2697.L_OP_IGET_BYTE: /* 0x56 */
2698/* File: x86/OP_IGET_BYTE.S */
2699/* File: x86/OP_IGET.S */
2700    /*
2701     * General 32-bit instance field get.
2702     *
2703     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2704     */
2705    /* op vA, vB, field@CCCC */
2706    movl    rSELF,%ecx
2707    SPILL(rIBASE)                               # preserve rIBASE
2708    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
2709    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
2710    movzbl  rINSTbl,%ecx                        # ecx<- BA
2711    sarl    $4,%ecx                            # ecx<- B
2712    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2713    andb    $0xf,rINSTbl                       # rINST<- A
2714    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2715    movl    (%eax,rIBASE,4),%eax                # resolved entry
2716    testl   %eax,%eax                           # is resolved entry null?
2717    jne     .LOP_IGET_BYTE_finish                  # no, already resolved
2718    movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
2719    movl    rSELF,rIBASE
2720    EXPORT_PC
2721    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
2722    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
2723    SPILL_TMP1(%ecx)                            # save obj pointer across call
2724    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
2725    call    dvmResolveInstField                 #  ... to dvmResolveInstField
2726    UNSPILL_TMP1(%ecx)
2727    testl   %eax,%eax                           #  returns InstrField ptr
2728    jne     .LOP_IGET_BYTE_finish
2729    jmp     common_exceptionThrown
2730
2731.LOP_IGET_BYTE_finish:
2732    /*
2733     * Currently:
2734     *   eax holds resolved field
2735     *   ecx holds object
2736     *   rINST holds A
2737     */
2738    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
2739    testl   %ecx,%ecx                           # object null?
2740    je      common_errNullObject                # object was null
2741    movsbl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
2742    FETCH_INST_OPCODE 2 %eax
2743    UNSPILL(rIBASE)
2744    SET_VREG %ecx rINST
2745    ADVANCE_PC 2
2746    GOTO_NEXT_R %eax
2747
2748
2749/* ------------------------------ */
2750.L_OP_IGET_CHAR: /* 0x57 */
2751/* File: x86/OP_IGET_CHAR.S */
2752/* File: x86/OP_IGET.S */
2753    /*
2754     * General 32-bit instance field get.
2755     *
2756     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2757     */
2758    /* op vA, vB, field@CCCC */
2759    movl    rSELF,%ecx
2760    SPILL(rIBASE)                               # preserve rIBASE
2761    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
2762    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
2763    movzbl  rINSTbl,%ecx                        # ecx<- BA
2764    sarl    $4,%ecx                            # ecx<- B
2765    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2766    andb    $0xf,rINSTbl                       # rINST<- A
2767    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2768    movl    (%eax,rIBASE,4),%eax                # resolved entry
2769    testl   %eax,%eax                           # is resolved entry null?
2770    jne     .LOP_IGET_CHAR_finish                  # no, already resolved
2771    movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
2772    movl    rSELF,rIBASE
2773    EXPORT_PC
2774    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
2775    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
2776    SPILL_TMP1(%ecx)                            # save obj pointer across call
2777    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
2778    call    dvmResolveInstField                 #  ... to dvmResolveInstField
2779    UNSPILL_TMP1(%ecx)
2780    testl   %eax,%eax                           #  returns InstrField ptr
2781    jne     .LOP_IGET_CHAR_finish
2782    jmp     common_exceptionThrown
2783
2784.LOP_IGET_CHAR_finish:
2785    /*
2786     * Currently:
2787     *   eax holds resolved field
2788     *   ecx holds object
2789     *   rINST holds A
2790     */
2791    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
2792    testl   %ecx,%ecx                           # object null?
2793    je      common_errNullObject                # object was null
2794    movzwl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
2795    FETCH_INST_OPCODE 2 %eax
2796    UNSPILL(rIBASE)
2797    SET_VREG %ecx rINST
2798    ADVANCE_PC 2
2799    GOTO_NEXT_R %eax
2800
2801
2802/* ------------------------------ */
2803.L_OP_IGET_SHORT: /* 0x58 */
2804/* File: x86/OP_IGET_SHORT.S */
2805/* File: x86/OP_IGET.S */
2806    /*
2807     * General 32-bit instance field get.
2808     *
2809     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2810     */
2811    /* op vA, vB, field@CCCC */
2812    movl    rSELF,%ecx
2813    SPILL(rIBASE)                               # preserve rIBASE
2814    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
2815    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
2816    movzbl  rINSTbl,%ecx                        # ecx<- BA
2817    sarl    $4,%ecx                            # ecx<- B
2818    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2819    andb    $0xf,rINSTbl                       # rINST<- A
2820    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2821    movl    (%eax,rIBASE,4),%eax                # resolved entry
2822    testl   %eax,%eax                           # is resolved entry null?
2823    jne     .LOP_IGET_SHORT_finish                  # no, already resolved
2824    movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
2825    movl    rSELF,rIBASE
2826    EXPORT_PC
2827    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
2828    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
2829    SPILL_TMP1(%ecx)                            # save obj pointer across call
2830    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
2831    call    dvmResolveInstField                 #  ... to dvmResolveInstField
2832    UNSPILL_TMP1(%ecx)
2833    testl   %eax,%eax                           #  returns InstrField ptr
2834    jne     .LOP_IGET_SHORT_finish
2835    jmp     common_exceptionThrown
2836
2837.LOP_IGET_SHORT_finish:
2838    /*
2839     * Currently:
2840     *   eax holds resolved field
2841     *   ecx holds object
2842     *   rINST holds A
2843     */
2844    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
2845    testl   %ecx,%ecx                           # object null?
2846    je      common_errNullObject                # object was null
2847    movswl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
2848    FETCH_INST_OPCODE 2 %eax
2849    UNSPILL(rIBASE)
2850    SET_VREG %ecx rINST
2851    ADVANCE_PC 2
2852    GOTO_NEXT_R %eax
2853
2854
2855/* ------------------------------ */
2856.L_OP_IPUT: /* 0x59 */
2857/* File: x86/OP_IPUT.S */
2858
2859    /*
2860     * General 32-bit instance field put.
2861     *
2862     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
2863     */
2864    /* op vA, vB, field@CCCC */
2865    movl    rSELF,%ecx
2866    SPILL   (rIBASE)
2867    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
2868    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
2869    movzbl  rINSTbl,%ecx                        # ecx<- BA
2870    sarl    $4,%ecx                            # ecx<- B
2871    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2872    andb    $0xf,rINSTbl                       # rINST<- A
2873    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2874    movl    (%eax,rIBASE,4),%eax                # resolved entry
2875    testl   %eax,%eax                           # is resolved entry null?
2876    jne     .LOP_IPUT_finish                  # no, already resolved
2877    movl    rIBASE,OUT_ARG1(%esp)
2878    movl    rSELF,rIBASE
2879    EXPORT_PC
2880    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
2881    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
2882    SPILL_TMP1(%ecx)                            # save obj pointer across call
2883    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
2884    call    dvmResolveInstField                 #  ... to dvmResolveInstField
2885    UNSPILL_TMP1(%ecx)
2886    testl   %eax,%eax                           # returns InstrField ptr
2887    jne     .LOP_IPUT_finish
2888    jmp     common_exceptionThrown
2889
2890.LOP_IPUT_finish:
2891    /*
2892     * Currently:
2893     *   eax holds resolved field
2894     *   ecx holds object
2895     *   rINST holds A
2896     */
2897    GET_VREG_R rINST rINST                       # rINST<- v[A]
2898    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
2899    testl   %ecx,%ecx                            # object null?
2900    je      common_errNullObject                 # object was null
2901    movl   rINST,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
2902    FETCH_INST_OPCODE 2 %ecx
2903    UNSPILL(rIBASE)
2904    ADVANCE_PC 2
2905    GOTO_NEXT_R %ecx
2906
2907/* ------------------------------ */
2908.L_OP_IPUT_WIDE: /* 0x5a */
2909/* File: x86/OP_IPUT_WIDE.S */
2910    /*
2911     * 64-bit instance field put.
2912     *
2913     */
2914    /* op vA, vB, field@CCCC */
2915    movl    rSELF,%ecx
2916    SPILL(rIBASE)
2917    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
2918    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
2919    movzbl  rINSTbl,%ecx                        # ecx<- BA
2920    sarl    $4,%ecx                            # ecx<- B
2921    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2922    andb    $0xf,rINSTbl                       # rINST<- A
2923    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2924    movl    (%eax,rIBASE,4),%eax                # resolved entry
2925    testl   %eax,%eax                           # is resolved entry null?
2926    jne     .LOP_IPUT_WIDE_finish                  # no, already resolved
2927    movl    rIBASE,OUT_ARG1(%esp)
2928    movl    rSELF,rIBASE
2929    EXPORT_PC
2930    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
2931    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
2932    SPILL_TMP1(%ecx)                            # save obj pointer across call
2933    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
2934    call    dvmResolveInstField                 #  ... to dvmResolveInstField
2935    UNSPILL_TMP1(%ecx)
2936    testl   %eax,%eax                           #  ... which returns InstrField ptr
2937    jne     .LOP_IPUT_WIDE_finish
2938    jmp     common_exceptionThrown
2939
2940.LOP_IPUT_WIDE_finish:
2941    /*
2942     * Currently:
2943     *   eax holds resolved field
2944     *   ecx holds object
2945     *   rIBASE is scratch, but needs to be unspilled
2946     *   rINST holds A
2947     */
2948    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
2949    testl   %ecx,%ecx                           # object null?
2950    je      common_errNullObject                # object was null
2951    leal    (%ecx,%eax,1),%eax                  # eax<- address of field
2952    GET_VREG_WORD %ecx rINST 0                  # ecx<- lsw
2953    GET_VREG_WORD rINST rINST 1                 # rINST<- msw
2954    movl    rINST,4(%eax)
2955    movl    %ecx,(%eax)
2956    FETCH_INST_OPCODE 2 %ecx
2957    UNSPILL(rIBASE)
2958    ADVANCE_PC 2
2959    GOTO_NEXT_R %ecx
2960
2961/* ------------------------------ */
2962.L_OP_IPUT_OBJECT: /* 0x5b */
2963/* File: x86/OP_IPUT_OBJECT.S */
2964    /*
2965     * Object field put.
2966     *
2967     * for: iput-object
2968     */
2969    /* op vA, vB, field@CCCC */
2970    movl    rSELF,%ecx
2971    SPILL(rIBASE)
2972    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
2973    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
2974    movzbl  rINSTbl,%ecx                        # ecx<- BA
2975    sarl    $4,%ecx                            # ecx<- B
2976    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2977    andb    $0xf,rINSTbl                       # rINST<- A
2978    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2979    movl    (%eax,rIBASE,4),%eax                  # resolved entry
2980    testl   %eax,%eax                           # is resolved entry null?
2981    jne     .LOP_IPUT_OBJECT_finish                  # no, already resolved
2982    movl    rIBASE,OUT_ARG1(%esp)
2983    movl    rSELF,rIBASE
2984    EXPORT_PC
2985    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
2986    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
2987    SPILL_TMP1(%ecx)                            # save obj pointer across call
2988    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
2989    call    dvmResolveInstField                 #  ... to dvmResolveInstField
2990    UNSPILL_TMP1(%ecx)
2991    testl   %eax,%eax                           # returns InstrField ptr
2992    jne     .LOP_IPUT_OBJECT_finish
2993    jmp     common_exceptionThrown
2994
2995.LOP_IPUT_OBJECT_finish:
2996    /*
2997     * Currently:
2998     *   eax holds resolved field
2999     *   ecx holds object
3000     *   rIBASE is scratch, but needs to be unspilled
3001     *   rINST holds A
3002     */
3003    GET_VREG_R rINST rINST                      # rINST<- v[A]
3004    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
3005    testl   %ecx,%ecx                           # object null?
3006    je      common_errNullObject                # object was null
3007    movl    rINST,(%ecx,%eax)      # obj.field <- v[A](8/16/32 bits)
3008    movl    rSELF,%eax
3009    testl   rINST,rINST                         # stored a NULL?
3010    movl    offThread_cardTable(%eax),%eax      # get card table base
3011    je      1f                                  # skip card mark if null store
3012    shrl    $GC_CARD_SHIFT,%ecx                # object head to card number
3013    movb    %al,(%eax,%ecx)                     # mark card using object head
30141:
3015    UNSPILL(rIBASE)
3016    FETCH_INST_OPCODE 2 %ecx
3017    ADVANCE_PC 2
3018    GOTO_NEXT_R %ecx
3019
3020/* ------------------------------ */
3021.L_OP_IPUT_BOOLEAN: /* 0x5c */
3022/* File: x86/OP_IPUT_BOOLEAN.S */
3023/* File: x86/OP_IPUT.S */
3024
3025    /*
3026     * General 32-bit instance field put.
3027     *
3028     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
3029     */
3030    /* op vA, vB, field@CCCC */
3031    movl    rSELF,%ecx
3032    SPILL   (rIBASE)
3033    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
3034    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
3035    movzbl  rINSTbl,%ecx                        # ecx<- BA
3036    sarl    $4,%ecx                            # ecx<- B
3037    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
3038    andb    $0xf,rINSTbl                       # rINST<- A
3039    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
3040    movl    (%eax,rIBASE,4),%eax                # resolved entry
3041    testl   %eax,%eax                           # is resolved entry null?
3042    jne     .LOP_IPUT_BOOLEAN_finish                  # no, already resolved
3043    movl    rIBASE,OUT_ARG1(%esp)
3044    movl    rSELF,rIBASE
3045    EXPORT_PC
3046    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
3047    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
3048    SPILL_TMP1(%ecx)                            # save obj pointer across call
3049    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
3050    call    dvmResolveInstField                 #  ... to dvmResolveInstField
3051    UNSPILL_TMP1(%ecx)
3052    testl   %eax,%eax                           # returns InstrField ptr
3053    jne     .LOP_IPUT_BOOLEAN_finish
3054    jmp     common_exceptionThrown
3055
3056.LOP_IPUT_BOOLEAN_finish:
3057    /*
3058     * Currently:
3059     *   eax holds resolved field
3060     *   ecx holds object
3061     *   rINST holds A
3062     */
3063    GET_VREG_R rINST rINST                       # rINST<- v[A]
3064    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
3065    testl   %ecx,%ecx                            # object null?
3066    je      common_errNullObject                 # object was null
3067    movb   rINSTbl,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
3068    FETCH_INST_OPCODE 2 %ecx
3069    UNSPILL(rIBASE)
3070    ADVANCE_PC 2
3071    GOTO_NEXT_R %ecx
3072
3073
3074/* ------------------------------ */
3075.L_OP_IPUT_BYTE: /* 0x5d */
3076/* File: x86/OP_IPUT_BYTE.S */
3077/* File: x86/OP_IPUT.S */
3078
3079    /*
3080     * General 32-bit instance field put.
3081     *
3082     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
3083     */
3084    /* op vA, vB, field@CCCC */
3085    movl    rSELF,%ecx
3086    SPILL   (rIBASE)
3087    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
3088    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
3089    movzbl  rINSTbl,%ecx                        # ecx<- BA
3090    sarl    $4,%ecx                            # ecx<- B
3091    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
3092    andb    $0xf,rINSTbl                       # rINST<- A
3093    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
3094    movl    (%eax,rIBASE,4),%eax                # resolved entry
3095    testl   %eax,%eax                           # is resolved entry null?
3096    jne     .LOP_IPUT_BYTE_finish                  # no, already resolved
3097    movl    rIBASE,OUT_ARG1(%esp)
3098    movl    rSELF,rIBASE
3099    EXPORT_PC
3100    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
3101    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
3102    SPILL_TMP1(%ecx)                            # save obj pointer across call
3103    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
3104    call    dvmResolveInstField                 #  ... to dvmResolveInstField
3105    UNSPILL_TMP1(%ecx)
3106    testl   %eax,%eax                           # returns InstrField ptr
3107    jne     .LOP_IPUT_BYTE_finish
3108    jmp     common_exceptionThrown
3109
3110.LOP_IPUT_BYTE_finish:
3111    /*
3112     * Currently:
3113     *   eax holds resolved field
3114     *   ecx holds object
3115     *   rINST holds A
3116     */
3117    GET_VREG_R rINST rINST                       # rINST<- v[A]
3118    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
3119    testl   %ecx,%ecx                            # object null?
3120    je      common_errNullObject                 # object was null
3121    movb   rINSTbl,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
3122    FETCH_INST_OPCODE 2 %ecx
3123    UNSPILL(rIBASE)
3124    ADVANCE_PC 2
3125    GOTO_NEXT_R %ecx
3126
3127
3128/* ------------------------------ */
3129.L_OP_IPUT_CHAR: /* 0x5e */
3130/* File: x86/OP_IPUT_CHAR.S */
3131/* File: x86/OP_IPUT.S */
3132
3133    /*
3134     * General 32-bit instance field put.
3135     *
3136     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
3137     */
3138    /* op vA, vB, field@CCCC */
3139    movl    rSELF,%ecx
3140    SPILL   (rIBASE)
3141    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
3142    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
3143    movzbl  rINSTbl,%ecx                        # ecx<- BA
3144    sarl    $4,%ecx                            # ecx<- B
3145    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
3146    andb    $0xf,rINSTbl                       # rINST<- A
3147    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
3148    movl    (%eax,rIBASE,4),%eax                # resolved entry
3149    testl   %eax,%eax                           # is resolved entry null?
3150    jne     .LOP_IPUT_CHAR_finish                  # no, already resolved
3151    movl    rIBASE,OUT_ARG1(%esp)
3152    movl    rSELF,rIBASE
3153    EXPORT_PC
3154    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
3155    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
3156    SPILL_TMP1(%ecx)                            # save obj pointer across call
3157    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
3158    call    dvmResolveInstField                 #  ... to dvmResolveInstField
3159    UNSPILL_TMP1(%ecx)
3160    testl   %eax,%eax                           # returns InstrField ptr
3161    jne     .LOP_IPUT_CHAR_finish
3162    jmp     common_exceptionThrown
3163
3164.LOP_IPUT_CHAR_finish:
3165    /*
3166     * Currently:
3167     *   eax holds resolved field
3168     *   ecx holds object
3169     *   rINST holds A
3170     */
3171    GET_VREG_R rINST rINST                       # rINST<- v[A]
3172    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
3173    testl   %ecx,%ecx                            # object null?
3174    je      common_errNullObject                 # object was null
3175    movw   rINSTw,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
3176    FETCH_INST_OPCODE 2 %ecx
3177    UNSPILL(rIBASE)
3178    ADVANCE_PC 2
3179    GOTO_NEXT_R %ecx
3180
3181
3182/* ------------------------------ */
3183.L_OP_IPUT_SHORT: /* 0x5f */
3184/* File: x86/OP_IPUT_SHORT.S */
3185/* File: x86/OP_IPUT.S */
3186
3187    /*
3188     * General 32-bit instance field put.
3189     *
3190     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
3191     */
3192    /* op vA, vB, field@CCCC */
3193    movl    rSELF,%ecx
3194    SPILL   (rIBASE)
3195    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
3196    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
3197    movzbl  rINSTbl,%ecx                        # ecx<- BA
3198    sarl    $4,%ecx                            # ecx<- B
3199    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
3200    andb    $0xf,rINSTbl                       # rINST<- A
3201    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
3202    movl    (%eax,rIBASE,4),%eax                # resolved entry
3203    testl   %eax,%eax                           # is resolved entry null?
3204    jne     .LOP_IPUT_SHORT_finish                  # no, already resolved
3205    movl    rIBASE,OUT_ARG1(%esp)
3206    movl    rSELF,rIBASE
3207    EXPORT_PC
3208    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
3209    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
3210    SPILL_TMP1(%ecx)                            # save obj pointer across call
3211    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
3212    call    dvmResolveInstField                 #  ... to dvmResolveInstField
3213    UNSPILL_TMP1(%ecx)
3214    testl   %eax,%eax                           # returns InstrField ptr
3215    jne     .LOP_IPUT_SHORT_finish
3216    jmp     common_exceptionThrown
3217
3218.LOP_IPUT_SHORT_finish:
3219    /*
3220     * Currently:
3221     *   eax holds resolved field
3222     *   ecx holds object
3223     *   rINST holds A
3224     */
3225    GET_VREG_R rINST rINST                       # rINST<- v[A]
3226    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
3227    testl   %ecx,%ecx                            # object null?
3228    je      common_errNullObject                 # object was null
3229    movw   rINSTw,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
3230    FETCH_INST_OPCODE 2 %ecx
3231    UNSPILL(rIBASE)
3232    ADVANCE_PC 2
3233    GOTO_NEXT_R %ecx
3234
3235
3236/* ------------------------------ */
3237.L_OP_SGET: /* 0x60 */
3238/* File: x86/OP_SGET.S */
3239    /*
3240     * General 32-bit SGET handler.
3241     *
3242     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
3243     */
3244    /* op vAA, field@BBBB */
3245    movl      rSELF,%ecx
3246    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3247    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3248    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3249    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3250    testl     %eax,%eax                          # resolved entry null?
3251    je        .LOP_SGET_resolve                # if not, make it so
3252.LOP_SGET_finish:     # field ptr in eax
3253    movl      offStaticField_value(%eax),%eax
3254    FETCH_INST_OPCODE 2 %ecx
3255    ADVANCE_PC 2
3256    SET_VREG %eax rINST
3257    GOTO_NEXT_R %ecx
3258
3259    /*
3260     * Go resolve the field
3261     */
3262.LOP_SGET_resolve:
3263    movl     rSELF,%ecx
3264    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3265    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3266    EXPORT_PC                                   # could throw, need to export
3267    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3268    movl     %eax,OUT_ARG1(%esp)
3269    movl     %ecx,OUT_ARG0(%esp)
3270    SPILL(rIBASE)
3271    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3272    UNSPILL(rIBASE)
3273    testl    %eax,%eax
3274    jne      .LOP_SGET_finish                 # success, continue
3275    jmp      common_exceptionThrown             # no, handle exception
3276
3277/* ------------------------------ */
3278.L_OP_SGET_WIDE: /* 0x61 */
3279/* File: x86/OP_SGET_WIDE.S */
3280    /*
3281     * 64-bit SGET handler.
3282     *
3283     */
3284    /* sget-wide vAA, field@BBBB */
3285    movl      rSELF,%ecx
3286    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3287    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3288    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3289    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3290    testl     %eax,%eax                          # resolved entry null?
3291    je        .LOP_SGET_WIDE_resolve                # if not, make it so
3292.LOP_SGET_WIDE_finish:     # field ptr in eax
3293    movl      offStaticField_value(%eax),%ecx    # ecx<- lsw
3294    movl      4+offStaticField_value(%eax),%eax  # eax<- msw
3295    SET_VREG_WORD %ecx rINST 0
3296    FETCH_INST_OPCODE 2 %ecx
3297    SET_VREG_WORD %eax rINST 1
3298    ADVANCE_PC 2
3299    GOTO_NEXT_R %ecx
3300
3301    /*
3302     * Go resolve the field
3303     */
3304.LOP_SGET_WIDE_resolve:
3305    movl     rSELF,%ecx
3306    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3307    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3308    EXPORT_PC                                   # could throw, need to export
3309    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3310    movl     %eax,OUT_ARG1(%esp)
3311    movl     %ecx,OUT_ARG0(%esp)
3312    SPILL(rIBASE)
3313    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3314    UNSPILL(rIBASE)
3315    testl    %eax,%eax
3316    jne      .LOP_SGET_WIDE_finish                 # success, continue
3317    jmp      common_exceptionThrown             # no, handle exception
3318
3319/* ------------------------------ */
3320.L_OP_SGET_OBJECT: /* 0x62 */
3321/* File: x86/OP_SGET_OBJECT.S */
3322/* File: x86/OP_SGET.S */
3323    /*
3324     * General 32-bit SGET handler.
3325     *
3326     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
3327     */
3328    /* op vAA, field@BBBB */
3329    movl      rSELF,%ecx
3330    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3331    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3332    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3333    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3334    testl     %eax,%eax                          # resolved entry null?
3335    je        .LOP_SGET_OBJECT_resolve                # if not, make it so
3336.LOP_SGET_OBJECT_finish:     # field ptr in eax
3337    movl      offStaticField_value(%eax),%eax
3338    FETCH_INST_OPCODE 2 %ecx
3339    ADVANCE_PC 2
3340    SET_VREG %eax rINST
3341    GOTO_NEXT_R %ecx
3342
3343    /*
3344     * Go resolve the field
3345     */
3346.LOP_SGET_OBJECT_resolve:
3347    movl     rSELF,%ecx
3348    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3349    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3350    EXPORT_PC                                   # could throw, need to export
3351    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3352    movl     %eax,OUT_ARG1(%esp)
3353    movl     %ecx,OUT_ARG0(%esp)
3354    SPILL(rIBASE)
3355    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3356    UNSPILL(rIBASE)
3357    testl    %eax,%eax
3358    jne      .LOP_SGET_OBJECT_finish                 # success, continue
3359    jmp      common_exceptionThrown             # no, handle exception
3360
3361
3362/* ------------------------------ */
3363.L_OP_SGET_BOOLEAN: /* 0x63 */
3364/* File: x86/OP_SGET_BOOLEAN.S */
3365/* File: x86/OP_SGET.S */
3366    /*
3367     * General 32-bit SGET handler.
3368     *
3369     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
3370     */
3371    /* op vAA, field@BBBB */
3372    movl      rSELF,%ecx
3373    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3374    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3375    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3376    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3377    testl     %eax,%eax                          # resolved entry null?
3378    je        .LOP_SGET_BOOLEAN_resolve                # if not, make it so
3379.LOP_SGET_BOOLEAN_finish:     # field ptr in eax
3380    movl      offStaticField_value(%eax),%eax
3381    FETCH_INST_OPCODE 2 %ecx
3382    ADVANCE_PC 2
3383    SET_VREG %eax rINST
3384    GOTO_NEXT_R %ecx
3385
3386    /*
3387     * Go resolve the field
3388     */
3389.LOP_SGET_BOOLEAN_resolve:
3390    movl     rSELF,%ecx
3391    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3392    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3393    EXPORT_PC                                   # could throw, need to export
3394    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3395    movl     %eax,OUT_ARG1(%esp)
3396    movl     %ecx,OUT_ARG0(%esp)
3397    SPILL(rIBASE)
3398    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3399    UNSPILL(rIBASE)
3400    testl    %eax,%eax
3401    jne      .LOP_SGET_BOOLEAN_finish                 # success, continue
3402    jmp      common_exceptionThrown             # no, handle exception
3403
3404
3405/* ------------------------------ */
3406.L_OP_SGET_BYTE: /* 0x64 */
3407/* File: x86/OP_SGET_BYTE.S */
3408/* File: x86/OP_SGET.S */
3409    /*
3410     * General 32-bit SGET handler.
3411     *
3412     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
3413     */
3414    /* op vAA, field@BBBB */
3415    movl      rSELF,%ecx
3416    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3417    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3418    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3419    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3420    testl     %eax,%eax                          # resolved entry null?
3421    je        .LOP_SGET_BYTE_resolve                # if not, make it so
3422.LOP_SGET_BYTE_finish:     # field ptr in eax
3423    movl      offStaticField_value(%eax),%eax
3424    FETCH_INST_OPCODE 2 %ecx
3425    ADVANCE_PC 2
3426    SET_VREG %eax rINST
3427    GOTO_NEXT_R %ecx
3428
3429    /*
3430     * Go resolve the field
3431     */
3432.LOP_SGET_BYTE_resolve:
3433    movl     rSELF,%ecx
3434    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3435    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3436    EXPORT_PC                                   # could throw, need to export
3437    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3438    movl     %eax,OUT_ARG1(%esp)
3439    movl     %ecx,OUT_ARG0(%esp)
3440    SPILL(rIBASE)
3441    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3442    UNSPILL(rIBASE)
3443    testl    %eax,%eax
3444    jne      .LOP_SGET_BYTE_finish                 # success, continue
3445    jmp      common_exceptionThrown             # no, handle exception
3446
3447
3448/* ------------------------------ */
3449.L_OP_SGET_CHAR: /* 0x65 */
3450/* File: x86/OP_SGET_CHAR.S */
3451/* File: x86/OP_SGET.S */
3452    /*
3453     * General 32-bit SGET handler.
3454     *
3455     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
3456     */
3457    /* op vAA, field@BBBB */
3458    movl      rSELF,%ecx
3459    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3460    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3461    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3462    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3463    testl     %eax,%eax                          # resolved entry null?
3464    je        .LOP_SGET_CHAR_resolve                # if not, make it so
3465.LOP_SGET_CHAR_finish:     # field ptr in eax
3466    movl      offStaticField_value(%eax),%eax
3467    FETCH_INST_OPCODE 2 %ecx
3468    ADVANCE_PC 2
3469    SET_VREG %eax rINST
3470    GOTO_NEXT_R %ecx
3471
3472    /*
3473     * Go resolve the field
3474     */
3475.LOP_SGET_CHAR_resolve:
3476    movl     rSELF,%ecx
3477    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3478    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3479    EXPORT_PC                                   # could throw, need to export
3480    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3481    movl     %eax,OUT_ARG1(%esp)
3482    movl     %ecx,OUT_ARG0(%esp)
3483    SPILL(rIBASE)
3484    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3485    UNSPILL(rIBASE)
3486    testl    %eax,%eax
3487    jne      .LOP_SGET_CHAR_finish                 # success, continue
3488    jmp      common_exceptionThrown             # no, handle exception
3489
3490
3491/* ------------------------------ */
3492.L_OP_SGET_SHORT: /* 0x66 */
3493/* File: x86/OP_SGET_SHORT.S */
3494/* File: x86/OP_SGET.S */
3495    /*
3496     * General 32-bit SGET handler.
3497     *
3498     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
3499     */
3500    /* op vAA, field@BBBB */
3501    movl      rSELF,%ecx
3502    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3503    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3504    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3505    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3506    testl     %eax,%eax                          # resolved entry null?
3507    je        .LOP_SGET_SHORT_resolve                # if not, make it so
3508.LOP_SGET_SHORT_finish:     # field ptr in eax
3509    movl      offStaticField_value(%eax),%eax
3510    FETCH_INST_OPCODE 2 %ecx
3511    ADVANCE_PC 2
3512    SET_VREG %eax rINST
3513    GOTO_NEXT_R %ecx
3514
3515    /*
3516     * Go resolve the field
3517     */
3518.LOP_SGET_SHORT_resolve:
3519    movl     rSELF,%ecx
3520    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3521    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3522    EXPORT_PC                                   # could throw, need to export
3523    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3524    movl     %eax,OUT_ARG1(%esp)
3525    movl     %ecx,OUT_ARG0(%esp)
3526    SPILL(rIBASE)
3527    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3528    UNSPILL(rIBASE)
3529    testl    %eax,%eax
3530    jne      .LOP_SGET_SHORT_finish                 # success, continue
3531    jmp      common_exceptionThrown             # no, handle exception
3532
3533
3534/* ------------------------------ */
3535.L_OP_SPUT: /* 0x67 */
3536/* File: x86/OP_SPUT.S */
3537    /*
3538     * General 32-bit SPUT handler.
3539     *
3540     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3541     */
3542    /* op vAA, field@BBBB */
3543    movl      rSELF,%ecx
3544    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3545    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3546    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3547    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3548    testl     %eax,%eax                          # resolved entry null?
3549    je        .LOP_SPUT_resolve                # if not, make it so
3550.LOP_SPUT_finish:     # field ptr in eax
3551    GET_VREG_R  rINST rINST
3552    FETCH_INST_OPCODE 2 %ecx
3553    ADVANCE_PC 2
3554    movl      rINST,offStaticField_value(%eax)
3555    GOTO_NEXT_R %ecx
3556
3557    /*
3558     * Go resolve the field
3559     */
3560.LOP_SPUT_resolve:
3561    movl     rSELF,%ecx
3562    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3563    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3564    EXPORT_PC                                   # could throw, need to export
3565    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3566    movl     %eax,OUT_ARG1(%esp)
3567    movl     %ecx,OUT_ARG0(%esp)
3568    SPILL(rIBASE)
3569    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3570    UNSPILL(rIBASE)
3571    testl    %eax,%eax
3572    jne      .LOP_SPUT_finish                 # success, continue
3573    jmp      common_exceptionThrown             # no, handle exception
3574
3575/* ------------------------------ */
3576.L_OP_SPUT_WIDE: /* 0x68 */
3577/* File: x86/OP_SPUT_WIDE.S */
3578    /*
3579     * General 32-bit SPUT handler.
3580     *
3581     * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
3582     */
3583    /* op vAA, field@BBBB */
3584    movl      rSELF,%ecx
3585    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3586    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3587    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3588    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3589    testl     %eax,%eax                          # resolved entry null?
3590    je        .LOP_SPUT_WIDE_resolve                # if not, make it so
3591.LOP_SPUT_WIDE_finish:     # field ptr in eax
3592    GET_VREG_WORD %ecx rINST 0                  # rINST<- lsw
3593    GET_VREG_WORD rINST rINST 1                 # ecx<- msw
3594    movl      %ecx,offStaticField_value(%eax)
3595    FETCH_INST_OPCODE 2 %ecx
3596    movl      rINST,4+offStaticField_value(%eax)
3597    ADVANCE_PC 2
3598    GOTO_NEXT_R %ecx
3599
3600    /*
3601     * Go resolve the field
3602     */
3603.LOP_SPUT_WIDE_resolve:
3604    movl     rSELF,%ecx
3605    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3606    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3607    EXPORT_PC                                   # could throw, need to export
3608    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3609    movl     %eax,OUT_ARG1(%esp)
3610    movl     %ecx,OUT_ARG0(%esp)
3611    SPILL(rIBASE)
3612    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3613    UNSPILL(rIBASE)
3614    testl    %eax,%eax
3615    jne      .LOP_SPUT_WIDE_finish                 # success, continue
3616    jmp      common_exceptionThrown             # no, handle exception
3617
3618/* ------------------------------ */
3619.L_OP_SPUT_OBJECT: /* 0x69 */
3620/* File: x86/OP_SPUT_OBJECT.S */
3621    /*
3622     * SPUT object handler.
3623     */
3624    /* op vAA, field@BBBB */
3625    movl      rSELF,%ecx
3626    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3627    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3628    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3629    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField
3630    testl     %eax,%eax                          # resolved entry null?
3631    je        .LOP_SPUT_OBJECT_resolve                # if not, make it so
3632.LOP_SPUT_OBJECT_finish:                              # field ptr in eax
3633    movzbl    rINSTbl,%ecx                       # ecx<- AA
3634    GET_VREG_R  %ecx %ecx
3635    movl      %ecx,offStaticField_value(%eax)    # do the store
3636    testl     %ecx,%ecx                          # stored null object ptr?
3637    je        1f                                 # skip card mark if null
3638    movl      rSELF,%ecx
3639    movl      offField_clazz(%eax),%eax          # eax<- method->clazz
3640    movl      offThread_cardTable(%ecx),%ecx       # get card table base
3641    shrl      $GC_CARD_SHIFT,%eax               # head to card number
3642    movb      %cl,(%ecx,%eax)                    # mark card
36431:
3644    FETCH_INST_OPCODE 2 %ecx
3645    ADVANCE_PC 2
3646    GOTO_NEXT_R %ecx
3647
3648.LOP_SPUT_OBJECT_resolve:
3649    movl     rSELF,%ecx
3650    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3651    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3652    EXPORT_PC                                   # could throw, need to export
3653    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3654    movl     %eax,OUT_ARG1(%esp)
3655    movl     %ecx,OUT_ARG0(%esp)
3656    SPILL(rIBASE)
3657    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3658    UNSPILL(rIBASE)
3659    testl    %eax,%eax
3660    jne      .LOP_SPUT_OBJECT_finish                 # success, continue
3661    jmp      common_exceptionThrown             # no, handle exception
3662
3663/* ------------------------------ */
3664.L_OP_SPUT_BOOLEAN: /* 0x6a */
3665/* File: x86/OP_SPUT_BOOLEAN.S */
3666/* File: x86/OP_SPUT.S */
3667    /*
3668     * General 32-bit SPUT handler.
3669     *
3670     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3671     */
3672    /* op vAA, field@BBBB */
3673    movl      rSELF,%ecx
3674    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3675    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3676    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3677    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3678    testl     %eax,%eax                          # resolved entry null?
3679    je        .LOP_SPUT_BOOLEAN_resolve                # if not, make it so
3680.LOP_SPUT_BOOLEAN_finish:     # field ptr in eax
3681    GET_VREG_R  rINST rINST
3682    FETCH_INST_OPCODE 2 %ecx
3683    ADVANCE_PC 2
3684    movl      rINST,offStaticField_value(%eax)
3685    GOTO_NEXT_R %ecx
3686
3687    /*
3688     * Go resolve the field
3689     */
3690.LOP_SPUT_BOOLEAN_resolve:
3691    movl     rSELF,%ecx
3692    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3693    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3694    EXPORT_PC                                   # could throw, need to export
3695    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3696    movl     %eax,OUT_ARG1(%esp)
3697    movl     %ecx,OUT_ARG0(%esp)
3698    SPILL(rIBASE)
3699    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3700    UNSPILL(rIBASE)
3701    testl    %eax,%eax
3702    jne      .LOP_SPUT_BOOLEAN_finish                 # success, continue
3703    jmp      common_exceptionThrown             # no, handle exception
3704
3705
3706/* ------------------------------ */
3707.L_OP_SPUT_BYTE: /* 0x6b */
3708/* File: x86/OP_SPUT_BYTE.S */
3709/* File: x86/OP_SPUT.S */
3710    /*
3711     * General 32-bit SPUT handler.
3712     *
3713     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3714     */
3715    /* op vAA, field@BBBB */
3716    movl      rSELF,%ecx
3717    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3718    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3719    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3720    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3721    testl     %eax,%eax                          # resolved entry null?
3722    je        .LOP_SPUT_BYTE_resolve                # if not, make it so
3723.LOP_SPUT_BYTE_finish:     # field ptr in eax
3724    GET_VREG_R  rINST rINST
3725    FETCH_INST_OPCODE 2 %ecx
3726    ADVANCE_PC 2
3727    movl      rINST,offStaticField_value(%eax)
3728    GOTO_NEXT_R %ecx
3729
3730    /*
3731     * Go resolve the field
3732     */
3733.LOP_SPUT_BYTE_resolve:
3734    movl     rSELF,%ecx
3735    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3736    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3737    EXPORT_PC                                   # could throw, need to export
3738    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3739    movl     %eax,OUT_ARG1(%esp)
3740    movl     %ecx,OUT_ARG0(%esp)
3741    SPILL(rIBASE)
3742    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3743    UNSPILL(rIBASE)
3744    testl    %eax,%eax
3745    jne      .LOP_SPUT_BYTE_finish                 # success, continue
3746    jmp      common_exceptionThrown             # no, handle exception
3747
3748
3749/* ------------------------------ */
3750.L_OP_SPUT_CHAR: /* 0x6c */
3751/* File: x86/OP_SPUT_CHAR.S */
3752/* File: x86/OP_SPUT.S */
3753    /*
3754     * General 32-bit SPUT handler.
3755     *
3756     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3757     */
3758    /* op vAA, field@BBBB */
3759    movl      rSELF,%ecx
3760    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3761    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3762    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3763    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3764    testl     %eax,%eax                          # resolved entry null?
3765    je        .LOP_SPUT_CHAR_resolve                # if not, make it so
3766.LOP_SPUT_CHAR_finish:     # field ptr in eax
3767    GET_VREG_R  rINST rINST
3768    FETCH_INST_OPCODE 2 %ecx
3769    ADVANCE_PC 2
3770    movl      rINST,offStaticField_value(%eax)
3771    GOTO_NEXT_R %ecx
3772
3773    /*
3774     * Go resolve the field
3775     */
3776.LOP_SPUT_CHAR_resolve:
3777    movl     rSELF,%ecx
3778    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3779    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3780    EXPORT_PC                                   # could throw, need to export
3781    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3782    movl     %eax,OUT_ARG1(%esp)
3783    movl     %ecx,OUT_ARG0(%esp)
3784    SPILL(rIBASE)
3785    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3786    UNSPILL(rIBASE)
3787    testl    %eax,%eax
3788    jne      .LOP_SPUT_CHAR_finish                 # success, continue
3789    jmp      common_exceptionThrown             # no, handle exception
3790
3791
3792/* ------------------------------ */
3793.L_OP_SPUT_SHORT: /* 0x6d */
3794/* File: x86/OP_SPUT_SHORT.S */
3795/* File: x86/OP_SPUT.S */
3796    /*
3797     * General 32-bit SPUT handler.
3798     *
3799     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3800     */
3801    /* op vAA, field@BBBB */
3802    movl      rSELF,%ecx
3803    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3804    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3805    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3806    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3807    testl     %eax,%eax                          # resolved entry null?
3808    je        .LOP_SPUT_SHORT_resolve                # if not, make it so
3809.LOP_SPUT_SHORT_finish:     # field ptr in eax
3810    GET_VREG_R  rINST rINST
3811    FETCH_INST_OPCODE 2 %ecx
3812    ADVANCE_PC 2
3813    movl      rINST,offStaticField_value(%eax)
3814    GOTO_NEXT_R %ecx
3815
3816    /*
3817     * Go resolve the field
3818     */
3819.LOP_SPUT_SHORT_resolve:
3820    movl     rSELF,%ecx
3821    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3822    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3823    EXPORT_PC                                   # could throw, need to export
3824    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3825    movl     %eax,OUT_ARG1(%esp)
3826    movl     %ecx,OUT_ARG0(%esp)
3827    SPILL(rIBASE)
3828    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3829    UNSPILL(rIBASE)
3830    testl    %eax,%eax
3831    jne      .LOP_SPUT_SHORT_finish                 # success, continue
3832    jmp      common_exceptionThrown             # no, handle exception
3833
3834
3835/* ------------------------------ */
3836.L_OP_INVOKE_VIRTUAL: /* 0x6e */
3837/* File: x86/OP_INVOKE_VIRTUAL.S */
3838
3839    /*
3840     * Handle a virtual method call.
3841     *
3842     * for: invoke-virtual, invoke-virtual/range
3843     */
3844    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3845    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3846    movl      rSELF,%eax
3847    movzwl    2(rPC),%ecx                 # ecx<- BBBB
3848    movl      offThread_methodClassDex(%eax),%eax  # eax<- pDvmDex
3849    EXPORT_PC
3850    movl      offDvmDex_pResMethods(%eax),%eax   # eax<- pDvmDex->pResMethods
3851    movl      (%eax,%ecx,4),%eax          # eax<- resolved baseMethod
3852    testl     %eax,%eax                   # already resolved?
3853    jne       .LOP_INVOKE_VIRTUAL_continue        # yes, continue
3854    movl      rSELF,%eax
3855    movl      %ecx,OUT_ARG1(%esp)         # arg1<- ref
3856    movl      offThread_method(%eax),%eax   # eax<- self->method
3857    movl      offMethod_clazz(%eax),%eax  # ecx<- method->clazz
3858    movl      %eax,OUT_ARG0(%esp)         # arg0<- clazz
3859    movl      $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags
3860    call      dvmResolveMethod            # eax<- call(clazz, ref, flags)
3861    testl     %eax,%eax                   # got null?
3862    jne       .LOP_INVOKE_VIRTUAL_continue        # no, continue
3863    jmp       common_exceptionThrown      # yes, handle exception
3864
3865    /* At this point:
3866     *   eax = resolved base method
3867     *   ecx = scratch
3868     */
3869.LOP_INVOKE_VIRTUAL_continue:
3870    movzwl    4(rPC),%ecx               # ecx<- GFED or CCCC
3871    .if       (!0)
3872    andl      $0xf,%ecx                # ecx<- D (or stays CCCC)
3873    .endif
3874    GET_VREG_R  %ecx %ecx               # ecx<- "this"
3875    movzwl    offMethod_methodIndex(%eax),%eax  # eax<- baseMethod->methodIndex
3876    testl     %ecx,%ecx                 # null this?
3877    je        common_errNullObject      # go if so
3878    movl      offObject_clazz(%ecx),%ecx  # ecx<- thisPtr->clazz
3879    movl      offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable
3880    movl      (%ecx,%eax,4),%eax        # eax<- vtable[methodIndex]
3881    jmp       common_invokeMethodNoRange
3882
3883/* ------------------------------ */
3884.L_OP_INVOKE_SUPER: /* 0x6f */
3885/* File: x86/OP_INVOKE_SUPER.S */
3886    /*
3887     * Handle a "super" method call.
3888     *
3889     * for: invoke-super, invoke-super/range
3890     */
3891    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3892    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3893    movl      rSELF,rINST
3894    movzwl    2(rPC),%eax               # eax<- BBBB
3895    movl      offThread_methodClassDex(rINST),%ecx # ecx<- pDvmDex
3896    EXPORT_PC
3897    movl      offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods
3898    movl      (%ecx,%eax,4),%ecx        # ecx<- resolved baseMethod
3899    movl      offThread_method(rINST),%eax # eax<- method
3900    movzwl    4(rPC),rINST              # rINST<- GFED or CCCC
3901    .if       (!0)
3902    andl      $0xf,rINST               # rINST<- D (or stays CCCC)
3903    .endif
3904    GET_VREG_R  rINST rINST             # rINST<- "this" ptr
3905    testl     rINST,rINST               # null "this"?
3906    je        common_errNullObject      # yes, throw
3907    movl      offMethod_clazz(%eax),%eax # eax<- method->clazz
3908    testl     %ecx,%ecx                 # already resolved?
3909    je       .LOP_INVOKE_SUPER_resolve
3910    /*
3911     * At this point:
3912     *  ecx = resolved base method [r0]
3913     *  eax = method->clazz [r9]
3914     */
3915.LOP_INVOKE_SUPER_continue:
3916    movl    offClassObject_super(%eax),%eax   # eax<- method->clazz->super
3917    movzwl  offMethod_methodIndex(%ecx),%ecx  # ecx<- baseMthod->methodIndex
3918    cmpl    offClassObject_vtableCount(%eax),%ecx # compare(methodIndex,vtableCount)
3919    jae     .LOP_INVOKE_SUPER_nsm           # method not present in superclass
3920    movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
3921    movl    (%eax,%ecx,4),%eax        # eax<- vtable[methodIndex]
3922    jmp     common_invokeMethodNoRange
3923
3924
3925    /* At this point:
3926     * ecx = null (needs to be resolved base method)
3927     * eax = method->clazz
3928    */
3929.LOP_INVOKE_SUPER_resolve:
3930    SPILL_TMP1(%eax)                    # method->clazz
3931    movl    %eax,OUT_ARG0(%esp)         # arg0<- method->clazz
3932    movzwl  2(rPC),%ecx                 # ecx<- BBBB
3933    movl    $METHOD_VIRTUAL,OUT_ARG2(%esp)  # arg2<- resolver method type
3934    movl    %ecx,OUT_ARG1(%esp)         # arg1<- ref
3935    call    dvmResolveMethod            # eax<- call(clazz, ref, flags)
3936    testl   %eax,%eax                   # got null?
3937    movl    %eax,%ecx                   # ecx<- resolved base method
3938    UNSPILL_TMP1(%eax)                  # restore method->clazz
3939    jne     .LOP_INVOKE_SUPER_continue        # good to go - continue
3940    jmp     common_exceptionThrown      # handle exception
3941
3942    /*
3943     * Throw a NoSuchMethodError with the method name as the message.
3944     *  ecx = resolved base method
3945     */
3946.LOP_INVOKE_SUPER_nsm:
3947    movl    offMethod_name(%ecx),%eax
3948    jmp     common_errNoSuchMethod
3949
3950/* ------------------------------ */
3951.L_OP_INVOKE_DIRECT: /* 0x70 */
3952/* File: x86/OP_INVOKE_DIRECT.S */
3953    /*
3954     * Handle a direct method call.
3955     *
3956     * (We could defer the "is 'this' pointer null" test to the common
3957     * method invocation code, and use a flag to indicate that static
3958     * calls don't count.  If we do this as part of copying the arguments
3959     * out we could avoiding loading the first arg twice.)
3960     *
3961     * for: invoke-direct, invoke-direct/range
3962     */
3963    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3964    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3965    movl      rSELF,%ecx
3966    movzwl    2(rPC),%eax              # eax<- BBBB
3967    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
3968    EXPORT_PC
3969    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
3970    movzwl    4(rPC),rIBASE            # rIBASE<- GFED or CCCC
3971    movl      (%ecx,%eax,4),%eax       # eax<- resolved methodToCall
3972    .if       (!0)
3973    andl      $0xf,rIBASE             # rIBASE<- D (or stays CCCC)
3974    .endif
3975    testl     %eax,%eax                # already resolved?
3976    GET_VREG_R  %ecx rIBASE            # ecx<- "this" ptr
3977    je        .LOP_INVOKE_DIRECT_resolve      # not resolved, do it now
3978.LOP_INVOKE_DIRECT_finish:
3979    testl     %ecx,%ecx                # null "this"?
3980    jne       common_invokeMethodNoRange  # no, continue on
3981    jmp       common_errNullObject
3982
3983    /*
3984     * On entry:
3985     *   TMP_SPILL  <- "this" register
3986     * Things a bit ugly on this path, but it's the less
3987     * frequent one.  We'll have to do some reloading.
3988     */
3989.LOP_INVOKE_DIRECT_resolve:
3990     SPILL_TMP1(%ecx)
3991     movl     rSELF,%ecx
3992     movl     offThread_method(%ecx),%ecx  # ecx<- self->method
3993     movzwl   2(rPC),%eax      # reference (BBBB or CCCC)
3994     movl     offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
3995     movl     $METHOD_DIRECT,OUT_ARG2(%esp)
3996     movl     %eax,OUT_ARG1(%esp)
3997     movl     %ecx,OUT_ARG0(%esp)
3998     call     dvmResolveMethod # eax<- call(clazz, ref, flags)
3999     UNSPILL_TMP1(%ecx)
4000     testl    %eax,%eax
4001     jne      .LOP_INVOKE_DIRECT_finish
4002     jmp      common_exceptionThrown
4003
4004/* ------------------------------ */
4005.L_OP_INVOKE_STATIC: /* 0x71 */
4006/* File: x86/OP_INVOKE_STATIC.S */
4007    /*
4008     * Handle a static method call.
4009     *
4010     * for: invoke-static, invoke-static/range
4011     */
4012    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
4013    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
4014    movl      rSELF,%ecx
4015    movzwl    2(rPC),%eax               # eax<- BBBB
4016    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
4017    EXPORT_PC
4018    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
4019    movl      (%ecx,%eax,4),%eax        # eax<- resolved methodToCall
4020    testl     %eax,%eax
4021    jne       common_invokeMethodNoRange
4022    movl      rSELF,%ecx
4023    movl      offThread_method(%ecx),%ecx # ecx<- self->method
4024    movzwl    2(rPC),%eax
4025    movl      offMethod_clazz(%ecx),%ecx# ecx<- method->clazz
4026    movl      %eax,OUT_ARG1(%esp)       # arg1<- BBBB
4027    movl      %ecx,OUT_ARG0(%esp)       # arg0<- clazz
4028    movl      $METHOD_STATIC,%eax
4029    movl      %eax,OUT_ARG2(%esp)       # arg2<- flags
4030    call      dvmResolveMethod          # call(clazz,ref,flags)
4031    testl     %eax,%eax                 # got null?
4032    jne       common_invokeMethodNoRange
4033    jmp       common_exceptionThrown
4034
4035/* ------------------------------ */
4036.L_OP_INVOKE_INTERFACE: /* 0x72 */
4037/* File: x86/OP_INVOKE_INTERFACE.S */
4038    /*
4039     * Handle an interface method call.
4040     *
4041     * for: invoke-interface, invoke-interface/range
4042     */
4043    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
4044    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
4045    movzwl     4(rPC),%eax              # eax<- FEDC or CCCC
4046    movl       rSELF,%ecx
4047    .if        (!0)
4048    andl       $0xf,%eax               # eax<- C (or stays CCCC)
4049    .endif
4050    GET_VREG_R   %eax %eax              # eax<- "this"
4051    EXPORT_PC
4052    testl      %eax,%eax                # null this?
4053    je         common_errNullObject     # yes, fail
4054    movl       offObject_clazz(%eax),%eax# eax<- thisPtr->clazz
4055    movl       %eax,OUT_ARG0(%esp)                 # arg0<- class
4056    movl       offThread_methodClassDex(%ecx),%eax   # eax<- methodClassDex
4057    movl       offThread_method(%ecx),%ecx           # ecx<- method
4058    movl       %eax,OUT_ARG3(%esp)                 # arg3<- dex
4059    movzwl     2(rPC),%eax                         # eax<- BBBB
4060    movl       %ecx,OUT_ARG2(%esp)                 # arg2<- method
4061    movl       %eax,OUT_ARG1(%esp)                 # arg1<- BBBB
4062    call       dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex)
4063    testl      %eax,%eax
4064    je         common_exceptionThrown
4065    jmp        common_invokeMethodNoRange
4066
4067/* ------------------------------ */
4068.L_OP_UNUSED_73: /* 0x73 */
4069/* File: x86/OP_UNUSED_73.S */
4070/* File: x86/unused.S */
4071    jmp     common_abort
4072
4073
4074/* ------------------------------ */
4075.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
4076/* File: x86/OP_INVOKE_VIRTUAL_RANGE.S */
4077/* File: x86/OP_INVOKE_VIRTUAL.S */
4078
4079    /*
4080     * Handle a virtual method call.
4081     *
4082     * for: invoke-virtual, invoke-virtual/range
4083     */
4084    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
4085    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
4086    movl      rSELF,%eax
4087    movzwl    2(rPC),%ecx                 # ecx<- BBBB
4088    movl      offThread_methodClassDex(%eax),%eax  # eax<- pDvmDex
4089    EXPORT_PC
4090    movl      offDvmDex_pResMethods(%eax),%eax   # eax<- pDvmDex->pResMethods
4091    movl      (%eax,%ecx,4),%eax          # eax<- resolved baseMethod
4092    testl     %eax,%eax                   # already resolved?
4093    jne       .LOP_INVOKE_VIRTUAL_RANGE_continue        # yes, continue
4094    movl      rSELF,%eax
4095    movl      %ecx,OUT_ARG1(%esp)         # arg1<- ref
4096    movl      offThread_method(%eax),%eax   # eax<- self->method
4097    movl      offMethod_clazz(%eax),%eax  # ecx<- method->clazz
4098    movl      %eax,OUT_ARG0(%esp)         # arg0<- clazz
4099    movl      $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags
4100    call      dvmResolveMethod            # eax<- call(clazz, ref, flags)
4101    testl     %eax,%eax                   # got null?
4102    jne       .LOP_INVOKE_VIRTUAL_RANGE_continue        # no, continue
4103    jmp       common_exceptionThrown      # yes, handle exception
4104
4105    /* At this point:
4106     *   eax = resolved base method
4107     *   ecx = scratch
4108     */
4109.LOP_INVOKE_VIRTUAL_RANGE_continue:
4110    movzwl    4(rPC),%ecx               # ecx<- GFED or CCCC
4111    .if       (!1)
4112    andl      $0xf,%ecx                # ecx<- D (or stays CCCC)
4113    .endif
4114    GET_VREG_R  %ecx %ecx               # ecx<- "this"
4115    movzwl    offMethod_methodIndex(%eax),%eax  # eax<- baseMethod->methodIndex
4116    testl     %ecx,%ecx                 # null this?
4117    je        common_errNullObject      # go if so
4118    movl      offObject_clazz(%ecx),%ecx  # ecx<- thisPtr->clazz
4119    movl      offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable
4120    movl      (%ecx,%eax,4),%eax        # eax<- vtable[methodIndex]
4121    jmp       common_invokeMethodRange
4122
4123
4124/* ------------------------------ */
4125.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */
4126/* File: x86/OP_INVOKE_SUPER_RANGE.S */
4127/* File: x86/OP_INVOKE_SUPER.S */
4128    /*
4129     * Handle a "super" method call.
4130     *
4131     * for: invoke-super, invoke-super/range
4132     */
4133    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
4134    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
4135    movl      rSELF,rINST
4136    movzwl    2(rPC),%eax               # eax<- BBBB
4137    movl      offThread_methodClassDex(rINST),%ecx # ecx<- pDvmDex
4138    EXPORT_PC
4139    movl      offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods
4140    movl      (%ecx,%eax,4),%ecx        # ecx<- resolved baseMethod
4141    movl      offThread_method(rINST),%eax # eax<- method
4142    movzwl    4(rPC),rINST              # rINST<- GFED or CCCC
4143    .if       (!1)
4144    andl      $0xf,rINST               # rINST<- D (or stays CCCC)
4145    .endif
4146    GET_VREG_R  rINST rINST             # rINST<- "this" ptr
4147    testl     rINST,rINST               # null "this"?
4148    je        common_errNullObject      # yes, throw
4149    movl      offMethod_clazz(%eax),%eax # eax<- method->clazz
4150    testl     %ecx,%ecx                 # already resolved?
4151    je       .LOP_INVOKE_SUPER_RANGE_resolve
4152    /*
4153     * At this point:
4154     *  ecx = resolved base method [r0]
4155     *  eax = method->clazz [r9]
4156     */
4157.LOP_INVOKE_SUPER_RANGE_continue:
4158    movl    offClassObject_super(%eax),%eax   # eax<- method->clazz->super
4159    movzwl  offMethod_methodIndex(%ecx),%ecx  # ecx<- baseMthod->methodIndex
4160    cmpl    offClassObject_vtableCount(%eax),%ecx # compare(methodIndex,vtableCount)
4161    jae     .LOP_INVOKE_SUPER_RANGE_nsm           # method not present in superclass
4162    movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
4163    movl    (%eax,%ecx,4),%eax        # eax<- vtable[methodIndex]
4164    jmp     common_invokeMethodRange
4165
4166
4167    /* At this point:
4168     * ecx = null (needs to be resolved base method)
4169     * eax = method->clazz
4170    */
4171.LOP_INVOKE_SUPER_RANGE_resolve:
4172    SPILL_TMP1(%eax)                    # method->clazz
4173    movl    %eax,OUT_ARG0(%esp)         # arg0<- method->clazz
4174    movzwl  2(rPC),%ecx                 # ecx<- BBBB
4175    movl    $METHOD_VIRTUAL,OUT_ARG2(%esp)  # arg2<- resolver method type
4176    movl    %ecx,OUT_ARG1(%esp)         # arg1<- ref
4177    call    dvmResolveMethod            # eax<- call(clazz, ref, flags)
4178    testl   %eax,%eax                   # got null?
4179    movl    %eax,%ecx                   # ecx<- resolved base method
4180    UNSPILL_TMP1(%eax)                  # restore method->clazz
4181    jne     .LOP_INVOKE_SUPER_RANGE_continue        # good to go - continue
4182    jmp     common_exceptionThrown      # handle exception
4183
4184    /*
4185     * Throw a NoSuchMethodError with the method name as the message.
4186     *  ecx = resolved base method
4187     */
4188.LOP_INVOKE_SUPER_RANGE_nsm:
4189    movl    offMethod_name(%ecx),%eax
4190    jmp     common_errNoSuchMethod
4191
4192
4193/* ------------------------------ */
4194.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
4195/* File: x86/OP_INVOKE_DIRECT_RANGE.S */
4196/* File: x86/OP_INVOKE_DIRECT.S */
4197    /*
4198     * Handle a direct method call.
4199     *
4200     * (We could defer the "is 'this' pointer null" test to the common
4201     * method invocation code, and use a flag to indicate that static
4202     * calls don't count.  If we do this as part of copying the arguments
4203     * out we could avoiding loading the first arg twice.)
4204     *
4205     * for: invoke-direct, invoke-direct/range
4206     */
4207    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
4208    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
4209    movl      rSELF,%ecx
4210    movzwl    2(rPC),%eax              # eax<- BBBB
4211    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
4212    EXPORT_PC
4213    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
4214    movzwl    4(rPC),rIBASE            # rIBASE<- GFED or CCCC
4215    movl      (%ecx,%eax,4),%eax       # eax<- resolved methodToCall
4216    .if       (!1)
4217    andl      $0xf,rIBASE             # rIBASE<- D (or stays CCCC)
4218    .endif
4219    testl     %eax,%eax                # already resolved?
4220    GET_VREG_R  %ecx rIBASE            # ecx<- "this" ptr
4221    je        .LOP_INVOKE_DIRECT_RANGE_resolve      # not resolved, do it now
4222.LOP_INVOKE_DIRECT_RANGE_finish:
4223    testl     %ecx,%ecx                # null "this"?
4224    jne       common_invokeMethodRange  # no, continue on
4225    jmp       common_errNullObject
4226
4227    /*
4228     * On entry:
4229     *   TMP_SPILL  <- "this" register
4230     * Things a bit ugly on this path, but it's the less
4231     * frequent one.  We'll have to do some reloading.
4232     */
4233.LOP_INVOKE_DIRECT_RANGE_resolve:
4234     SPILL_TMP1(%ecx)
4235     movl     rSELF,%ecx
4236     movl     offThread_method(%ecx),%ecx  # ecx<- self->method
4237     movzwl   2(rPC),%eax      # reference (BBBB or CCCC)
4238     movl     offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
4239     movl     $METHOD_DIRECT,OUT_ARG2(%esp)
4240     movl     %eax,OUT_ARG1(%esp)
4241     movl     %ecx,OUT_ARG0(%esp)
4242     call     dvmResolveMethod # eax<- call(clazz, ref, flags)
4243     UNSPILL_TMP1(%ecx)
4244     testl    %eax,%eax
4245     jne      .LOP_INVOKE_DIRECT_RANGE_finish
4246     jmp      common_exceptionThrown
4247
4248
4249/* ------------------------------ */
4250.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */
4251/* File: x86/OP_INVOKE_STATIC_RANGE.S */
4252/* File: x86/OP_INVOKE_STATIC.S */
4253    /*
4254     * Handle a static method call.
4255     *
4256     * for: invoke-static, invoke-static/range
4257     */
4258    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
4259    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
4260    movl      rSELF,%ecx
4261    movzwl    2(rPC),%eax               # eax<- BBBB
4262    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
4263    EXPORT_PC
4264    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
4265    movl      (%ecx,%eax,4),%eax        # eax<- resolved methodToCall
4266    testl     %eax,%eax
4267    jne       common_invokeMethodRange
4268    movl      rSELF,%ecx
4269    movl      offThread_method(%ecx),%ecx # ecx<- self->method
4270    movzwl    2(rPC),%eax
4271    movl      offMethod_clazz(%ecx),%ecx# ecx<- method->clazz
4272    movl      %eax,OUT_ARG1(%esp)       # arg1<- BBBB
4273    movl      %ecx,OUT_ARG0(%esp)       # arg0<- clazz
4274    movl      $METHOD_STATIC,%eax
4275    movl      %eax,OUT_ARG2(%esp)       # arg2<- flags
4276    call      dvmResolveMethod          # call(clazz,ref,flags)
4277    testl     %eax,%eax                 # got null?
4278    jne       common_invokeMethodRange
4279    jmp       common_exceptionThrown
4280
4281
4282/* ------------------------------ */
4283.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
4284/* File: x86/OP_INVOKE_INTERFACE_RANGE.S */
4285/* File: x86/OP_INVOKE_INTERFACE.S */
4286    /*
4287     * Handle an interface method call.
4288     *
4289     * for: invoke-interface, invoke-interface/range
4290     */
4291    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
4292    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
4293    movzwl     4(rPC),%eax              # eax<- FEDC or CCCC
4294    movl       rSELF,%ecx
4295    .if        (!1)
4296    andl       $0xf,%eax               # eax<- C (or stays CCCC)
4297    .endif
4298    GET_VREG_R   %eax %eax              # eax<- "this"
4299    EXPORT_PC
4300    testl      %eax,%eax                # null this?
4301    je         common_errNullObject     # yes, fail
4302    movl       offObject_clazz(%eax),%eax# eax<- thisPtr->clazz
4303    movl       %eax,OUT_ARG0(%esp)                 # arg0<- class
4304    movl       offThread_methodClassDex(%ecx),%eax   # eax<- methodClassDex
4305    movl       offThread_method(%ecx),%ecx           # ecx<- method
4306    movl       %eax,OUT_ARG3(%esp)                 # arg3<- dex
4307    movzwl     2(rPC),%eax                         # eax<- BBBB
4308    movl       %ecx,OUT_ARG2(%esp)                 # arg2<- method
4309    movl       %eax,OUT_ARG1(%esp)                 # arg1<- BBBB
4310    call       dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex)
4311    testl      %eax,%eax
4312    je         common_exceptionThrown
4313    jmp        common_invokeMethodRange
4314
4315
4316/* ------------------------------ */
4317.L_OP_UNUSED_79: /* 0x79 */
4318/* File: x86/OP_UNUSED_79.S */
4319/* File: x86/unused.S */
4320    jmp     common_abort
4321
4322
4323/* ------------------------------ */
4324.L_OP_UNUSED_7A: /* 0x7a */
4325/* File: x86/OP_UNUSED_7A.S */
4326/* File: x86/unused.S */
4327    jmp     common_abort
4328
4329
4330/* ------------------------------ */
4331.L_OP_NEG_INT: /* 0x7b */
4332/* File: x86/OP_NEG_INT.S */
4333/* File: x86/unop.S */
4334    /*
4335     * Generic 32-bit unary operation.  Provide an "instr" line that
4336     * specifies an instruction that performs "result = op eax".
4337     */
4338    /* unop vA, vB */
4339    movzbl   rINSTbl,%ecx           # ecx<- A+
4340    sarl     $4,rINST             # rINST<- B
4341    GET_VREG_R %eax rINST           # eax<- vB
4342    andb     $0xf,%cl              # ecx<- A
4343
4344
4345    negl %eax
4346    SET_VREG %eax %ecx
4347    FETCH_INST_OPCODE 1 %ecx
4348    ADVANCE_PC 1
4349    GOTO_NEXT_R %ecx
4350
4351
4352/* ------------------------------ */
4353.L_OP_NOT_INT: /* 0x7c */
4354/* File: x86/OP_NOT_INT.S */
4355/* File: x86/unop.S */
4356    /*
4357     * Generic 32-bit unary operation.  Provide an "instr" line that
4358     * specifies an instruction that performs "result = op eax".
4359     */
4360    /* unop vA, vB */
4361    movzbl   rINSTbl,%ecx           # ecx<- A+
4362    sarl     $4,rINST             # rINST<- B
4363    GET_VREG_R %eax rINST           # eax<- vB
4364    andb     $0xf,%cl              # ecx<- A
4365
4366
4367    notl %eax
4368    SET_VREG %eax %ecx
4369    FETCH_INST_OPCODE 1 %ecx
4370    ADVANCE_PC 1
4371    GOTO_NEXT_R %ecx
4372
4373
4374/* ------------------------------ */
4375.L_OP_NEG_LONG: /* 0x7d */
4376/* File: x86/OP_NEG_LONG.S */
4377    /* unop vA, vB */
4378    movzbl    rINSTbl,%ecx        # ecx<- BA
4379    sarl      $4,%ecx            # ecx<- B
4380    andb      $0xf,rINSTbl       # rINST<- A
4381    GET_VREG_WORD %eax %ecx 0     # eax<- v[B+0]
4382    GET_VREG_WORD %ecx %ecx 1     # ecx<- v[B+1]
4383    negl      %eax
4384    adcl      $0,%ecx
4385    negl      %ecx
4386    SET_VREG_WORD %eax rINST 0    # v[A+0]<- eax
4387    FETCH_INST_OPCODE 1 %eax
4388    SET_VREG_WORD %ecx rINST 1    # v[A+1]<- ecx
4389    ADVANCE_PC 1
4390    GOTO_NEXT_R %eax
4391
4392/* ------------------------------ */
4393.L_OP_NOT_LONG: /* 0x7e */
4394/* File: x86/OP_NOT_LONG.S */
4395    /* unop vA, vB */
4396    movzbl    rINSTbl,%ecx       # ecx<- BA
4397    sarl      $4,%ecx           # ecx<- B
4398    andb      $0xf,rINSTbl      # rINST<- A
4399    GET_VREG_WORD %eax %ecx 0    # eax<- v[B+0]
4400    GET_VREG_WORD %ecx %ecx 1    # ecx<- v[B+1]
4401    notl      %eax
4402    notl      %ecx
4403    SET_VREG_WORD %eax rINST 0   # v[A+0]<- eax
4404    FETCH_INST_OPCODE 1 %eax
4405    SET_VREG_WORD %ecx rINST 1   # v[A+1]<- ecx
4406    ADVANCE_PC 1
4407    GOTO_NEXT_R %eax
4408
4409/* ------------------------------ */
4410.L_OP_NEG_FLOAT: /* 0x7f */
4411/* File: x86/OP_NEG_FLOAT.S */
4412/* File: x86/fpcvt.S */
4413    /*
4414     * Generic 32-bit FP conversion operation.
4415     */
4416    /* unop vA, vB */
4417    movzbl   rINSTbl,%ecx       # ecx<- A+
4418    sarl     $4,rINST         # rINST<- B
4419    flds    (rFP,rINST,4)      # %st0<- vB
4420    andb     $0xf,%cl          # ecx<- A
4421    fchs
4422    fstps  (rFP,%ecx,4)        # vA<- %st0
4423    FETCH_INST_OPCODE 1 %ecx
4424    ADVANCE_PC 1
4425    GOTO_NEXT_R %ecx
4426
4427
4428/* ------------------------------ */
4429.L_OP_NEG_DOUBLE: /* 0x80 */
4430/* File: x86/OP_NEG_DOUBLE.S */
4431/* File: x86/fpcvt.S */
4432    /*
4433     * Generic 32-bit FP conversion operation.
4434     */
4435    /* unop vA, vB */
4436    movzbl   rINSTbl,%ecx       # ecx<- A+
4437    sarl     $4,rINST         # rINST<- B
4438    fldl    (rFP,rINST,4)      # %st0<- vB
4439    andb     $0xf,%cl          # ecx<- A
4440    fchs
4441    fstpl  (rFP,%ecx,4)        # vA<- %st0
4442    FETCH_INST_OPCODE 1 %ecx
4443    ADVANCE_PC 1
4444    GOTO_NEXT_R %ecx
4445
4446
4447/* ------------------------------ */
4448.L_OP_INT_TO_LONG: /* 0x81 */
4449/* File: x86/OP_INT_TO_LONG.S */
4450    /* int to long vA, vB */
4451    movzbl  rINSTbl,%eax                # eax<- +A
4452    sarl    $4,%eax                    # eax<- B
4453    GET_VREG_R %eax %eax                # eax<- vB
4454    andb    $0xf,rINSTbl               # rINST<- A
4455    SPILL(rIBASE)                       # cltd trashes rIBASE/edx
4456    cltd                                # rINST:eax<- sssssssBBBBBBBB
4457    SET_VREG_WORD rIBASE rINST 1        # v[A+1]<- rIBASE/rPC
4458    FETCH_INST_OPCODE 1 %ecx
4459    UNSPILL(rIBASE)
4460    SET_VREG_WORD %eax rINST 0          # v[A+0]<- %eax
4461    ADVANCE_PC 1
4462    GOTO_NEXT_R %ecx
4463
4464/* ------------------------------ */
4465.L_OP_INT_TO_FLOAT: /* 0x82 */
4466/* File: x86/OP_INT_TO_FLOAT.S */
4467/* File: x86/fpcvt.S */
4468    /*
4469     * Generic 32-bit FP conversion operation.
4470     */
4471    /* unop vA, vB */
4472    movzbl   rINSTbl,%ecx       # ecx<- A+
4473    sarl     $4,rINST         # rINST<- B
4474    fildl    (rFP,rINST,4)      # %st0<- vB
4475    andb     $0xf,%cl          # ecx<- A
4476
4477    fstps  (rFP,%ecx,4)        # vA<- %st0
4478    FETCH_INST_OPCODE 1 %ecx
4479    ADVANCE_PC 1
4480    GOTO_NEXT_R %ecx
4481
4482
4483/* ------------------------------ */
4484.L_OP_INT_TO_DOUBLE: /* 0x83 */
4485/* File: x86/OP_INT_TO_DOUBLE.S */
4486/* File: x86/fpcvt.S */
4487    /*
4488     * Generic 32-bit FP conversion operation.
4489     */
4490    /* unop vA, vB */
4491    movzbl   rINSTbl,%ecx       # ecx<- A+
4492    sarl     $4,rINST         # rINST<- B
4493    fildl    (rFP,rINST,4)      # %st0<- vB
4494    andb     $0xf,%cl          # ecx<- A
4495
4496    fstpl  (rFP,%ecx,4)        # vA<- %st0
4497    FETCH_INST_OPCODE 1 %ecx
4498    ADVANCE_PC 1
4499    GOTO_NEXT_R %ecx
4500
4501
4502/* ------------------------------ */
4503.L_OP_LONG_TO_INT: /* 0x84 */
4504/* File: x86/OP_LONG_TO_INT.S */
4505/* we ignore the high word, making this equivalent to a 32-bit reg move */
4506/* File: x86/OP_MOVE.S */
4507    /* for move, move-object, long-to-int */
4508    /* op vA, vB */
4509    movzbl rINSTbl,%eax          # eax<- BA
4510    andb   $0xf,%al             # eax<- A
4511    shrl   $4,rINST            # rINST<- B
4512    GET_VREG_R rINST rINST
4513    FETCH_INST_OPCODE 1 %ecx
4514    ADVANCE_PC 1
4515    SET_VREG rINST %eax           # fp[A]<-fp[B]
4516    GOTO_NEXT_R %ecx
4517
4518
4519/* ------------------------------ */
4520.L_OP_LONG_TO_FLOAT: /* 0x85 */
4521/* File: x86/OP_LONG_TO_FLOAT.S */
4522/* File: x86/fpcvt.S */
4523    /*
4524     * Generic 32-bit FP conversion operation.
4525     */
4526    /* unop vA, vB */
4527    movzbl   rINSTbl,%ecx       # ecx<- A+
4528    sarl     $4,rINST         # rINST<- B
4529    fildll    (rFP,rINST,4)      # %st0<- vB
4530    andb     $0xf,%cl          # ecx<- A
4531
4532    fstps  (rFP,%ecx,4)        # vA<- %st0
4533    FETCH_INST_OPCODE 1 %ecx
4534    ADVANCE_PC 1
4535    GOTO_NEXT_R %ecx
4536
4537
4538/* ------------------------------ */
4539.L_OP_LONG_TO_DOUBLE: /* 0x86 */
4540/* File: x86/OP_LONG_TO_DOUBLE.S */
4541/* File: x86/fpcvt.S */
4542    /*
4543     * Generic 32-bit FP conversion operation.
4544     */
4545    /* unop vA, vB */
4546    movzbl   rINSTbl,%ecx       # ecx<- A+
4547    sarl     $4,rINST         # rINST<- B
4548    fildll    (rFP,rINST,4)      # %st0<- vB
4549    andb     $0xf,%cl          # ecx<- A
4550
4551    fstpl  (rFP,%ecx,4)        # vA<- %st0
4552    FETCH_INST_OPCODE 1 %ecx
4553    ADVANCE_PC 1
4554    GOTO_NEXT_R %ecx
4555
4556
4557/* ------------------------------ */
4558.L_OP_FLOAT_TO_INT: /* 0x87 */
4559/* File: x86/OP_FLOAT_TO_INT.S */
4560/* File: x86/cvtfp_int.S */
4561/* On fp to int conversions, Java requires that
4562 * if the result > maxint, it should be clamped to maxint.  If it is less
4563 * than minint, it should be clamped to minint.  If it is a nan, the result
4564 * should be zero.  Further, the rounding mode is to truncate.  This model
4565 * differs from what is delivered normally via the x86 fpu, so we have
4566 * to play some games.
4567 */
4568    /* float/double to int/long vA, vB */
4569    movzbl    rINSTbl,%ecx       # ecx<- A+
4570    sarl      $4,rINST         # rINST<- B
4571    .if 0
4572    fldl     (rFP,rINST,4)       # %st0<- vB
4573    .else
4574    flds     (rFP,rINST,4)       # %st0<- vB
4575    .endif
4576    ftst
4577    fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
4578    movzwl   LOCAL0_OFFSET(%ebp),%eax
4579    movb     $0xc,%ah
4580    movw     %ax,LOCAL0_OFFSET+2(%ebp)
4581    fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
4582    andb     $0xf,%cl                # ecx<- A
4583    .if 0
4584    fistpll  (rFP,%ecx,4)             # convert and store
4585    .else
4586    fistpl   (rFP,%ecx,4)             # convert and store
4587    .endif
4588    fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
4589    .if 0
4590    movl     $0x80000000,%eax
4591    xorl     4(rFP,%ecx,4),%eax
4592    orl      (rFP,%ecx,4),%eax
4593    .else
4594    cmpl     $0x80000000,(rFP,%ecx,4)
4595    .endif
4596    je       .LOP_FLOAT_TO_INT_special_case # fix up result
4597
4598.LOP_FLOAT_TO_INT_finish:
4599    FETCH_INST_OPCODE 1 %ecx
4600    ADVANCE_PC 1
4601    GOTO_NEXT_R %ecx
4602
4603.LOP_FLOAT_TO_INT_special_case:
4604    fnstsw   %ax
4605    sahf
4606    jp       .LOP_FLOAT_TO_INT_isNaN
4607    adcl     $-1,(rFP,%ecx,4)
4608    .if 0
4609    adcl     $-1,4(rFP,%ecx,4)
4610    .endif
4611   jmp       .LOP_FLOAT_TO_INT_finish
4612.LOP_FLOAT_TO_INT_isNaN:
4613    movl      $0,(rFP,%ecx,4)
4614    .if 0
4615    movl      $0,4(rFP,%ecx,4)
4616    .endif
4617    jmp       .LOP_FLOAT_TO_INT_finish
4618
4619
4620/* ------------------------------ */
4621.L_OP_FLOAT_TO_LONG: /* 0x88 */
4622/* File: x86/OP_FLOAT_TO_LONG.S */
4623/* File: x86/cvtfp_int.S */
4624/* On fp to int conversions, Java requires that
4625 * if the result > maxint, it should be clamped to maxint.  If it is less
4626 * than minint, it should be clamped to minint.  If it is a nan, the result
4627 * should be zero.  Further, the rounding mode is to truncate.  This model
4628 * differs from what is delivered normally via the x86 fpu, so we have
4629 * to play some games.
4630 */
4631    /* float/double to int/long vA, vB */
4632    movzbl    rINSTbl,%ecx       # ecx<- A+
4633    sarl      $4,rINST         # rINST<- B
4634    .if 0
4635    fldl     (rFP,rINST,4)       # %st0<- vB
4636    .else
4637    flds     (rFP,rINST,4)       # %st0<- vB
4638    .endif
4639    ftst
4640    fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
4641    movzwl   LOCAL0_OFFSET(%ebp),%eax
4642    movb     $0xc,%ah
4643    movw     %ax,LOCAL0_OFFSET+2(%ebp)
4644    fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
4645    andb     $0xf,%cl                # ecx<- A
4646    .if 1
4647    fistpll  (rFP,%ecx,4)             # convert and store
4648    .else
4649    fistpl   (rFP,%ecx,4)             # convert and store
4650    .endif
4651    fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
4652    .if 1
4653    movl     $0x80000000,%eax
4654    xorl     4(rFP,%ecx,4),%eax
4655    orl      (rFP,%ecx,4),%eax
4656    .else
4657    cmpl     $0x80000000,(rFP,%ecx,4)
4658    .endif
4659    je       .LOP_FLOAT_TO_LONG_special_case # fix up result
4660
4661.LOP_FLOAT_TO_LONG_finish:
4662    FETCH_INST_OPCODE 1 %ecx
4663    ADVANCE_PC 1
4664    GOTO_NEXT_R %ecx
4665
4666.LOP_FLOAT_TO_LONG_special_case:
4667    fnstsw   %ax
4668    sahf
4669    jp       .LOP_FLOAT_TO_LONG_isNaN
4670    adcl     $-1,(rFP,%ecx,4)
4671    .if 1
4672    adcl     $-1,4(rFP,%ecx,4)
4673    .endif
4674   jmp       .LOP_FLOAT_TO_LONG_finish
4675.LOP_FLOAT_TO_LONG_isNaN:
4676    movl      $0,(rFP,%ecx,4)
4677    .if 1
4678    movl      $0,4(rFP,%ecx,4)
4679    .endif
4680    jmp       .LOP_FLOAT_TO_LONG_finish
4681
4682
4683/* ------------------------------ */
4684.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */
4685/* File: x86/OP_FLOAT_TO_DOUBLE.S */
4686/* File: x86/fpcvt.S */
4687    /*
4688     * Generic 32-bit FP conversion operation.
4689     */
4690    /* unop vA, vB */
4691    movzbl   rINSTbl,%ecx       # ecx<- A+
4692    sarl     $4,rINST         # rINST<- B
4693    flds    (rFP,rINST,4)      # %st0<- vB
4694    andb     $0xf,%cl          # ecx<- A
4695
4696    fstpl  (rFP,%ecx,4)        # vA<- %st0
4697    FETCH_INST_OPCODE 1 %ecx
4698    ADVANCE_PC 1
4699    GOTO_NEXT_R %ecx
4700
4701
4702/* ------------------------------ */
4703.L_OP_DOUBLE_TO_INT: /* 0x8a */
4704/* File: x86/OP_DOUBLE_TO_INT.S */
4705/* File: x86/cvtfp_int.S */
4706/* On fp to int conversions, Java requires that
4707 * if the result > maxint, it should be clamped to maxint.  If it is less
4708 * than minint, it should be clamped to minint.  If it is a nan, the result
4709 * should be zero.  Further, the rounding mode is to truncate.  This model
4710 * differs from what is delivered normally via the x86 fpu, so we have
4711 * to play some games.
4712 */
4713    /* float/double to int/long vA, vB */
4714    movzbl    rINSTbl,%ecx       # ecx<- A+
4715    sarl      $4,rINST         # rINST<- B
4716    .if 1
4717    fldl     (rFP,rINST,4)       # %st0<- vB
4718    .else
4719    flds     (rFP,rINST,4)       # %st0<- vB
4720    .endif
4721    ftst
4722    fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
4723    movzwl   LOCAL0_OFFSET(%ebp),%eax
4724    movb     $0xc,%ah
4725    movw     %ax,LOCAL0_OFFSET+2(%ebp)
4726    fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
4727    andb     $0xf,%cl                # ecx<- A
4728    .if 0
4729    fistpll  (rFP,%ecx,4)             # convert and store
4730    .else
4731    fistpl   (rFP,%ecx,4)             # convert and store
4732    .endif
4733    fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
4734    .if 0
4735    movl     $0x80000000,%eax
4736    xorl     4(rFP,%ecx,4),%eax
4737    orl      (rFP,%ecx,4),%eax
4738    .else
4739    cmpl     $0x80000000,(rFP,%ecx,4)
4740    .endif
4741    je       .LOP_DOUBLE_TO_INT_special_case # fix up result
4742
4743.LOP_DOUBLE_TO_INT_finish:
4744    FETCH_INST_OPCODE 1 %ecx
4745    ADVANCE_PC 1
4746    GOTO_NEXT_R %ecx
4747
4748.LOP_DOUBLE_TO_INT_special_case:
4749    fnstsw   %ax
4750    sahf
4751    jp       .LOP_DOUBLE_TO_INT_isNaN
4752    adcl     $-1,(rFP,%ecx,4)
4753    .if 0
4754    adcl     $-1,4(rFP,%ecx,4)
4755    .endif
4756   jmp       .LOP_DOUBLE_TO_INT_finish
4757.LOP_DOUBLE_TO_INT_isNaN:
4758    movl      $0,(rFP,%ecx,4)
4759    .if 0
4760    movl      $0,4(rFP,%ecx,4)
4761    .endif
4762    jmp       .LOP_DOUBLE_TO_INT_finish
4763
4764
4765/* ------------------------------ */
4766.L_OP_DOUBLE_TO_LONG: /* 0x8b */
4767/* File: x86/OP_DOUBLE_TO_LONG.S */
4768/* File: x86/cvtfp_int.S */
4769/* On fp to int conversions, Java requires that
4770 * if the result > maxint, it should be clamped to maxint.  If it is less
4771 * than minint, it should be clamped to minint.  If it is a nan, the result
4772 * should be zero.  Further, the rounding mode is to truncate.  This model
4773 * differs from what is delivered normally via the x86 fpu, so we have
4774 * to play some games.
4775 */
4776    /* float/double to int/long vA, vB */
4777    movzbl    rINSTbl,%ecx       # ecx<- A+
4778    sarl      $4,rINST         # rINST<- B
4779    .if 1
4780    fldl     (rFP,rINST,4)       # %st0<- vB
4781    .else
4782    flds     (rFP,rINST,4)       # %st0<- vB
4783    .endif
4784    ftst
4785    fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
4786    movzwl   LOCAL0_OFFSET(%ebp),%eax
4787    movb     $0xc,%ah
4788    movw     %ax,LOCAL0_OFFSET+2(%ebp)
4789    fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
4790    andb     $0xf,%cl                # ecx<- A
4791    .if 1
4792    fistpll  (rFP,%ecx,4)             # convert and store
4793    .else
4794    fistpl   (rFP,%ecx,4)             # convert and store
4795    .endif
4796    fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
4797    .if 1
4798    movl     $0x80000000,%eax
4799    xorl     4(rFP,%ecx,4),%eax
4800    orl      (rFP,%ecx,4),%eax
4801    .else
4802    cmpl     $0x80000000,(rFP,%ecx,4)
4803    .endif
4804    je       .LOP_DOUBLE_TO_LONG_special_case # fix up result
4805
4806.LOP_DOUBLE_TO_LONG_finish:
4807    FETCH_INST_OPCODE 1 %ecx
4808    ADVANCE_PC 1
4809    GOTO_NEXT_R %ecx
4810
4811.LOP_DOUBLE_TO_LONG_special_case:
4812    fnstsw   %ax
4813    sahf
4814    jp       .LOP_DOUBLE_TO_LONG_isNaN
4815    adcl     $-1,(rFP,%ecx,4)
4816    .if 1
4817    adcl     $-1,4(rFP,%ecx,4)
4818    .endif
4819   jmp       .LOP_DOUBLE_TO_LONG_finish
4820.LOP_DOUBLE_TO_LONG_isNaN:
4821    movl      $0,(rFP,%ecx,4)
4822    .if 1
4823    movl      $0,4(rFP,%ecx,4)
4824    .endif
4825    jmp       .LOP_DOUBLE_TO_LONG_finish
4826
4827
4828/* ------------------------------ */
4829.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */
4830/* File: x86/OP_DOUBLE_TO_FLOAT.S */
4831/* File: x86/fpcvt.S */
4832    /*
4833     * Generic 32-bit FP conversion operation.
4834     */
4835    /* unop vA, vB */
4836    movzbl   rINSTbl,%ecx       # ecx<- A+
4837    sarl     $4,rINST         # rINST<- B
4838    fldl    (rFP,rINST,4)      # %st0<- vB
4839    andb     $0xf,%cl          # ecx<- A
4840
4841    fstps  (rFP,%ecx,4)        # vA<- %st0
4842    FETCH_INST_OPCODE 1 %ecx
4843    ADVANCE_PC 1
4844    GOTO_NEXT_R %ecx
4845
4846
4847/* ------------------------------ */
4848.L_OP_INT_TO_BYTE: /* 0x8d */
4849/* File: x86/OP_INT_TO_BYTE.S */
4850/* File: x86/unop.S */
4851    /*
4852     * Generic 32-bit unary operation.  Provide an "instr" line that
4853     * specifies an instruction that performs "result = op eax".
4854     */
4855    /* unop vA, vB */
4856    movzbl   rINSTbl,%ecx           # ecx<- A+
4857    sarl     $4,rINST             # rINST<- B
4858    GET_VREG_R %eax rINST           # eax<- vB
4859    andb     $0xf,%cl              # ecx<- A
4860
4861
4862    movsbl %al,%eax
4863    SET_VREG %eax %ecx
4864    FETCH_INST_OPCODE 1 %ecx
4865    ADVANCE_PC 1
4866    GOTO_NEXT_R %ecx
4867
4868
4869/* ------------------------------ */
4870.L_OP_INT_TO_CHAR: /* 0x8e */
4871/* File: x86/OP_INT_TO_CHAR.S */
4872/* File: x86/unop.S */
4873    /*
4874     * Generic 32-bit unary operation.  Provide an "instr" line that
4875     * specifies an instruction that performs "result = op eax".
4876     */
4877    /* unop vA, vB */
4878    movzbl   rINSTbl,%ecx           # ecx<- A+
4879    sarl     $4,rINST             # rINST<- B
4880    GET_VREG_R %eax rINST           # eax<- vB
4881    andb     $0xf,%cl              # ecx<- A
4882
4883
4884    movzwl %ax,%eax
4885    SET_VREG %eax %ecx
4886    FETCH_INST_OPCODE 1 %ecx
4887    ADVANCE_PC 1
4888    GOTO_NEXT_R %ecx
4889
4890
4891/* ------------------------------ */
4892.L_OP_INT_TO_SHORT: /* 0x8f */
4893/* File: x86/OP_INT_TO_SHORT.S */
4894/* File: x86/unop.S */
4895    /*
4896     * Generic 32-bit unary operation.  Provide an "instr" line that
4897     * specifies an instruction that performs "result = op eax".
4898     */
4899    /* unop vA, vB */
4900    movzbl   rINSTbl,%ecx           # ecx<- A+
4901    sarl     $4,rINST             # rINST<- B
4902    GET_VREG_R %eax rINST           # eax<- vB
4903    andb     $0xf,%cl              # ecx<- A
4904
4905
4906    movswl %ax,%eax
4907    SET_VREG %eax %ecx
4908    FETCH_INST_OPCODE 1 %ecx
4909    ADVANCE_PC 1
4910    GOTO_NEXT_R %ecx
4911
4912
4913/* ------------------------------ */
4914.L_OP_ADD_INT: /* 0x90 */
4915/* File: x86/OP_ADD_INT.S */
4916/* File: x86/binop.S */
4917    /*
4918     * Generic 32-bit binary operation.  Provide an "instr" line that
4919     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
4920     * This could be an x86 instruction or a function call.  (If the result
4921     * comes back in a register other than eax, you can override "result".)
4922     *
4923     * For: add-int, sub-int, and-int, or-int,
4924     *      xor-int, shl-int, shr-int, ushr-int
4925     */
4926    /* binop vAA, vBB, vCC */
4927    movzbl   2(rPC),%eax   # eax<- BB
4928    movzbl   3(rPC),%ecx   # ecx<- CC
4929    GET_VREG_R %eax %eax   # eax<- vBB
4930    addl (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
4931    SET_VREG %eax rINST
4932    FETCH_INST_OPCODE 2 %ecx
4933    ADVANCE_PC 2
4934    GOTO_NEXT_R %ecx
4935
4936
4937/* ------------------------------ */
4938.L_OP_SUB_INT: /* 0x91 */
4939/* File: x86/OP_SUB_INT.S */
4940/* File: x86/binop.S */
4941    /*
4942     * Generic 32-bit binary operation.  Provide an "instr" line that
4943     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
4944     * This could be an x86 instruction or a function call.  (If the result
4945     * comes back in a register other than eax, you can override "result".)
4946     *
4947     * For: add-int, sub-int, and-int, or-int,
4948     *      xor-int, shl-int, shr-int, ushr-int
4949     */
4950    /* binop vAA, vBB, vCC */
4951    movzbl   2(rPC),%eax   # eax<- BB
4952    movzbl   3(rPC),%ecx   # ecx<- CC
4953    GET_VREG_R %eax %eax   # eax<- vBB
4954    subl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
4955    SET_VREG %eax rINST
4956    FETCH_INST_OPCODE 2 %ecx
4957    ADVANCE_PC 2
4958    GOTO_NEXT_R %ecx
4959
4960
4961/* ------------------------------ */
4962.L_OP_MUL_INT: /* 0x92 */
4963/* File: x86/OP_MUL_INT.S */
4964    /*
4965     * 32-bit binary multiplication.
4966     */
4967    /* mul vAA, vBB, vCC */
4968    movzbl   2(rPC),%eax            # eax<- BB
4969    movzbl   3(rPC),%ecx            # ecx<- CC
4970    GET_VREG_R %eax %eax            # eax<- vBB
4971    SPILL(rIBASE)
4972    imull    (rFP,%ecx,4),%eax      # trashes rIBASE/edx
4973    UNSPILL(rIBASE)
4974    FETCH_INST_OPCODE 2 %ecx
4975    ADVANCE_PC 2
4976    SET_VREG %eax rINST
4977    GOTO_NEXT_R %ecx
4978
4979/* ------------------------------ */
4980.L_OP_DIV_INT: /* 0x93 */
4981/* File: x86/OP_DIV_INT.S */
4982/* File: x86/bindiv.S */
4983
4984    /*
4985     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
4986     * op1=-1.
4987     */
4988    /* binop vAA, vBB, vCC */
4989    movzbl   2(rPC),%eax            # eax<- BB
4990    movzbl   3(rPC),%ecx            # ecx<- CC
4991    GET_VREG_R %eax %eax            # eax<- vBB
4992    GET_VREG_R %ecx %ecx            # eax<- vBB
4993    SPILL(rIBASE)
4994    cmpl     $0,%ecx
4995    je       common_errDivideByZero
4996    cmpl     $-1,%ecx
4997    jne      .LOP_DIV_INT_continue_div
4998    cmpl     $0x80000000,%eax
4999    jne      .LOP_DIV_INT_continue_div
5000    movl     $0x80000000,%eax
5001    SET_VREG %eax rINST
5002    UNSPILL(rIBASE)
5003    FETCH_INST_OPCODE 2 %ecx
5004    ADVANCE_PC 2
5005    GOTO_NEXT_R %ecx
5006
5007.LOP_DIV_INT_continue_div:
5008    cltd
5009    idivl   %ecx
5010    SET_VREG %eax rINST
5011    UNSPILL(rIBASE)
5012    FETCH_INST_OPCODE 2 %ecx
5013    ADVANCE_PC 2
5014    GOTO_NEXT_R %ecx
5015
5016
5017/* ------------------------------ */
5018.L_OP_REM_INT: /* 0x94 */
5019/* File: x86/OP_REM_INT.S */
5020/* File: x86/bindiv.S */
5021
5022    /*
5023     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
5024     * op1=-1.
5025     */
5026    /* binop vAA, vBB, vCC */
5027    movzbl   2(rPC),%eax            # eax<- BB
5028    movzbl   3(rPC),%ecx            # ecx<- CC
5029    GET_VREG_R %eax %eax            # eax<- vBB
5030    GET_VREG_R %ecx %ecx            # eax<- vBB
5031    SPILL(rIBASE)
5032    cmpl     $0,%ecx
5033    je       common_errDivideByZero
5034    cmpl     $-1,%ecx
5035    jne      .LOP_REM_INT_continue_div
5036    cmpl     $0x80000000,%eax
5037    jne      .LOP_REM_INT_continue_div
5038    movl     $0,rIBASE
5039    SET_VREG rIBASE rINST
5040    UNSPILL(rIBASE)
5041    FETCH_INST_OPCODE 2 %ecx
5042    ADVANCE_PC 2
5043    GOTO_NEXT_R %ecx
5044
5045.LOP_REM_INT_continue_div:
5046    cltd
5047    idivl   %ecx
5048    SET_VREG rIBASE rINST
5049    UNSPILL(rIBASE)
5050    FETCH_INST_OPCODE 2 %ecx
5051    ADVANCE_PC 2
5052    GOTO_NEXT_R %ecx
5053
5054
5055/* ------------------------------ */
5056.L_OP_AND_INT: /* 0x95 */
5057/* File: x86/OP_AND_INT.S */
5058/* File: x86/binop.S */
5059    /*
5060     * Generic 32-bit binary operation.  Provide an "instr" line that
5061     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
5062     * This could be an x86 instruction or a function call.  (If the result
5063     * comes back in a register other than eax, you can override "result".)
5064     *
5065     * For: add-int, sub-int, and-int, or-int,
5066     *      xor-int, shl-int, shr-int, ushr-int
5067     */
5068    /* binop vAA, vBB, vCC */
5069    movzbl   2(rPC),%eax   # eax<- BB
5070    movzbl   3(rPC),%ecx   # ecx<- CC
5071    GET_VREG_R %eax %eax   # eax<- vBB
5072    andl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
5073    SET_VREG %eax rINST
5074    FETCH_INST_OPCODE 2 %ecx
5075    ADVANCE_PC 2
5076    GOTO_NEXT_R %ecx
5077
5078
5079/* ------------------------------ */
5080.L_OP_OR_INT: /* 0x96 */
5081/* File: x86/OP_OR_INT.S */
5082/* File: x86/binop.S */
5083    /*
5084     * Generic 32-bit binary operation.  Provide an "instr" line that
5085     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
5086     * This could be an x86 instruction or a function call.  (If the result
5087     * comes back in a register other than eax, you can override "result".)
5088     *
5089     * For: add-int, sub-int, and-int, or-int,
5090     *      xor-int, shl-int, shr-int, ushr-int
5091     */
5092    /* binop vAA, vBB, vCC */
5093    movzbl   2(rPC),%eax   # eax<- BB
5094    movzbl   3(rPC),%ecx   # ecx<- CC
5095    GET_VREG_R %eax %eax   # eax<- vBB
5096    orl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
5097    SET_VREG %eax rINST
5098    FETCH_INST_OPCODE 2 %ecx
5099    ADVANCE_PC 2
5100    GOTO_NEXT_R %ecx
5101
5102
5103/* ------------------------------ */
5104.L_OP_XOR_INT: /* 0x97 */
5105/* File: x86/OP_XOR_INT.S */
5106/* File: x86/binop.S */
5107    /*
5108     * Generic 32-bit binary operation.  Provide an "instr" line that
5109     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
5110     * This could be an x86 instruction or a function call.  (If the result
5111     * comes back in a register other than eax, you can override "result".)
5112     *
5113     * For: add-int, sub-int, and-int, or-int,
5114     *      xor-int, shl-int, shr-int, ushr-int
5115     */
5116    /* binop vAA, vBB, vCC */
5117    movzbl   2(rPC),%eax   # eax<- BB
5118    movzbl   3(rPC),%ecx   # ecx<- CC
5119    GET_VREG_R %eax %eax   # eax<- vBB
5120    xorl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
5121    SET_VREG %eax rINST
5122    FETCH_INST_OPCODE 2 %ecx
5123    ADVANCE_PC 2
5124    GOTO_NEXT_R %ecx
5125
5126
5127/* ------------------------------ */
5128.L_OP_SHL_INT: /* 0x98 */
5129/* File: x86/OP_SHL_INT.S */
5130/* File: x86/binop1.S */
5131    /*
5132     * Generic 32-bit binary operation in which both operands loaded to
5133     * registers (op0 in eax, op1 in ecx).
5134     */
5135    /* binop vAA, vBB, vCC */
5136    movzbl   2(rPC),%eax            # eax<- BB
5137    movzbl   3(rPC),%ecx            # ecx<- CC
5138    GET_VREG_R %eax %eax            # eax<- vBB
5139    GET_VREG_R %ecx %ecx            # eax<- vBB
5140    sall    %cl,%eax                          # ex: addl    %ecx,%eax
5141    SET_VREG %eax rINST
5142    FETCH_INST_OPCODE 2 %ecx
5143    ADVANCE_PC 2
5144    GOTO_NEXT_R %ecx
5145
5146
5147/* ------------------------------ */
5148.L_OP_SHR_INT: /* 0x99 */
5149/* File: x86/OP_SHR_INT.S */
5150/* File: x86/binop1.S */
5151    /*
5152     * Generic 32-bit binary operation in which both operands loaded to
5153     * registers (op0 in eax, op1 in ecx).
5154     */
5155    /* binop vAA, vBB, vCC */
5156    movzbl   2(rPC),%eax            # eax<- BB
5157    movzbl   3(rPC),%ecx            # ecx<- CC
5158    GET_VREG_R %eax %eax            # eax<- vBB
5159    GET_VREG_R %ecx %ecx            # eax<- vBB
5160    sarl    %cl,%eax                          # ex: addl    %ecx,%eax
5161    SET_VREG %eax rINST
5162    FETCH_INST_OPCODE 2 %ecx
5163    ADVANCE_PC 2
5164    GOTO_NEXT_R %ecx
5165
5166
5167/* ------------------------------ */
5168.L_OP_USHR_INT: /* 0x9a */
5169/* File: x86/OP_USHR_INT.S */
5170/* File: x86/binop1.S */
5171    /*
5172     * Generic 32-bit binary operation in which both operands loaded to
5173     * registers (op0 in eax, op1 in ecx).
5174     */
5175    /* binop vAA, vBB, vCC */
5176    movzbl   2(rPC),%eax            # eax<- BB
5177    movzbl   3(rPC),%ecx            # ecx<- CC
5178    GET_VREG_R %eax %eax            # eax<- vBB
5179    GET_VREG_R %ecx %ecx            # eax<- vBB
5180    shrl    %cl,%eax                          # ex: addl    %ecx,%eax
5181    SET_VREG %eax rINST
5182    FETCH_INST_OPCODE 2 %ecx
5183    ADVANCE_PC 2
5184    GOTO_NEXT_R %ecx
5185
5186
5187/* ------------------------------ */
5188.L_OP_ADD_LONG: /* 0x9b */
5189/* File: x86/OP_ADD_LONG.S */
5190/* File: x86/binopWide.S */
5191    /*
5192     * Generic 64-bit binary operation.
5193     */
5194    /* binop vAA, vBB, vCC */
5195
5196    movzbl    2(rPC),%eax               # eax<- BB
5197    movzbl    3(rPC),%ecx               # ecx<- CC
5198    SPILL(rIBASE)                       # save rIBASE
5199    GET_VREG_WORD rIBASE %eax 0         # rIBASE<- v[BB+0]
5200    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
5201    addl (rFP,%ecx,4),rIBASE         # ex: addl   (rFP,%ecx,4),rIBASE
5202    adcl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
5203    SET_VREG_WORD rIBASE rINST 0        # v[AA+0] <- rIBASE
5204    FETCH_INST_OPCODE 2 %ecx
5205    UNSPILL(rIBASE)                     # restore rIBASE
5206    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
5207    ADVANCE_PC 2
5208    GOTO_NEXT_R %ecx
5209
5210
5211/* ------------------------------ */
5212.L_OP_SUB_LONG: /* 0x9c */
5213/* File: x86/OP_SUB_LONG.S */
5214/* File: x86/binopWide.S */
5215    /*
5216     * Generic 64-bit binary operation.
5217     */
5218    /* binop vAA, vBB, vCC */
5219
5220    movzbl    2(rPC),%eax               # eax<- BB
5221    movzbl    3(rPC),%ecx               # ecx<- CC
5222    SPILL(rIBASE)                       # save rIBASE
5223    GET_VREG_WORD rIBASE %eax 0         # rIBASE<- v[BB+0]
5224    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
5225    subl (rFP,%ecx,4),rIBASE         # ex: addl   (rFP,%ecx,4),rIBASE
5226    sbbl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
5227    SET_VREG_WORD rIBASE rINST 0        # v[AA+0] <- rIBASE
5228    FETCH_INST_OPCODE 2 %ecx
5229    UNSPILL(rIBASE)                     # restore rIBASE
5230    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
5231    ADVANCE_PC 2
5232    GOTO_NEXT_R %ecx
5233
5234
5235/* ------------------------------ */
5236.L_OP_MUL_LONG: /* 0x9d */
5237/* File: x86/OP_MUL_LONG.S */
5238    /*
5239     * Signed 64-bit integer multiply.
5240     *
5241     * We could definately use more free registers for
5242     * this code.   We spill rINSTw (ebx),
5243     * giving us eax, ebc, ecx and edx as computational
5244     * temps.  On top of that, we'll spill edi (rFP)
5245     * for use as the vB pointer and esi (rPC) for use
5246     * as the vC pointer.  Yuck.
5247     */
5248    /* mul-long vAA, vBB, vCC */
5249    movzbl    2(rPC),%eax              # eax<- B
5250    movzbl    3(rPC),%ecx              # ecx<- C
5251    SPILL_TMP2(%esi)                   # save Dalvik PC
5252    SPILL(rFP)
5253    SPILL(rINST)
5254    SPILL(rIBASE)
5255    leal      (rFP,%eax,4),%esi        # esi<- &v[B]
5256    leal      (rFP,%ecx,4),rFP         # rFP<- &v[C]
5257    movl      4(%esi),%ecx             # ecx<- Bmsw
5258    imull     (rFP),%ecx               # ecx<- (Bmsw*Clsw)
5259    movl      4(rFP),%eax              # eax<- Cmsw
5260    imull     (%esi),%eax              # eax<- (Cmsw*Blsw)
5261    addl      %eax,%ecx                # ecx<- (Bmsw*Clsw)+(Cmsw*Blsw)
5262    movl      (rFP),%eax               # eax<- Clsw
5263    mull      (%esi)                   # eax<- (Clsw*Alsw)
5264    UNSPILL(rINST)
5265    UNSPILL(rFP)
5266    leal      (%ecx,rIBASE),rIBASE # full result now in rIBASE:%eax
5267    UNSPILL_TMP2(%esi)             # Restore Dalvik PC
5268    FETCH_INST_OPCODE 2 %ecx       # Fetch next instruction
5269    movl      rIBASE,4(rFP,rINST,4)# v[B+1]<- rIBASE
5270    UNSPILL(rIBASE)
5271    movl      %eax,(rFP,rINST,4)   # v[B]<- %eax
5272    ADVANCE_PC 2
5273    GOTO_NEXT_R %ecx
5274
5275/* ------------------------------ */
5276.L_OP_DIV_LONG: /* 0x9e */
5277/* File: x86/OP_DIV_LONG.S */
5278    /* div vAA, vBB, vCC */
5279    movzbl    3(rPC),%eax              # eax<- CC
5280    movzbl    2(rPC),%ecx              # ecx<- BB
5281    SPILL(rIBASE)                      # save rIBASE/%edx
5282    GET_VREG_WORD rIBASE %eax 0
5283    GET_VREG_WORD %eax %eax 1
5284    movl     rIBASE,OUT_ARG2(%esp)
5285    testl    %eax,%eax
5286    je       .LOP_DIV_LONG_check_zero
5287    cmpl     $-1,%eax
5288    je       .LOP_DIV_LONG_check_neg1
5289.LOP_DIV_LONG_notSpecial:
5290    GET_VREG_WORD rIBASE %ecx 0
5291    GET_VREG_WORD %ecx %ecx 1
5292.LOP_DIV_LONG_notSpecial1:
5293    movl     %eax,OUT_ARG3(%esp)
5294    movl     rIBASE,OUT_ARG0(%esp)
5295    movl     %ecx,OUT_ARG1(%esp)
5296    call     __divdi3
5297.LOP_DIV_LONG_finish:
5298    SET_VREG_WORD rIBASE rINST 1
5299    UNSPILL(rIBASE)                 # restore rIBASE/%edx
5300    SET_VREG_WORD %eax rINST 0
5301    FETCH_INST_OPCODE 2 %ecx
5302    ADVANCE_PC 2
5303    GOTO_NEXT_R %ecx
5304
5305.LOP_DIV_LONG_check_zero:
5306    testl   rIBASE,rIBASE
5307    jne     .LOP_DIV_LONG_notSpecial
5308    jmp     common_errDivideByZero
5309.LOP_DIV_LONG_check_neg1:
5310    testl   rIBASE,%eax
5311    jne     .LOP_DIV_LONG_notSpecial
5312    GET_VREG_WORD rIBASE %ecx 0
5313    GET_VREG_WORD %ecx %ecx 1
5314    testl    rIBASE,rIBASE
5315    jne      .LOP_DIV_LONG_notSpecial1
5316    cmpl     $0x80000000,%ecx
5317    jne      .LOP_DIV_LONG_notSpecial1
5318    /* minint / -1, return minint on div, 0 on rem */
5319    xorl     %eax,%eax
5320    movl     $0x80000000,rIBASE
5321    jmp      .LOP_DIV_LONG_finish
5322
5323/* ------------------------------ */
5324.L_OP_REM_LONG: /* 0x9f */
5325/* File: x86/OP_REM_LONG.S */
5326/* File: x86/OP_DIV_LONG.S */
5327    /* div vAA, vBB, vCC */
5328    movzbl    3(rPC),%eax              # eax<- CC
5329    movzbl    2(rPC),%ecx              # ecx<- BB
5330    SPILL(rIBASE)                      # save rIBASE/%edx
5331    GET_VREG_WORD rIBASE %eax 0
5332    GET_VREG_WORD %eax %eax 1
5333    movl     rIBASE,OUT_ARG2(%esp)
5334    testl    %eax,%eax
5335    je       .LOP_REM_LONG_check_zero
5336    cmpl     $-1,%eax
5337    je       .LOP_REM_LONG_check_neg1
5338.LOP_REM_LONG_notSpecial:
5339    GET_VREG_WORD rIBASE %ecx 0
5340    GET_VREG_WORD %ecx %ecx 1
5341.LOP_REM_LONG_notSpecial1:
5342    movl     %eax,OUT_ARG3(%esp)
5343    movl     rIBASE,OUT_ARG0(%esp)
5344    movl     %ecx,OUT_ARG1(%esp)
5345    call     __moddi3
5346.LOP_REM_LONG_finish:
5347    SET_VREG_WORD rIBASE rINST 1
5348    UNSPILL(rIBASE)                 # restore rIBASE/%edx
5349    SET_VREG_WORD %eax rINST 0
5350    FETCH_INST_OPCODE 2 %ecx
5351    ADVANCE_PC 2
5352    GOTO_NEXT_R %ecx
5353
5354.LOP_REM_LONG_check_zero:
5355    testl   rIBASE,rIBASE
5356    jne     .LOP_REM_LONG_notSpecial
5357    jmp     common_errDivideByZero
5358.LOP_REM_LONG_check_neg1:
5359    testl   rIBASE,%eax
5360    jne     .LOP_REM_LONG_notSpecial
5361    GET_VREG_WORD rIBASE %ecx 0
5362    GET_VREG_WORD %ecx %ecx 1
5363    testl    rIBASE,rIBASE
5364    jne      .LOP_REM_LONG_notSpecial1
5365    cmpl     $0x80000000,%ecx
5366    jne      .LOP_REM_LONG_notSpecial1
5367    /* minint / -1, return minint on div, 0 on rem */
5368    xorl     %eax,%eax
5369    movl     $0,rIBASE
5370    jmp      .LOP_REM_LONG_finish
5371
5372
5373/* ------------------------------ */
5374.L_OP_AND_LONG: /* 0xa0 */
5375/* File: x86/OP_AND_LONG.S */
5376/* File: x86/binopWide.S */
5377    /*
5378     * Generic 64-bit binary operation.
5379     */
5380    /* binop vAA, vBB, vCC */
5381
5382    movzbl    2(rPC),%eax               # eax<- BB
5383    movzbl    3(rPC),%ecx               # ecx<- CC
5384    SPILL(rIBASE)                       # save rIBASE
5385    GET_VREG_WORD rIBASE %eax 0         # rIBASE<- v[BB+0]
5386    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
5387    andl (rFP,%ecx,4),rIBASE         # ex: addl   (rFP,%ecx,4),rIBASE
5388    andl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
5389    SET_VREG_WORD rIBASE rINST 0        # v[AA+0] <- rIBASE
5390    FETCH_INST_OPCODE 2 %ecx
5391    UNSPILL(rIBASE)                     # restore rIBASE
5392    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
5393    ADVANCE_PC 2
5394    GOTO_NEXT_R %ecx
5395
5396
5397/* ------------------------------ */
5398.L_OP_OR_LONG: /* 0xa1 */
5399/* File: x86/OP_OR_LONG.S */
5400/* File: x86/binopWide.S */
5401    /*
5402     * Generic 64-bit binary operation.
5403     */
5404    /* binop vAA, vBB, vCC */
5405
5406    movzbl    2(rPC),%eax               # eax<- BB
5407    movzbl    3(rPC),%ecx               # ecx<- CC
5408    SPILL(rIBASE)                       # save rIBASE
5409    GET_VREG_WORD rIBASE %eax 0         # rIBASE<- v[BB+0]
5410    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
5411    orl (rFP,%ecx,4),rIBASE         # ex: addl   (rFP,%ecx,4),rIBASE
5412    orl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
5413    SET_VREG_WORD rIBASE rINST 0        # v[AA+0] <- rIBASE
5414    FETCH_INST_OPCODE 2 %ecx
5415    UNSPILL(rIBASE)                     # restore rIBASE
5416    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
5417    ADVANCE_PC 2
5418    GOTO_NEXT_R %ecx
5419
5420
5421/* ------------------------------ */
5422.L_OP_XOR_LONG: /* 0xa2 */
5423/* File: x86/OP_XOR_LONG.S */
5424/* File: x86/binopWide.S */
5425    /*
5426     * Generic 64-bit binary operation.
5427     */
5428    /* binop vAA, vBB, vCC */
5429
5430    movzbl    2(rPC),%eax               # eax<- BB
5431    movzbl    3(rPC),%ecx               # ecx<- CC
5432    SPILL(rIBASE)                       # save rIBASE
5433    GET_VREG_WORD rIBASE %eax 0         # rIBASE<- v[BB+0]
5434    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
5435    xorl (rFP,%ecx,4),rIBASE         # ex: addl   (rFP,%ecx,4),rIBASE
5436    xorl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
5437    SET_VREG_WORD rIBASE rINST 0        # v[AA+0] <- rIBASE
5438    FETCH_INST_OPCODE 2 %ecx
5439    UNSPILL(rIBASE)                     # restore rIBASE
5440    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
5441    ADVANCE_PC 2
5442    GOTO_NEXT_R %ecx
5443
5444
5445/* ------------------------------ */
5446.L_OP_SHL_LONG: /* 0xa3 */
5447/* File: x86/OP_SHL_LONG.S */
5448    /*
5449     * Long integer shift.  This is different from the generic 32/64-bit
5450     * binary operations because vAA/vBB are 64-bit but vCC (the shift
5451     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
5452     * 6 bits of the shift distance.  x86 shifts automatically mask off
5453     * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
5454     * case specially.
5455     */
5456    /* shl-long vAA, vBB, vCC */
5457    /* ecx gets shift count */
5458    /* Need to spill rINST */
5459    /* rINSTw gets AA */
5460    movzbl    2(rPC),%eax               # eax<- BB
5461    movzbl    3(rPC),%ecx               # ecx<- CC
5462    SPILL(rIBASE)
5463    GET_VREG_WORD rIBASE %eax 1         # ecx<- v[BB+1]
5464    GET_VREG_R   %ecx %ecx              # ecx<- vCC
5465    GET_VREG_WORD %eax %eax 0           # eax<- v[BB+0]
5466    shldl     %eax,rIBASE
5467    sall      %cl,%eax
5468    testb     $32,%cl
5469    je        2f
5470    movl      %eax,rIBASE
5471    xorl      %eax,%eax
54722:
5473    SET_VREG_WORD rIBASE rINST 1        # v[AA+1]<- rIBASE
5474    FETCH_INST_OPCODE 2 %ecx
5475    UNSPILL(rIBASE)
5476    SET_VREG_WORD %eax rINST 0          # v[AA+0]<- %eax
5477    ADVANCE_PC 2
5478    GOTO_NEXT_R %ecx
5479
5480/* ------------------------------ */
5481.L_OP_SHR_LONG: /* 0xa4 */
5482/* File: x86/OP_SHR_LONG.S */
5483    /*
5484     * Long integer shift.  This is different from the generic 32/64-bit
5485     * binary operations because vAA/vBB are 64-bit but vCC (the shift
5486     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
5487     * 6 bits of the shift distance.  x86 shifts automatically mask off
5488     * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
5489     * case specially.
5490     */
5491    /* shr-long vAA, vBB, vCC */
5492    /* ecx gets shift count */
5493    /* Need to spill rIBASE */
5494    /* rINSTw gets AA */
5495    movzbl    2(rPC),%eax               # eax<- BB
5496    movzbl    3(rPC),%ecx               # ecx<- CC
5497    SPILL(rIBASE)
5498    GET_VREG_WORD rIBASE %eax 1         # rIBASE<- v[BB+1]
5499    GET_VREG_R   %ecx %ecx              # ecx<- vCC
5500    GET_VREG_WORD %eax %eax 0           # eax<- v[BB+0]
5501    shrdl     rIBASE,%eax
5502    sarl      %cl,rIBASE
5503    testb     $32,%cl
5504    je        2f
5505    movl      rIBASE,%eax
5506    sarl      $31,rIBASE
55072:
5508    SET_VREG_WORD rIBASE rINST 1        # v[AA+1]<- rIBASE
5509    FETCH_INST_OPCODE 2 %ecx
5510    UNSPILL(rIBASE)
5511    SET_VREG_WORD %eax rINST 0          # v[AA+0]<- eax
5512    ADVANCE_PC 2
5513    GOTO_NEXT_R %ecx
5514
5515/* ------------------------------ */
5516.L_OP_USHR_LONG: /* 0xa5 */
5517/* File: x86/OP_USHR_LONG.S */
5518    /*
5519     * Long integer shift.  This is different from the generic 32/64-bit
5520     * binary operations because vAA/vBB are 64-bit but vCC (the shift
5521     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
5522     * 6 bits of the shift distance.  x86 shifts automatically mask off
5523     * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
5524     * case specially.
5525     */
5526    /* shr-long vAA, vBB, vCC */
5527    /* ecx gets shift count */
5528    /* Need to spill rIBASE */
5529    /* rINSTw gets AA */
5530    movzbl    2(rPC),%eax               # eax<- BB
5531    movzbl    3(rPC),%ecx               # ecx<- CC
5532    SPILL(rIBASE)
5533    GET_VREG_WORD rIBASE %eax 1         # rIBASE<- v[BB+1]
5534    GET_VREG_R  %ecx %ecx               # ecx<- vCC
5535    GET_VREG_WORD %eax %eax 0           # eax<- v[BB+0]
5536    shrdl     rIBASE,%eax
5537    shrl      %cl,rIBASE
5538    testb     $32,%cl
5539    je        2f
5540    movl      rIBASE,%eax
5541    xorl      rIBASE,rIBASE
55422:
5543    SET_VREG_WORD rIBASE rINST 1          # v[AA+1]<- rIBASE
5544    FETCH_INST_OPCODE 2 %ecx
5545    UNSPILL(rIBASE)
5546    SET_VREG_WORD %eax rINST 0         # v[BB+0]<- eax
5547    ADVANCE_PC 2
5548    GOTO_NEXT_R %ecx
5549
5550/* ------------------------------ */
5551.L_OP_ADD_FLOAT: /* 0xa6 */
5552/* File: x86/OP_ADD_FLOAT.S */
5553/* File: x86/binflop.S */
5554    /*
5555     * Generic 32-bit binary float operation.
5556     *
5557     * For: add-fp, sub-fp, mul-fp, div-fp
5558     */
5559    /* binop vAA, vBB, vCC */
5560    movzbl   2(rPC),%eax          # eax<- CC
5561    movzbl   3(rPC),%ecx          # ecx<- BB
5562    flds    (rFP,%eax,4)         # vCC to fp stack
5563    fadds   (rFP,%ecx,4)         # ex: faddp
5564    FETCH_INST_OPCODE 2 %ecx
5565    ADVANCE_PC 2
5566    fstps   (rFP,rINST,4)         # %st to vAA
5567    GOTO_NEXT_R %ecx
5568
5569
5570/* ------------------------------ */
5571.L_OP_SUB_FLOAT: /* 0xa7 */
5572/* File: x86/OP_SUB_FLOAT.S */
5573/* File: x86/binflop.S */
5574    /*
5575     * Generic 32-bit binary float operation.
5576     *
5577     * For: add-fp, sub-fp, mul-fp, div-fp
5578     */
5579    /* binop vAA, vBB, vCC */
5580    movzbl   2(rPC),%eax          # eax<- CC
5581    movzbl   3(rPC),%ecx          # ecx<- BB
5582    flds    (rFP,%eax,4)         # vCC to fp stack
5583    fsubs   (rFP,%ecx,4)         # ex: faddp
5584    FETCH_INST_OPCODE 2 %ecx
5585    ADVANCE_PC 2
5586    fstps   (rFP,rINST,4)         # %st to vAA
5587    GOTO_NEXT_R %ecx
5588
5589
5590/* ------------------------------ */
5591.L_OP_MUL_FLOAT: /* 0xa8 */
5592/* File: x86/OP_MUL_FLOAT.S */
5593/* File: x86/binflop.S */
5594    /*
5595     * Generic 32-bit binary float operation.
5596     *
5597     * For: add-fp, sub-fp, mul-fp, div-fp
5598     */
5599    /* binop vAA, vBB, vCC */
5600    movzbl   2(rPC),%eax          # eax<- CC
5601    movzbl   3(rPC),%ecx          # ecx<- BB
5602    flds    (rFP,%eax,4)         # vCC to fp stack
5603    fmuls   (rFP,%ecx,4)         # ex: faddp
5604    FETCH_INST_OPCODE 2 %ecx
5605    ADVANCE_PC 2
5606    fstps   (rFP,rINST,4)         # %st to vAA
5607    GOTO_NEXT_R %ecx
5608
5609
5610/* ------------------------------ */
5611.L_OP_DIV_FLOAT: /* 0xa9 */
5612/* File: x86/OP_DIV_FLOAT.S */
5613/* File: x86/binflop.S */
5614    /*
5615     * Generic 32-bit binary float operation.
5616     *
5617     * For: add-fp, sub-fp, mul-fp, div-fp
5618     */
5619    /* binop vAA, vBB, vCC */
5620    movzbl   2(rPC),%eax          # eax<- CC
5621    movzbl   3(rPC),%ecx          # ecx<- BB
5622    flds    (rFP,%eax,4)         # vCC to fp stack
5623    fdivs   (rFP,%ecx,4)         # ex: faddp
5624    FETCH_INST_OPCODE 2 %ecx
5625    ADVANCE_PC 2
5626    fstps   (rFP,rINST,4)         # %st to vAA
5627    GOTO_NEXT_R %ecx
5628
5629
5630/* ------------------------------ */
5631.L_OP_REM_FLOAT: /* 0xaa */
5632/* File: x86/OP_REM_FLOAT.S */
5633    /* rem_float vAA, vBB, vCC */
5634    movzbl   3(rPC),%ecx            # ecx<- BB
5635    movzbl   2(rPC),%eax            # eax<- CC
5636    flds     (rFP,%ecx,4)           # vCC to fp stack
5637    flds     (rFP,%eax,4)           # vCC to fp stack
5638    movzbl   rINSTbl,%ecx           # ecx<- AA
56391:
5640    fprem
5641    fstsw     %ax
5642    sahf
5643    jp        1b
5644    fstp      %st(1)
5645    FETCH_INST_OPCODE 2 %eax
5646    ADVANCE_PC 2
5647    fstps    (rFP,%ecx,4)           # %st to vAA
5648    GOTO_NEXT_R %eax
5649
5650/* ------------------------------ */
5651.L_OP_ADD_DOUBLE: /* 0xab */
5652/* File: x86/OP_ADD_DOUBLE.S */
5653/* File: x86/binflop.S */
5654    /*
5655     * Generic 32-bit binary float operation.
5656     *
5657     * For: add-fp, sub-fp, mul-fp, div-fp
5658     */
5659    /* binop vAA, vBB, vCC */
5660    movzbl   2(rPC),%eax          # eax<- CC
5661    movzbl   3(rPC),%ecx          # ecx<- BB
5662    fldl    (rFP,%eax,4)         # vCC to fp stack
5663    faddl   (rFP,%ecx,4)         # ex: faddp
5664    FETCH_INST_OPCODE 2 %ecx
5665    ADVANCE_PC 2
5666    fstpl   (rFP,rINST,4)         # %st to vAA
5667    GOTO_NEXT_R %ecx
5668
5669
5670/* ------------------------------ */
5671.L_OP_SUB_DOUBLE: /* 0xac */
5672/* File: x86/OP_SUB_DOUBLE.S */
5673/* File: x86/binflop.S */
5674    /*
5675     * Generic 32-bit binary float operation.
5676     *
5677     * For: add-fp, sub-fp, mul-fp, div-fp
5678     */
5679    /* binop vAA, vBB, vCC */
5680    movzbl   2(rPC),%eax          # eax<- CC
5681    movzbl   3(rPC),%ecx          # ecx<- BB
5682    fldl    (rFP,%eax,4)         # vCC to fp stack
5683    fsubl   (rFP,%ecx,4)         # ex: faddp
5684    FETCH_INST_OPCODE 2 %ecx
5685    ADVANCE_PC 2
5686    fstpl   (rFP,rINST,4)         # %st to vAA
5687    GOTO_NEXT_R %ecx
5688
5689
5690/* ------------------------------ */
5691.L_OP_MUL_DOUBLE: /* 0xad */
5692/* File: x86/OP_MUL_DOUBLE.S */
5693/* File: x86/binflop.S */
5694    /*
5695     * Generic 32-bit binary float operation.
5696     *
5697     * For: add-fp, sub-fp, mul-fp, div-fp
5698     */
5699    /* binop vAA, vBB, vCC */
5700    movzbl   2(rPC),%eax          # eax<- CC
5701    movzbl   3(rPC),%ecx          # ecx<- BB
5702    fldl    (rFP,%eax,4)         # vCC to fp stack
5703    fmull   (rFP,%ecx,4)         # ex: faddp
5704    FETCH_INST_OPCODE 2 %ecx
5705    ADVANCE_PC 2
5706    fstpl   (rFP,rINST,4)         # %st to vAA
5707    GOTO_NEXT_R %ecx
5708
5709
5710/* ------------------------------ */
5711.L_OP_DIV_DOUBLE: /* 0xae */
5712/* File: x86/OP_DIV_DOUBLE.S */
5713/* File: x86/binflop.S */
5714    /*
5715     * Generic 32-bit binary float operation.
5716     *
5717     * For: add-fp, sub-fp, mul-fp, div-fp
5718     */
5719    /* binop vAA, vBB, vCC */
5720    movzbl   2(rPC),%eax          # eax<- CC
5721    movzbl   3(rPC),%ecx          # ecx<- BB
5722    fldl    (rFP,%eax,4)         # vCC to fp stack
5723    fdivl   (rFP,%ecx,4)         # ex: faddp
5724    FETCH_INST_OPCODE 2 %ecx
5725    ADVANCE_PC 2
5726    fstpl   (rFP,rINST,4)         # %st to vAA
5727    GOTO_NEXT_R %ecx
5728
5729
5730/* ------------------------------ */
5731.L_OP_REM_DOUBLE: /* 0xaf */
5732/* File: x86/OP_REM_DOUBLE.S */
5733    /* rem_float vAA, vBB, vCC */
5734    movzbl   3(rPC),%ecx            # ecx<- BB
5735    movzbl   2(rPC),%eax            # eax<- CC
5736    fldl     (rFP,%ecx,4)           # vCC to fp stack
5737    fldl     (rFP,%eax,4)           # vCC to fp stack
5738    FETCH_INST_OPCODE 2 %ecx
57391:
5740    fprem
5741    fstsw     %ax
5742    sahf
5743    jp        1b
5744    fstp      %st(1)
5745    ADVANCE_PC 2
5746    fstpl    (rFP,rINST,4)           # %st to vAA
5747    GOTO_NEXT_R %ecx
5748
5749/* ------------------------------ */
5750.L_OP_ADD_INT_2ADDR: /* 0xb0 */
5751/* File: x86/OP_ADD_INT_2ADDR.S */
5752/* File: x86/binop2addr.S */
5753    /*
5754     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5755     * that specifies an instruction that performs "result = r0 op r1".
5756     * This could be an ARM instruction or a function call.  (If the result
5757     * comes back in a register other than r0, you can override "result".)
5758     *
5759     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5760     * vCC (r1).  Useful for integer division and modulus.
5761     *
5762     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5763     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5764     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5765     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5766     */
5767    /* binop/2addr vA, vB */
5768    movzx   rINSTbl,%ecx               # ecx<- A+
5769    sarl    $4,rINST                 # rINST<- B
5770    GET_VREG_R %eax rINST              # eax<- vB
5771    andb    $0xf,%cl                  # ecx<- A
5772    addl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
5773    FETCH_INST_OPCODE 1 %ecx
5774    ADVANCE_PC 1
5775    GOTO_NEXT_R %ecx
5776
5777
5778/* ------------------------------ */
5779.L_OP_SUB_INT_2ADDR: /* 0xb1 */
5780/* File: x86/OP_SUB_INT_2ADDR.S */
5781/* File: x86/binop2addr.S */
5782    /*
5783     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5784     * that specifies an instruction that performs "result = r0 op r1".
5785     * This could be an ARM instruction or a function call.  (If the result
5786     * comes back in a register other than r0, you can override "result".)
5787     *
5788     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5789     * vCC (r1).  Useful for integer division and modulus.
5790     *
5791     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5792     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5793     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5794     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5795     */
5796    /* binop/2addr vA, vB */
5797    movzx   rINSTbl,%ecx               # ecx<- A+
5798    sarl    $4,rINST                 # rINST<- B
5799    GET_VREG_R %eax rINST              # eax<- vB
5800    andb    $0xf,%cl                  # ecx<- A
5801    subl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
5802    FETCH_INST_OPCODE 1 %ecx
5803    ADVANCE_PC 1
5804    GOTO_NEXT_R %ecx
5805
5806
5807/* ------------------------------ */
5808.L_OP_MUL_INT_2ADDR: /* 0xb2 */
5809/* File: x86/OP_MUL_INT_2ADDR.S */
5810    /* mul vA, vB */
5811    movzx   rINSTbl,%ecx              # ecx<- A+
5812    sarl    $4,rINST                 # rINST<- B
5813    GET_VREG_R %eax rINST             # eax<- vB
5814    andb    $0xf,%cl                 # ecx<- A
5815    SPILL(rIBASE)
5816    imull   (rFP,%ecx,4),%eax         # trashes rIBASE/edx
5817    UNSPILL(rIBASE)
5818    SET_VREG %eax %ecx
5819    FETCH_INST_OPCODE 1 %ecx
5820    ADVANCE_PC 1
5821    GOTO_NEXT_R %ecx
5822
5823/* ------------------------------ */
5824.L_OP_DIV_INT_2ADDR: /* 0xb3 */
5825/* File: x86/OP_DIV_INT_2ADDR.S */
5826/* File: x86/bindiv2addr.S */
5827    /*
5828     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
5829     * op1=-1.
5830     */
5831    /* div/rem/2addr vA, vB */
5832    movzx    rINSTbl,%ecx          # eax<- BA
5833    SPILL(rIBASE)
5834    sarl     $4,%ecx              # ecx<- B
5835    GET_VREG_R %ecx %ecx           # eax<- vBB
5836    andb     $0xf,rINSTbl         # rINST<- A
5837    GET_VREG_R %eax rINST          # eax<- vBB
5838    cmpl     $0,%ecx
5839    je       common_errDivideByZero
5840    cmpl     $-1,%ecx
5841    jne      .LOP_DIV_INT_2ADDR_continue_div2addr
5842    cmpl     $0x80000000,%eax
5843    jne      .LOP_DIV_INT_2ADDR_continue_div2addr
5844    movl     $0x80000000,%eax
5845    SET_VREG %eax rINST
5846    UNSPILL(rIBASE)
5847    FETCH_INST_OPCODE 1 %ecx
5848    ADVANCE_PC 1
5849    GOTO_NEXT_R %ecx
5850
5851.LOP_DIV_INT_2ADDR_continue_div2addr:
5852    cltd
5853    idivl   %ecx
5854    SET_VREG %eax rINST
5855    UNSPILL(rIBASE)
5856    FETCH_INST_OPCODE 1 %ecx
5857    ADVANCE_PC 1
5858    GOTO_NEXT_R %ecx
5859
5860
5861/* ------------------------------ */
5862.L_OP_REM_INT_2ADDR: /* 0xb4 */
5863/* File: x86/OP_REM_INT_2ADDR.S */
5864/* File: x86/bindiv2addr.S */
5865    /*
5866     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
5867     * op1=-1.
5868     */
5869    /* div/rem/2addr vA, vB */
5870    movzx    rINSTbl,%ecx          # eax<- BA
5871    SPILL(rIBASE)
5872    sarl     $4,%ecx              # ecx<- B
5873    GET_VREG_R %ecx %ecx           # eax<- vBB
5874    andb     $0xf,rINSTbl         # rINST<- A
5875    GET_VREG_R %eax rINST          # eax<- vBB
5876    cmpl     $0,%ecx
5877    je       common_errDivideByZero
5878    cmpl     $-1,%ecx
5879    jne      .LOP_REM_INT_2ADDR_continue_div2addr
5880    cmpl     $0x80000000,%eax
5881    jne      .LOP_REM_INT_2ADDR_continue_div2addr
5882    movl     $0,rIBASE
5883    SET_VREG rIBASE rINST
5884    UNSPILL(rIBASE)
5885    FETCH_INST_OPCODE 1 %ecx
5886    ADVANCE_PC 1
5887    GOTO_NEXT_R %ecx
5888
5889.LOP_REM_INT_2ADDR_continue_div2addr:
5890    cltd
5891    idivl   %ecx
5892    SET_VREG rIBASE rINST
5893    UNSPILL(rIBASE)
5894    FETCH_INST_OPCODE 1 %ecx
5895    ADVANCE_PC 1
5896    GOTO_NEXT_R %ecx
5897
5898
5899/* ------------------------------ */
5900.L_OP_AND_INT_2ADDR: /* 0xb5 */
5901/* File: x86/OP_AND_INT_2ADDR.S */
5902/* File: x86/binop2addr.S */
5903    /*
5904     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5905     * that specifies an instruction that performs "result = r0 op r1".
5906     * This could be an ARM instruction or a function call.  (If the result
5907     * comes back in a register other than r0, you can override "result".)
5908     *
5909     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5910     * vCC (r1).  Useful for integer division and modulus.
5911     *
5912     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5913     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5914     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5915     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5916     */
5917    /* binop/2addr vA, vB */
5918    movzx   rINSTbl,%ecx               # ecx<- A+
5919    sarl    $4,rINST                 # rINST<- B
5920    GET_VREG_R %eax rINST              # eax<- vB
5921    andb    $0xf,%cl                  # ecx<- A
5922    andl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
5923    FETCH_INST_OPCODE 1 %ecx
5924    ADVANCE_PC 1
5925    GOTO_NEXT_R %ecx
5926
5927
5928/* ------------------------------ */
5929.L_OP_OR_INT_2ADDR: /* 0xb6 */
5930/* File: x86/OP_OR_INT_2ADDR.S */
5931/* File: x86/binop2addr.S */
5932    /*
5933     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5934     * that specifies an instruction that performs "result = r0 op r1".
5935     * This could be an ARM instruction or a function call.  (If the result
5936     * comes back in a register other than r0, you can override "result".)
5937     *
5938     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5939     * vCC (r1).  Useful for integer division and modulus.
5940     *
5941     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5942     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5943     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5944     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5945     */
5946    /* binop/2addr vA, vB */
5947    movzx   rINSTbl,%ecx               # ecx<- A+
5948    sarl    $4,rINST                 # rINST<- B
5949    GET_VREG_R %eax rINST              # eax<- vB
5950    andb    $0xf,%cl                  # ecx<- A
5951    orl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
5952    FETCH_INST_OPCODE 1 %ecx
5953    ADVANCE_PC 1
5954    GOTO_NEXT_R %ecx
5955
5956
5957/* ------------------------------ */
5958.L_OP_XOR_INT_2ADDR: /* 0xb7 */
5959/* File: x86/OP_XOR_INT_2ADDR.S */
5960/* File: x86/binop2addr.S */
5961    /*
5962     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5963     * that specifies an instruction that performs "result = r0 op r1".
5964     * This could be an ARM instruction or a function call.  (If the result
5965     * comes back in a register other than r0, you can override "result".)
5966     *
5967     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5968     * vCC (r1).  Useful for integer division and modulus.
5969     *
5970     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5971     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5972     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5973     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5974     */
5975    /* binop/2addr vA, vB */
5976    movzx   rINSTbl,%ecx               # ecx<- A+
5977    sarl    $4,rINST                 # rINST<- B
5978    GET_VREG_R %eax rINST              # eax<- vB
5979    andb    $0xf,%cl                  # ecx<- A
5980    xorl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
5981    FETCH_INST_OPCODE 1 %ecx
5982    ADVANCE_PC 1
5983    GOTO_NEXT_R %ecx
5984
5985
5986/* ------------------------------ */
5987.L_OP_SHL_INT_2ADDR: /* 0xb8 */
5988/* File: x86/OP_SHL_INT_2ADDR.S */
5989/* File: x86/shop2addr.S */
5990    /*
5991     * Generic 32-bit "shift/2addr" operation.
5992     */
5993    /* shift/2addr vA, vB */
5994    movzx    rINSTbl,%ecx           # eax<- BA
5995    sarl     $4,%ecx               # ecx<- B
5996    GET_VREG_R %ecx %ecx            # eax<- vBB
5997    andb     $0xf,rINSTbl          # rINST<- A
5998    GET_VREG_R %eax rINST           # eax<- vAA
5999    sall    %cl,%eax                          # ex: sarl %cl,%eax
6000    FETCH_INST_OPCODE 1 %ecx
6001    SET_VREG %eax rINST
6002    ADVANCE_PC 1
6003    GOTO_NEXT_R %ecx
6004
6005
6006/* ------------------------------ */
6007.L_OP_SHR_INT_2ADDR: /* 0xb9 */
6008/* File: x86/OP_SHR_INT_2ADDR.S */
6009/* File: x86/shop2addr.S */
6010    /*
6011     * Generic 32-bit "shift/2addr" operation.
6012     */
6013    /* shift/2addr vA, vB */
6014    movzx    rINSTbl,%ecx           # eax<- BA
6015    sarl     $4,%ecx               # ecx<- B
6016    GET_VREG_R %ecx %ecx            # eax<- vBB
6017    andb     $0xf,rINSTbl          # rINST<- A
6018    GET_VREG_R %eax rINST           # eax<- vAA
6019    sarl    %cl,%eax                          # ex: sarl %cl,%eax
6020    FETCH_INST_OPCODE 1 %ecx
6021    SET_VREG %eax rINST
6022    ADVANCE_PC 1
6023    GOTO_NEXT_R %ecx
6024
6025
6026/* ------------------------------ */
6027.L_OP_USHR_INT_2ADDR: /* 0xba */
6028/* File: x86/OP_USHR_INT_2ADDR.S */
6029/* File: x86/shop2addr.S */
6030    /*
6031     * Generic 32-bit "shift/2addr" operation.
6032     */
6033    /* shift/2addr vA, vB */
6034    movzx    rINSTbl,%ecx           # eax<- BA
6035    sarl     $4,%ecx               # ecx<- B
6036    GET_VREG_R %ecx %ecx            # eax<- vBB
6037    andb     $0xf,rINSTbl          # rINST<- A
6038    GET_VREG_R %eax rINST           # eax<- vAA
6039    shrl    %cl,%eax                          # ex: sarl %cl,%eax
6040    FETCH_INST_OPCODE 1 %ecx
6041    SET_VREG %eax rINST
6042    ADVANCE_PC 1
6043    GOTO_NEXT_R %ecx
6044
6045
6046/* ------------------------------ */
6047.L_OP_ADD_LONG_2ADDR: /* 0xbb */
6048/* File: x86/OP_ADD_LONG_2ADDR.S */
6049/* File: x86/binopWide2addr.S */
6050    /*
6051     * Generic 64-bit binary operation.
6052     */
6053    /* binop/2addr vA, vB */
6054    movzbl    rINSTbl,%ecx              # ecx<- BA
6055    sarl      $4,%ecx                  # ecx<- B
6056    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
6057    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
6058    andb      $0xF,rINSTbl             # rINST<- A
6059    addl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
6060    adcl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
6061    FETCH_INST_OPCODE 1 %ecx
6062    ADVANCE_PC 1
6063    GOTO_NEXT_R %ecx
6064
6065
6066/* ------------------------------ */
6067.L_OP_SUB_LONG_2ADDR: /* 0xbc */
6068/* File: x86/OP_SUB_LONG_2ADDR.S */
6069/* File: x86/binopWide2addr.S */
6070    /*
6071     * Generic 64-bit binary operation.
6072     */
6073    /* binop/2addr vA, vB */
6074    movzbl    rINSTbl,%ecx              # ecx<- BA
6075    sarl      $4,%ecx                  # ecx<- B
6076    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
6077    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
6078    andb      $0xF,rINSTbl             # rINST<- A
6079    subl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
6080    sbbl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
6081    FETCH_INST_OPCODE 1 %ecx
6082    ADVANCE_PC 1
6083    GOTO_NEXT_R %ecx
6084
6085
6086/* ------------------------------ */
6087.L_OP_MUL_LONG_2ADDR: /* 0xbd */
6088/* File: x86/OP_MUL_LONG_2ADDR.S */
6089    /*
6090     * Signed 64-bit integer multiply, 2-addr version
6091     *
6092     * We could definately use more free registers for
6093     * this code.  We must spill %edx (rIBASE) because it
6094     * is used by imul.  We'll also spill rINST (ebx),
6095     * giving us eax, ebc, ecx and rIBASE as computational
6096     * temps.  On top of that, we'll spill %esi (edi)
6097     * for use as the vA pointer and rFP (esi) for use
6098     * as the vB pointer.  Yuck.
6099     */
6100    /* mul-long/2addr vA, vB */
6101    movzbl    rINSTbl,%eax             # eax<- BA
6102    andb      $0xf,%al                # eax<- A
6103    sarl      $4,rINST                # rINST<- B
6104    SPILL_TMP2(%esi)
6105    SPILL(rFP)
6106    SPILL(rIBASE)
6107    leal      (rFP,%eax,4),%esi        # %esi<- &v[A]
6108    leal      (rFP,rINST,4),rFP        # rFP<- &v[B]
6109    movl      4(%esi),%ecx             # ecx<- Amsw
6110    imull     (rFP),%ecx               # ecx<- (Amsw*Blsw)
6111    movl      4(rFP),%eax              # eax<- Bmsw
6112    imull     (%esi),%eax              # eax<- (Bmsw*Alsw)
6113    addl      %eax,%ecx                # ecx<- (Amsw*Blsw)+(Bmsw*Alsw)
6114    movl      (rFP),%eax               # eax<- Blsw
6115    mull      (%esi)                   # eax<- (Blsw*Alsw)
6116    leal      (%ecx,rIBASE),rIBASE     # full result now in %edx:%eax
6117    movl      rIBASE,4(%esi)           # v[A+1]<- rIBASE
6118    movl      %eax,(%esi)              # v[A]<- %eax
6119    UNSPILL_TMP2(%esi)
6120    FETCH_INST_OPCODE 1 %ecx
6121    UNSPILL(rIBASE)
6122    UNSPILL(rFP)
6123    ADVANCE_PC 1
6124    GOTO_NEXT_R %ecx
6125
6126/* ------------------------------ */
6127.L_OP_DIV_LONG_2ADDR: /* 0xbe */
6128/* File: x86/OP_DIV_LONG_2ADDR.S */
6129    /* div/2addr vA, vB */
6130    movzbl    rINSTbl,%eax
6131    shrl      $4,%eax                  # eax<- B
6132    andb      $0xf,rINSTbl             # rINST<- A
6133    SPILL(rIBASE)                       # save rIBASE/%edx
6134    GET_VREG_WORD rIBASE %eax 0
6135    GET_VREG_WORD %eax %eax 1
6136    movl     rIBASE,OUT_ARG2(%esp)
6137    testl    %eax,%eax
6138    je       .LOP_DIV_LONG_2ADDR_check_zero
6139    cmpl     $-1,%eax
6140    je       .LOP_DIV_LONG_2ADDR_check_neg1
6141.LOP_DIV_LONG_2ADDR_notSpecial:
6142    GET_VREG_WORD rIBASE rINST 0
6143    GET_VREG_WORD %ecx rINST 1
6144.LOP_DIV_LONG_2ADDR_notSpecial1:
6145    movl     %eax,OUT_ARG3(%esp)
6146    movl     rIBASE,OUT_ARG0(%esp)
6147    movl     %ecx,OUT_ARG1(%esp)
6148    call     __divdi3
6149.LOP_DIV_LONG_2ADDR_finish:
6150    SET_VREG_WORD rIBASE rINST 1
6151    UNSPILL(rIBASE)                    # restore rIBASE/%edx
6152    SET_VREG_WORD %eax rINST 0
6153    FETCH_INST_OPCODE 1 %ecx
6154    ADVANCE_PC 1
6155    GOTO_NEXT_R %ecx
6156
6157.LOP_DIV_LONG_2ADDR_check_zero:
6158    testl   rIBASE,rIBASE
6159    jne     .LOP_DIV_LONG_2ADDR_notSpecial
6160    jmp     common_errDivideByZero
6161.LOP_DIV_LONG_2ADDR_check_neg1:
6162    testl   rIBASE,%eax
6163    jne     .LOP_DIV_LONG_2ADDR_notSpecial
6164    GET_VREG_WORD rIBASE rINST 0
6165    GET_VREG_WORD %ecx rINST 1
6166    testl    rIBASE,rIBASE
6167    jne      .LOP_DIV_LONG_2ADDR_notSpecial1
6168    cmpl     $0x80000000,%ecx
6169    jne      .LOP_DIV_LONG_2ADDR_notSpecial1
6170    /* minint / -1, return minint on div, 0 on rem */
6171    xorl     %eax,%eax
6172    movl     $0x80000000,rIBASE
6173    jmp      .LOP_DIV_LONG_2ADDR_finish
6174
6175/* ------------------------------ */
6176.L_OP_REM_LONG_2ADDR: /* 0xbf */
6177/* File: x86/OP_REM_LONG_2ADDR.S */
6178/* File: x86/OP_DIV_LONG_2ADDR.S */
6179    /* div/2addr vA, vB */
6180    movzbl    rINSTbl,%eax
6181    shrl      $4,%eax                  # eax<- B
6182    andb      $0xf,rINSTbl             # rINST<- A
6183    SPILL(rIBASE)                       # save rIBASE/%edx
6184    GET_VREG_WORD rIBASE %eax 0
6185    GET_VREG_WORD %eax %eax 1
6186    movl     rIBASE,OUT_ARG2(%esp)
6187    testl    %eax,%eax
6188    je       .LOP_REM_LONG_2ADDR_check_zero
6189    cmpl     $-1,%eax
6190    je       .LOP_REM_LONG_2ADDR_check_neg1
6191.LOP_REM_LONG_2ADDR_notSpecial:
6192    GET_VREG_WORD rIBASE rINST 0
6193    GET_VREG_WORD %ecx rINST 1
6194.LOP_REM_LONG_2ADDR_notSpecial1:
6195    movl     %eax,OUT_ARG3(%esp)
6196    movl     rIBASE,OUT_ARG0(%esp)
6197    movl     %ecx,OUT_ARG1(%esp)
6198    call     __moddi3
6199.LOP_REM_LONG_2ADDR_finish:
6200    SET_VREG_WORD rIBASE rINST 1
6201    UNSPILL(rIBASE)                    # restore rIBASE/%edx
6202    SET_VREG_WORD %eax rINST 0
6203    FETCH_INST_OPCODE 1 %ecx
6204    ADVANCE_PC 1
6205    GOTO_NEXT_R %ecx
6206
6207.LOP_REM_LONG_2ADDR_check_zero:
6208    testl   rIBASE,rIBASE
6209    jne     .LOP_REM_LONG_2ADDR_notSpecial
6210    jmp     common_errDivideByZero
6211.LOP_REM_LONG_2ADDR_check_neg1:
6212    testl   rIBASE,%eax
6213    jne     .LOP_REM_LONG_2ADDR_notSpecial
6214    GET_VREG_WORD rIBASE rINST 0
6215    GET_VREG_WORD %ecx rINST 1
6216    testl    rIBASE,rIBASE
6217    jne      .LOP_REM_LONG_2ADDR_notSpecial1
6218    cmpl     $0x80000000,%ecx
6219    jne      .LOP_REM_LONG_2ADDR_notSpecial1
6220    /* minint / -1, return minint on div, 0 on rem */
6221    xorl     %eax,%eax
6222    movl     $0,rIBASE
6223    jmp      .LOP_REM_LONG_2ADDR_finish
6224
6225
6226/* ------------------------------ */
6227.L_OP_AND_LONG_2ADDR: /* 0xc0 */
6228/* File: x86/OP_AND_LONG_2ADDR.S */
6229/* File: x86/binopWide2addr.S */
6230    /*
6231     * Generic 64-bit binary operation.
6232     */
6233    /* binop/2addr vA, vB */
6234    movzbl    rINSTbl,%ecx              # ecx<- BA
6235    sarl      $4,%ecx                  # ecx<- B
6236    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
6237    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
6238    andb      $0xF,rINSTbl             # rINST<- A
6239    andl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
6240    andl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
6241    FETCH_INST_OPCODE 1 %ecx
6242    ADVANCE_PC 1
6243    GOTO_NEXT_R %ecx
6244
6245
6246/* ------------------------------ */
6247.L_OP_OR_LONG_2ADDR: /* 0xc1 */
6248/* File: x86/OP_OR_LONG_2ADDR.S */
6249/* File: x86/binopWide2addr.S */
6250    /*
6251     * Generic 64-bit binary operation.
6252     */
6253    /* binop/2addr vA, vB */
6254    movzbl    rINSTbl,%ecx              # ecx<- BA
6255    sarl      $4,%ecx                  # ecx<- B
6256    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
6257    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
6258    andb      $0xF,rINSTbl             # rINST<- A
6259    orl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
6260    orl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
6261    FETCH_INST_OPCODE 1 %ecx
6262    ADVANCE_PC 1
6263    GOTO_NEXT_R %ecx
6264
6265
6266/* ------------------------------ */
6267.L_OP_XOR_LONG_2ADDR: /* 0xc2 */
6268/* File: x86/OP_XOR_LONG_2ADDR.S */
6269/* File: x86/binopWide2addr.S */
6270    /*
6271     * Generic 64-bit binary operation.
6272     */
6273    /* binop/2addr vA, vB */
6274    movzbl    rINSTbl,%ecx              # ecx<- BA
6275    sarl      $4,%ecx                  # ecx<- B
6276    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
6277    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
6278    andb      $0xF,rINSTbl             # rINST<- A
6279    xorl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
6280    xorl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
6281    FETCH_INST_OPCODE 1 %ecx
6282    ADVANCE_PC 1
6283    GOTO_NEXT_R %ecx
6284
6285
6286/* ------------------------------ */
6287.L_OP_SHL_LONG_2ADDR: /* 0xc3 */
6288/* File: x86/OP_SHL_LONG_2ADDR.S */
6289    /*
6290     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6291     * 32-bit shift distance.
6292     */
6293    /* shl-long/2addr vA, vB */
6294    /* ecx gets shift count */
6295    /* Need to spill rIBASE */
6296    /* rINSTw gets AA */
6297    movzbl    rINSTbl,%ecx             # ecx<- BA
6298    andb      $0xf,rINSTbl            # rINST<- A
6299    GET_VREG_WORD %eax rINST 0         # eax<- v[AA+0]
6300    sarl      $4,%ecx                 # ecx<- B
6301    SPILL(rIBASE)
6302    GET_VREG_WORD rIBASE rINST 1       # rIBASE<- v[AA+1]
6303    GET_VREG_R  %ecx %ecx              # ecx<- vBB
6304    shldl     %eax,rIBASE
6305    sall      %cl,%eax
6306    testb     $32,%cl
6307    je        2f
6308    movl      %eax,rIBASE
6309    xorl      %eax,%eax
63102:
6311    SET_VREG_WORD rIBASE rINST 1       # v[AA+1]<- rIBASE
6312    UNSPILL(rIBASE)
6313    FETCH_INST_OPCODE 1 %ecx
6314    SET_VREG_WORD %eax rINST 0         # v[AA+0]<- eax
6315    ADVANCE_PC 1
6316    GOTO_NEXT_R %ecx
6317
6318/* ------------------------------ */
6319.L_OP_SHR_LONG_2ADDR: /* 0xc4 */
6320/* File: x86/OP_SHR_LONG_2ADDR.S */
6321    /*
6322     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6323     * 32-bit shift distance.
6324     */
6325    /* shl-long/2addr vA, vB */
6326    /* ecx gets shift count */
6327    /* Need to spill rIBASE */
6328    /* rINSTw gets AA */
6329    movzbl    rINSTbl,%ecx         # ecx<- BA
6330    andb      $0xf,rINSTbl        # rINST<- A
6331    GET_VREG_WORD %eax rINST 0     # eax<- v[AA+0]
6332    sarl      $4,%ecx             # ecx<- B
6333    SPILL(rIBASE)
6334    GET_VREG_WORD rIBASE rINST 1   # rIBASE<- v[AA+1]
6335    GET_VREG_R %ecx %ecx           # ecx<- vBB
6336    shrdl     rIBASE,%eax
6337    sarl      %cl,rIBASE
6338    testb     $32,%cl
6339    je        2f
6340    movl      rIBASE,%eax
6341    sarl      $31,rIBASE
63422:
6343    SET_VREG_WORD rIBASE rINST 1   # v[AA+1]<- rIBASE
6344    UNSPILL(rIBASE)
6345    FETCH_INST_OPCODE 1 %ecx
6346    SET_VREG_WORD %eax rINST 0    # v[AA+0]<- eax
6347    ADVANCE_PC 1
6348    GOTO_NEXT_R %ecx
6349
6350/* ------------------------------ */
6351.L_OP_USHR_LONG_2ADDR: /* 0xc5 */
6352/* File: x86/OP_USHR_LONG_2ADDR.S */
6353    /*
6354     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6355     * 32-bit shift distance.
6356     */
6357    /* shl-long/2addr vA, vB */
6358    /* ecx gets shift count */
6359    /* Need to spill rIBASE */
6360    /* rINSTw gets AA */
6361    movzbl    rINSTbl,%ecx             # ecx<- BA
6362    andb      $0xf,rINSTbl            # rINST<- A
6363    GET_VREG_WORD %eax rINST 0         # eax<- v[AA+0]
6364    sarl      $4,%ecx                 # ecx<- B
6365    SPILL(rIBASE)
6366    GET_VREG_WORD rIBASE rINST 1       # rIBASE<- v[AA+1]
6367    GET_VREG_R %ecx %ecx               # ecx<- vBB
6368    shrdl     rIBASE,%eax
6369    shrl      %cl,rIBASE
6370    testb     $32,%cl
6371    je        2f
6372    movl      rIBASE,%eax
6373    xorl      rIBASE,rIBASE
63742:
6375    SET_VREG_WORD rIBASE rINST 1       # v[AA+1]<- rIBASE
6376    FETCH_INST_OPCODE 1 %ecx
6377    UNSPILL(rIBASE)
6378    SET_VREG_WORD %eax rINST 0         # v[AA+0]<- eax
6379    ADVANCE_PC 1
6380    GOTO_NEXT_R %ecx
6381
6382/* ------------------------------ */
6383.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
6384/* File: x86/OP_ADD_FLOAT_2ADDR.S */
6385/* File: x86/binflop2addr.S */
6386    /*
6387     * Generic 32-bit binary float operation.
6388     *
6389     * For: add-fp, sub-fp, mul-fp, div-fp
6390     */
6391
6392    /* binop/2addr vA, vB */
6393    movzx   rINSTbl,%ecx           # ecx<- A+
6394    andb    $0xf,%cl              # ecx<- A
6395    flds    (rFP,%ecx,4)          # vAA to fp stack
6396    sarl    $4,rINST             # rINST<- B
6397    fadds   (rFP,rINST,4)         # ex: faddp
6398    FETCH_INST_OPCODE 1 %eax
6399    ADVANCE_PC 1
6400    fstps    (rFP,%ecx,4)         # %st to vA
6401    GOTO_NEXT_R %eax
6402
6403
6404/* ------------------------------ */
6405.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
6406/* File: x86/OP_SUB_FLOAT_2ADDR.S */
6407/* File: x86/binflop2addr.S */
6408    /*
6409     * Generic 32-bit binary float operation.
6410     *
6411     * For: add-fp, sub-fp, mul-fp, div-fp
6412     */
6413
6414    /* binop/2addr vA, vB */
6415    movzx   rINSTbl,%ecx           # ecx<- A+
6416    andb    $0xf,%cl              # ecx<- A
6417    flds    (rFP,%ecx,4)          # vAA to fp stack
6418    sarl    $4,rINST             # rINST<- B
6419    fsubs   (rFP,rINST,4)         # ex: faddp
6420    FETCH_INST_OPCODE 1 %eax
6421    ADVANCE_PC 1
6422    fstps    (rFP,%ecx,4)         # %st to vA
6423    GOTO_NEXT_R %eax
6424
6425
6426/* ------------------------------ */
6427.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
6428/* File: x86/OP_MUL_FLOAT_2ADDR.S */
6429/* File: x86/binflop2addr.S */
6430    /*
6431     * Generic 32-bit binary float operation.
6432     *
6433     * For: add-fp, sub-fp, mul-fp, div-fp
6434     */
6435
6436    /* binop/2addr vA, vB */
6437    movzx   rINSTbl,%ecx           # ecx<- A+
6438    andb    $0xf,%cl              # ecx<- A
6439    flds    (rFP,%ecx,4)          # vAA to fp stack
6440    sarl    $4,rINST             # rINST<- B
6441    fmuls   (rFP,rINST,4)         # ex: faddp
6442    FETCH_INST_OPCODE 1 %eax
6443    ADVANCE_PC 1
6444    fstps    (rFP,%ecx,4)         # %st to vA
6445    GOTO_NEXT_R %eax
6446
6447
6448/* ------------------------------ */
6449.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
6450/* File: x86/OP_DIV_FLOAT_2ADDR.S */
6451/* File: x86/binflop2addr.S */
6452    /*
6453     * Generic 32-bit binary float operation.
6454     *
6455     * For: add-fp, sub-fp, mul-fp, div-fp
6456     */
6457
6458    /* binop/2addr vA, vB */
6459    movzx   rINSTbl,%ecx           # ecx<- A+
6460    andb    $0xf,%cl              # ecx<- A
6461    flds    (rFP,%ecx,4)          # vAA to fp stack
6462    sarl    $4,rINST             # rINST<- B
6463    fdivs   (rFP,rINST,4)         # ex: faddp
6464    FETCH_INST_OPCODE 1 %eax
6465    ADVANCE_PC 1
6466    fstps    (rFP,%ecx,4)         # %st to vA
6467    GOTO_NEXT_R %eax
6468
6469
6470/* ------------------------------ */
6471.L_OP_REM_FLOAT_2ADDR: /* 0xca */
6472/* File: x86/OP_REM_FLOAT_2ADDR.S */
6473    /* rem_float/2addr vA, vB */
6474    movzx   rINSTbl,%ecx                # ecx<- A+
6475    sarl    $4,rINST                  # rINST<- B
6476    flds     (rFP,rINST,4)              # vBB to fp stack
6477    andb    $0xf,%cl                   # ecx<- A
6478    flds     (rFP,%ecx,4)               # vAA to fp stack
64791:
6480    fprem
6481    fstsw     %ax
6482    sahf
6483    jp        1b
6484    fstp      %st(1)
6485    FETCH_INST_OPCODE 1 %eax
6486    ADVANCE_PC 1
6487    fstps    (rFP,%ecx,4)               # %st to vA
6488    GOTO_NEXT_R %eax
6489
6490/* ------------------------------ */
6491.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
6492/* File: x86/OP_ADD_DOUBLE_2ADDR.S */
6493/* File: x86/binflop2addr.S */
6494    /*
6495     * Generic 32-bit binary float operation.
6496     *
6497     * For: add-fp, sub-fp, mul-fp, div-fp
6498     */
6499
6500    /* binop/2addr vA, vB */
6501    movzx   rINSTbl,%ecx           # ecx<- A+
6502    andb    $0xf,%cl              # ecx<- A
6503    fldl    (rFP,%ecx,4)          # vAA to fp stack
6504    sarl    $4,rINST             # rINST<- B
6505    faddl   (rFP,rINST,4)         # ex: faddp
6506    FETCH_INST_OPCODE 1 %eax
6507    ADVANCE_PC 1
6508    fstpl    (rFP,%ecx,4)         # %st to vA
6509    GOTO_NEXT_R %eax
6510
6511
6512/* ------------------------------ */
6513.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
6514/* File: x86/OP_SUB_DOUBLE_2ADDR.S */
6515/* File: x86/binflop2addr.S */
6516    /*
6517     * Generic 32-bit binary float operation.
6518     *
6519     * For: add-fp, sub-fp, mul-fp, div-fp
6520     */
6521
6522    /* binop/2addr vA, vB */
6523    movzx   rINSTbl,%ecx           # ecx<- A+
6524    andb    $0xf,%cl              # ecx<- A
6525    fldl    (rFP,%ecx,4)          # vAA to fp stack
6526    sarl    $4,rINST             # rINST<- B
6527    fsubl   (rFP,rINST,4)         # ex: faddp
6528    FETCH_INST_OPCODE 1 %eax
6529    ADVANCE_PC 1
6530    fstpl    (rFP,%ecx,4)         # %st to vA
6531    GOTO_NEXT_R %eax
6532
6533
6534/* ------------------------------ */
6535.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
6536/* File: x86/OP_MUL_DOUBLE_2ADDR.S */
6537/* File: x86/binflop2addr.S */
6538    /*
6539     * Generic 32-bit binary float operation.
6540     *
6541     * For: add-fp, sub-fp, mul-fp, div-fp
6542     */
6543
6544    /* binop/2addr vA, vB */
6545    movzx   rINSTbl,%ecx           # ecx<- A+
6546    andb    $0xf,%cl              # ecx<- A
6547    fldl    (rFP,%ecx,4)          # vAA to fp stack
6548    sarl    $4,rINST             # rINST<- B
6549    fmull   (rFP,rINST,4)         # ex: faddp
6550    FETCH_INST_OPCODE 1 %eax
6551    ADVANCE_PC 1
6552    fstpl    (rFP,%ecx,4)         # %st to vA
6553    GOTO_NEXT_R %eax
6554
6555
6556/* ------------------------------ */
6557.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */
6558/* File: x86/OP_DIV_DOUBLE_2ADDR.S */
6559/* File: x86/binflop2addr.S */
6560    /*
6561     * Generic 32-bit binary float operation.
6562     *
6563     * For: add-fp, sub-fp, mul-fp, div-fp
6564     */
6565
6566    /* binop/2addr vA, vB */
6567    movzx   rINSTbl,%ecx           # ecx<- A+
6568    andb    $0xf,%cl              # ecx<- A
6569    fldl    (rFP,%ecx,4)          # vAA to fp stack
6570    sarl    $4,rINST             # rINST<- B
6571    fdivl   (rFP,rINST,4)         # ex: faddp
6572    FETCH_INST_OPCODE 1 %eax
6573    ADVANCE_PC 1
6574    fstpl    (rFP,%ecx,4)         # %st to vA
6575    GOTO_NEXT_R %eax
6576
6577
6578/* ------------------------------ */
6579.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */
6580/* File: x86/OP_REM_DOUBLE_2ADDR.S */
6581    /* rem_float/2addr vA, vB */
6582    movzx   rINSTbl,%ecx                # ecx<- A+
6583    sarl    $4,rINST                  # rINST<- B
6584    fldl     (rFP,rINST,4)              # vBB to fp stack
6585    andb    $0xf,%cl                   # ecx<- A
6586    fldl     (rFP,%ecx,4)               # vAA to fp stack
65871:
6588    fprem
6589    fstsw     %ax
6590    sahf
6591    jp        1b
6592    fstp      %st(1)
6593    FETCH_INST_OPCODE 1 %eax
6594    ADVANCE_PC 1
6595    fstpl    (rFP,%ecx,4)               # %st to vA
6596    GOTO_NEXT_R %eax
6597
6598/* ------------------------------ */
6599.L_OP_ADD_INT_LIT16: /* 0xd0 */
6600/* File: x86/OP_ADD_INT_LIT16.S */
6601/* File: x86/binopLit16.S */
6602    /*
6603     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6604     * that specifies an instruction that performs "result = eax op ecx".
6605     * This could be an x86 instruction or a function call.  (If the result
6606     * comes back in a register other than eax, you can override "result".)
6607     *
6608     * For: add-int/lit16, rsub-int,
6609     *      and-int/lit16, or-int/lit16, xor-int/lit16
6610     */
6611    /* binop/lit16 vA, vB, #+CCCC */
6612    movzbl   rINSTbl,%eax               # eax<- 000000BA
6613    sarl     $4,%eax                   # eax<- B
6614    GET_VREG_R %eax %eax                # eax<- vB
6615    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
6616    andb     $0xf,rINSTbl              # rINST<- A
6617    addl %ecx,%eax                              # for example: addl %ecx, %eax
6618    SET_VREG %eax rINST
6619    FETCH_INST_OPCODE 2 %ecx
6620    ADVANCE_PC 2
6621    GOTO_NEXT_R %ecx
6622
6623
6624/* ------------------------------ */
6625.L_OP_RSUB_INT: /* 0xd1 */
6626/* File: x86/OP_RSUB_INT.S */
6627/* File: x86/binopLit16.S */
6628    /*
6629     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6630     * that specifies an instruction that performs "result = eax op ecx".
6631     * This could be an x86 instruction or a function call.  (If the result
6632     * comes back in a register other than eax, you can override "result".)
6633     *
6634     * For: add-int/lit16, rsub-int,
6635     *      and-int/lit16, or-int/lit16, xor-int/lit16
6636     */
6637    /* binop/lit16 vA, vB, #+CCCC */
6638    movzbl   rINSTbl,%eax               # eax<- 000000BA
6639    sarl     $4,%eax                   # eax<- B
6640    GET_VREG_R %eax %eax                # eax<- vB
6641    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
6642    andb     $0xf,rINSTbl              # rINST<- A
6643    subl %eax,%ecx                              # for example: addl %ecx, %eax
6644    SET_VREG %ecx rINST
6645    FETCH_INST_OPCODE 2 %ecx
6646    ADVANCE_PC 2
6647    GOTO_NEXT_R %ecx
6648
6649
6650/* ------------------------------ */
6651.L_OP_MUL_INT_LIT16: /* 0xd2 */
6652/* File: x86/OP_MUL_INT_LIT16.S */
6653    /* mul/lit16 vA, vB, #+CCCC */
6654    /* Need A in rINST, ssssCCCC in ecx, vB in eax */
6655    movzbl   rINSTbl,%eax               # eax<- 000000BA
6656    sarl     $4,%eax                   # eax<- B
6657    GET_VREG_R %eax %eax                # eax<- vB
6658    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
6659    andb     $0xf,rINSTbl              # rINST<- A
6660    SPILL(rIBASE)
6661    imull     %ecx,%eax                 # trashes rIBASE/edx
6662    UNSPILL(rIBASE)
6663    FETCH_INST_OPCODE 2 %ecx
6664    ADVANCE_PC 2
6665    SET_VREG %eax rINST
6666    GOTO_NEXT_R %ecx
6667
6668/* ------------------------------ */
6669.L_OP_DIV_INT_LIT16: /* 0xd3 */
6670/* File: x86/OP_DIV_INT_LIT16.S */
6671/* File: x86/bindivLit16.S */
6672    /*
6673     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
6674     * op1=-1.
6675     */
6676    /* div/rem/lit16 vA, vB, #+CCCC */
6677    /* Need A in rINST, ssssCCCC in ecx, vB in eax */
6678    movzbl   rINSTbl,%eax         # eax<- 000000BA
6679    SPILL(rIBASE)
6680    sarl     $4,%eax             # eax<- B
6681    GET_VREG_R %eax %eax          # eax<- vB
6682    movswl   2(rPC),%ecx          # ecx<- ssssCCCC
6683    andb     $0xf,rINSTbl        # rINST<- A
6684    cmpl     $0,%ecx
6685    je       common_errDivideByZero
6686    cmpl     $-1,%ecx
6687    jne      .LOP_DIV_INT_LIT16_continue_div
6688    cmpl     $0x80000000,%eax
6689    jne      .LOP_DIV_INT_LIT16_continue_div
6690    movl     $0x80000000,%eax
6691    SET_VREG %eax rINST
6692    UNSPILL(rIBASE)
6693    FETCH_INST_OPCODE 2 %ecx
6694    ADVANCE_PC 2
6695    GOTO_NEXT_R %ecx
6696
6697.LOP_DIV_INT_LIT16_continue_div:
6698    cltd
6699    idivl   %ecx
6700    SET_VREG %eax rINST
6701    UNSPILL(rIBASE)
6702    FETCH_INST_OPCODE 2 %ecx
6703    ADVANCE_PC 2
6704    GOTO_NEXT_R %ecx
6705
6706
6707/* ------------------------------ */
6708.L_OP_REM_INT_LIT16: /* 0xd4 */
6709/* File: x86/OP_REM_INT_LIT16.S */
6710/* File: x86/bindivLit16.S */
6711    /*
6712     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
6713     * op1=-1.
6714     */
6715    /* div/rem/lit16 vA, vB, #+CCCC */
6716    /* Need A in rINST, ssssCCCC in ecx, vB in eax */
6717    movzbl   rINSTbl,%eax         # eax<- 000000BA
6718    SPILL(rIBASE)
6719    sarl     $4,%eax             # eax<- B
6720    GET_VREG_R %eax %eax          # eax<- vB
6721    movswl   2(rPC),%ecx          # ecx<- ssssCCCC
6722    andb     $0xf,rINSTbl        # rINST<- A
6723    cmpl     $0,%ecx
6724    je       common_errDivideByZero
6725    cmpl     $-1,%ecx
6726    jne      .LOP_REM_INT_LIT16_continue_div
6727    cmpl     $0x80000000,%eax
6728    jne      .LOP_REM_INT_LIT16_continue_div
6729    movl     $0,rIBASE
6730    SET_VREG rIBASE rINST
6731    UNSPILL(rIBASE)
6732    FETCH_INST_OPCODE 2 %ecx
6733    ADVANCE_PC 2
6734    GOTO_NEXT_R %ecx
6735
6736.LOP_REM_INT_LIT16_continue_div:
6737    cltd
6738    idivl   %ecx
6739    SET_VREG rIBASE rINST
6740    UNSPILL(rIBASE)
6741    FETCH_INST_OPCODE 2 %ecx
6742    ADVANCE_PC 2
6743    GOTO_NEXT_R %ecx
6744
6745
6746/* ------------------------------ */
6747.L_OP_AND_INT_LIT16: /* 0xd5 */
6748/* File: x86/OP_AND_INT_LIT16.S */
6749/* File: x86/binopLit16.S */
6750    /*
6751     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6752     * that specifies an instruction that performs "result = eax op ecx".
6753     * This could be an x86 instruction or a function call.  (If the result
6754     * comes back in a register other than eax, you can override "result".)
6755     *
6756     * For: add-int/lit16, rsub-int,
6757     *      and-int/lit16, or-int/lit16, xor-int/lit16
6758     */
6759    /* binop/lit16 vA, vB, #+CCCC */
6760    movzbl   rINSTbl,%eax               # eax<- 000000BA
6761    sarl     $4,%eax                   # eax<- B
6762    GET_VREG_R %eax %eax                # eax<- vB
6763    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
6764    andb     $0xf,rINSTbl              # rINST<- A
6765    andl %ecx,%eax                              # for example: addl %ecx, %eax
6766    SET_VREG %eax rINST
6767    FETCH_INST_OPCODE 2 %ecx
6768    ADVANCE_PC 2
6769    GOTO_NEXT_R %ecx
6770
6771
6772/* ------------------------------ */
6773.L_OP_OR_INT_LIT16: /* 0xd6 */
6774/* File: x86/OP_OR_INT_LIT16.S */
6775/* File: x86/binopLit16.S */
6776    /*
6777     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6778     * that specifies an instruction that performs "result = eax op ecx".
6779     * This could be an x86 instruction or a function call.  (If the result
6780     * comes back in a register other than eax, you can override "result".)
6781     *
6782     * For: add-int/lit16, rsub-int,
6783     *      and-int/lit16, or-int/lit16, xor-int/lit16
6784     */
6785    /* binop/lit16 vA, vB, #+CCCC */
6786    movzbl   rINSTbl,%eax               # eax<- 000000BA
6787    sarl     $4,%eax                   # eax<- B
6788    GET_VREG_R %eax %eax                # eax<- vB
6789    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
6790    andb     $0xf,rINSTbl              # rINST<- A
6791    orl     %ecx,%eax                              # for example: addl %ecx, %eax
6792    SET_VREG %eax rINST
6793    FETCH_INST_OPCODE 2 %ecx
6794    ADVANCE_PC 2
6795    GOTO_NEXT_R %ecx
6796
6797
6798/* ------------------------------ */
6799.L_OP_XOR_INT_LIT16: /* 0xd7 */
6800/* File: x86/OP_XOR_INT_LIT16.S */
6801/* File: x86/binopLit16.S */
6802    /*
6803     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6804     * that specifies an instruction that performs "result = eax op ecx".
6805     * This could be an x86 instruction or a function call.  (If the result
6806     * comes back in a register other than eax, you can override "result".)
6807     *
6808     * For: add-int/lit16, rsub-int,
6809     *      and-int/lit16, or-int/lit16, xor-int/lit16
6810     */
6811    /* binop/lit16 vA, vB, #+CCCC */
6812    movzbl   rINSTbl,%eax               # eax<- 000000BA
6813    sarl     $4,%eax                   # eax<- B
6814    GET_VREG_R %eax %eax                # eax<- vB
6815    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
6816    andb     $0xf,rINSTbl              # rINST<- A
6817    xor    %ecx,%eax                              # for example: addl %ecx, %eax
6818    SET_VREG %eax rINST
6819    FETCH_INST_OPCODE 2 %ecx
6820    ADVANCE_PC 2
6821    GOTO_NEXT_R %ecx
6822
6823
6824/* ------------------------------ */
6825.L_OP_ADD_INT_LIT8: /* 0xd8 */
6826/* File: x86/OP_ADD_INT_LIT8.S */
6827/* File: x86/binopLit8.S */
6828    /*
6829     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6830     * that specifies an instruction that performs "result = eax op ecx".
6831     * This could be an x86 instruction or a function call.  (If the result
6832     * comes back in a register other than r0, you can override "result".)
6833     *
6834     * For: add-int/lit8, rsub-int/lit8
6835     *      and-int/lit8, or-int/lit8, xor-int/lit8,
6836     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6837     */
6838    /* binop/lit8 vAA, vBB, #+CC */
6839    movzbl    2(rPC),%eax              # eax<- BB
6840    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
6841    GET_VREG_R   %eax %eax             # eax<- rBB
6842    addl %ecx,%eax                             # ex: addl %ecx,%eax
6843    SET_VREG   %eax rINST
6844    FETCH_INST_OPCODE 2 %ecx
6845    ADVANCE_PC 2
6846    GOTO_NEXT_R %ecx
6847
6848
6849/* ------------------------------ */
6850.L_OP_RSUB_INT_LIT8: /* 0xd9 */
6851/* File: x86/OP_RSUB_INT_LIT8.S */
6852/* File: x86/binopLit8.S */
6853    /*
6854     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6855     * that specifies an instruction that performs "result = eax op ecx".
6856     * This could be an x86 instruction or a function call.  (If the result
6857     * comes back in a register other than r0, you can override "result".)
6858     *
6859     * For: add-int/lit8, rsub-int/lit8
6860     *      and-int/lit8, or-int/lit8, xor-int/lit8,
6861     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6862     */
6863    /* binop/lit8 vAA, vBB, #+CC */
6864    movzbl    2(rPC),%eax              # eax<- BB
6865    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
6866    GET_VREG_R   %eax %eax             # eax<- rBB
6867    subl  %eax,%ecx                             # ex: addl %ecx,%eax
6868    SET_VREG   %ecx rINST
6869    FETCH_INST_OPCODE 2 %ecx
6870    ADVANCE_PC 2
6871    GOTO_NEXT_R %ecx
6872
6873
6874/* ------------------------------ */
6875.L_OP_MUL_INT_LIT8: /* 0xda */
6876/* File: x86/OP_MUL_INT_LIT8.S */
6877    /* mul/lit8 vAA, vBB, #+CC */
6878    movzbl    2(rPC),%eax              # eax<- BB
6879    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
6880    GET_VREG_R   %eax %eax             # eax<- rBB
6881    SPILL(rIBASE)
6882    imull     %ecx,%eax                # trashes rIBASE/edx
6883    UNSPILL(rIBASE)
6884    FETCH_INST_OPCODE 2 %ecx
6885    ADVANCE_PC 2
6886    SET_VREG  %eax rINST
6887    GOTO_NEXT_R %ecx
6888
6889/* ------------------------------ */
6890.L_OP_DIV_INT_LIT8: /* 0xdb */
6891/* File: x86/OP_DIV_INT_LIT8.S */
6892/* File: x86/bindivLit8.S */
6893    /*
6894     * 32-bit div/rem "lit8" binary operation.  Handles special case of
6895     * op0=minint & op1=-1
6896     */
6897    /* div/rem/lit8 vAA, vBB, #+CC */
6898    movzbl    2(rPC),%eax        # eax<- BB
6899    movsbl    3(rPC),%ecx        # ecx<- ssssssCC
6900    SPILL(rIBASE)
6901    GET_VREG_R  %eax %eax        # eax<- rBB
6902    cmpl     $0,%ecx
6903    je       common_errDivideByZero
6904    cmpl     $0x80000000,%eax
6905    jne      .LOP_DIV_INT_LIT8_continue_div
6906    cmpl     $-1,%ecx
6907    jne      .LOP_DIV_INT_LIT8_continue_div
6908    movl     $0x80000000,%eax
6909    SET_VREG %eax rINST
6910    UNSPILL(rIBASE)
6911    FETCH_INST_OPCODE 2 %ecx
6912    ADVANCE_PC 2
6913    GOTO_NEXT_R %ecx
6914
6915.LOP_DIV_INT_LIT8_continue_div:
6916    cltd
6917    idivl   %ecx
6918    SET_VREG %eax rINST
6919    UNSPILL(rIBASE)
6920    FETCH_INST_OPCODE 2 %ecx
6921    ADVANCE_PC 2
6922    GOTO_NEXT_R %ecx
6923
6924
6925/* ------------------------------ */
6926.L_OP_REM_INT_LIT8: /* 0xdc */
6927/* File: x86/OP_REM_INT_LIT8.S */
6928/* File: x86/bindivLit8.S */
6929    /*
6930     * 32-bit div/rem "lit8" binary operation.  Handles special case of
6931     * op0=minint & op1=-1
6932     */
6933    /* div/rem/lit8 vAA, vBB, #+CC */
6934    movzbl    2(rPC),%eax        # eax<- BB
6935    movsbl    3(rPC),%ecx        # ecx<- ssssssCC
6936    SPILL(rIBASE)
6937    GET_VREG_R  %eax %eax        # eax<- rBB
6938    cmpl     $0,%ecx
6939    je       common_errDivideByZero
6940    cmpl     $0x80000000,%eax
6941    jne      .LOP_REM_INT_LIT8_continue_div
6942    cmpl     $-1,%ecx
6943    jne      .LOP_REM_INT_LIT8_continue_div
6944    movl     $0,rIBASE
6945    SET_VREG rIBASE rINST
6946    UNSPILL(rIBASE)
6947    FETCH_INST_OPCODE 2 %ecx
6948    ADVANCE_PC 2
6949    GOTO_NEXT_R %ecx
6950
6951.LOP_REM_INT_LIT8_continue_div:
6952    cltd
6953    idivl   %ecx
6954    SET_VREG rIBASE rINST
6955    UNSPILL(rIBASE)
6956    FETCH_INST_OPCODE 2 %ecx
6957    ADVANCE_PC 2
6958    GOTO_NEXT_R %ecx
6959
6960
6961/* ------------------------------ */
6962.L_OP_AND_INT_LIT8: /* 0xdd */
6963/* File: x86/OP_AND_INT_LIT8.S */
6964/* File: x86/binopLit8.S */
6965    /*
6966     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6967     * that specifies an instruction that performs "result = eax op ecx".
6968     * This could be an x86 instruction or a function call.  (If the result
6969     * comes back in a register other than r0, you can override "result".)
6970     *
6971     * For: add-int/lit8, rsub-int/lit8
6972     *      and-int/lit8, or-int/lit8, xor-int/lit8,
6973     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6974     */
6975    /* binop/lit8 vAA, vBB, #+CC */
6976    movzbl    2(rPC),%eax              # eax<- BB
6977    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
6978    GET_VREG_R   %eax %eax             # eax<- rBB
6979    andl %ecx,%eax                             # ex: addl %ecx,%eax
6980    SET_VREG   %eax rINST
6981    FETCH_INST_OPCODE 2 %ecx
6982    ADVANCE_PC 2
6983    GOTO_NEXT_R %ecx
6984
6985
6986/* ------------------------------ */
6987.L_OP_OR_INT_LIT8: /* 0xde */
6988/* File: x86/OP_OR_INT_LIT8.S */
6989/* File: x86/binopLit8.S */
6990    /*
6991     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6992     * that specifies an instruction that performs "result = eax op ecx".
6993     * This could be an x86 instruction or a function call.  (If the result
6994     * comes back in a register other than r0, you can override "result".)
6995     *
6996     * For: add-int/lit8, rsub-int/lit8
6997     *      and-int/lit8, or-int/lit8, xor-int/lit8,
6998     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6999     */
7000    /* binop/lit8 vAA, vBB, #+CC */
7001    movzbl    2(rPC),%eax              # eax<- BB
7002    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
7003    GET_VREG_R   %eax %eax             # eax<- rBB
7004    orl     %ecx,%eax                             # ex: addl %ecx,%eax
7005    SET_VREG   %eax rINST
7006    FETCH_INST_OPCODE 2 %ecx
7007    ADVANCE_PC 2
7008    GOTO_NEXT_R %ecx
7009
7010
7011/* ------------------------------ */
7012.L_OP_XOR_INT_LIT8: /* 0xdf */
7013/* File: x86/OP_XOR_INT_LIT8.S */
7014/* File: x86/binopLit8.S */
7015    /*
7016     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7017     * that specifies an instruction that performs "result = eax op ecx".
7018     * This could be an x86 instruction or a function call.  (If the result
7019     * comes back in a register other than r0, you can override "result".)
7020     *
7021     * For: add-int/lit8, rsub-int/lit8
7022     *      and-int/lit8, or-int/lit8, xor-int/lit8,
7023     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7024     */
7025    /* binop/lit8 vAA, vBB, #+CC */
7026    movzbl    2(rPC),%eax              # eax<- BB
7027    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
7028    GET_VREG_R   %eax %eax             # eax<- rBB
7029    xor    %ecx,%eax                             # ex: addl %ecx,%eax
7030    SET_VREG   %eax rINST
7031    FETCH_INST_OPCODE 2 %ecx
7032    ADVANCE_PC 2
7033    GOTO_NEXT_R %ecx
7034
7035
7036/* ------------------------------ */
7037.L_OP_SHL_INT_LIT8: /* 0xe0 */
7038/* File: x86/OP_SHL_INT_LIT8.S */
7039/* File: x86/binopLit8.S */
7040    /*
7041     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7042     * that specifies an instruction that performs "result = eax op ecx".
7043     * This could be an x86 instruction or a function call.  (If the result
7044     * comes back in a register other than r0, you can override "result".)
7045     *
7046     * For: add-int/lit8, rsub-int/lit8
7047     *      and-int/lit8, or-int/lit8, xor-int/lit8,
7048     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7049     */
7050    /* binop/lit8 vAA, vBB, #+CC */
7051    movzbl    2(rPC),%eax              # eax<- BB
7052    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
7053    GET_VREG_R   %eax %eax             # eax<- rBB
7054    sall  %cl,%eax                             # ex: addl %ecx,%eax
7055    SET_VREG   %eax rINST
7056    FETCH_INST_OPCODE 2 %ecx
7057    ADVANCE_PC 2
7058    GOTO_NEXT_R %ecx
7059
7060
7061/* ------------------------------ */
7062.L_OP_SHR_INT_LIT8: /* 0xe1 */
7063/* File: x86/OP_SHR_INT_LIT8.S */
7064/* File: x86/binopLit8.S */
7065    /*
7066     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7067     * that specifies an instruction that performs "result = eax op ecx".
7068     * This could be an x86 instruction or a function call.  (If the result
7069     * comes back in a register other than r0, you can override "result".)
7070     *
7071     * For: add-int/lit8, rsub-int/lit8
7072     *      and-int/lit8, or-int/lit8, xor-int/lit8,
7073     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7074     */
7075    /* binop/lit8 vAA, vBB, #+CC */
7076    movzbl    2(rPC),%eax              # eax<- BB
7077    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
7078    GET_VREG_R   %eax %eax             # eax<- rBB
7079    sarl    %cl,%eax                             # ex: addl %ecx,%eax
7080    SET_VREG   %eax rINST
7081    FETCH_INST_OPCODE 2 %ecx
7082    ADVANCE_PC 2
7083    GOTO_NEXT_R %ecx
7084
7085
7086/* ------------------------------ */
7087.L_OP_USHR_INT_LIT8: /* 0xe2 */
7088/* File: x86/OP_USHR_INT_LIT8.S */
7089/* File: x86/binopLit8.S */
7090    /*
7091     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7092     * that specifies an instruction that performs "result = eax op ecx".
7093     * This could be an x86 instruction or a function call.  (If the result
7094     * comes back in a register other than r0, you can override "result".)
7095     *
7096     * For: add-int/lit8, rsub-int/lit8
7097     *      and-int/lit8, or-int/lit8, xor-int/lit8,
7098     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7099     */
7100    /* binop/lit8 vAA, vBB, #+CC */
7101    movzbl    2(rPC),%eax              # eax<- BB
7102    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
7103    GET_VREG_R   %eax %eax             # eax<- rBB
7104    shrl     %cl,%eax                             # ex: addl %ecx,%eax
7105    SET_VREG   %eax rINST
7106    FETCH_INST_OPCODE 2 %ecx
7107    ADVANCE_PC 2
7108    GOTO_NEXT_R %ecx
7109
7110
7111/* ------------------------------ */
7112.L_OP_IGET_VOLATILE: /* 0xe3 */
7113/* File: x86/OP_IGET_VOLATILE.S */
7114/* File: x86/OP_IGET.S */
7115    /*
7116     * General 32-bit instance field get.
7117     *
7118     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7119     */
7120    /* op vA, vB, field@CCCC */
7121    movl    rSELF,%ecx
7122    SPILL(rIBASE)                               # preserve rIBASE
7123    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
7124    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
7125    movzbl  rINSTbl,%ecx                        # ecx<- BA
7126    sarl    $4,%ecx                            # ecx<- B
7127    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
7128    andb    $0xf,rINSTbl                       # rINST<- A
7129    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
7130    movl    (%eax,rIBASE,4),%eax                # resolved entry
7131    testl   %eax,%eax                           # is resolved entry null?
7132    jne     .LOP_IGET_VOLATILE_finish                  # no, already resolved
7133    movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
7134    movl    rSELF,rIBASE
7135    EXPORT_PC
7136    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
7137    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
7138    SPILL_TMP1(%ecx)                            # save obj pointer across call
7139    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
7140    call    dvmResolveInstField                 #  ... to dvmResolveInstField
7141    UNSPILL_TMP1(%ecx)
7142    testl   %eax,%eax                           #  returns InstrField ptr
7143    jne     .LOP_IGET_VOLATILE_finish
7144    jmp     common_exceptionThrown
7145
7146.LOP_IGET_VOLATILE_finish:
7147    /*
7148     * Currently:
7149     *   eax holds resolved field
7150     *   ecx holds object
7151     *   rINST holds A
7152     */
7153    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
7154    testl   %ecx,%ecx                           # object null?
7155    je      common_errNullObject                # object was null
7156    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
7157    FETCH_INST_OPCODE 2 %eax
7158    UNSPILL(rIBASE)
7159    SET_VREG %ecx rINST
7160    ADVANCE_PC 2
7161    GOTO_NEXT_R %eax
7162
7163
7164/* ------------------------------ */
7165.L_OP_IPUT_VOLATILE: /* 0xe4 */
7166/* File: x86/OP_IPUT_VOLATILE.S */
7167/* File: x86/OP_IPUT.S */
7168
7169    /*
7170     * General 32-bit instance field put.
7171     *
7172     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
7173     */
7174    /* op vA, vB, field@CCCC */
7175    movl    rSELF,%ecx
7176    SPILL   (rIBASE)
7177    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
7178    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
7179    movzbl  rINSTbl,%ecx                        # ecx<- BA
7180    sarl    $4,%ecx                            # ecx<- B
7181    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
7182    andb    $0xf,rINSTbl                       # rINST<- A
7183    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
7184    movl    (%eax,rIBASE,4),%eax                # resolved entry
7185    testl   %eax,%eax                           # is resolved entry null?
7186    jne     .LOP_IPUT_VOLATILE_finish                  # no, already resolved
7187    movl    rIBASE,OUT_ARG1(%esp)
7188    movl    rSELF,rIBASE
7189    EXPORT_PC
7190    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
7191    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
7192    SPILL_TMP1(%ecx)                            # save obj pointer across call
7193    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
7194    call    dvmResolveInstField                 #  ... to dvmResolveInstField
7195    UNSPILL_TMP1(%ecx)
7196    testl   %eax,%eax                           # returns InstrField ptr
7197    jne     .LOP_IPUT_VOLATILE_finish
7198    jmp     common_exceptionThrown
7199
7200.LOP_IPUT_VOLATILE_finish:
7201    /*
7202     * Currently:
7203     *   eax holds resolved field
7204     *   ecx holds object
7205     *   rINST holds A
7206     */
7207    GET_VREG_R rINST rINST                       # rINST<- v[A]
7208    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
7209    testl   %ecx,%ecx                            # object null?
7210    je      common_errNullObject                 # object was null
7211    movl   rINST,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
7212    FETCH_INST_OPCODE 2 %ecx
7213    UNSPILL(rIBASE)
7214    ADVANCE_PC 2
7215    GOTO_NEXT_R %ecx
7216
7217
7218/* ------------------------------ */
7219.L_OP_SGET_VOLATILE: /* 0xe5 */
7220/* File: x86/OP_SGET_VOLATILE.S */
7221/* File: x86/OP_SGET.S */
7222    /*
7223     * General 32-bit SGET handler.
7224     *
7225     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7226     */
7227    /* op vAA, field@BBBB */
7228    movl      rSELF,%ecx
7229    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
7230    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7231    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7232    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7233    testl     %eax,%eax                          # resolved entry null?
7234    je        .LOP_SGET_VOLATILE_resolve                # if not, make it so
7235.LOP_SGET_VOLATILE_finish:     # field ptr in eax
7236    movl      offStaticField_value(%eax),%eax
7237    FETCH_INST_OPCODE 2 %ecx
7238    ADVANCE_PC 2
7239    SET_VREG %eax rINST
7240    GOTO_NEXT_R %ecx
7241
7242    /*
7243     * Go resolve the field
7244     */
7245.LOP_SGET_VOLATILE_resolve:
7246    movl     rSELF,%ecx
7247    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
7248    movl     offThread_method(%ecx),%ecx          # ecx<- current method
7249    EXPORT_PC                                   # could throw, need to export
7250    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
7251    movl     %eax,OUT_ARG1(%esp)
7252    movl     %ecx,OUT_ARG0(%esp)
7253    SPILL(rIBASE)
7254    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
7255    UNSPILL(rIBASE)
7256    testl    %eax,%eax
7257    jne      .LOP_SGET_VOLATILE_finish                 # success, continue
7258    jmp      common_exceptionThrown             # no, handle exception
7259
7260
7261/* ------------------------------ */
7262.L_OP_SPUT_VOLATILE: /* 0xe6 */
7263/* File: x86/OP_SPUT_VOLATILE.S */
7264/* File: x86/OP_SPUT.S */
7265    /*
7266     * General 32-bit SPUT handler.
7267     *
7268     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
7269     */
7270    /* op vAA, field@BBBB */
7271    movl      rSELF,%ecx
7272    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
7273    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7274    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7275    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7276    testl     %eax,%eax                          # resolved entry null?
7277    je        .LOP_SPUT_VOLATILE_resolve                # if not, make it so
7278.LOP_SPUT_VOLATILE_finish:     # field ptr in eax
7279    GET_VREG_R  rINST rINST
7280    FETCH_INST_OPCODE 2 %ecx
7281    ADVANCE_PC 2
7282    movl      rINST,offStaticField_value(%eax)
7283    GOTO_NEXT_R %ecx
7284
7285    /*
7286     * Go resolve the field
7287     */
7288.LOP_SPUT_VOLATILE_resolve:
7289    movl     rSELF,%ecx
7290    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
7291    movl     offThread_method(%ecx),%ecx          # ecx<- current method
7292    EXPORT_PC                                   # could throw, need to export
7293    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
7294    movl     %eax,OUT_ARG1(%esp)
7295    movl     %ecx,OUT_ARG0(%esp)
7296    SPILL(rIBASE)
7297    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
7298    UNSPILL(rIBASE)
7299    testl    %eax,%eax
7300    jne      .LOP_SPUT_VOLATILE_finish                 # success, continue
7301    jmp      common_exceptionThrown             # no, handle exception
7302
7303
7304/* ------------------------------ */
7305.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
7306/* File: x86/OP_IGET_OBJECT_VOLATILE.S */
7307/* File: x86/OP_IGET.S */
7308    /*
7309     * General 32-bit instance field get.
7310     *
7311     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7312     */
7313    /* op vA, vB, field@CCCC */
7314    movl    rSELF,%ecx
7315    SPILL(rIBASE)                               # preserve rIBASE
7316    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
7317    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
7318    movzbl  rINSTbl,%ecx                        # ecx<- BA
7319    sarl    $4,%ecx                            # ecx<- B
7320    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
7321    andb    $0xf,rINSTbl                       # rINST<- A
7322    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
7323    movl    (%eax,rIBASE,4),%eax                # resolved entry
7324    testl   %eax,%eax                           # is resolved entry null?
7325    jne     .LOP_IGET_OBJECT_VOLATILE_finish                  # no, already resolved
7326    movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
7327    movl    rSELF,rIBASE
7328    EXPORT_PC
7329    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
7330    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
7331    SPILL_TMP1(%ecx)                            # save obj pointer across call
7332    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
7333    call    dvmResolveInstField                 #  ... to dvmResolveInstField
7334    UNSPILL_TMP1(%ecx)
7335    testl   %eax,%eax                           #  returns InstrField ptr
7336    jne     .LOP_IGET_OBJECT_VOLATILE_finish
7337    jmp     common_exceptionThrown
7338
7339.LOP_IGET_OBJECT_VOLATILE_finish:
7340    /*
7341     * Currently:
7342     *   eax holds resolved field
7343     *   ecx holds object
7344     *   rINST holds A
7345     */
7346    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
7347    testl   %ecx,%ecx                           # object null?
7348    je      common_errNullObject                # object was null
7349    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
7350    FETCH_INST_OPCODE 2 %eax
7351    UNSPILL(rIBASE)
7352    SET_VREG %ecx rINST
7353    ADVANCE_PC 2
7354    GOTO_NEXT_R %eax
7355
7356
7357/* ------------------------------ */
7358.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
7359    /* (stub) */
7360    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
7361    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
7362    call      dvmMterp_OP_IGET_WIDE_VOLATILE     # do the real work
7363    movl      rSELF,%ecx
7364    LOAD_PC_FP_FROM_SELF             # retrieve updated values
7365    movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
7366    FETCH_INST
7367    GOTO_NEXT
7368/* ------------------------------ */
7369.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
7370    /* (stub) */
7371    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
7372    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
7373    call      dvmMterp_OP_IPUT_WIDE_VOLATILE     # do the real work
7374    movl      rSELF,%ecx
7375    LOAD_PC_FP_FROM_SELF             # retrieve updated values
7376    movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
7377    FETCH_INST
7378    GOTO_NEXT
7379/* ------------------------------ */
7380.L_OP_SGET_WIDE_VOLATILE: /* 0xea */
7381    /* (stub) */
7382    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
7383    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
7384    call      dvmMterp_OP_SGET_WIDE_VOLATILE     # do the real work
7385    movl      rSELF,%ecx
7386    LOAD_PC_FP_FROM_SELF             # retrieve updated values
7387    movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
7388    FETCH_INST
7389    GOTO_NEXT
7390/* ------------------------------ */
7391.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
7392    /* (stub) */
7393    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
7394    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
7395    call      dvmMterp_OP_SPUT_WIDE_VOLATILE     # do the real work
7396    movl      rSELF,%ecx
7397    LOAD_PC_FP_FROM_SELF             # retrieve updated values
7398    movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
7399    FETCH_INST
7400    GOTO_NEXT
7401/* ------------------------------ */
7402.L_OP_BREAKPOINT: /* 0xec */
7403/* File: x86/OP_BREAKPOINT.S */
7404    /*
7405     * Breakpoint handler.
7406     *
7407     * Restart this instruction with the original opcode.  By
7408     * the time we get here, the breakpoint will have already been
7409     * handled.  We also assume that all other special "checkBefore"
7410     * actions have been handled, so we'll transition directly
7411     * to the real handler
7412     */
7413    SPILL(rIBASE)
7414    movl    rPC,OUT_ARG0(%esp)
7415    call    dvmGetOriginalOpcode
7416    UNSPILL(rIBASE)
7417    movl    rSELF,%ecx
7418    movzbl  1(rPC),rINST
7419    movl    offThread_mainHandlerTable(%ecx),%ecx
7420    jmp     *(%ecx,%eax,4)
7421
7422
7423/* ------------------------------ */
7424.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */
7425/* File: x86/OP_THROW_VERIFICATION_ERROR.S */
7426    /*
7427     * Handle a throw-verification-error instruction.  This throws an
7428     * exception for an error discovered during verification.  The
7429     * exception is indicated by AA, with some detail provided by BBBB.
7430     */
7431    /* op AA, ref@BBBB */
7432    movl     rSELF,%ecx
7433    movzwl   2(rPC),%eax                     # eax<- BBBB
7434    movl     offThread_method(%ecx),%ecx       # ecx<- self->method
7435    EXPORT_PC
7436    movl     %eax,OUT_ARG2(%esp)             # arg2<- BBBB
7437    movl     rINST,OUT_ARG1(%esp)            # arg1<- AA
7438    movl     %ecx,OUT_ARG0(%esp)             # arg0<- method
7439    call     dvmThrowVerificationError       # call(method, kind, ref)
7440    jmp      common_exceptionThrown          # handle exception
7441
7442/* ------------------------------ */
7443.L_OP_EXECUTE_INLINE: /* 0xee */
7444/* File: x86/OP_EXECUTE_INLINE.S */
7445    /*
7446     * Execute a "native inline" instruction.
7447     *
7448     * We will be calling through a function table:
7449     *
7450     * (*gDvmInlineOpsTable[opIndex].func)(arg0, arg1, arg2, arg3, pResult)
7451     *
7452     * Ignores argument count - always loads 4.
7453     *
7454     */
7455    /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */
7456    movl      rSELF,%ecx
7457    EXPORT_PC
7458    movzwl    2(rPC),%eax               # eax<- BBBB
7459    leal      offThread_retval(%ecx),%ecx # ecx<- & self->retval
7460    SPILL(rIBASE)                       # preserve rIBASE
7461    movl      %ecx,OUT_ARG4(%esp)
7462    call      .LOP_EXECUTE_INLINE_continue      # make call; will return after
7463    UNSPILL(rIBASE)                     # restore rIBASE
7464    testl     %eax,%eax                 # successful?
7465    FETCH_INST_OPCODE 3 %ecx
7466    je        common_exceptionThrown    # no, handle exception
7467    ADVANCE_PC 3
7468    GOTO_NEXT_R %ecx
7469
7470.LOP_EXECUTE_INLINE_continue:
7471    /*
7472     * Extract args, call function.
7473     *  ecx = #of args (0-4)
7474     *  eax = call index
7475     *  @esp = return addr
7476     *  esp is -4 from normal
7477     *
7478     *  Go ahead and load all 4 args, even if not used.
7479     */
7480    movzwl    4(rPC),rIBASE
7481
7482    movl      $0xf,%ecx
7483    andl      rIBASE,%ecx
7484    GET_VREG_R  %ecx %ecx
7485    sarl      $4,rIBASE
7486    movl      %ecx,4+OUT_ARG0(%esp)
7487
7488    movl      $0xf,%ecx
7489    andl      rIBASE,%ecx
7490    GET_VREG_R  %ecx %ecx
7491    sarl      $4,rIBASE
7492    movl      %ecx,4+OUT_ARG1(%esp)
7493
7494    movl      $0xf,%ecx
7495    andl      rIBASE,%ecx
7496    GET_VREG_R  %ecx %ecx
7497    sarl      $4,rIBASE
7498    movl      %ecx,4+OUT_ARG2(%esp)
7499
7500    movl      $0xf,%ecx
7501    andl      rIBASE,%ecx
7502    GET_VREG_R  %ecx %ecx
7503    sarl      $4,rIBASE
7504    movl      %ecx,4+OUT_ARG3(%esp)
7505
7506    sall      $4,%eax      # index *= sizeof(table entry)
7507    jmp       *gDvmInlineOpsTable(%eax)
7508    # will return to caller of .LOP_EXECUTE_INLINE_continue
7509
7510/* ------------------------------ */
7511.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */
7512    /* (stub) */
7513    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
7514    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
7515    call      dvmMterp_OP_EXECUTE_INLINE_RANGE     # do the real work
7516    movl      rSELF,%ecx
7517    LOAD_PC_FP_FROM_SELF             # retrieve updated values
7518    movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
7519    FETCH_INST
7520    GOTO_NEXT
7521/* ------------------------------ */
7522.L_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */
7523    /* (stub) */
7524    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
7525    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
7526    call      dvmMterp_OP_INVOKE_OBJECT_INIT_RANGE     # do the real work
7527    movl      rSELF,%ecx
7528    LOAD_PC_FP_FROM_SELF             # retrieve updated values
7529    movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
7530    FETCH_INST
7531    GOTO_NEXT
7532/* ------------------------------ */
7533.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */
7534    /* (stub) */
7535    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
7536    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
7537    call      dvmMterp_OP_RETURN_VOID_BARRIER     # do the real work
7538    movl      rSELF,%ecx
7539    LOAD_PC_FP_FROM_SELF             # retrieve updated values
7540    movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
7541    FETCH_INST
7542    GOTO_NEXT
7543/* ------------------------------ */
7544.L_OP_IGET_QUICK: /* 0xf2 */
7545/* File: x86/OP_IGET_QUICK.S */
7546    /* For: iget-quick, iget-object-quick */
7547    /* op vA, vB, offset@CCCC */
7548    movzbl    rINSTbl,%ecx              # ecx<- BA
7549    sarl      $4,%ecx                  # ecx<- B
7550    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
7551    movzwl    2(rPC),%eax               # eax<- field byte offset
7552    cmpl      $0,%ecx                  # is object null?
7553    je        common_errNullObject
7554    movl      (%ecx,%eax,1),%eax
7555    FETCH_INST_OPCODE 2 %ecx
7556    ADVANCE_PC 2
7557    andb      $0xf,rINSTbl             # rINST<- A
7558    SET_VREG  %eax rINST                # fp[A]<- result
7559    GOTO_NEXT_R %ecx
7560
7561/* ------------------------------ */
7562.L_OP_IGET_WIDE_QUICK: /* 0xf3 */
7563/* File: x86/OP_IGET_WIDE_QUICK.S */
7564    /* For: iget-wide-quick */
7565    /* op vA, vB, offset@CCCC */
7566    movzbl    rINSTbl,%ecx              # ecx<- BA
7567    sarl      $4,%ecx                  # ecx<- B
7568    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
7569    movzwl    2(rPC),%eax               # eax<- field byte offset
7570    cmpl      $0,%ecx                  # is object null?
7571    je        common_errNullObject
7572    leal      (%ecx,%eax,1),%eax        # eax<- address of 64-bit source
7573    movl      (%eax),%ecx               # ecx<- lsw
7574    movl      4(%eax),%eax              # eax<- msw
7575    andb      $0xf,rINSTbl             # rINST<- A
7576    SET_VREG_WORD %ecx rINST 0          # v[A+0]<- lsw
7577    FETCH_INST_OPCODE 2 %ecx
7578    SET_VREG_WORD %eax rINST 1          # v[A+1]<- msw
7579    ADVANCE_PC 2
7580    GOTO_NEXT_R %ecx
7581
7582/* ------------------------------ */
7583.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */
7584/* File: x86/OP_IGET_OBJECT_QUICK.S */
7585/* File: x86/OP_IGET_QUICK.S */
7586    /* For: iget-quick, iget-object-quick */
7587    /* op vA, vB, offset@CCCC */
7588    movzbl    rINSTbl,%ecx              # ecx<- BA
7589    sarl      $4,%ecx                  # ecx<- B
7590    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
7591    movzwl    2(rPC),%eax               # eax<- field byte offset
7592    cmpl      $0,%ecx                  # is object null?
7593    je        common_errNullObject
7594    movl      (%ecx,%eax,1),%eax
7595    FETCH_INST_OPCODE 2 %ecx
7596    ADVANCE_PC 2
7597    andb      $0xf,rINSTbl             # rINST<- A
7598    SET_VREG  %eax rINST                # fp[A]<- result
7599    GOTO_NEXT_R %ecx
7600
7601
7602/* ------------------------------ */
7603.L_OP_IPUT_QUICK: /* 0xf5 */
7604/* File: x86/OP_IPUT_QUICK.S */
7605    /* For: iput-quick */
7606    /* op vA, vB, offset@CCCC */
7607    movzbl    rINSTbl,%ecx              # ecx<- BA
7608    sarl      $4,%ecx                  # ecx<- B
7609    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
7610    andb      $0xf,rINSTbl             # rINST<- A
7611    GET_VREG_R  rINST,rINST             # rINST<- v[A]
7612    movzwl    2(rPC),%eax               # eax<- field byte offset
7613    testl     %ecx,%ecx                 # is object null?
7614    je        common_errNullObject
7615    movl      rINST,(%ecx,%eax,1)
7616    FETCH_INST_OPCODE 2 %ecx
7617    ADVANCE_PC 2
7618    GOTO_NEXT_R %ecx
7619
7620/* ------------------------------ */
7621.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */
7622/* File: x86/OP_IPUT_WIDE_QUICK.S */
7623    /* For: iput-wide-quick */
7624    /* op vA, vB, offset@CCCC */
7625    movzbl    rINSTbl,%ecx              # ecx<- BA
7626    sarl      $4,%ecx                  # ecx<- B
7627    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
7628    movzwl    2(rPC),%eax               # eax<- field byte offset
7629    testl      %ecx,%ecx                # is object null?
7630    je        common_errNullObject
7631    leal      (%ecx,%eax,1),%ecx        # ecx<- Address of 64-bit target
7632    andb      $0xf,rINSTbl             # rINST<- A
7633    GET_VREG_WORD %eax rINST 0          # eax<- lsw
7634    GET_VREG_WORD rINST rINST 1         # rINST<- msw
7635    movl      %eax,(%ecx)
7636    movl      rINST,4(%ecx)
7637    FETCH_INST_OPCODE 2 %ecx
7638    ADVANCE_PC 2
7639    GOTO_NEXT_R %ecx
7640
7641/* ------------------------------ */
7642.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
7643/* File: x86/OP_IPUT_OBJECT_QUICK.S */
7644    /* For: iput-object-quick */
7645    /* op vA, vB, offset@CCCC */
7646    movzbl    rINSTbl,%ecx              # ecx<- BA
7647    sarl      $4,%ecx                  # ecx<- B
7648    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
7649    andb      $0xf,rINSTbl             # rINST<- A
7650    GET_VREG_R  rINST rINST             # rINST<- v[A]
7651    movzwl    2(rPC),%eax               # eax<- field byte offset
7652    testl     %ecx,%ecx                 # is object null?
7653    je        common_errNullObject
7654    movl      rINST,(%ecx,%eax,1)
7655    movl      rSELF,%eax
7656    testl     rINST,rINST               # did we store null?
7657    movl      offThread_cardTable(%eax),%eax  # get card table base
7658    je        1f                            # skip card mark if null store
7659    shrl      $GC_CARD_SHIFT,%ecx          # object head to card number
7660    movb      %al,(%eax,%ecx)               # mark card based on object head
76611:
7662    FETCH_INST_OPCODE 2 %ecx
7663    ADVANCE_PC 2
7664    GOTO_NEXT_R %ecx
7665
7666/* ------------------------------ */
7667.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
7668/* File: x86/OP_INVOKE_VIRTUAL_QUICK.S */
7669    /*
7670     * Handle an optimized virtual method call.
7671     *
7672     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7673     */
7674    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7675    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7676    movzwl    4(rPC),%eax               # eax<- FEDC or CCCC
7677    movzwl    2(rPC),%ecx               # ecx<- BBBB
7678    .if     (!0)
7679    andl      $0xf,%eax                # eax<- C (or stays CCCC)
7680    .endif
7681    GET_VREG_R  %eax %eax               # eax<- vC ("this" ptr)
7682    testl     %eax,%eax                 # null?
7683    je        common_errNullObject      # yep, throw exception
7684    movl      offObject_clazz(%eax),%eax # eax<- thisPtr->clazz
7685    movl      offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable
7686    EXPORT_PC                           # might throw later - get ready
7687    movl      (%eax,%ecx,4),%eax        # eax<- vtable[BBBB]
7688    jmp       common_invokeMethodNoRange
7689
7690/* ------------------------------ */
7691.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
7692/* File: x86/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */
7693/* File: x86/OP_INVOKE_VIRTUAL_QUICK.S */
7694    /*
7695     * Handle an optimized virtual method call.
7696     *
7697     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7698     */
7699    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7700    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7701    movzwl    4(rPC),%eax               # eax<- FEDC or CCCC
7702    movzwl    2(rPC),%ecx               # ecx<- BBBB
7703    .if     (!1)
7704    andl      $0xf,%eax                # eax<- C (or stays CCCC)
7705    .endif
7706    GET_VREG_R  %eax %eax               # eax<- vC ("this" ptr)
7707    testl     %eax,%eax                 # null?
7708    je        common_errNullObject      # yep, throw exception
7709    movl      offObject_clazz(%eax),%eax # eax<- thisPtr->clazz
7710    movl      offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable
7711    EXPORT_PC                           # might throw later - get ready
7712    movl      (%eax,%ecx,4),%eax        # eax<- vtable[BBBB]
7713    jmp       common_invokeMethodRange
7714
7715
7716/* ------------------------------ */
7717.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */
7718/* File: x86/OP_INVOKE_SUPER_QUICK.S */
7719    /*
7720     * Handle an optimized "super" method call.
7721     *
7722     * for: [opt] invoke-super-quick, invoke-super-quick/range
7723     */
7724    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7725    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7726    movl      rSELF,%ecx
7727    movzwl    4(rPC),%eax               # eax<- GFED or CCCC
7728    movl      offThread_method(%ecx),%ecx # ecx<- current method
7729    .if       (!0)
7730    andl      $0xf,%eax                # eax<- D (or stays CCCC)
7731    .endif
7732    movl      offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
7733    GET_VREG_R  %eax %eax               # eax<- "this"
7734    movl      offClassObject_super(%ecx),%ecx # ecx<- method->clazz->super
7735    testl     %eax,%eax                 # null "this"?
7736    je        common_errNullObject      # "this" is null, throw exception
7737    movzwl    2(rPC),%eax               # eax<- BBBB
7738    movl      offClassObject_vtable(%ecx),%ecx # ecx<- vtable
7739    EXPORT_PC
7740    movl      (%ecx,%eax,4),%eax        # eax<- super->vtable[BBBB]
7741    jmp       common_invokeMethodNoRange
7742
7743/* ------------------------------ */
7744.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
7745/* File: x86/OP_INVOKE_SUPER_QUICK_RANGE.S */
7746/* File: x86/OP_INVOKE_SUPER_QUICK.S */
7747    /*
7748     * Handle an optimized "super" method call.
7749     *
7750     * for: [opt] invoke-super-quick, invoke-super-quick/range
7751     */
7752    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7753    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7754    movl      rSELF,%ecx
7755    movzwl    4(rPC),%eax               # eax<- GFED or CCCC
7756    movl      offThread_method(%ecx),%ecx # ecx<- current method
7757    .if       (!1)
7758    andl      $0xf,%eax                # eax<- D (or stays CCCC)
7759    .endif
7760    movl      offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
7761    GET_VREG_R  %eax %eax               # eax<- "this"
7762    movl      offClassObject_super(%ecx),%ecx # ecx<- method->clazz->super
7763    testl     %eax,%eax                 # null "this"?
7764    je        common_errNullObject      # "this" is null, throw exception
7765    movzwl    2(rPC),%eax               # eax<- BBBB
7766    movl      offClassObject_vtable(%ecx),%ecx # ecx<- vtable
7767    EXPORT_PC
7768    movl      (%ecx,%eax,4),%eax        # eax<- super->vtable[BBBB]
7769    jmp       common_invokeMethodRange
7770
7771
7772/* ------------------------------ */
7773.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
7774/* File: x86/OP_IPUT_OBJECT_VOLATILE.S */
7775/* File: x86/OP_IPUT_OBJECT.S */
7776    /*
7777     * Object field put.
7778     *
7779     * for: iput-object
7780     */
7781    /* op vA, vB, field@CCCC */
7782    movl    rSELF,%ecx
7783    SPILL(rIBASE)
7784    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
7785    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
7786    movzbl  rINSTbl,%ecx                        # ecx<- BA
7787    sarl    $4,%ecx                            # ecx<- B
7788    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
7789    andb    $0xf,rINSTbl                       # rINST<- A
7790    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
7791    movl    (%eax,rIBASE,4),%eax                  # resolved entry
7792    testl   %eax,%eax                           # is resolved entry null?
7793    jne     .LOP_IPUT_OBJECT_VOLATILE_finish                  # no, already resolved
7794    movl    rIBASE,OUT_ARG1(%esp)
7795    movl    rSELF,rIBASE
7796    EXPORT_PC
7797    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
7798    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
7799    SPILL_TMP1(%ecx)                            # save obj pointer across call
7800    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
7801    call    dvmResolveInstField                 #  ... to dvmResolveInstField
7802    UNSPILL_TMP1(%ecx)
7803    testl   %eax,%eax                           # returns InstrField ptr
7804    jne     .LOP_IPUT_OBJECT_VOLATILE_finish
7805    jmp     common_exceptionThrown
7806
7807.LOP_IPUT_OBJECT_VOLATILE_finish:
7808    /*
7809     * Currently:
7810     *   eax holds resolved field
7811     *   ecx holds object
7812     *   rIBASE is scratch, but needs to be unspilled
7813     *   rINST holds A
7814     */
7815    GET_VREG_R rINST rINST                      # rINST<- v[A]
7816    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
7817    testl   %ecx,%ecx                           # object null?
7818    je      common_errNullObject                # object was null
7819    movl    rINST,(%ecx,%eax)      # obj.field <- v[A](8/16/32 bits)
7820    movl    rSELF,%eax
7821    testl   rINST,rINST                         # stored a NULL?
7822    movl    offThread_cardTable(%eax),%eax      # get card table base
7823    je      1f                                  # skip card mark if null store
7824    shrl    $GC_CARD_SHIFT,%ecx                # object head to card number
7825    movb    %al,(%eax,%ecx)                     # mark card using object head
78261:
7827    UNSPILL(rIBASE)
7828    FETCH_INST_OPCODE 2 %ecx
7829    ADVANCE_PC 2
7830    GOTO_NEXT_R %ecx
7831
7832
7833/* ------------------------------ */
7834.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
7835/* File: x86/OP_SGET_OBJECT_VOLATILE.S */
7836/* File: x86/OP_SGET.S */
7837    /*
7838     * General 32-bit SGET handler.
7839     *
7840     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7841     */
7842    /* op vAA, field@BBBB */
7843    movl      rSELF,%ecx
7844    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
7845    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7846    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7847    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7848    testl     %eax,%eax                          # resolved entry null?
7849    je        .LOP_SGET_OBJECT_VOLATILE_resolve                # if not, make it so
7850.LOP_SGET_OBJECT_VOLATILE_finish:     # field ptr in eax
7851    movl      offStaticField_value(%eax),%eax
7852    FETCH_INST_OPCODE 2 %ecx
7853    ADVANCE_PC 2
7854    SET_VREG %eax rINST
7855    GOTO_NEXT_R %ecx
7856
7857    /*
7858     * Go resolve the field
7859     */
7860.LOP_SGET_OBJECT_VOLATILE_resolve:
7861    movl     rSELF,%ecx
7862    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
7863    movl     offThread_method(%ecx),%ecx          # ecx<- current method
7864    EXPORT_PC                                   # could throw, need to export
7865    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
7866    movl     %eax,OUT_ARG1(%esp)
7867    movl     %ecx,OUT_ARG0(%esp)
7868    SPILL(rIBASE)
7869    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
7870    UNSPILL(rIBASE)
7871    testl    %eax,%eax
7872    jne      .LOP_SGET_OBJECT_VOLATILE_finish                 # success, continue
7873    jmp      common_exceptionThrown             # no, handle exception
7874
7875
7876/* ------------------------------ */
7877.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
7878/* File: x86/OP_SPUT_OBJECT_VOLATILE.S */
7879/* File: x86/OP_SPUT_OBJECT.S */
7880    /*
7881     * SPUT object handler.
7882     */
7883    /* op vAA, field@BBBB */
7884    movl      rSELF,%ecx
7885    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
7886    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7887    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7888    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField
7889    testl     %eax,%eax                          # resolved entry null?
7890    je        .LOP_SPUT_OBJECT_VOLATILE_resolve                # if not, make it so
7891.LOP_SPUT_OBJECT_VOLATILE_finish:                              # field ptr in eax
7892    movzbl    rINSTbl,%ecx                       # ecx<- AA
7893    GET_VREG_R  %ecx %ecx
7894    movl      %ecx,offStaticField_value(%eax)    # do the store
7895    testl     %ecx,%ecx                          # stored null object ptr?
7896    je        1f                                 # skip card mark if null
7897    movl      rSELF,%ecx
7898    movl      offField_clazz(%eax),%eax          # eax<- method->clazz
7899    movl      offThread_cardTable(%ecx),%ecx       # get card table base
7900    shrl      $GC_CARD_SHIFT,%eax               # head to card number
7901    movb      %cl,(%ecx,%eax)                    # mark card
79021:
7903    FETCH_INST_OPCODE 2 %ecx
7904    ADVANCE_PC 2
7905    GOTO_NEXT_R %ecx
7906
7907.LOP_SPUT_OBJECT_VOLATILE_resolve:
7908    movl     rSELF,%ecx
7909    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
7910    movl     offThread_method(%ecx),%ecx          # ecx<- current method
7911    EXPORT_PC                                   # could throw, need to export
7912    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
7913    movl     %eax,OUT_ARG1(%esp)
7914    movl     %ecx,OUT_ARG0(%esp)
7915    SPILL(rIBASE)
7916    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
7917    UNSPILL(rIBASE)
7918    testl    %eax,%eax
7919    jne      .LOP_SPUT_OBJECT_VOLATILE_finish                 # success, continue
7920    jmp      common_exceptionThrown             # no, handle exception
7921
7922
7923/* ------------------------------ */
7924.L_OP_UNUSED_FF: /* 0xff */
7925/* File: x86/OP_UNUSED_FF.S */
7926/* File: x86/unused.S */
7927    jmp     common_abort
7928
7929
7930    .size   dvmAsmInstructionStartCode, .-dvmAsmInstructionStartCode
7931    .global dvmAsmInstructionEndCode
7932dvmAsmInstructionEndCode:
7933
7934    .global dvmAsmAltInstructionStartCode
7935    .type   dvmAsmAltInstructionStartCode, %function
7936    .text
7937
7938dvmAsmAltInstructionStartCode = .L_ALT_OP_NOP
7939/* ------------------------------ */
7940.L_ALT_OP_NOP: /* 0x00 */
7941/* File: x86/alt_stub.S */
7942/*
7943 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
7944 * any interesting requests and then jump to the real instruction
7945 * handler.  Unlike the Arm handler, we can't do this as a tail call
7946 * because rIBASE is caller save and we need to reload it.
7947 *
7948 * Note that unlike in the Arm implementation, we should never arrive
7949 * here with a zero breakFlag because we always refresh rIBASE on
7950 * return.
7951 */
7952    EXPORT_PC
7953    movl   rSELF, %eax
7954    movl   rPC, OUT_ARG0(%esp)
7955    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
7956    movl   rFP, OUT_ARG1(%esp)
7957    je     1f                                # reload rIBASE & resume if not
7958    movl   %eax, OUT_ARG2(%esp)
7959    call   dvmCheckBefore                    # (dPC, dFP, self)
7960    movl   rSELF, %eax
79611:
7962    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
7963    jmp    *dvmAsmInstructionStart+(0*4)
7964
7965/* ------------------------------ */
7966.L_ALT_OP_MOVE: /* 0x01 */
7967/* File: x86/alt_stub.S */
7968/*
7969 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
7970 * any interesting requests and then jump to the real instruction
7971 * handler.  Unlike the Arm handler, we can't do this as a tail call
7972 * because rIBASE is caller save and we need to reload it.
7973 *
7974 * Note that unlike in the Arm implementation, we should never arrive
7975 * here with a zero breakFlag because we always refresh rIBASE on
7976 * return.
7977 */
7978    EXPORT_PC
7979    movl   rSELF, %eax
7980    movl   rPC, OUT_ARG0(%esp)
7981    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
7982    movl   rFP, OUT_ARG1(%esp)
7983    je     1f                                # reload rIBASE & resume if not
7984    movl   %eax, OUT_ARG2(%esp)
7985    call   dvmCheckBefore                    # (dPC, dFP, self)
7986    movl   rSELF, %eax
79871:
7988    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
7989    jmp    *dvmAsmInstructionStart+(1*4)
7990
7991/* ------------------------------ */
7992.L_ALT_OP_MOVE_FROM16: /* 0x02 */
7993/* File: x86/alt_stub.S */
7994/*
7995 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
7996 * any interesting requests and then jump to the real instruction
7997 * handler.  Unlike the Arm handler, we can't do this as a tail call
7998 * because rIBASE is caller save and we need to reload it.
7999 *
8000 * Note that unlike in the Arm implementation, we should never arrive
8001 * here with a zero breakFlag because we always refresh rIBASE on
8002 * return.
8003 */
8004    EXPORT_PC
8005    movl   rSELF, %eax
8006    movl   rPC, OUT_ARG0(%esp)
8007    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8008    movl   rFP, OUT_ARG1(%esp)
8009    je     1f                                # reload rIBASE & resume if not
8010    movl   %eax, OUT_ARG2(%esp)
8011    call   dvmCheckBefore                    # (dPC, dFP, self)
8012    movl   rSELF, %eax
80131:
8014    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8015    jmp    *dvmAsmInstructionStart+(2*4)
8016
8017/* ------------------------------ */
8018.L_ALT_OP_MOVE_16: /* 0x03 */
8019/* File: x86/alt_stub.S */
8020/*
8021 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8022 * any interesting requests and then jump to the real instruction
8023 * handler.  Unlike the Arm handler, we can't do this as a tail call
8024 * because rIBASE is caller save and we need to reload it.
8025 *
8026 * Note that unlike in the Arm implementation, we should never arrive
8027 * here with a zero breakFlag because we always refresh rIBASE on
8028 * return.
8029 */
8030    EXPORT_PC
8031    movl   rSELF, %eax
8032    movl   rPC, OUT_ARG0(%esp)
8033    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8034    movl   rFP, OUT_ARG1(%esp)
8035    je     1f                                # reload rIBASE & resume if not
8036    movl   %eax, OUT_ARG2(%esp)
8037    call   dvmCheckBefore                    # (dPC, dFP, self)
8038    movl   rSELF, %eax
80391:
8040    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8041    jmp    *dvmAsmInstructionStart+(3*4)
8042
8043/* ------------------------------ */
8044.L_ALT_OP_MOVE_WIDE: /* 0x04 */
8045/* File: x86/alt_stub.S */
8046/*
8047 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8048 * any interesting requests and then jump to the real instruction
8049 * handler.  Unlike the Arm handler, we can't do this as a tail call
8050 * because rIBASE is caller save and we need to reload it.
8051 *
8052 * Note that unlike in the Arm implementation, we should never arrive
8053 * here with a zero breakFlag because we always refresh rIBASE on
8054 * return.
8055 */
8056    EXPORT_PC
8057    movl   rSELF, %eax
8058    movl   rPC, OUT_ARG0(%esp)
8059    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8060    movl   rFP, OUT_ARG1(%esp)
8061    je     1f                                # reload rIBASE & resume if not
8062    movl   %eax, OUT_ARG2(%esp)
8063    call   dvmCheckBefore                    # (dPC, dFP, self)
8064    movl   rSELF, %eax
80651:
8066    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8067    jmp    *dvmAsmInstructionStart+(4*4)
8068
8069/* ------------------------------ */
8070.L_ALT_OP_MOVE_WIDE_FROM16: /* 0x05 */
8071/* File: x86/alt_stub.S */
8072/*
8073 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8074 * any interesting requests and then jump to the real instruction
8075 * handler.  Unlike the Arm handler, we can't do this as a tail call
8076 * because rIBASE is caller save and we need to reload it.
8077 *
8078 * Note that unlike in the Arm implementation, we should never arrive
8079 * here with a zero breakFlag because we always refresh rIBASE on
8080 * return.
8081 */
8082    EXPORT_PC
8083    movl   rSELF, %eax
8084    movl   rPC, OUT_ARG0(%esp)
8085    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8086    movl   rFP, OUT_ARG1(%esp)
8087    je     1f                                # reload rIBASE & resume if not
8088    movl   %eax, OUT_ARG2(%esp)
8089    call   dvmCheckBefore                    # (dPC, dFP, self)
8090    movl   rSELF, %eax
80911:
8092    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8093    jmp    *dvmAsmInstructionStart+(5*4)
8094
8095/* ------------------------------ */
8096.L_ALT_OP_MOVE_WIDE_16: /* 0x06 */
8097/* File: x86/alt_stub.S */
8098/*
8099 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8100 * any interesting requests and then jump to the real instruction
8101 * handler.  Unlike the Arm handler, we can't do this as a tail call
8102 * because rIBASE is caller save and we need to reload it.
8103 *
8104 * Note that unlike in the Arm implementation, we should never arrive
8105 * here with a zero breakFlag because we always refresh rIBASE on
8106 * return.
8107 */
8108    EXPORT_PC
8109    movl   rSELF, %eax
8110    movl   rPC, OUT_ARG0(%esp)
8111    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8112    movl   rFP, OUT_ARG1(%esp)
8113    je     1f                                # reload rIBASE & resume if not
8114    movl   %eax, OUT_ARG2(%esp)
8115    call   dvmCheckBefore                    # (dPC, dFP, self)
8116    movl   rSELF, %eax
81171:
8118    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8119    jmp    *dvmAsmInstructionStart+(6*4)
8120
8121/* ------------------------------ */
8122.L_ALT_OP_MOVE_OBJECT: /* 0x07 */
8123/* File: x86/alt_stub.S */
8124/*
8125 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8126 * any interesting requests and then jump to the real instruction
8127 * handler.  Unlike the Arm handler, we can't do this as a tail call
8128 * because rIBASE is caller save and we need to reload it.
8129 *
8130 * Note that unlike in the Arm implementation, we should never arrive
8131 * here with a zero breakFlag because we always refresh rIBASE on
8132 * return.
8133 */
8134    EXPORT_PC
8135    movl   rSELF, %eax
8136    movl   rPC, OUT_ARG0(%esp)
8137    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8138    movl   rFP, OUT_ARG1(%esp)
8139    je     1f                                # reload rIBASE & resume if not
8140    movl   %eax, OUT_ARG2(%esp)
8141    call   dvmCheckBefore                    # (dPC, dFP, self)
8142    movl   rSELF, %eax
81431:
8144    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8145    jmp    *dvmAsmInstructionStart+(7*4)
8146
8147/* ------------------------------ */
8148.L_ALT_OP_MOVE_OBJECT_FROM16: /* 0x08 */
8149/* File: x86/alt_stub.S */
8150/*
8151 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8152 * any interesting requests and then jump to the real instruction
8153 * handler.  Unlike the Arm handler, we can't do this as a tail call
8154 * because rIBASE is caller save and we need to reload it.
8155 *
8156 * Note that unlike in the Arm implementation, we should never arrive
8157 * here with a zero breakFlag because we always refresh rIBASE on
8158 * return.
8159 */
8160    EXPORT_PC
8161    movl   rSELF, %eax
8162    movl   rPC, OUT_ARG0(%esp)
8163    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8164    movl   rFP, OUT_ARG1(%esp)
8165    je     1f                                # reload rIBASE & resume if not
8166    movl   %eax, OUT_ARG2(%esp)
8167    call   dvmCheckBefore                    # (dPC, dFP, self)
8168    movl   rSELF, %eax
81691:
8170    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8171    jmp    *dvmAsmInstructionStart+(8*4)
8172
8173/* ------------------------------ */
8174.L_ALT_OP_MOVE_OBJECT_16: /* 0x09 */
8175/* File: x86/alt_stub.S */
8176/*
8177 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8178 * any interesting requests and then jump to the real instruction
8179 * handler.  Unlike the Arm handler, we can't do this as a tail call
8180 * because rIBASE is caller save and we need to reload it.
8181 *
8182 * Note that unlike in the Arm implementation, we should never arrive
8183 * here with a zero breakFlag because we always refresh rIBASE on
8184 * return.
8185 */
8186    EXPORT_PC
8187    movl   rSELF, %eax
8188    movl   rPC, OUT_ARG0(%esp)
8189    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8190    movl   rFP, OUT_ARG1(%esp)
8191    je     1f                                # reload rIBASE & resume if not
8192    movl   %eax, OUT_ARG2(%esp)
8193    call   dvmCheckBefore                    # (dPC, dFP, self)
8194    movl   rSELF, %eax
81951:
8196    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8197    jmp    *dvmAsmInstructionStart+(9*4)
8198
8199/* ------------------------------ */
8200.L_ALT_OP_MOVE_RESULT: /* 0x0a */
8201/* File: x86/alt_stub.S */
8202/*
8203 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8204 * any interesting requests and then jump to the real instruction
8205 * handler.  Unlike the Arm handler, we can't do this as a tail call
8206 * because rIBASE is caller save and we need to reload it.
8207 *
8208 * Note that unlike in the Arm implementation, we should never arrive
8209 * here with a zero breakFlag because we always refresh rIBASE on
8210 * return.
8211 */
8212    EXPORT_PC
8213    movl   rSELF, %eax
8214    movl   rPC, OUT_ARG0(%esp)
8215    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8216    movl   rFP, OUT_ARG1(%esp)
8217    je     1f                                # reload rIBASE & resume if not
8218    movl   %eax, OUT_ARG2(%esp)
8219    call   dvmCheckBefore                    # (dPC, dFP, self)
8220    movl   rSELF, %eax
82211:
8222    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8223    jmp    *dvmAsmInstructionStart+(10*4)
8224
8225/* ------------------------------ */
8226.L_ALT_OP_MOVE_RESULT_WIDE: /* 0x0b */
8227/* File: x86/alt_stub.S */
8228/*
8229 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8230 * any interesting requests and then jump to the real instruction
8231 * handler.  Unlike the Arm handler, we can't do this as a tail call
8232 * because rIBASE is caller save and we need to reload it.
8233 *
8234 * Note that unlike in the Arm implementation, we should never arrive
8235 * here with a zero breakFlag because we always refresh rIBASE on
8236 * return.
8237 */
8238    EXPORT_PC
8239    movl   rSELF, %eax
8240    movl   rPC, OUT_ARG0(%esp)
8241    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8242    movl   rFP, OUT_ARG1(%esp)
8243    je     1f                                # reload rIBASE & resume if not
8244    movl   %eax, OUT_ARG2(%esp)
8245    call   dvmCheckBefore                    # (dPC, dFP, self)
8246    movl   rSELF, %eax
82471:
8248    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8249    jmp    *dvmAsmInstructionStart+(11*4)
8250
8251/* ------------------------------ */
8252.L_ALT_OP_MOVE_RESULT_OBJECT: /* 0x0c */
8253/* File: x86/alt_stub.S */
8254/*
8255 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8256 * any interesting requests and then jump to the real instruction
8257 * handler.  Unlike the Arm handler, we can't do this as a tail call
8258 * because rIBASE is caller save and we need to reload it.
8259 *
8260 * Note that unlike in the Arm implementation, we should never arrive
8261 * here with a zero breakFlag because we always refresh rIBASE on
8262 * return.
8263 */
8264    EXPORT_PC
8265    movl   rSELF, %eax
8266    movl   rPC, OUT_ARG0(%esp)
8267    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8268    movl   rFP, OUT_ARG1(%esp)
8269    je     1f                                # reload rIBASE & resume if not
8270    movl   %eax, OUT_ARG2(%esp)
8271    call   dvmCheckBefore                    # (dPC, dFP, self)
8272    movl   rSELF, %eax
82731:
8274    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8275    jmp    *dvmAsmInstructionStart+(12*4)
8276
8277/* ------------------------------ */
8278.L_ALT_OP_MOVE_EXCEPTION: /* 0x0d */
8279/* File: x86/alt_stub.S */
8280/*
8281 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8282 * any interesting requests and then jump to the real instruction
8283 * handler.  Unlike the Arm handler, we can't do this as a tail call
8284 * because rIBASE is caller save and we need to reload it.
8285 *
8286 * Note that unlike in the Arm implementation, we should never arrive
8287 * here with a zero breakFlag because we always refresh rIBASE on
8288 * return.
8289 */
8290    EXPORT_PC
8291    movl   rSELF, %eax
8292    movl   rPC, OUT_ARG0(%esp)
8293    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8294    movl   rFP, OUT_ARG1(%esp)
8295    je     1f                                # reload rIBASE & resume if not
8296    movl   %eax, OUT_ARG2(%esp)
8297    call   dvmCheckBefore                    # (dPC, dFP, self)
8298    movl   rSELF, %eax
82991:
8300    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8301    jmp    *dvmAsmInstructionStart+(13*4)
8302
8303/* ------------------------------ */
8304.L_ALT_OP_RETURN_VOID: /* 0x0e */
8305/* File: x86/alt_stub.S */
8306/*
8307 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8308 * any interesting requests and then jump to the real instruction
8309 * handler.  Unlike the Arm handler, we can't do this as a tail call
8310 * because rIBASE is caller save and we need to reload it.
8311 *
8312 * Note that unlike in the Arm implementation, we should never arrive
8313 * here with a zero breakFlag because we always refresh rIBASE on
8314 * return.
8315 */
8316    EXPORT_PC
8317    movl   rSELF, %eax
8318    movl   rPC, OUT_ARG0(%esp)
8319    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8320    movl   rFP, OUT_ARG1(%esp)
8321    je     1f                                # reload rIBASE & resume if not
8322    movl   %eax, OUT_ARG2(%esp)
8323    call   dvmCheckBefore                    # (dPC, dFP, self)
8324    movl   rSELF, %eax
83251:
8326    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8327    jmp    *dvmAsmInstructionStart+(14*4)
8328
8329/* ------------------------------ */
8330.L_ALT_OP_RETURN: /* 0x0f */
8331/* File: x86/alt_stub.S */
8332/*
8333 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8334 * any interesting requests and then jump to the real instruction
8335 * handler.  Unlike the Arm handler, we can't do this as a tail call
8336 * because rIBASE is caller save and we need to reload it.
8337 *
8338 * Note that unlike in the Arm implementation, we should never arrive
8339 * here with a zero breakFlag because we always refresh rIBASE on
8340 * return.
8341 */
8342    EXPORT_PC
8343    movl   rSELF, %eax
8344    movl   rPC, OUT_ARG0(%esp)
8345    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8346    movl   rFP, OUT_ARG1(%esp)
8347    je     1f                                # reload rIBASE & resume if not
8348    movl   %eax, OUT_ARG2(%esp)
8349    call   dvmCheckBefore                    # (dPC, dFP, self)
8350    movl   rSELF, %eax
83511:
8352    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8353    jmp    *dvmAsmInstructionStart+(15*4)
8354
8355/* ------------------------------ */
8356.L_ALT_OP_RETURN_WIDE: /* 0x10 */
8357/* File: x86/alt_stub.S */
8358/*
8359 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8360 * any interesting requests and then jump to the real instruction
8361 * handler.  Unlike the Arm handler, we can't do this as a tail call
8362 * because rIBASE is caller save and we need to reload it.
8363 *
8364 * Note that unlike in the Arm implementation, we should never arrive
8365 * here with a zero breakFlag because we always refresh rIBASE on
8366 * return.
8367 */
8368    EXPORT_PC
8369    movl   rSELF, %eax
8370    movl   rPC, OUT_ARG0(%esp)
8371    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8372    movl   rFP, OUT_ARG1(%esp)
8373    je     1f                                # reload rIBASE & resume if not
8374    movl   %eax, OUT_ARG2(%esp)
8375    call   dvmCheckBefore                    # (dPC, dFP, self)
8376    movl   rSELF, %eax
83771:
8378    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8379    jmp    *dvmAsmInstructionStart+(16*4)
8380
8381/* ------------------------------ */
8382.L_ALT_OP_RETURN_OBJECT: /* 0x11 */
8383/* File: x86/alt_stub.S */
8384/*
8385 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8386 * any interesting requests and then jump to the real instruction
8387 * handler.  Unlike the Arm handler, we can't do this as a tail call
8388 * because rIBASE is caller save and we need to reload it.
8389 *
8390 * Note that unlike in the Arm implementation, we should never arrive
8391 * here with a zero breakFlag because we always refresh rIBASE on
8392 * return.
8393 */
8394    EXPORT_PC
8395    movl   rSELF, %eax
8396    movl   rPC, OUT_ARG0(%esp)
8397    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8398    movl   rFP, OUT_ARG1(%esp)
8399    je     1f                                # reload rIBASE & resume if not
8400    movl   %eax, OUT_ARG2(%esp)
8401    call   dvmCheckBefore                    # (dPC, dFP, self)
8402    movl   rSELF, %eax
84031:
8404    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8405    jmp    *dvmAsmInstructionStart+(17*4)
8406
8407/* ------------------------------ */
8408.L_ALT_OP_CONST_4: /* 0x12 */
8409/* File: x86/alt_stub.S */
8410/*
8411 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8412 * any interesting requests and then jump to the real instruction
8413 * handler.  Unlike the Arm handler, we can't do this as a tail call
8414 * because rIBASE is caller save and we need to reload it.
8415 *
8416 * Note that unlike in the Arm implementation, we should never arrive
8417 * here with a zero breakFlag because we always refresh rIBASE on
8418 * return.
8419 */
8420    EXPORT_PC
8421    movl   rSELF, %eax
8422    movl   rPC, OUT_ARG0(%esp)
8423    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8424    movl   rFP, OUT_ARG1(%esp)
8425    je     1f                                # reload rIBASE & resume if not
8426    movl   %eax, OUT_ARG2(%esp)
8427    call   dvmCheckBefore                    # (dPC, dFP, self)
8428    movl   rSELF, %eax
84291:
8430    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8431    jmp    *dvmAsmInstructionStart+(18*4)
8432
8433/* ------------------------------ */
8434.L_ALT_OP_CONST_16: /* 0x13 */
8435/* File: x86/alt_stub.S */
8436/*
8437 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8438 * any interesting requests and then jump to the real instruction
8439 * handler.  Unlike the Arm handler, we can't do this as a tail call
8440 * because rIBASE is caller save and we need to reload it.
8441 *
8442 * Note that unlike in the Arm implementation, we should never arrive
8443 * here with a zero breakFlag because we always refresh rIBASE on
8444 * return.
8445 */
8446    EXPORT_PC
8447    movl   rSELF, %eax
8448    movl   rPC, OUT_ARG0(%esp)
8449    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8450    movl   rFP, OUT_ARG1(%esp)
8451    je     1f                                # reload rIBASE & resume if not
8452    movl   %eax, OUT_ARG2(%esp)
8453    call   dvmCheckBefore                    # (dPC, dFP, self)
8454    movl   rSELF, %eax
84551:
8456    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8457    jmp    *dvmAsmInstructionStart+(19*4)
8458
8459/* ------------------------------ */
8460.L_ALT_OP_CONST: /* 0x14 */
8461/* File: x86/alt_stub.S */
8462/*
8463 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8464 * any interesting requests and then jump to the real instruction
8465 * handler.  Unlike the Arm handler, we can't do this as a tail call
8466 * because rIBASE is caller save and we need to reload it.
8467 *
8468 * Note that unlike in the Arm implementation, we should never arrive
8469 * here with a zero breakFlag because we always refresh rIBASE on
8470 * return.
8471 */
8472    EXPORT_PC
8473    movl   rSELF, %eax
8474    movl   rPC, OUT_ARG0(%esp)
8475    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8476    movl   rFP, OUT_ARG1(%esp)
8477    je     1f                                # reload rIBASE & resume if not
8478    movl   %eax, OUT_ARG2(%esp)
8479    call   dvmCheckBefore                    # (dPC, dFP, self)
8480    movl   rSELF, %eax
84811:
8482    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8483    jmp    *dvmAsmInstructionStart+(20*4)
8484
8485/* ------------------------------ */
8486.L_ALT_OP_CONST_HIGH16: /* 0x15 */
8487/* File: x86/alt_stub.S */
8488/*
8489 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8490 * any interesting requests and then jump to the real instruction
8491 * handler.  Unlike the Arm handler, we can't do this as a tail call
8492 * because rIBASE is caller save and we need to reload it.
8493 *
8494 * Note that unlike in the Arm implementation, we should never arrive
8495 * here with a zero breakFlag because we always refresh rIBASE on
8496 * return.
8497 */
8498    EXPORT_PC
8499    movl   rSELF, %eax
8500    movl   rPC, OUT_ARG0(%esp)
8501    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8502    movl   rFP, OUT_ARG1(%esp)
8503    je     1f                                # reload rIBASE & resume if not
8504    movl   %eax, OUT_ARG2(%esp)
8505    call   dvmCheckBefore                    # (dPC, dFP, self)
8506    movl   rSELF, %eax
85071:
8508    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8509    jmp    *dvmAsmInstructionStart+(21*4)
8510
8511/* ------------------------------ */
8512.L_ALT_OP_CONST_WIDE_16: /* 0x16 */
8513/* File: x86/alt_stub.S */
8514/*
8515 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8516 * any interesting requests and then jump to the real instruction
8517 * handler.  Unlike the Arm handler, we can't do this as a tail call
8518 * because rIBASE is caller save and we need to reload it.
8519 *
8520 * Note that unlike in the Arm implementation, we should never arrive
8521 * here with a zero breakFlag because we always refresh rIBASE on
8522 * return.
8523 */
8524    EXPORT_PC
8525    movl   rSELF, %eax
8526    movl   rPC, OUT_ARG0(%esp)
8527    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8528    movl   rFP, OUT_ARG1(%esp)
8529    je     1f                                # reload rIBASE & resume if not
8530    movl   %eax, OUT_ARG2(%esp)
8531    call   dvmCheckBefore                    # (dPC, dFP, self)
8532    movl   rSELF, %eax
85331:
8534    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8535    jmp    *dvmAsmInstructionStart+(22*4)
8536
8537/* ------------------------------ */
8538.L_ALT_OP_CONST_WIDE_32: /* 0x17 */
8539/* File: x86/alt_stub.S */
8540/*
8541 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8542 * any interesting requests and then jump to the real instruction
8543 * handler.  Unlike the Arm handler, we can't do this as a tail call
8544 * because rIBASE is caller save and we need to reload it.
8545 *
8546 * Note that unlike in the Arm implementation, we should never arrive
8547 * here with a zero breakFlag because we always refresh rIBASE on
8548 * return.
8549 */
8550    EXPORT_PC
8551    movl   rSELF, %eax
8552    movl   rPC, OUT_ARG0(%esp)
8553    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8554    movl   rFP, OUT_ARG1(%esp)
8555    je     1f                                # reload rIBASE & resume if not
8556    movl   %eax, OUT_ARG2(%esp)
8557    call   dvmCheckBefore                    # (dPC, dFP, self)
8558    movl   rSELF, %eax
85591:
8560    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8561    jmp    *dvmAsmInstructionStart+(23*4)
8562
8563/* ------------------------------ */
8564.L_ALT_OP_CONST_WIDE: /* 0x18 */
8565/* File: x86/alt_stub.S */
8566/*
8567 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8568 * any interesting requests and then jump to the real instruction
8569 * handler.  Unlike the Arm handler, we can't do this as a tail call
8570 * because rIBASE is caller save and we need to reload it.
8571 *
8572 * Note that unlike in the Arm implementation, we should never arrive
8573 * here with a zero breakFlag because we always refresh rIBASE on
8574 * return.
8575 */
8576    EXPORT_PC
8577    movl   rSELF, %eax
8578    movl   rPC, OUT_ARG0(%esp)
8579    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8580    movl   rFP, OUT_ARG1(%esp)
8581    je     1f                                # reload rIBASE & resume if not
8582    movl   %eax, OUT_ARG2(%esp)
8583    call   dvmCheckBefore                    # (dPC, dFP, self)
8584    movl   rSELF, %eax
85851:
8586    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8587    jmp    *dvmAsmInstructionStart+(24*4)
8588
8589/* ------------------------------ */
8590.L_ALT_OP_CONST_WIDE_HIGH16: /* 0x19 */
8591/* File: x86/alt_stub.S */
8592/*
8593 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8594 * any interesting requests and then jump to the real instruction
8595 * handler.  Unlike the Arm handler, we can't do this as a tail call
8596 * because rIBASE is caller save and we need to reload it.
8597 *
8598 * Note that unlike in the Arm implementation, we should never arrive
8599 * here with a zero breakFlag because we always refresh rIBASE on
8600 * return.
8601 */
8602    EXPORT_PC
8603    movl   rSELF, %eax
8604    movl   rPC, OUT_ARG0(%esp)
8605    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8606    movl   rFP, OUT_ARG1(%esp)
8607    je     1f                                # reload rIBASE & resume if not
8608    movl   %eax, OUT_ARG2(%esp)
8609    call   dvmCheckBefore                    # (dPC, dFP, self)
8610    movl   rSELF, %eax
86111:
8612    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8613    jmp    *dvmAsmInstructionStart+(25*4)
8614
8615/* ------------------------------ */
8616.L_ALT_OP_CONST_STRING: /* 0x1a */
8617/* File: x86/alt_stub.S */
8618/*
8619 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8620 * any interesting requests and then jump to the real instruction
8621 * handler.  Unlike the Arm handler, we can't do this as a tail call
8622 * because rIBASE is caller save and we need to reload it.
8623 *
8624 * Note that unlike in the Arm implementation, we should never arrive
8625 * here with a zero breakFlag because we always refresh rIBASE on
8626 * return.
8627 */
8628    EXPORT_PC
8629    movl   rSELF, %eax
8630    movl   rPC, OUT_ARG0(%esp)
8631    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8632    movl   rFP, OUT_ARG1(%esp)
8633    je     1f                                # reload rIBASE & resume if not
8634    movl   %eax, OUT_ARG2(%esp)
8635    call   dvmCheckBefore                    # (dPC, dFP, self)
8636    movl   rSELF, %eax
86371:
8638    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8639    jmp    *dvmAsmInstructionStart+(26*4)
8640
8641/* ------------------------------ */
8642.L_ALT_OP_CONST_STRING_JUMBO: /* 0x1b */
8643/* File: x86/alt_stub.S */
8644/*
8645 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8646 * any interesting requests and then jump to the real instruction
8647 * handler.  Unlike the Arm handler, we can't do this as a tail call
8648 * because rIBASE is caller save and we need to reload it.
8649 *
8650 * Note that unlike in the Arm implementation, we should never arrive
8651 * here with a zero breakFlag because we always refresh rIBASE on
8652 * return.
8653 */
8654    EXPORT_PC
8655    movl   rSELF, %eax
8656    movl   rPC, OUT_ARG0(%esp)
8657    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8658    movl   rFP, OUT_ARG1(%esp)
8659    je     1f                                # reload rIBASE & resume if not
8660    movl   %eax, OUT_ARG2(%esp)
8661    call   dvmCheckBefore                    # (dPC, dFP, self)
8662    movl   rSELF, %eax
86631:
8664    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8665    jmp    *dvmAsmInstructionStart+(27*4)
8666
8667/* ------------------------------ */
8668.L_ALT_OP_CONST_CLASS: /* 0x1c */
8669/* File: x86/alt_stub.S */
8670/*
8671 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8672 * any interesting requests and then jump to the real instruction
8673 * handler.  Unlike the Arm handler, we can't do this as a tail call
8674 * because rIBASE is caller save and we need to reload it.
8675 *
8676 * Note that unlike in the Arm implementation, we should never arrive
8677 * here with a zero breakFlag because we always refresh rIBASE on
8678 * return.
8679 */
8680    EXPORT_PC
8681    movl   rSELF, %eax
8682    movl   rPC, OUT_ARG0(%esp)
8683    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8684    movl   rFP, OUT_ARG1(%esp)
8685    je     1f                                # reload rIBASE & resume if not
8686    movl   %eax, OUT_ARG2(%esp)
8687    call   dvmCheckBefore                    # (dPC, dFP, self)
8688    movl   rSELF, %eax
86891:
8690    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8691    jmp    *dvmAsmInstructionStart+(28*4)
8692
8693/* ------------------------------ */
8694.L_ALT_OP_MONITOR_ENTER: /* 0x1d */
8695/* File: x86/alt_stub.S */
8696/*
8697 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8698 * any interesting requests and then jump to the real instruction
8699 * handler.  Unlike the Arm handler, we can't do this as a tail call
8700 * because rIBASE is caller save and we need to reload it.
8701 *
8702 * Note that unlike in the Arm implementation, we should never arrive
8703 * here with a zero breakFlag because we always refresh rIBASE on
8704 * return.
8705 */
8706    EXPORT_PC
8707    movl   rSELF, %eax
8708    movl   rPC, OUT_ARG0(%esp)
8709    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8710    movl   rFP, OUT_ARG1(%esp)
8711    je     1f                                # reload rIBASE & resume if not
8712    movl   %eax, OUT_ARG2(%esp)
8713    call   dvmCheckBefore                    # (dPC, dFP, self)
8714    movl   rSELF, %eax
87151:
8716    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8717    jmp    *dvmAsmInstructionStart+(29*4)
8718
8719/* ------------------------------ */
8720.L_ALT_OP_MONITOR_EXIT: /* 0x1e */
8721/* File: x86/alt_stub.S */
8722/*
8723 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8724 * any interesting requests and then jump to the real instruction
8725 * handler.  Unlike the Arm handler, we can't do this as a tail call
8726 * because rIBASE is caller save and we need to reload it.
8727 *
8728 * Note that unlike in the Arm implementation, we should never arrive
8729 * here with a zero breakFlag because we always refresh rIBASE on
8730 * return.
8731 */
8732    EXPORT_PC
8733    movl   rSELF, %eax
8734    movl   rPC, OUT_ARG0(%esp)
8735    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8736    movl   rFP, OUT_ARG1(%esp)
8737    je     1f                                # reload rIBASE & resume if not
8738    movl   %eax, OUT_ARG2(%esp)
8739    call   dvmCheckBefore                    # (dPC, dFP, self)
8740    movl   rSELF, %eax
87411:
8742    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8743    jmp    *dvmAsmInstructionStart+(30*4)
8744
8745/* ------------------------------ */
8746.L_ALT_OP_CHECK_CAST: /* 0x1f */
8747/* File: x86/alt_stub.S */
8748/*
8749 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8750 * any interesting requests and then jump to the real instruction
8751 * handler.  Unlike the Arm handler, we can't do this as a tail call
8752 * because rIBASE is caller save and we need to reload it.
8753 *
8754 * Note that unlike in the Arm implementation, we should never arrive
8755 * here with a zero breakFlag because we always refresh rIBASE on
8756 * return.
8757 */
8758    EXPORT_PC
8759    movl   rSELF, %eax
8760    movl   rPC, OUT_ARG0(%esp)
8761    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8762    movl   rFP, OUT_ARG1(%esp)
8763    je     1f                                # reload rIBASE & resume if not
8764    movl   %eax, OUT_ARG2(%esp)
8765    call   dvmCheckBefore                    # (dPC, dFP, self)
8766    movl   rSELF, %eax
87671:
8768    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8769    jmp    *dvmAsmInstructionStart+(31*4)
8770
8771/* ------------------------------ */
8772.L_ALT_OP_INSTANCE_OF: /* 0x20 */
8773/* File: x86/alt_stub.S */
8774/*
8775 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8776 * any interesting requests and then jump to the real instruction
8777 * handler.  Unlike the Arm handler, we can't do this as a tail call
8778 * because rIBASE is caller save and we need to reload it.
8779 *
8780 * Note that unlike in the Arm implementation, we should never arrive
8781 * here with a zero breakFlag because we always refresh rIBASE on
8782 * return.
8783 */
8784    EXPORT_PC
8785    movl   rSELF, %eax
8786    movl   rPC, OUT_ARG0(%esp)
8787    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8788    movl   rFP, OUT_ARG1(%esp)
8789    je     1f                                # reload rIBASE & resume if not
8790    movl   %eax, OUT_ARG2(%esp)
8791    call   dvmCheckBefore                    # (dPC, dFP, self)
8792    movl   rSELF, %eax
87931:
8794    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8795    jmp    *dvmAsmInstructionStart+(32*4)
8796
8797/* ------------------------------ */
8798.L_ALT_OP_ARRAY_LENGTH: /* 0x21 */
8799/* File: x86/alt_stub.S */
8800/*
8801 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8802 * any interesting requests and then jump to the real instruction
8803 * handler.  Unlike the Arm handler, we can't do this as a tail call
8804 * because rIBASE is caller save and we need to reload it.
8805 *
8806 * Note that unlike in the Arm implementation, we should never arrive
8807 * here with a zero breakFlag because we always refresh rIBASE on
8808 * return.
8809 */
8810    EXPORT_PC
8811    movl   rSELF, %eax
8812    movl   rPC, OUT_ARG0(%esp)
8813    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8814    movl   rFP, OUT_ARG1(%esp)
8815    je     1f                                # reload rIBASE & resume if not
8816    movl   %eax, OUT_ARG2(%esp)
8817    call   dvmCheckBefore                    # (dPC, dFP, self)
8818    movl   rSELF, %eax
88191:
8820    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8821    jmp    *dvmAsmInstructionStart+(33*4)
8822
8823/* ------------------------------ */
8824.L_ALT_OP_NEW_INSTANCE: /* 0x22 */
8825/* File: x86/alt_stub.S */
8826/*
8827 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8828 * any interesting requests and then jump to the real instruction
8829 * handler.  Unlike the Arm handler, we can't do this as a tail call
8830 * because rIBASE is caller save and we need to reload it.
8831 *
8832 * Note that unlike in the Arm implementation, we should never arrive
8833 * here with a zero breakFlag because we always refresh rIBASE on
8834 * return.
8835 */
8836    EXPORT_PC
8837    movl   rSELF, %eax
8838    movl   rPC, OUT_ARG0(%esp)
8839    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8840    movl   rFP, OUT_ARG1(%esp)
8841    je     1f                                # reload rIBASE & resume if not
8842    movl   %eax, OUT_ARG2(%esp)
8843    call   dvmCheckBefore                    # (dPC, dFP, self)
8844    movl   rSELF, %eax
88451:
8846    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8847    jmp    *dvmAsmInstructionStart+(34*4)
8848
8849/* ------------------------------ */
8850.L_ALT_OP_NEW_ARRAY: /* 0x23 */
8851/* File: x86/alt_stub.S */
8852/*
8853 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8854 * any interesting requests and then jump to the real instruction
8855 * handler.  Unlike the Arm handler, we can't do this as a tail call
8856 * because rIBASE is caller save and we need to reload it.
8857 *
8858 * Note that unlike in the Arm implementation, we should never arrive
8859 * here with a zero breakFlag because we always refresh rIBASE on
8860 * return.
8861 */
8862    EXPORT_PC
8863    movl   rSELF, %eax
8864    movl   rPC, OUT_ARG0(%esp)
8865    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8866    movl   rFP, OUT_ARG1(%esp)
8867    je     1f                                # reload rIBASE & resume if not
8868    movl   %eax, OUT_ARG2(%esp)
8869    call   dvmCheckBefore                    # (dPC, dFP, self)
8870    movl   rSELF, %eax
88711:
8872    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8873    jmp    *dvmAsmInstructionStart+(35*4)
8874
8875/* ------------------------------ */
8876.L_ALT_OP_FILLED_NEW_ARRAY: /* 0x24 */
8877/* File: x86/alt_stub.S */
8878/*
8879 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8880 * any interesting requests and then jump to the real instruction
8881 * handler.  Unlike the Arm handler, we can't do this as a tail call
8882 * because rIBASE is caller save and we need to reload it.
8883 *
8884 * Note that unlike in the Arm implementation, we should never arrive
8885 * here with a zero breakFlag because we always refresh rIBASE on
8886 * return.
8887 */
8888    EXPORT_PC
8889    movl   rSELF, %eax
8890    movl   rPC, OUT_ARG0(%esp)
8891    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8892    movl   rFP, OUT_ARG1(%esp)
8893    je     1f                                # reload rIBASE & resume if not
8894    movl   %eax, OUT_ARG2(%esp)
8895    call   dvmCheckBefore                    # (dPC, dFP, self)
8896    movl   rSELF, %eax
88971:
8898    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8899    jmp    *dvmAsmInstructionStart+(36*4)
8900
8901/* ------------------------------ */
8902.L_ALT_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
8903/* File: x86/alt_stub.S */
8904/*
8905 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8906 * any interesting requests and then jump to the real instruction
8907 * handler.  Unlike the Arm handler, we can't do this as a tail call
8908 * because rIBASE is caller save and we need to reload it.
8909 *
8910 * Note that unlike in the Arm implementation, we should never arrive
8911 * here with a zero breakFlag because we always refresh rIBASE on
8912 * return.
8913 */
8914    EXPORT_PC
8915    movl   rSELF, %eax
8916    movl   rPC, OUT_ARG0(%esp)
8917    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8918    movl   rFP, OUT_ARG1(%esp)
8919    je     1f                                # reload rIBASE & resume if not
8920    movl   %eax, OUT_ARG2(%esp)
8921    call   dvmCheckBefore                    # (dPC, dFP, self)
8922    movl   rSELF, %eax
89231:
8924    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8925    jmp    *dvmAsmInstructionStart+(37*4)
8926
8927/* ------------------------------ */
8928.L_ALT_OP_FILL_ARRAY_DATA: /* 0x26 */
8929/* File: x86/alt_stub.S */
8930/*
8931 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8932 * any interesting requests and then jump to the real instruction
8933 * handler.  Unlike the Arm handler, we can't do this as a tail call
8934 * because rIBASE is caller save and we need to reload it.
8935 *
8936 * Note that unlike in the Arm implementation, we should never arrive
8937 * here with a zero breakFlag because we always refresh rIBASE on
8938 * return.
8939 */
8940    EXPORT_PC
8941    movl   rSELF, %eax
8942    movl   rPC, OUT_ARG0(%esp)
8943    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8944    movl   rFP, OUT_ARG1(%esp)
8945    je     1f                                # reload rIBASE & resume if not
8946    movl   %eax, OUT_ARG2(%esp)
8947    call   dvmCheckBefore                    # (dPC, dFP, self)
8948    movl   rSELF, %eax
89491:
8950    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8951    jmp    *dvmAsmInstructionStart+(38*4)
8952
8953/* ------------------------------ */
8954.L_ALT_OP_THROW: /* 0x27 */
8955/* File: x86/alt_stub.S */
8956/*
8957 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8958 * any interesting requests and then jump to the real instruction
8959 * handler.  Unlike the Arm handler, we can't do this as a tail call
8960 * because rIBASE is caller save and we need to reload it.
8961 *
8962 * Note that unlike in the Arm implementation, we should never arrive
8963 * here with a zero breakFlag because we always refresh rIBASE on
8964 * return.
8965 */
8966    EXPORT_PC
8967    movl   rSELF, %eax
8968    movl   rPC, OUT_ARG0(%esp)
8969    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8970    movl   rFP, OUT_ARG1(%esp)
8971    je     1f                                # reload rIBASE & resume if not
8972    movl   %eax, OUT_ARG2(%esp)
8973    call   dvmCheckBefore                    # (dPC, dFP, self)
8974    movl   rSELF, %eax
89751:
8976    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8977    jmp    *dvmAsmInstructionStart+(39*4)
8978
8979/* ------------------------------ */
8980.L_ALT_OP_GOTO: /* 0x28 */
8981/* File: x86/alt_stub.S */
8982/*
8983 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8984 * any interesting requests and then jump to the real instruction
8985 * handler.  Unlike the Arm handler, we can't do this as a tail call
8986 * because rIBASE is caller save and we need to reload it.
8987 *
8988 * Note that unlike in the Arm implementation, we should never arrive
8989 * here with a zero breakFlag because we always refresh rIBASE on
8990 * return.
8991 */
8992    EXPORT_PC
8993    movl   rSELF, %eax
8994    movl   rPC, OUT_ARG0(%esp)
8995    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8996    movl   rFP, OUT_ARG1(%esp)
8997    je     1f                                # reload rIBASE & resume if not
8998    movl   %eax, OUT_ARG2(%esp)
8999    call   dvmCheckBefore                    # (dPC, dFP, self)
9000    movl   rSELF, %eax
90011:
9002    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9003    jmp    *dvmAsmInstructionStart+(40*4)
9004
9005/* ------------------------------ */
9006.L_ALT_OP_GOTO_16: /* 0x29 */
9007/* File: x86/alt_stub.S */
9008/*
9009 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9010 * any interesting requests and then jump to the real instruction
9011 * handler.  Unlike the Arm handler, we can't do this as a tail call
9012 * because rIBASE is caller save and we need to reload it.
9013 *
9014 * Note that unlike in the Arm implementation, we should never arrive
9015 * here with a zero breakFlag because we always refresh rIBASE on
9016 * return.
9017 */
9018    EXPORT_PC
9019    movl   rSELF, %eax
9020    movl   rPC, OUT_ARG0(%esp)
9021    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9022    movl   rFP, OUT_ARG1(%esp)
9023    je     1f                                # reload rIBASE & resume if not
9024    movl   %eax, OUT_ARG2(%esp)
9025    call   dvmCheckBefore                    # (dPC, dFP, self)
9026    movl   rSELF, %eax
90271:
9028    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9029    jmp    *dvmAsmInstructionStart+(41*4)
9030
9031/* ------------------------------ */
9032.L_ALT_OP_GOTO_32: /* 0x2a */
9033/* File: x86/alt_stub.S */
9034/*
9035 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9036 * any interesting requests and then jump to the real instruction
9037 * handler.  Unlike the Arm handler, we can't do this as a tail call
9038 * because rIBASE is caller save and we need to reload it.
9039 *
9040 * Note that unlike in the Arm implementation, we should never arrive
9041 * here with a zero breakFlag because we always refresh rIBASE on
9042 * return.
9043 */
9044    EXPORT_PC
9045    movl   rSELF, %eax
9046    movl   rPC, OUT_ARG0(%esp)
9047    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9048    movl   rFP, OUT_ARG1(%esp)
9049    je     1f                                # reload rIBASE & resume if not
9050    movl   %eax, OUT_ARG2(%esp)
9051    call   dvmCheckBefore                    # (dPC, dFP, self)
9052    movl   rSELF, %eax
90531:
9054    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9055    jmp    *dvmAsmInstructionStart+(42*4)
9056
9057/* ------------------------------ */
9058.L_ALT_OP_PACKED_SWITCH: /* 0x2b */
9059/* File: x86/alt_stub.S */
9060/*
9061 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9062 * any interesting requests and then jump to the real instruction
9063 * handler.  Unlike the Arm handler, we can't do this as a tail call
9064 * because rIBASE is caller save and we need to reload it.
9065 *
9066 * Note that unlike in the Arm implementation, we should never arrive
9067 * here with a zero breakFlag because we always refresh rIBASE on
9068 * return.
9069 */
9070    EXPORT_PC
9071    movl   rSELF, %eax
9072    movl   rPC, OUT_ARG0(%esp)
9073    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9074    movl   rFP, OUT_ARG1(%esp)
9075    je     1f                                # reload rIBASE & resume if not
9076    movl   %eax, OUT_ARG2(%esp)
9077    call   dvmCheckBefore                    # (dPC, dFP, self)
9078    movl   rSELF, %eax
90791:
9080    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9081    jmp    *dvmAsmInstructionStart+(43*4)
9082
9083/* ------------------------------ */
9084.L_ALT_OP_SPARSE_SWITCH: /* 0x2c */
9085/* File: x86/alt_stub.S */
9086/*
9087 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9088 * any interesting requests and then jump to the real instruction
9089 * handler.  Unlike the Arm handler, we can't do this as a tail call
9090 * because rIBASE is caller save and we need to reload it.
9091 *
9092 * Note that unlike in the Arm implementation, we should never arrive
9093 * here with a zero breakFlag because we always refresh rIBASE on
9094 * return.
9095 */
9096    EXPORT_PC
9097    movl   rSELF, %eax
9098    movl   rPC, OUT_ARG0(%esp)
9099    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9100    movl   rFP, OUT_ARG1(%esp)
9101    je     1f                                # reload rIBASE & resume if not
9102    movl   %eax, OUT_ARG2(%esp)
9103    call   dvmCheckBefore                    # (dPC, dFP, self)
9104    movl   rSELF, %eax
91051:
9106    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9107    jmp    *dvmAsmInstructionStart+(44*4)
9108
9109/* ------------------------------ */
9110.L_ALT_OP_CMPL_FLOAT: /* 0x2d */
9111/* File: x86/alt_stub.S */
9112/*
9113 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9114 * any interesting requests and then jump to the real instruction
9115 * handler.  Unlike the Arm handler, we can't do this as a tail call
9116 * because rIBASE is caller save and we need to reload it.
9117 *
9118 * Note that unlike in the Arm implementation, we should never arrive
9119 * here with a zero breakFlag because we always refresh rIBASE on
9120 * return.
9121 */
9122    EXPORT_PC
9123    movl   rSELF, %eax
9124    movl   rPC, OUT_ARG0(%esp)
9125    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9126    movl   rFP, OUT_ARG1(%esp)
9127    je     1f                                # reload rIBASE & resume if not
9128    movl   %eax, OUT_ARG2(%esp)
9129    call   dvmCheckBefore                    # (dPC, dFP, self)
9130    movl   rSELF, %eax
91311:
9132    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9133    jmp    *dvmAsmInstructionStart+(45*4)
9134
9135/* ------------------------------ */
9136.L_ALT_OP_CMPG_FLOAT: /* 0x2e */
9137/* File: x86/alt_stub.S */
9138/*
9139 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9140 * any interesting requests and then jump to the real instruction
9141 * handler.  Unlike the Arm handler, we can't do this as a tail call
9142 * because rIBASE is caller save and we need to reload it.
9143 *
9144 * Note that unlike in the Arm implementation, we should never arrive
9145 * here with a zero breakFlag because we always refresh rIBASE on
9146 * return.
9147 */
9148    EXPORT_PC
9149    movl   rSELF, %eax
9150    movl   rPC, OUT_ARG0(%esp)
9151    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9152    movl   rFP, OUT_ARG1(%esp)
9153    je     1f                                # reload rIBASE & resume if not
9154    movl   %eax, OUT_ARG2(%esp)
9155    call   dvmCheckBefore                    # (dPC, dFP, self)
9156    movl   rSELF, %eax
91571:
9158    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9159    jmp    *dvmAsmInstructionStart+(46*4)
9160
9161/* ------------------------------ */
9162.L_ALT_OP_CMPL_DOUBLE: /* 0x2f */
9163/* File: x86/alt_stub.S */
9164/*
9165 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9166 * any interesting requests and then jump to the real instruction
9167 * handler.  Unlike the Arm handler, we can't do this as a tail call
9168 * because rIBASE is caller save and we need to reload it.
9169 *
9170 * Note that unlike in the Arm implementation, we should never arrive
9171 * here with a zero breakFlag because we always refresh rIBASE on
9172 * return.
9173 */
9174    EXPORT_PC
9175    movl   rSELF, %eax
9176    movl   rPC, OUT_ARG0(%esp)
9177    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9178    movl   rFP, OUT_ARG1(%esp)
9179    je     1f                                # reload rIBASE & resume if not
9180    movl   %eax, OUT_ARG2(%esp)
9181    call   dvmCheckBefore                    # (dPC, dFP, self)
9182    movl   rSELF, %eax
91831:
9184    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9185    jmp    *dvmAsmInstructionStart+(47*4)
9186
9187/* ------------------------------ */
9188.L_ALT_OP_CMPG_DOUBLE: /* 0x30 */
9189/* File: x86/alt_stub.S */
9190/*
9191 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9192 * any interesting requests and then jump to the real instruction
9193 * handler.  Unlike the Arm handler, we can't do this as a tail call
9194 * because rIBASE is caller save and we need to reload it.
9195 *
9196 * Note that unlike in the Arm implementation, we should never arrive
9197 * here with a zero breakFlag because we always refresh rIBASE on
9198 * return.
9199 */
9200    EXPORT_PC
9201    movl   rSELF, %eax
9202    movl   rPC, OUT_ARG0(%esp)
9203    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9204    movl   rFP, OUT_ARG1(%esp)
9205    je     1f                                # reload rIBASE & resume if not
9206    movl   %eax, OUT_ARG2(%esp)
9207    call   dvmCheckBefore                    # (dPC, dFP, self)
9208    movl   rSELF, %eax
92091:
9210    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9211    jmp    *dvmAsmInstructionStart+(48*4)
9212
9213/* ------------------------------ */
9214.L_ALT_OP_CMP_LONG: /* 0x31 */
9215/* File: x86/alt_stub.S */
9216/*
9217 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9218 * any interesting requests and then jump to the real instruction
9219 * handler.  Unlike the Arm handler, we can't do this as a tail call
9220 * because rIBASE is caller save and we need to reload it.
9221 *
9222 * Note that unlike in the Arm implementation, we should never arrive
9223 * here with a zero breakFlag because we always refresh rIBASE on
9224 * return.
9225 */
9226    EXPORT_PC
9227    movl   rSELF, %eax
9228    movl   rPC, OUT_ARG0(%esp)
9229    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9230    movl   rFP, OUT_ARG1(%esp)
9231    je     1f                                # reload rIBASE & resume if not
9232    movl   %eax, OUT_ARG2(%esp)
9233    call   dvmCheckBefore                    # (dPC, dFP, self)
9234    movl   rSELF, %eax
92351:
9236    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9237    jmp    *dvmAsmInstructionStart+(49*4)
9238
9239/* ------------------------------ */
9240.L_ALT_OP_IF_EQ: /* 0x32 */
9241/* File: x86/alt_stub.S */
9242/*
9243 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9244 * any interesting requests and then jump to the real instruction
9245 * handler.  Unlike the Arm handler, we can't do this as a tail call
9246 * because rIBASE is caller save and we need to reload it.
9247 *
9248 * Note that unlike in the Arm implementation, we should never arrive
9249 * here with a zero breakFlag because we always refresh rIBASE on
9250 * return.
9251 */
9252    EXPORT_PC
9253    movl   rSELF, %eax
9254    movl   rPC, OUT_ARG0(%esp)
9255    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9256    movl   rFP, OUT_ARG1(%esp)
9257    je     1f                                # reload rIBASE & resume if not
9258    movl   %eax, OUT_ARG2(%esp)
9259    call   dvmCheckBefore                    # (dPC, dFP, self)
9260    movl   rSELF, %eax
92611:
9262    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9263    jmp    *dvmAsmInstructionStart+(50*4)
9264
9265/* ------------------------------ */
9266.L_ALT_OP_IF_NE: /* 0x33 */
9267/* File: x86/alt_stub.S */
9268/*
9269 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9270 * any interesting requests and then jump to the real instruction
9271 * handler.  Unlike the Arm handler, we can't do this as a tail call
9272 * because rIBASE is caller save and we need to reload it.
9273 *
9274 * Note that unlike in the Arm implementation, we should never arrive
9275 * here with a zero breakFlag because we always refresh rIBASE on
9276 * return.
9277 */
9278    EXPORT_PC
9279    movl   rSELF, %eax
9280    movl   rPC, OUT_ARG0(%esp)
9281    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9282    movl   rFP, OUT_ARG1(%esp)
9283    je     1f                                # reload rIBASE & resume if not
9284    movl   %eax, OUT_ARG2(%esp)
9285    call   dvmCheckBefore                    # (dPC, dFP, self)
9286    movl   rSELF, %eax
92871:
9288    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9289    jmp    *dvmAsmInstructionStart+(51*4)
9290
9291/* ------------------------------ */
9292.L_ALT_OP_IF_LT: /* 0x34 */
9293/* File: x86/alt_stub.S */
9294/*
9295 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9296 * any interesting requests and then jump to the real instruction
9297 * handler.  Unlike the Arm handler, we can't do this as a tail call
9298 * because rIBASE is caller save and we need to reload it.
9299 *
9300 * Note that unlike in the Arm implementation, we should never arrive
9301 * here with a zero breakFlag because we always refresh rIBASE on
9302 * return.
9303 */
9304    EXPORT_PC
9305    movl   rSELF, %eax
9306    movl   rPC, OUT_ARG0(%esp)
9307    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9308    movl   rFP, OUT_ARG1(%esp)
9309    je     1f                                # reload rIBASE & resume if not
9310    movl   %eax, OUT_ARG2(%esp)
9311    call   dvmCheckBefore                    # (dPC, dFP, self)
9312    movl   rSELF, %eax
93131:
9314    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9315    jmp    *dvmAsmInstructionStart+(52*4)
9316
9317/* ------------------------------ */
9318.L_ALT_OP_IF_GE: /* 0x35 */
9319/* File: x86/alt_stub.S */
9320/*
9321 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9322 * any interesting requests and then jump to the real instruction
9323 * handler.  Unlike the Arm handler, we can't do this as a tail call
9324 * because rIBASE is caller save and we need to reload it.
9325 *
9326 * Note that unlike in the Arm implementation, we should never arrive
9327 * here with a zero breakFlag because we always refresh rIBASE on
9328 * return.
9329 */
9330    EXPORT_PC
9331    movl   rSELF, %eax
9332    movl   rPC, OUT_ARG0(%esp)
9333    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9334    movl   rFP, OUT_ARG1(%esp)
9335    je     1f                                # reload rIBASE & resume if not
9336    movl   %eax, OUT_ARG2(%esp)
9337    call   dvmCheckBefore                    # (dPC, dFP, self)
9338    movl   rSELF, %eax
93391:
9340    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9341    jmp    *dvmAsmInstructionStart+(53*4)
9342
9343/* ------------------------------ */
9344.L_ALT_OP_IF_GT: /* 0x36 */
9345/* File: x86/alt_stub.S */
9346/*
9347 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9348 * any interesting requests and then jump to the real instruction
9349 * handler.  Unlike the Arm handler, we can't do this as a tail call
9350 * because rIBASE is caller save and we need to reload it.
9351 *
9352 * Note that unlike in the Arm implementation, we should never arrive
9353 * here with a zero breakFlag because we always refresh rIBASE on
9354 * return.
9355 */
9356    EXPORT_PC
9357    movl   rSELF, %eax
9358    movl   rPC, OUT_ARG0(%esp)
9359    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9360    movl   rFP, OUT_ARG1(%esp)
9361    je     1f                                # reload rIBASE & resume if not
9362    movl   %eax, OUT_ARG2(%esp)
9363    call   dvmCheckBefore                    # (dPC, dFP, self)
9364    movl   rSELF, %eax
93651:
9366    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9367    jmp    *dvmAsmInstructionStart+(54*4)
9368
9369/* ------------------------------ */
9370.L_ALT_OP_IF_LE: /* 0x37 */
9371/* File: x86/alt_stub.S */
9372/*
9373 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9374 * any interesting requests and then jump to the real instruction
9375 * handler.  Unlike the Arm handler, we can't do this as a tail call
9376 * because rIBASE is caller save and we need to reload it.
9377 *
9378 * Note that unlike in the Arm implementation, we should never arrive
9379 * here with a zero breakFlag because we always refresh rIBASE on
9380 * return.
9381 */
9382    EXPORT_PC
9383    movl   rSELF, %eax
9384    movl   rPC, OUT_ARG0(%esp)
9385    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9386    movl   rFP, OUT_ARG1(%esp)
9387    je     1f                                # reload rIBASE & resume if not
9388    movl   %eax, OUT_ARG2(%esp)
9389    call   dvmCheckBefore                    # (dPC, dFP, self)
9390    movl   rSELF, %eax
93911:
9392    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9393    jmp    *dvmAsmInstructionStart+(55*4)
9394
9395/* ------------------------------ */
9396.L_ALT_OP_IF_EQZ: /* 0x38 */
9397/* File: x86/alt_stub.S */
9398/*
9399 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9400 * any interesting requests and then jump to the real instruction
9401 * handler.  Unlike the Arm handler, we can't do this as a tail call
9402 * because rIBASE is caller save and we need to reload it.
9403 *
9404 * Note that unlike in the Arm implementation, we should never arrive
9405 * here with a zero breakFlag because we always refresh rIBASE on
9406 * return.
9407 */
9408    EXPORT_PC
9409    movl   rSELF, %eax
9410    movl   rPC, OUT_ARG0(%esp)
9411    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9412    movl   rFP, OUT_ARG1(%esp)
9413    je     1f                                # reload rIBASE & resume if not
9414    movl   %eax, OUT_ARG2(%esp)
9415    call   dvmCheckBefore                    # (dPC, dFP, self)
9416    movl   rSELF, %eax
94171:
9418    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9419    jmp    *dvmAsmInstructionStart+(56*4)
9420
9421/* ------------------------------ */
9422.L_ALT_OP_IF_NEZ: /* 0x39 */
9423/* File: x86/alt_stub.S */
9424/*
9425 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9426 * any interesting requests and then jump to the real instruction
9427 * handler.  Unlike the Arm handler, we can't do this as a tail call
9428 * because rIBASE is caller save and we need to reload it.
9429 *
9430 * Note that unlike in the Arm implementation, we should never arrive
9431 * here with a zero breakFlag because we always refresh rIBASE on
9432 * return.
9433 */
9434    EXPORT_PC
9435    movl   rSELF, %eax
9436    movl   rPC, OUT_ARG0(%esp)
9437    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9438    movl   rFP, OUT_ARG1(%esp)
9439    je     1f                                # reload rIBASE & resume if not
9440    movl   %eax, OUT_ARG2(%esp)
9441    call   dvmCheckBefore                    # (dPC, dFP, self)
9442    movl   rSELF, %eax
94431:
9444    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9445    jmp    *dvmAsmInstructionStart+(57*4)
9446
9447/* ------------------------------ */
9448.L_ALT_OP_IF_LTZ: /* 0x3a */
9449/* File: x86/alt_stub.S */
9450/*
9451 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9452 * any interesting requests and then jump to the real instruction
9453 * handler.  Unlike the Arm handler, we can't do this as a tail call
9454 * because rIBASE is caller save and we need to reload it.
9455 *
9456 * Note that unlike in the Arm implementation, we should never arrive
9457 * here with a zero breakFlag because we always refresh rIBASE on
9458 * return.
9459 */
9460    EXPORT_PC
9461    movl   rSELF, %eax
9462    movl   rPC, OUT_ARG0(%esp)
9463    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9464    movl   rFP, OUT_ARG1(%esp)
9465    je     1f                                # reload rIBASE & resume if not
9466    movl   %eax, OUT_ARG2(%esp)
9467    call   dvmCheckBefore                    # (dPC, dFP, self)
9468    movl   rSELF, %eax
94691:
9470    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9471    jmp    *dvmAsmInstructionStart+(58*4)
9472
9473/* ------------------------------ */
9474.L_ALT_OP_IF_GEZ: /* 0x3b */
9475/* File: x86/alt_stub.S */
9476/*
9477 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9478 * any interesting requests and then jump to the real instruction
9479 * handler.  Unlike the Arm handler, we can't do this as a tail call
9480 * because rIBASE is caller save and we need to reload it.
9481 *
9482 * Note that unlike in the Arm implementation, we should never arrive
9483 * here with a zero breakFlag because we always refresh rIBASE on
9484 * return.
9485 */
9486    EXPORT_PC
9487    movl   rSELF, %eax
9488    movl   rPC, OUT_ARG0(%esp)
9489    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9490    movl   rFP, OUT_ARG1(%esp)
9491    je     1f                                # reload rIBASE & resume if not
9492    movl   %eax, OUT_ARG2(%esp)
9493    call   dvmCheckBefore                    # (dPC, dFP, self)
9494    movl   rSELF, %eax
94951:
9496    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9497    jmp    *dvmAsmInstructionStart+(59*4)
9498
9499/* ------------------------------ */
9500.L_ALT_OP_IF_GTZ: /* 0x3c */
9501/* File: x86/alt_stub.S */
9502/*
9503 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9504 * any interesting requests and then jump to the real instruction
9505 * handler.  Unlike the Arm handler, we can't do this as a tail call
9506 * because rIBASE is caller save and we need to reload it.
9507 *
9508 * Note that unlike in the Arm implementation, we should never arrive
9509 * here with a zero breakFlag because we always refresh rIBASE on
9510 * return.
9511 */
9512    EXPORT_PC
9513    movl   rSELF, %eax
9514    movl   rPC, OUT_ARG0(%esp)
9515    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9516    movl   rFP, OUT_ARG1(%esp)
9517    je     1f                                # reload rIBASE & resume if not
9518    movl   %eax, OUT_ARG2(%esp)
9519    call   dvmCheckBefore                    # (dPC, dFP, self)
9520    movl   rSELF, %eax
95211:
9522    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9523    jmp    *dvmAsmInstructionStart+(60*4)
9524
9525/* ------------------------------ */
9526.L_ALT_OP_IF_LEZ: /* 0x3d */
9527/* File: x86/alt_stub.S */
9528/*
9529 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9530 * any interesting requests and then jump to the real instruction
9531 * handler.  Unlike the Arm handler, we can't do this as a tail call
9532 * because rIBASE is caller save and we need to reload it.
9533 *
9534 * Note that unlike in the Arm implementation, we should never arrive
9535 * here with a zero breakFlag because we always refresh rIBASE on
9536 * return.
9537 */
9538    EXPORT_PC
9539    movl   rSELF, %eax
9540    movl   rPC, OUT_ARG0(%esp)
9541    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9542    movl   rFP, OUT_ARG1(%esp)
9543    je     1f                                # reload rIBASE & resume if not
9544    movl   %eax, OUT_ARG2(%esp)
9545    call   dvmCheckBefore                    # (dPC, dFP, self)
9546    movl   rSELF, %eax
95471:
9548    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9549    jmp    *dvmAsmInstructionStart+(61*4)
9550
9551/* ------------------------------ */
9552.L_ALT_OP_UNUSED_3E: /* 0x3e */
9553/* File: x86/alt_stub.S */
9554/*
9555 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9556 * any interesting requests and then jump to the real instruction
9557 * handler.  Unlike the Arm handler, we can't do this as a tail call
9558 * because rIBASE is caller save and we need to reload it.
9559 *
9560 * Note that unlike in the Arm implementation, we should never arrive
9561 * here with a zero breakFlag because we always refresh rIBASE on
9562 * return.
9563 */
9564    EXPORT_PC
9565    movl   rSELF, %eax
9566    movl   rPC, OUT_ARG0(%esp)
9567    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9568    movl   rFP, OUT_ARG1(%esp)
9569    je     1f                                # reload rIBASE & resume if not
9570    movl   %eax, OUT_ARG2(%esp)
9571    call   dvmCheckBefore                    # (dPC, dFP, self)
9572    movl   rSELF, %eax
95731:
9574    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9575    jmp    *dvmAsmInstructionStart+(62*4)
9576
9577/* ------------------------------ */
9578.L_ALT_OP_UNUSED_3F: /* 0x3f */
9579/* File: x86/alt_stub.S */
9580/*
9581 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9582 * any interesting requests and then jump to the real instruction
9583 * handler.  Unlike the Arm handler, we can't do this as a tail call
9584 * because rIBASE is caller save and we need to reload it.
9585 *
9586 * Note that unlike in the Arm implementation, we should never arrive
9587 * here with a zero breakFlag because we always refresh rIBASE on
9588 * return.
9589 */
9590    EXPORT_PC
9591    movl   rSELF, %eax
9592    movl   rPC, OUT_ARG0(%esp)
9593    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9594    movl   rFP, OUT_ARG1(%esp)
9595    je     1f                                # reload rIBASE & resume if not
9596    movl   %eax, OUT_ARG2(%esp)
9597    call   dvmCheckBefore                    # (dPC, dFP, self)
9598    movl   rSELF, %eax
95991:
9600    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9601    jmp    *dvmAsmInstructionStart+(63*4)
9602
9603/* ------------------------------ */
9604.L_ALT_OP_UNUSED_40: /* 0x40 */
9605/* File: x86/alt_stub.S */
9606/*
9607 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9608 * any interesting requests and then jump to the real instruction
9609 * handler.  Unlike the Arm handler, we can't do this as a tail call
9610 * because rIBASE is caller save and we need to reload it.
9611 *
9612 * Note that unlike in the Arm implementation, we should never arrive
9613 * here with a zero breakFlag because we always refresh rIBASE on
9614 * return.
9615 */
9616    EXPORT_PC
9617    movl   rSELF, %eax
9618    movl   rPC, OUT_ARG0(%esp)
9619    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9620    movl   rFP, OUT_ARG1(%esp)
9621    je     1f                                # reload rIBASE & resume if not
9622    movl   %eax, OUT_ARG2(%esp)
9623    call   dvmCheckBefore                    # (dPC, dFP, self)
9624    movl   rSELF, %eax
96251:
9626    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9627    jmp    *dvmAsmInstructionStart+(64*4)
9628
9629/* ------------------------------ */
9630.L_ALT_OP_UNUSED_41: /* 0x41 */
9631/* File: x86/alt_stub.S */
9632/*
9633 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9634 * any interesting requests and then jump to the real instruction
9635 * handler.  Unlike the Arm handler, we can't do this as a tail call
9636 * because rIBASE is caller save and we need to reload it.
9637 *
9638 * Note that unlike in the Arm implementation, we should never arrive
9639 * here with a zero breakFlag because we always refresh rIBASE on
9640 * return.
9641 */
9642    EXPORT_PC
9643    movl   rSELF, %eax
9644    movl   rPC, OUT_ARG0(%esp)
9645    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9646    movl   rFP, OUT_ARG1(%esp)
9647    je     1f                                # reload rIBASE & resume if not
9648    movl   %eax, OUT_ARG2(%esp)
9649    call   dvmCheckBefore                    # (dPC, dFP, self)
9650    movl   rSELF, %eax
96511:
9652    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9653    jmp    *dvmAsmInstructionStart+(65*4)
9654
9655/* ------------------------------ */
9656.L_ALT_OP_UNUSED_42: /* 0x42 */
9657/* File: x86/alt_stub.S */
9658/*
9659 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9660 * any interesting requests and then jump to the real instruction
9661 * handler.  Unlike the Arm handler, we can't do this as a tail call
9662 * because rIBASE is caller save and we need to reload it.
9663 *
9664 * Note that unlike in the Arm implementation, we should never arrive
9665 * here with a zero breakFlag because we always refresh rIBASE on
9666 * return.
9667 */
9668    EXPORT_PC
9669    movl   rSELF, %eax
9670    movl   rPC, OUT_ARG0(%esp)
9671    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9672    movl   rFP, OUT_ARG1(%esp)
9673    je     1f                                # reload rIBASE & resume if not
9674    movl   %eax, OUT_ARG2(%esp)
9675    call   dvmCheckBefore                    # (dPC, dFP, self)
9676    movl   rSELF, %eax
96771:
9678    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9679    jmp    *dvmAsmInstructionStart+(66*4)
9680
9681/* ------------------------------ */
9682.L_ALT_OP_UNUSED_43: /* 0x43 */
9683/* File: x86/alt_stub.S */
9684/*
9685 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9686 * any interesting requests and then jump to the real instruction
9687 * handler.  Unlike the Arm handler, we can't do this as a tail call
9688 * because rIBASE is caller save and we need to reload it.
9689 *
9690 * Note that unlike in the Arm implementation, we should never arrive
9691 * here with a zero breakFlag because we always refresh rIBASE on
9692 * return.
9693 */
9694    EXPORT_PC
9695    movl   rSELF, %eax
9696    movl   rPC, OUT_ARG0(%esp)
9697    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9698    movl   rFP, OUT_ARG1(%esp)
9699    je     1f                                # reload rIBASE & resume if not
9700    movl   %eax, OUT_ARG2(%esp)
9701    call   dvmCheckBefore                    # (dPC, dFP, self)
9702    movl   rSELF, %eax
97031:
9704    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9705    jmp    *dvmAsmInstructionStart+(67*4)
9706
9707/* ------------------------------ */
9708.L_ALT_OP_AGET: /* 0x44 */
9709/* File: x86/alt_stub.S */
9710/*
9711 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9712 * any interesting requests and then jump to the real instruction
9713 * handler.  Unlike the Arm handler, we can't do this as a tail call
9714 * because rIBASE is caller save and we need to reload it.
9715 *
9716 * Note that unlike in the Arm implementation, we should never arrive
9717 * here with a zero breakFlag because we always refresh rIBASE on
9718 * return.
9719 */
9720    EXPORT_PC
9721    movl   rSELF, %eax
9722    movl   rPC, OUT_ARG0(%esp)
9723    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9724    movl   rFP, OUT_ARG1(%esp)
9725    je     1f                                # reload rIBASE & resume if not
9726    movl   %eax, OUT_ARG2(%esp)
9727    call   dvmCheckBefore                    # (dPC, dFP, self)
9728    movl   rSELF, %eax
97291:
9730    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9731    jmp    *dvmAsmInstructionStart+(68*4)
9732
9733/* ------------------------------ */
9734.L_ALT_OP_AGET_WIDE: /* 0x45 */
9735/* File: x86/alt_stub.S */
9736/*
9737 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9738 * any interesting requests and then jump to the real instruction
9739 * handler.  Unlike the Arm handler, we can't do this as a tail call
9740 * because rIBASE is caller save and we need to reload it.
9741 *
9742 * Note that unlike in the Arm implementation, we should never arrive
9743 * here with a zero breakFlag because we always refresh rIBASE on
9744 * return.
9745 */
9746    EXPORT_PC
9747    movl   rSELF, %eax
9748    movl   rPC, OUT_ARG0(%esp)
9749    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9750    movl   rFP, OUT_ARG1(%esp)
9751    je     1f                                # reload rIBASE & resume if not
9752    movl   %eax, OUT_ARG2(%esp)
9753    call   dvmCheckBefore                    # (dPC, dFP, self)
9754    movl   rSELF, %eax
97551:
9756    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9757    jmp    *dvmAsmInstructionStart+(69*4)
9758
9759/* ------------------------------ */
9760.L_ALT_OP_AGET_OBJECT: /* 0x46 */
9761/* File: x86/alt_stub.S */
9762/*
9763 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9764 * any interesting requests and then jump to the real instruction
9765 * handler.  Unlike the Arm handler, we can't do this as a tail call
9766 * because rIBASE is caller save and we need to reload it.
9767 *
9768 * Note that unlike in the Arm implementation, we should never arrive
9769 * here with a zero breakFlag because we always refresh rIBASE on
9770 * return.
9771 */
9772    EXPORT_PC
9773    movl   rSELF, %eax
9774    movl   rPC, OUT_ARG0(%esp)
9775    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9776    movl   rFP, OUT_ARG1(%esp)
9777    je     1f                                # reload rIBASE & resume if not
9778    movl   %eax, OUT_ARG2(%esp)
9779    call   dvmCheckBefore                    # (dPC, dFP, self)
9780    movl   rSELF, %eax
97811:
9782    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9783    jmp    *dvmAsmInstructionStart+(70*4)
9784
9785/* ------------------------------ */
9786.L_ALT_OP_AGET_BOOLEAN: /* 0x47 */
9787/* File: x86/alt_stub.S */
9788/*
9789 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9790 * any interesting requests and then jump to the real instruction
9791 * handler.  Unlike the Arm handler, we can't do this as a tail call
9792 * because rIBASE is caller save and we need to reload it.
9793 *
9794 * Note that unlike in the Arm implementation, we should never arrive
9795 * here with a zero breakFlag because we always refresh rIBASE on
9796 * return.
9797 */
9798    EXPORT_PC
9799    movl   rSELF, %eax
9800    movl   rPC, OUT_ARG0(%esp)
9801    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9802    movl   rFP, OUT_ARG1(%esp)
9803    je     1f                                # reload rIBASE & resume if not
9804    movl   %eax, OUT_ARG2(%esp)
9805    call   dvmCheckBefore                    # (dPC, dFP, self)
9806    movl   rSELF, %eax
98071:
9808    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9809    jmp    *dvmAsmInstructionStart+(71*4)
9810
9811/* ------------------------------ */
9812.L_ALT_OP_AGET_BYTE: /* 0x48 */
9813/* File: x86/alt_stub.S */
9814/*
9815 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9816 * any interesting requests and then jump to the real instruction
9817 * handler.  Unlike the Arm handler, we can't do this as a tail call
9818 * because rIBASE is caller save and we need to reload it.
9819 *
9820 * Note that unlike in the Arm implementation, we should never arrive
9821 * here with a zero breakFlag because we always refresh rIBASE on
9822 * return.
9823 */
9824    EXPORT_PC
9825    movl   rSELF, %eax
9826    movl   rPC, OUT_ARG0(%esp)
9827    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9828    movl   rFP, OUT_ARG1(%esp)
9829    je     1f                                # reload rIBASE & resume if not
9830    movl   %eax, OUT_ARG2(%esp)
9831    call   dvmCheckBefore                    # (dPC, dFP, self)
9832    movl   rSELF, %eax
98331:
9834    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9835    jmp    *dvmAsmInstructionStart+(72*4)
9836
9837/* ------------------------------ */
9838.L_ALT_OP_AGET_CHAR: /* 0x49 */
9839/* File: x86/alt_stub.S */
9840/*
9841 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9842 * any interesting requests and then jump to the real instruction
9843 * handler.  Unlike the Arm handler, we can't do this as a tail call
9844 * because rIBASE is caller save and we need to reload it.
9845 *
9846 * Note that unlike in the Arm implementation, we should never arrive
9847 * here with a zero breakFlag because we always refresh rIBASE on
9848 * return.
9849 */
9850    EXPORT_PC
9851    movl   rSELF, %eax
9852    movl   rPC, OUT_ARG0(%esp)
9853    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9854    movl   rFP, OUT_ARG1(%esp)
9855    je     1f                                # reload rIBASE & resume if not
9856    movl   %eax, OUT_ARG2(%esp)
9857    call   dvmCheckBefore                    # (dPC, dFP, self)
9858    movl   rSELF, %eax
98591:
9860    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9861    jmp    *dvmAsmInstructionStart+(73*4)
9862
9863/* ------------------------------ */
9864.L_ALT_OP_AGET_SHORT: /* 0x4a */
9865/* File: x86/alt_stub.S */
9866/*
9867 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9868 * any interesting requests and then jump to the real instruction
9869 * handler.  Unlike the Arm handler, we can't do this as a tail call
9870 * because rIBASE is caller save and we need to reload it.
9871 *
9872 * Note that unlike in the Arm implementation, we should never arrive
9873 * here with a zero breakFlag because we always refresh rIBASE on
9874 * return.
9875 */
9876    EXPORT_PC
9877    movl   rSELF, %eax
9878    movl   rPC, OUT_ARG0(%esp)
9879    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9880    movl   rFP, OUT_ARG1(%esp)
9881    je     1f                                # reload rIBASE & resume if not
9882    movl   %eax, OUT_ARG2(%esp)
9883    call   dvmCheckBefore                    # (dPC, dFP, self)
9884    movl   rSELF, %eax
98851:
9886    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9887    jmp    *dvmAsmInstructionStart+(74*4)
9888
9889/* ------------------------------ */
9890.L_ALT_OP_APUT: /* 0x4b */
9891/* File: x86/alt_stub.S */
9892/*
9893 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9894 * any interesting requests and then jump to the real instruction
9895 * handler.  Unlike the Arm handler, we can't do this as a tail call
9896 * because rIBASE is caller save and we need to reload it.
9897 *
9898 * Note that unlike in the Arm implementation, we should never arrive
9899 * here with a zero breakFlag because we always refresh rIBASE on
9900 * return.
9901 */
9902    EXPORT_PC
9903    movl   rSELF, %eax
9904    movl   rPC, OUT_ARG0(%esp)
9905    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9906    movl   rFP, OUT_ARG1(%esp)
9907    je     1f                                # reload rIBASE & resume if not
9908    movl   %eax, OUT_ARG2(%esp)
9909    call   dvmCheckBefore                    # (dPC, dFP, self)
9910    movl   rSELF, %eax
99111:
9912    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9913    jmp    *dvmAsmInstructionStart+(75*4)
9914
9915/* ------------------------------ */
9916.L_ALT_OP_APUT_WIDE: /* 0x4c */
9917/* File: x86/alt_stub.S */
9918/*
9919 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9920 * any interesting requests and then jump to the real instruction
9921 * handler.  Unlike the Arm handler, we can't do this as a tail call
9922 * because rIBASE is caller save and we need to reload it.
9923 *
9924 * Note that unlike in the Arm implementation, we should never arrive
9925 * here with a zero breakFlag because we always refresh rIBASE on
9926 * return.
9927 */
9928    EXPORT_PC
9929    movl   rSELF, %eax
9930    movl   rPC, OUT_ARG0(%esp)
9931    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9932    movl   rFP, OUT_ARG1(%esp)
9933    je     1f                                # reload rIBASE & resume if not
9934    movl   %eax, OUT_ARG2(%esp)
9935    call   dvmCheckBefore                    # (dPC, dFP, self)
9936    movl   rSELF, %eax
99371:
9938    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9939    jmp    *dvmAsmInstructionStart+(76*4)
9940
9941/* ------------------------------ */
9942.L_ALT_OP_APUT_OBJECT: /* 0x4d */
9943/* File: x86/alt_stub.S */
9944/*
9945 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9946 * any interesting requests and then jump to the real instruction
9947 * handler.  Unlike the Arm handler, we can't do this as a tail call
9948 * because rIBASE is caller save and we need to reload it.
9949 *
9950 * Note that unlike in the Arm implementation, we should never arrive
9951 * here with a zero breakFlag because we always refresh rIBASE on
9952 * return.
9953 */
9954    EXPORT_PC
9955    movl   rSELF, %eax
9956    movl   rPC, OUT_ARG0(%esp)
9957    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9958    movl   rFP, OUT_ARG1(%esp)
9959    je     1f                                # reload rIBASE & resume if not
9960    movl   %eax, OUT_ARG2(%esp)
9961    call   dvmCheckBefore                    # (dPC, dFP, self)
9962    movl   rSELF, %eax
99631:
9964    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9965    jmp    *dvmAsmInstructionStart+(77*4)
9966
9967/* ------------------------------ */
9968.L_ALT_OP_APUT_BOOLEAN: /* 0x4e */
9969/* File: x86/alt_stub.S */
9970/*
9971 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9972 * any interesting requests and then jump to the real instruction
9973 * handler.  Unlike the Arm handler, we can't do this as a tail call
9974 * because rIBASE is caller save and we need to reload it.
9975 *
9976 * Note that unlike in the Arm implementation, we should never arrive
9977 * here with a zero breakFlag because we always refresh rIBASE on
9978 * return.
9979 */
9980    EXPORT_PC
9981    movl   rSELF, %eax
9982    movl   rPC, OUT_ARG0(%esp)
9983    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9984    movl   rFP, OUT_ARG1(%esp)
9985    je     1f                                # reload rIBASE & resume if not
9986    movl   %eax, OUT_ARG2(%esp)
9987    call   dvmCheckBefore                    # (dPC, dFP, self)
9988    movl   rSELF, %eax
99891:
9990    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9991    jmp    *dvmAsmInstructionStart+(78*4)
9992
9993/* ------------------------------ */
9994.L_ALT_OP_APUT_BYTE: /* 0x4f */
9995/* File: x86/alt_stub.S */
9996/*
9997 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9998 * any interesting requests and then jump to the real instruction
9999 * handler.  Unlike the Arm handler, we can't do this as a tail call
10000 * because rIBASE is caller save and we need to reload it.
10001 *
10002 * Note that unlike in the Arm implementation, we should never arrive
10003 * here with a zero breakFlag because we always refresh rIBASE on
10004 * return.
10005 */
10006    EXPORT_PC
10007    movl   rSELF, %eax
10008    movl   rPC, OUT_ARG0(%esp)
10009    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10010    movl   rFP, OUT_ARG1(%esp)
10011    je     1f                                # reload rIBASE & resume if not
10012    movl   %eax, OUT_ARG2(%esp)
10013    call   dvmCheckBefore                    # (dPC, dFP, self)
10014    movl   rSELF, %eax
100151:
10016    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10017    jmp    *dvmAsmInstructionStart+(79*4)
10018
10019/* ------------------------------ */
10020.L_ALT_OP_APUT_CHAR: /* 0x50 */
10021/* File: x86/alt_stub.S */
10022/*
10023 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10024 * any interesting requests and then jump to the real instruction
10025 * handler.  Unlike the Arm handler, we can't do this as a tail call
10026 * because rIBASE is caller save and we need to reload it.
10027 *
10028 * Note that unlike in the Arm implementation, we should never arrive
10029 * here with a zero breakFlag because we always refresh rIBASE on
10030 * return.
10031 */
10032    EXPORT_PC
10033    movl   rSELF, %eax
10034    movl   rPC, OUT_ARG0(%esp)
10035    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10036    movl   rFP, OUT_ARG1(%esp)
10037    je     1f                                # reload rIBASE & resume if not
10038    movl   %eax, OUT_ARG2(%esp)
10039    call   dvmCheckBefore                    # (dPC, dFP, self)
10040    movl   rSELF, %eax
100411:
10042    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10043    jmp    *dvmAsmInstructionStart+(80*4)
10044
10045/* ------------------------------ */
10046.L_ALT_OP_APUT_SHORT: /* 0x51 */
10047/* File: x86/alt_stub.S */
10048/*
10049 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10050 * any interesting requests and then jump to the real instruction
10051 * handler.  Unlike the Arm handler, we can't do this as a tail call
10052 * because rIBASE is caller save and we need to reload it.
10053 *
10054 * Note that unlike in the Arm implementation, we should never arrive
10055 * here with a zero breakFlag because we always refresh rIBASE on
10056 * return.
10057 */
10058    EXPORT_PC
10059    movl   rSELF, %eax
10060    movl   rPC, OUT_ARG0(%esp)
10061    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10062    movl   rFP, OUT_ARG1(%esp)
10063    je     1f                                # reload rIBASE & resume if not
10064    movl   %eax, OUT_ARG2(%esp)
10065    call   dvmCheckBefore                    # (dPC, dFP, self)
10066    movl   rSELF, %eax
100671:
10068    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10069    jmp    *dvmAsmInstructionStart+(81*4)
10070
10071/* ------------------------------ */
10072.L_ALT_OP_IGET: /* 0x52 */
10073/* File: x86/alt_stub.S */
10074/*
10075 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10076 * any interesting requests and then jump to the real instruction
10077 * handler.  Unlike the Arm handler, we can't do this as a tail call
10078 * because rIBASE is caller save and we need to reload it.
10079 *
10080 * Note that unlike in the Arm implementation, we should never arrive
10081 * here with a zero breakFlag because we always refresh rIBASE on
10082 * return.
10083 */
10084    EXPORT_PC
10085    movl   rSELF, %eax
10086    movl   rPC, OUT_ARG0(%esp)
10087    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10088    movl   rFP, OUT_ARG1(%esp)
10089    je     1f                                # reload rIBASE & resume if not
10090    movl   %eax, OUT_ARG2(%esp)
10091    call   dvmCheckBefore                    # (dPC, dFP, self)
10092    movl   rSELF, %eax
100931:
10094    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10095    jmp    *dvmAsmInstructionStart+(82*4)
10096
10097/* ------------------------------ */
10098.L_ALT_OP_IGET_WIDE: /* 0x53 */
10099/* File: x86/alt_stub.S */
10100/*
10101 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10102 * any interesting requests and then jump to the real instruction
10103 * handler.  Unlike the Arm handler, we can't do this as a tail call
10104 * because rIBASE is caller save and we need to reload it.
10105 *
10106 * Note that unlike in the Arm implementation, we should never arrive
10107 * here with a zero breakFlag because we always refresh rIBASE on
10108 * return.
10109 */
10110    EXPORT_PC
10111    movl   rSELF, %eax
10112    movl   rPC, OUT_ARG0(%esp)
10113    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10114    movl   rFP, OUT_ARG1(%esp)
10115    je     1f                                # reload rIBASE & resume if not
10116    movl   %eax, OUT_ARG2(%esp)
10117    call   dvmCheckBefore                    # (dPC, dFP, self)
10118    movl   rSELF, %eax
101191:
10120    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10121    jmp    *dvmAsmInstructionStart+(83*4)
10122
10123/* ------------------------------ */
10124.L_ALT_OP_IGET_OBJECT: /* 0x54 */
10125/* File: x86/alt_stub.S */
10126/*
10127 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10128 * any interesting requests and then jump to the real instruction
10129 * handler.  Unlike the Arm handler, we can't do this as a tail call
10130 * because rIBASE is caller save and we need to reload it.
10131 *
10132 * Note that unlike in the Arm implementation, we should never arrive
10133 * here with a zero breakFlag because we always refresh rIBASE on
10134 * return.
10135 */
10136    EXPORT_PC
10137    movl   rSELF, %eax
10138    movl   rPC, OUT_ARG0(%esp)
10139    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10140    movl   rFP, OUT_ARG1(%esp)
10141    je     1f                                # reload rIBASE & resume if not
10142    movl   %eax, OUT_ARG2(%esp)
10143    call   dvmCheckBefore                    # (dPC, dFP, self)
10144    movl   rSELF, %eax
101451:
10146    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10147    jmp    *dvmAsmInstructionStart+(84*4)
10148
10149/* ------------------------------ */
10150.L_ALT_OP_IGET_BOOLEAN: /* 0x55 */
10151/* File: x86/alt_stub.S */
10152/*
10153 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10154 * any interesting requests and then jump to the real instruction
10155 * handler.  Unlike the Arm handler, we can't do this as a tail call
10156 * because rIBASE is caller save and we need to reload it.
10157 *
10158 * Note that unlike in the Arm implementation, we should never arrive
10159 * here with a zero breakFlag because we always refresh rIBASE on
10160 * return.
10161 */
10162    EXPORT_PC
10163    movl   rSELF, %eax
10164    movl   rPC, OUT_ARG0(%esp)
10165    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10166    movl   rFP, OUT_ARG1(%esp)
10167    je     1f                                # reload rIBASE & resume if not
10168    movl   %eax, OUT_ARG2(%esp)
10169    call   dvmCheckBefore                    # (dPC, dFP, self)
10170    movl   rSELF, %eax
101711:
10172    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10173    jmp    *dvmAsmInstructionStart+(85*4)
10174
10175/* ------------------------------ */
10176.L_ALT_OP_IGET_BYTE: /* 0x56 */
10177/* File: x86/alt_stub.S */
10178/*
10179 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10180 * any interesting requests and then jump to the real instruction
10181 * handler.  Unlike the Arm handler, we can't do this as a tail call
10182 * because rIBASE is caller save and we need to reload it.
10183 *
10184 * Note that unlike in the Arm implementation, we should never arrive
10185 * here with a zero breakFlag because we always refresh rIBASE on
10186 * return.
10187 */
10188    EXPORT_PC
10189    movl   rSELF, %eax
10190    movl   rPC, OUT_ARG0(%esp)
10191    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10192    movl   rFP, OUT_ARG1(%esp)
10193    je     1f                                # reload rIBASE & resume if not
10194    movl   %eax, OUT_ARG2(%esp)
10195    call   dvmCheckBefore                    # (dPC, dFP, self)
10196    movl   rSELF, %eax
101971:
10198    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10199    jmp    *dvmAsmInstructionStart+(86*4)
10200
10201/* ------------------------------ */
10202.L_ALT_OP_IGET_CHAR: /* 0x57 */
10203/* File: x86/alt_stub.S */
10204/*
10205 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10206 * any interesting requests and then jump to the real instruction
10207 * handler.  Unlike the Arm handler, we can't do this as a tail call
10208 * because rIBASE is caller save and we need to reload it.
10209 *
10210 * Note that unlike in the Arm implementation, we should never arrive
10211 * here with a zero breakFlag because we always refresh rIBASE on
10212 * return.
10213 */
10214    EXPORT_PC
10215    movl   rSELF, %eax
10216    movl   rPC, OUT_ARG0(%esp)
10217    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10218    movl   rFP, OUT_ARG1(%esp)
10219    je     1f                                # reload rIBASE & resume if not
10220    movl   %eax, OUT_ARG2(%esp)
10221    call   dvmCheckBefore                    # (dPC, dFP, self)
10222    movl   rSELF, %eax
102231:
10224    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10225    jmp    *dvmAsmInstructionStart+(87*4)
10226
10227/* ------------------------------ */
10228.L_ALT_OP_IGET_SHORT: /* 0x58 */
10229/* File: x86/alt_stub.S */
10230/*
10231 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10232 * any interesting requests and then jump to the real instruction
10233 * handler.  Unlike the Arm handler, we can't do this as a tail call
10234 * because rIBASE is caller save and we need to reload it.
10235 *
10236 * Note that unlike in the Arm implementation, we should never arrive
10237 * here with a zero breakFlag because we always refresh rIBASE on
10238 * return.
10239 */
10240    EXPORT_PC
10241    movl   rSELF, %eax
10242    movl   rPC, OUT_ARG0(%esp)
10243    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10244    movl   rFP, OUT_ARG1(%esp)
10245    je     1f                                # reload rIBASE & resume if not
10246    movl   %eax, OUT_ARG2(%esp)
10247    call   dvmCheckBefore                    # (dPC, dFP, self)
10248    movl   rSELF, %eax
102491:
10250    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10251    jmp    *dvmAsmInstructionStart+(88*4)
10252
10253/* ------------------------------ */
10254.L_ALT_OP_IPUT: /* 0x59 */
10255/* File: x86/alt_stub.S */
10256/*
10257 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10258 * any interesting requests and then jump to the real instruction
10259 * handler.  Unlike the Arm handler, we can't do this as a tail call
10260 * because rIBASE is caller save and we need to reload it.
10261 *
10262 * Note that unlike in the Arm implementation, we should never arrive
10263 * here with a zero breakFlag because we always refresh rIBASE on
10264 * return.
10265 */
10266    EXPORT_PC
10267    movl   rSELF, %eax
10268    movl   rPC, OUT_ARG0(%esp)
10269    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10270    movl   rFP, OUT_ARG1(%esp)
10271    je     1f                                # reload rIBASE & resume if not
10272    movl   %eax, OUT_ARG2(%esp)
10273    call   dvmCheckBefore                    # (dPC, dFP, self)
10274    movl   rSELF, %eax
102751:
10276    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10277    jmp    *dvmAsmInstructionStart+(89*4)
10278
10279/* ------------------------------ */
10280.L_ALT_OP_IPUT_WIDE: /* 0x5a */
10281/* File: x86/alt_stub.S */
10282/*
10283 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10284 * any interesting requests and then jump to the real instruction
10285 * handler.  Unlike the Arm handler, we can't do this as a tail call
10286 * because rIBASE is caller save and we need to reload it.
10287 *
10288 * Note that unlike in the Arm implementation, we should never arrive
10289 * here with a zero breakFlag because we always refresh rIBASE on
10290 * return.
10291 */
10292    EXPORT_PC
10293    movl   rSELF, %eax
10294    movl   rPC, OUT_ARG0(%esp)
10295    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10296    movl   rFP, OUT_ARG1(%esp)
10297    je     1f                                # reload rIBASE & resume if not
10298    movl   %eax, OUT_ARG2(%esp)
10299    call   dvmCheckBefore                    # (dPC, dFP, self)
10300    movl   rSELF, %eax
103011:
10302    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10303    jmp    *dvmAsmInstructionStart+(90*4)
10304
10305/* ------------------------------ */
10306.L_ALT_OP_IPUT_OBJECT: /* 0x5b */
10307/* File: x86/alt_stub.S */
10308/*
10309 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10310 * any interesting requests and then jump to the real instruction
10311 * handler.  Unlike the Arm handler, we can't do this as a tail call
10312 * because rIBASE is caller save and we need to reload it.
10313 *
10314 * Note that unlike in the Arm implementation, we should never arrive
10315 * here with a zero breakFlag because we always refresh rIBASE on
10316 * return.
10317 */
10318    EXPORT_PC
10319    movl   rSELF, %eax
10320    movl   rPC, OUT_ARG0(%esp)
10321    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10322    movl   rFP, OUT_ARG1(%esp)
10323    je     1f                                # reload rIBASE & resume if not
10324    movl   %eax, OUT_ARG2(%esp)
10325    call   dvmCheckBefore                    # (dPC, dFP, self)
10326    movl   rSELF, %eax
103271:
10328    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10329    jmp    *dvmAsmInstructionStart+(91*4)
10330
10331/* ------------------------------ */
10332.L_ALT_OP_IPUT_BOOLEAN: /* 0x5c */
10333/* File: x86/alt_stub.S */
10334/*
10335 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10336 * any interesting requests and then jump to the real instruction
10337 * handler.  Unlike the Arm handler, we can't do this as a tail call
10338 * because rIBASE is caller save and we need to reload it.
10339 *
10340 * Note that unlike in the Arm implementation, we should never arrive
10341 * here with a zero breakFlag because we always refresh rIBASE on
10342 * return.
10343 */
10344    EXPORT_PC
10345    movl   rSELF, %eax
10346    movl   rPC, OUT_ARG0(%esp)
10347    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10348    movl   rFP, OUT_ARG1(%esp)
10349    je     1f                                # reload rIBASE & resume if not
10350    movl   %eax, OUT_ARG2(%esp)
10351    call   dvmCheckBefore                    # (dPC, dFP, self)
10352    movl   rSELF, %eax
103531:
10354    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10355    jmp    *dvmAsmInstructionStart+(92*4)
10356
10357/* ------------------------------ */
10358.L_ALT_OP_IPUT_BYTE: /* 0x5d */
10359/* File: x86/alt_stub.S */
10360/*
10361 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10362 * any interesting requests and then jump to the real instruction
10363 * handler.  Unlike the Arm handler, we can't do this as a tail call
10364 * because rIBASE is caller save and we need to reload it.
10365 *
10366 * Note that unlike in the Arm implementation, we should never arrive
10367 * here with a zero breakFlag because we always refresh rIBASE on
10368 * return.
10369 */
10370    EXPORT_PC
10371    movl   rSELF, %eax
10372    movl   rPC, OUT_ARG0(%esp)
10373    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10374    movl   rFP, OUT_ARG1(%esp)
10375    je     1f                                # reload rIBASE & resume if not
10376    movl   %eax, OUT_ARG2(%esp)
10377    call   dvmCheckBefore                    # (dPC, dFP, self)
10378    movl   rSELF, %eax
103791:
10380    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10381    jmp    *dvmAsmInstructionStart+(93*4)
10382
10383/* ------------------------------ */
10384.L_ALT_OP_IPUT_CHAR: /* 0x5e */
10385/* File: x86/alt_stub.S */
10386/*
10387 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10388 * any interesting requests and then jump to the real instruction
10389 * handler.  Unlike the Arm handler, we can't do this as a tail call
10390 * because rIBASE is caller save and we need to reload it.
10391 *
10392 * Note that unlike in the Arm implementation, we should never arrive
10393 * here with a zero breakFlag because we always refresh rIBASE on
10394 * return.
10395 */
10396    EXPORT_PC
10397    movl   rSELF, %eax
10398    movl   rPC, OUT_ARG0(%esp)
10399    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10400    movl   rFP, OUT_ARG1(%esp)
10401    je     1f                                # reload rIBASE & resume if not
10402    movl   %eax, OUT_ARG2(%esp)
10403    call   dvmCheckBefore                    # (dPC, dFP, self)
10404    movl   rSELF, %eax
104051:
10406    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10407    jmp    *dvmAsmInstructionStart+(94*4)
10408
10409/* ------------------------------ */
10410.L_ALT_OP_IPUT_SHORT: /* 0x5f */
10411/* File: x86/alt_stub.S */
10412/*
10413 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10414 * any interesting requests and then jump to the real instruction
10415 * handler.  Unlike the Arm handler, we can't do this as a tail call
10416 * because rIBASE is caller save and we need to reload it.
10417 *
10418 * Note that unlike in the Arm implementation, we should never arrive
10419 * here with a zero breakFlag because we always refresh rIBASE on
10420 * return.
10421 */
10422    EXPORT_PC
10423    movl   rSELF, %eax
10424    movl   rPC, OUT_ARG0(%esp)
10425    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10426    movl   rFP, OUT_ARG1(%esp)
10427    je     1f                                # reload rIBASE & resume if not
10428    movl   %eax, OUT_ARG2(%esp)
10429    call   dvmCheckBefore                    # (dPC, dFP, self)
10430    movl   rSELF, %eax
104311:
10432    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10433    jmp    *dvmAsmInstructionStart+(95*4)
10434
10435/* ------------------------------ */
10436.L_ALT_OP_SGET: /* 0x60 */
10437/* File: x86/alt_stub.S */
10438/*
10439 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10440 * any interesting requests and then jump to the real instruction
10441 * handler.  Unlike the Arm handler, we can't do this as a tail call
10442 * because rIBASE is caller save and we need to reload it.
10443 *
10444 * Note that unlike in the Arm implementation, we should never arrive
10445 * here with a zero breakFlag because we always refresh rIBASE on
10446 * return.
10447 */
10448    EXPORT_PC
10449    movl   rSELF, %eax
10450    movl   rPC, OUT_ARG0(%esp)
10451    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10452    movl   rFP, OUT_ARG1(%esp)
10453    je     1f                                # reload rIBASE & resume if not
10454    movl   %eax, OUT_ARG2(%esp)
10455    call   dvmCheckBefore                    # (dPC, dFP, self)
10456    movl   rSELF, %eax
104571:
10458    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10459    jmp    *dvmAsmInstructionStart+(96*4)
10460
10461/* ------------------------------ */
10462.L_ALT_OP_SGET_WIDE: /* 0x61 */
10463/* File: x86/alt_stub.S */
10464/*
10465 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10466 * any interesting requests and then jump to the real instruction
10467 * handler.  Unlike the Arm handler, we can't do this as a tail call
10468 * because rIBASE is caller save and we need to reload it.
10469 *
10470 * Note that unlike in the Arm implementation, we should never arrive
10471 * here with a zero breakFlag because we always refresh rIBASE on
10472 * return.
10473 */
10474    EXPORT_PC
10475    movl   rSELF, %eax
10476    movl   rPC, OUT_ARG0(%esp)
10477    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10478    movl   rFP, OUT_ARG1(%esp)
10479    je     1f                                # reload rIBASE & resume if not
10480    movl   %eax, OUT_ARG2(%esp)
10481    call   dvmCheckBefore                    # (dPC, dFP, self)
10482    movl   rSELF, %eax
104831:
10484    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10485    jmp    *dvmAsmInstructionStart+(97*4)
10486
10487/* ------------------------------ */
10488.L_ALT_OP_SGET_OBJECT: /* 0x62 */
10489/* File: x86/alt_stub.S */
10490/*
10491 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10492 * any interesting requests and then jump to the real instruction
10493 * handler.  Unlike the Arm handler, we can't do this as a tail call
10494 * because rIBASE is caller save and we need to reload it.
10495 *
10496 * Note that unlike in the Arm implementation, we should never arrive
10497 * here with a zero breakFlag because we always refresh rIBASE on
10498 * return.
10499 */
10500    EXPORT_PC
10501    movl   rSELF, %eax
10502    movl   rPC, OUT_ARG0(%esp)
10503    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10504    movl   rFP, OUT_ARG1(%esp)
10505    je     1f                                # reload rIBASE & resume if not
10506    movl   %eax, OUT_ARG2(%esp)
10507    call   dvmCheckBefore                    # (dPC, dFP, self)
10508    movl   rSELF, %eax
105091:
10510    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10511    jmp    *dvmAsmInstructionStart+(98*4)
10512
10513/* ------------------------------ */
10514.L_ALT_OP_SGET_BOOLEAN: /* 0x63 */
10515/* File: x86/alt_stub.S */
10516/*
10517 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10518 * any interesting requests and then jump to the real instruction
10519 * handler.  Unlike the Arm handler, we can't do this as a tail call
10520 * because rIBASE is caller save and we need to reload it.
10521 *
10522 * Note that unlike in the Arm implementation, we should never arrive
10523 * here with a zero breakFlag because we always refresh rIBASE on
10524 * return.
10525 */
10526    EXPORT_PC
10527    movl   rSELF, %eax
10528    movl   rPC, OUT_ARG0(%esp)
10529    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10530    movl   rFP, OUT_ARG1(%esp)
10531    je     1f                                # reload rIBASE & resume if not
10532    movl   %eax, OUT_ARG2(%esp)
10533    call   dvmCheckBefore                    # (dPC, dFP, self)
10534    movl   rSELF, %eax
105351:
10536    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10537    jmp    *dvmAsmInstructionStart+(99*4)
10538
10539/* ------------------------------ */
10540.L_ALT_OP_SGET_BYTE: /* 0x64 */
10541/* File: x86/alt_stub.S */
10542/*
10543 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10544 * any interesting requests and then jump to the real instruction
10545 * handler.  Unlike the Arm handler, we can't do this as a tail call
10546 * because rIBASE is caller save and we need to reload it.
10547 *
10548 * Note that unlike in the Arm implementation, we should never arrive
10549 * here with a zero breakFlag because we always refresh rIBASE on
10550 * return.
10551 */
10552    EXPORT_PC
10553    movl   rSELF, %eax
10554    movl   rPC, OUT_ARG0(%esp)
10555    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10556    movl   rFP, OUT_ARG1(%esp)
10557    je     1f                                # reload rIBASE & resume if not
10558    movl   %eax, OUT_ARG2(%esp)
10559    call   dvmCheckBefore                    # (dPC, dFP, self)
10560    movl   rSELF, %eax
105611:
10562    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10563    jmp    *dvmAsmInstructionStart+(100*4)
10564
10565/* ------------------------------ */
10566.L_ALT_OP_SGET_CHAR: /* 0x65 */
10567/* File: x86/alt_stub.S */
10568/*
10569 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10570 * any interesting requests and then jump to the real instruction
10571 * handler.  Unlike the Arm handler, we can't do this as a tail call
10572 * because rIBASE is caller save and we need to reload it.
10573 *
10574 * Note that unlike in the Arm implementation, we should never arrive
10575 * here with a zero breakFlag because we always refresh rIBASE on
10576 * return.
10577 */
10578    EXPORT_PC
10579    movl   rSELF, %eax
10580    movl   rPC, OUT_ARG0(%esp)
10581    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10582    movl   rFP, OUT_ARG1(%esp)
10583    je     1f                                # reload rIBASE & resume if not
10584    movl   %eax, OUT_ARG2(%esp)
10585    call   dvmCheckBefore                    # (dPC, dFP, self)
10586    movl   rSELF, %eax
105871:
10588    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10589    jmp    *dvmAsmInstructionStart+(101*4)
10590
10591/* ------------------------------ */
10592.L_ALT_OP_SGET_SHORT: /* 0x66 */
10593/* File: x86/alt_stub.S */
10594/*
10595 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10596 * any interesting requests and then jump to the real instruction
10597 * handler.  Unlike the Arm handler, we can't do this as a tail call
10598 * because rIBASE is caller save and we need to reload it.
10599 *
10600 * Note that unlike in the Arm implementation, we should never arrive
10601 * here with a zero breakFlag because we always refresh rIBASE on
10602 * return.
10603 */
10604    EXPORT_PC
10605    movl   rSELF, %eax
10606    movl   rPC, OUT_ARG0(%esp)
10607    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10608    movl   rFP, OUT_ARG1(%esp)
10609    je     1f                                # reload rIBASE & resume if not
10610    movl   %eax, OUT_ARG2(%esp)
10611    call   dvmCheckBefore                    # (dPC, dFP, self)
10612    movl   rSELF, %eax
106131:
10614    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10615    jmp    *dvmAsmInstructionStart+(102*4)
10616
10617/* ------------------------------ */
10618.L_ALT_OP_SPUT: /* 0x67 */
10619/* File: x86/alt_stub.S */
10620/*
10621 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10622 * any interesting requests and then jump to the real instruction
10623 * handler.  Unlike the Arm handler, we can't do this as a tail call
10624 * because rIBASE is caller save and we need to reload it.
10625 *
10626 * Note that unlike in the Arm implementation, we should never arrive
10627 * here with a zero breakFlag because we always refresh rIBASE on
10628 * return.
10629 */
10630    EXPORT_PC
10631    movl   rSELF, %eax
10632    movl   rPC, OUT_ARG0(%esp)
10633    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10634    movl   rFP, OUT_ARG1(%esp)
10635    je     1f                                # reload rIBASE & resume if not
10636    movl   %eax, OUT_ARG2(%esp)
10637    call   dvmCheckBefore                    # (dPC, dFP, self)
10638    movl   rSELF, %eax
106391:
10640    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10641    jmp    *dvmAsmInstructionStart+(103*4)
10642
10643/* ------------------------------ */
10644.L_ALT_OP_SPUT_WIDE: /* 0x68 */
10645/* File: x86/alt_stub.S */
10646/*
10647 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10648 * any interesting requests and then jump to the real instruction
10649 * handler.  Unlike the Arm handler, we can't do this as a tail call
10650 * because rIBASE is caller save and we need to reload it.
10651 *
10652 * Note that unlike in the Arm implementation, we should never arrive
10653 * here with a zero breakFlag because we always refresh rIBASE on
10654 * return.
10655 */
10656    EXPORT_PC
10657    movl   rSELF, %eax
10658    movl   rPC, OUT_ARG0(%esp)
10659    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10660    movl   rFP, OUT_ARG1(%esp)
10661    je     1f                                # reload rIBASE & resume if not
10662    movl   %eax, OUT_ARG2(%esp)
10663    call   dvmCheckBefore                    # (dPC, dFP, self)
10664    movl   rSELF, %eax
106651:
10666    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10667    jmp    *dvmAsmInstructionStart+(104*4)
10668
10669/* ------------------------------ */
10670.L_ALT_OP_SPUT_OBJECT: /* 0x69 */
10671/* File: x86/alt_stub.S */
10672/*
10673 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10674 * any interesting requests and then jump to the real instruction
10675 * handler.  Unlike the Arm handler, we can't do this as a tail call
10676 * because rIBASE is caller save and we need to reload it.
10677 *
10678 * Note that unlike in the Arm implementation, we should never arrive
10679 * here with a zero breakFlag because we always refresh rIBASE on
10680 * return.
10681 */
10682    EXPORT_PC
10683    movl   rSELF, %eax
10684    movl   rPC, OUT_ARG0(%esp)
10685    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10686    movl   rFP, OUT_ARG1(%esp)
10687    je     1f                                # reload rIBASE & resume if not
10688    movl   %eax, OUT_ARG2(%esp)
10689    call   dvmCheckBefore                    # (dPC, dFP, self)
10690    movl   rSELF, %eax
106911:
10692    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10693    jmp    *dvmAsmInstructionStart+(105*4)
10694
10695/* ------------------------------ */
10696.L_ALT_OP_SPUT_BOOLEAN: /* 0x6a */
10697/* File: x86/alt_stub.S */
10698/*
10699 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10700 * any interesting requests and then jump to the real instruction
10701 * handler.  Unlike the Arm handler, we can't do this as a tail call
10702 * because rIBASE is caller save and we need to reload it.
10703 *
10704 * Note that unlike in the Arm implementation, we should never arrive
10705 * here with a zero breakFlag because we always refresh rIBASE on
10706 * return.
10707 */
10708    EXPORT_PC
10709    movl   rSELF, %eax
10710    movl   rPC, OUT_ARG0(%esp)
10711    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10712    movl   rFP, OUT_ARG1(%esp)
10713    je     1f                                # reload rIBASE & resume if not
10714    movl   %eax, OUT_ARG2(%esp)
10715    call   dvmCheckBefore                    # (dPC, dFP, self)
10716    movl   rSELF, %eax
107171:
10718    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10719    jmp    *dvmAsmInstructionStart+(106*4)
10720
10721/* ------------------------------ */
10722.L_ALT_OP_SPUT_BYTE: /* 0x6b */
10723/* File: x86/alt_stub.S */
10724/*
10725 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10726 * any interesting requests and then jump to the real instruction
10727 * handler.  Unlike the Arm handler, we can't do this as a tail call
10728 * because rIBASE is caller save and we need to reload it.
10729 *
10730 * Note that unlike in the Arm implementation, we should never arrive
10731 * here with a zero breakFlag because we always refresh rIBASE on
10732 * return.
10733 */
10734    EXPORT_PC
10735    movl   rSELF, %eax
10736    movl   rPC, OUT_ARG0(%esp)
10737    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10738    movl   rFP, OUT_ARG1(%esp)
10739    je     1f                                # reload rIBASE & resume if not
10740    movl   %eax, OUT_ARG2(%esp)
10741    call   dvmCheckBefore                    # (dPC, dFP, self)
10742    movl   rSELF, %eax
107431:
10744    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10745    jmp    *dvmAsmInstructionStart+(107*4)
10746
10747/* ------------------------------ */
10748.L_ALT_OP_SPUT_CHAR: /* 0x6c */
10749/* File: x86/alt_stub.S */
10750/*
10751 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10752 * any interesting requests and then jump to the real instruction
10753 * handler.  Unlike the Arm handler, we can't do this as a tail call
10754 * because rIBASE is caller save and we need to reload it.
10755 *
10756 * Note that unlike in the Arm implementation, we should never arrive
10757 * here with a zero breakFlag because we always refresh rIBASE on
10758 * return.
10759 */
10760    EXPORT_PC
10761    movl   rSELF, %eax
10762    movl   rPC, OUT_ARG0(%esp)
10763    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10764    movl   rFP, OUT_ARG1(%esp)
10765    je     1f                                # reload rIBASE & resume if not
10766    movl   %eax, OUT_ARG2(%esp)
10767    call   dvmCheckBefore                    # (dPC, dFP, self)
10768    movl   rSELF, %eax
107691:
10770    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10771    jmp    *dvmAsmInstructionStart+(108*4)
10772
10773/* ------------------------------ */
10774.L_ALT_OP_SPUT_SHORT: /* 0x6d */
10775/* File: x86/alt_stub.S */
10776/*
10777 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10778 * any interesting requests and then jump to the real instruction
10779 * handler.  Unlike the Arm handler, we can't do this as a tail call
10780 * because rIBASE is caller save and we need to reload it.
10781 *
10782 * Note that unlike in the Arm implementation, we should never arrive
10783 * here with a zero breakFlag because we always refresh rIBASE on
10784 * return.
10785 */
10786    EXPORT_PC
10787    movl   rSELF, %eax
10788    movl   rPC, OUT_ARG0(%esp)
10789    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10790    movl   rFP, OUT_ARG1(%esp)
10791    je     1f                                # reload rIBASE & resume if not
10792    movl   %eax, OUT_ARG2(%esp)
10793    call   dvmCheckBefore                    # (dPC, dFP, self)
10794    movl   rSELF, %eax
107951:
10796    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10797    jmp    *dvmAsmInstructionStart+(109*4)
10798
10799/* ------------------------------ */
10800.L_ALT_OP_INVOKE_VIRTUAL: /* 0x6e */
10801/* File: x86/alt_stub.S */
10802/*
10803 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10804 * any interesting requests and then jump to the real instruction
10805 * handler.  Unlike the Arm handler, we can't do this as a tail call
10806 * because rIBASE is caller save and we need to reload it.
10807 *
10808 * Note that unlike in the Arm implementation, we should never arrive
10809 * here with a zero breakFlag because we always refresh rIBASE on
10810 * return.
10811 */
10812    EXPORT_PC
10813    movl   rSELF, %eax
10814    movl   rPC, OUT_ARG0(%esp)
10815    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10816    movl   rFP, OUT_ARG1(%esp)
10817    je     1f                                # reload rIBASE & resume if not
10818    movl   %eax, OUT_ARG2(%esp)
10819    call   dvmCheckBefore                    # (dPC, dFP, self)
10820    movl   rSELF, %eax
108211:
10822    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10823    jmp    *dvmAsmInstructionStart+(110*4)
10824
10825/* ------------------------------ */
10826.L_ALT_OP_INVOKE_SUPER: /* 0x6f */
10827/* File: x86/alt_stub.S */
10828/*
10829 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10830 * any interesting requests and then jump to the real instruction
10831 * handler.  Unlike the Arm handler, we can't do this as a tail call
10832 * because rIBASE is caller save and we need to reload it.
10833 *
10834 * Note that unlike in the Arm implementation, we should never arrive
10835 * here with a zero breakFlag because we always refresh rIBASE on
10836 * return.
10837 */
10838    EXPORT_PC
10839    movl   rSELF, %eax
10840    movl   rPC, OUT_ARG0(%esp)
10841    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10842    movl   rFP, OUT_ARG1(%esp)
10843    je     1f                                # reload rIBASE & resume if not
10844    movl   %eax, OUT_ARG2(%esp)
10845    call   dvmCheckBefore                    # (dPC, dFP, self)
10846    movl   rSELF, %eax
108471:
10848    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10849    jmp    *dvmAsmInstructionStart+(111*4)
10850
10851/* ------------------------------ */
10852.L_ALT_OP_INVOKE_DIRECT: /* 0x70 */
10853/* File: x86/alt_stub.S */
10854/*
10855 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10856 * any interesting requests and then jump to the real instruction
10857 * handler.  Unlike the Arm handler, we can't do this as a tail call
10858 * because rIBASE is caller save and we need to reload it.
10859 *
10860 * Note that unlike in the Arm implementation, we should never arrive
10861 * here with a zero breakFlag because we always refresh rIBASE on
10862 * return.
10863 */
10864    EXPORT_PC
10865    movl   rSELF, %eax
10866    movl   rPC, OUT_ARG0(%esp)
10867    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10868    movl   rFP, OUT_ARG1(%esp)
10869    je     1f                                # reload rIBASE & resume if not
10870    movl   %eax, OUT_ARG2(%esp)
10871    call   dvmCheckBefore                    # (dPC, dFP, self)
10872    movl   rSELF, %eax
108731:
10874    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10875    jmp    *dvmAsmInstructionStart+(112*4)
10876
10877/* ------------------------------ */
10878.L_ALT_OP_INVOKE_STATIC: /* 0x71 */
10879/* File: x86/alt_stub.S */
10880/*
10881 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10882 * any interesting requests and then jump to the real instruction
10883 * handler.  Unlike the Arm handler, we can't do this as a tail call
10884 * because rIBASE is caller save and we need to reload it.
10885 *
10886 * Note that unlike in the Arm implementation, we should never arrive
10887 * here with a zero breakFlag because we always refresh rIBASE on
10888 * return.
10889 */
10890    EXPORT_PC
10891    movl   rSELF, %eax
10892    movl   rPC, OUT_ARG0(%esp)
10893    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10894    movl   rFP, OUT_ARG1(%esp)
10895    je     1f                                # reload rIBASE & resume if not
10896    movl   %eax, OUT_ARG2(%esp)
10897    call   dvmCheckBefore                    # (dPC, dFP, self)
10898    movl   rSELF, %eax
108991:
10900    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10901    jmp    *dvmAsmInstructionStart+(113*4)
10902
10903/* ------------------------------ */
10904.L_ALT_OP_INVOKE_INTERFACE: /* 0x72 */
10905/* File: x86/alt_stub.S */
10906/*
10907 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10908 * any interesting requests and then jump to the real instruction
10909 * handler.  Unlike the Arm handler, we can't do this as a tail call
10910 * because rIBASE is caller save and we need to reload it.
10911 *
10912 * Note that unlike in the Arm implementation, we should never arrive
10913 * here with a zero breakFlag because we always refresh rIBASE on
10914 * return.
10915 */
10916    EXPORT_PC
10917    movl   rSELF, %eax
10918    movl   rPC, OUT_ARG0(%esp)
10919    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10920    movl   rFP, OUT_ARG1(%esp)
10921    je     1f                                # reload rIBASE & resume if not
10922    movl   %eax, OUT_ARG2(%esp)
10923    call   dvmCheckBefore                    # (dPC, dFP, self)
10924    movl   rSELF, %eax
109251:
10926    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10927    jmp    *dvmAsmInstructionStart+(114*4)
10928
10929/* ------------------------------ */
10930.L_ALT_OP_UNUSED_73: /* 0x73 */
10931/* File: x86/alt_stub.S */
10932/*
10933 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10934 * any interesting requests and then jump to the real instruction
10935 * handler.  Unlike the Arm handler, we can't do this as a tail call
10936 * because rIBASE is caller save and we need to reload it.
10937 *
10938 * Note that unlike in the Arm implementation, we should never arrive
10939 * here with a zero breakFlag because we always refresh rIBASE on
10940 * return.
10941 */
10942    EXPORT_PC
10943    movl   rSELF, %eax
10944    movl   rPC, OUT_ARG0(%esp)
10945    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10946    movl   rFP, OUT_ARG1(%esp)
10947    je     1f                                # reload rIBASE & resume if not
10948    movl   %eax, OUT_ARG2(%esp)
10949    call   dvmCheckBefore                    # (dPC, dFP, self)
10950    movl   rSELF, %eax
109511:
10952    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10953    jmp    *dvmAsmInstructionStart+(115*4)
10954
10955/* ------------------------------ */
10956.L_ALT_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
10957/* File: x86/alt_stub.S */
10958/*
10959 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10960 * any interesting requests and then jump to the real instruction
10961 * handler.  Unlike the Arm handler, we can't do this as a tail call
10962 * because rIBASE is caller save and we need to reload it.
10963 *
10964 * Note that unlike in the Arm implementation, we should never arrive
10965 * here with a zero breakFlag because we always refresh rIBASE on
10966 * return.
10967 */
10968    EXPORT_PC
10969    movl   rSELF, %eax
10970    movl   rPC, OUT_ARG0(%esp)
10971    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10972    movl   rFP, OUT_ARG1(%esp)
10973    je     1f                                # reload rIBASE & resume if not
10974    movl   %eax, OUT_ARG2(%esp)
10975    call   dvmCheckBefore                    # (dPC, dFP, self)
10976    movl   rSELF, %eax
109771:
10978    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10979    jmp    *dvmAsmInstructionStart+(116*4)
10980
10981/* ------------------------------ */
10982.L_ALT_OP_INVOKE_SUPER_RANGE: /* 0x75 */
10983/* File: x86/alt_stub.S */
10984/*
10985 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10986 * any interesting requests and then jump to the real instruction
10987 * handler.  Unlike the Arm handler, we can't do this as a tail call
10988 * because rIBASE is caller save and we need to reload it.
10989 *
10990 * Note that unlike in the Arm implementation, we should never arrive
10991 * here with a zero breakFlag because we always refresh rIBASE on
10992 * return.
10993 */
10994    EXPORT_PC
10995    movl   rSELF, %eax
10996    movl   rPC, OUT_ARG0(%esp)
10997    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10998    movl   rFP, OUT_ARG1(%esp)
10999    je     1f                                # reload rIBASE & resume if not
11000    movl   %eax, OUT_ARG2(%esp)
11001    call   dvmCheckBefore                    # (dPC, dFP, self)
11002    movl   rSELF, %eax
110031:
11004    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11005    jmp    *dvmAsmInstructionStart+(117*4)
11006
11007/* ------------------------------ */
11008.L_ALT_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
11009/* File: x86/alt_stub.S */
11010/*
11011 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11012 * any interesting requests and then jump to the real instruction
11013 * handler.  Unlike the Arm handler, we can't do this as a tail call
11014 * because rIBASE is caller save and we need to reload it.
11015 *
11016 * Note that unlike in the Arm implementation, we should never arrive
11017 * here with a zero breakFlag because we always refresh rIBASE on
11018 * return.
11019 */
11020    EXPORT_PC
11021    movl   rSELF, %eax
11022    movl   rPC, OUT_ARG0(%esp)
11023    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11024    movl   rFP, OUT_ARG1(%esp)
11025    je     1f                                # reload rIBASE & resume if not
11026    movl   %eax, OUT_ARG2(%esp)
11027    call   dvmCheckBefore                    # (dPC, dFP, self)
11028    movl   rSELF, %eax
110291:
11030    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11031    jmp    *dvmAsmInstructionStart+(118*4)
11032
11033/* ------------------------------ */
11034.L_ALT_OP_INVOKE_STATIC_RANGE: /* 0x77 */
11035/* File: x86/alt_stub.S */
11036/*
11037 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11038 * any interesting requests and then jump to the real instruction
11039 * handler.  Unlike the Arm handler, we can't do this as a tail call
11040 * because rIBASE is caller save and we need to reload it.
11041 *
11042 * Note that unlike in the Arm implementation, we should never arrive
11043 * here with a zero breakFlag because we always refresh rIBASE on
11044 * return.
11045 */
11046    EXPORT_PC
11047    movl   rSELF, %eax
11048    movl   rPC, OUT_ARG0(%esp)
11049    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11050    movl   rFP, OUT_ARG1(%esp)
11051    je     1f                                # reload rIBASE & resume if not
11052    movl   %eax, OUT_ARG2(%esp)
11053    call   dvmCheckBefore                    # (dPC, dFP, self)
11054    movl   rSELF, %eax
110551:
11056    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11057    jmp    *dvmAsmInstructionStart+(119*4)
11058
11059/* ------------------------------ */
11060.L_ALT_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
11061/* File: x86/alt_stub.S */
11062/*
11063 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11064 * any interesting requests and then jump to the real instruction
11065 * handler.  Unlike the Arm handler, we can't do this as a tail call
11066 * because rIBASE is caller save and we need to reload it.
11067 *
11068 * Note that unlike in the Arm implementation, we should never arrive
11069 * here with a zero breakFlag because we always refresh rIBASE on
11070 * return.
11071 */
11072    EXPORT_PC
11073    movl   rSELF, %eax
11074    movl   rPC, OUT_ARG0(%esp)
11075    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11076    movl   rFP, OUT_ARG1(%esp)
11077    je     1f                                # reload rIBASE & resume if not
11078    movl   %eax, OUT_ARG2(%esp)
11079    call   dvmCheckBefore                    # (dPC, dFP, self)
11080    movl   rSELF, %eax
110811:
11082    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11083    jmp    *dvmAsmInstructionStart+(120*4)
11084
11085/* ------------------------------ */
11086.L_ALT_OP_UNUSED_79: /* 0x79 */
11087/* File: x86/alt_stub.S */
11088/*
11089 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11090 * any interesting requests and then jump to the real instruction
11091 * handler.  Unlike the Arm handler, we can't do this as a tail call
11092 * because rIBASE is caller save and we need to reload it.
11093 *
11094 * Note that unlike in the Arm implementation, we should never arrive
11095 * here with a zero breakFlag because we always refresh rIBASE on
11096 * return.
11097 */
11098    EXPORT_PC
11099    movl   rSELF, %eax
11100    movl   rPC, OUT_ARG0(%esp)
11101    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11102    movl   rFP, OUT_ARG1(%esp)
11103    je     1f                                # reload rIBASE & resume if not
11104    movl   %eax, OUT_ARG2(%esp)
11105    call   dvmCheckBefore                    # (dPC, dFP, self)
11106    movl   rSELF, %eax
111071:
11108    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11109    jmp    *dvmAsmInstructionStart+(121*4)
11110
11111/* ------------------------------ */
11112.L_ALT_OP_UNUSED_7A: /* 0x7a */
11113/* File: x86/alt_stub.S */
11114/*
11115 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11116 * any interesting requests and then jump to the real instruction
11117 * handler.  Unlike the Arm handler, we can't do this as a tail call
11118 * because rIBASE is caller save and we need to reload it.
11119 *
11120 * Note that unlike in the Arm implementation, we should never arrive
11121 * here with a zero breakFlag because we always refresh rIBASE on
11122 * return.
11123 */
11124    EXPORT_PC
11125    movl   rSELF, %eax
11126    movl   rPC, OUT_ARG0(%esp)
11127    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11128    movl   rFP, OUT_ARG1(%esp)
11129    je     1f                                # reload rIBASE & resume if not
11130    movl   %eax, OUT_ARG2(%esp)
11131    call   dvmCheckBefore                    # (dPC, dFP, self)
11132    movl   rSELF, %eax
111331:
11134    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11135    jmp    *dvmAsmInstructionStart+(122*4)
11136
11137/* ------------------------------ */
11138.L_ALT_OP_NEG_INT: /* 0x7b */
11139/* File: x86/alt_stub.S */
11140/*
11141 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11142 * any interesting requests and then jump to the real instruction
11143 * handler.  Unlike the Arm handler, we can't do this as a tail call
11144 * because rIBASE is caller save and we need to reload it.
11145 *
11146 * Note that unlike in the Arm implementation, we should never arrive
11147 * here with a zero breakFlag because we always refresh rIBASE on
11148 * return.
11149 */
11150    EXPORT_PC
11151    movl   rSELF, %eax
11152    movl   rPC, OUT_ARG0(%esp)
11153    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11154    movl   rFP, OUT_ARG1(%esp)
11155    je     1f                                # reload rIBASE & resume if not
11156    movl   %eax, OUT_ARG2(%esp)
11157    call   dvmCheckBefore                    # (dPC, dFP, self)
11158    movl   rSELF, %eax
111591:
11160    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11161    jmp    *dvmAsmInstructionStart+(123*4)
11162
11163/* ------------------------------ */
11164.L_ALT_OP_NOT_INT: /* 0x7c */
11165/* File: x86/alt_stub.S */
11166/*
11167 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11168 * any interesting requests and then jump to the real instruction
11169 * handler.  Unlike the Arm handler, we can't do this as a tail call
11170 * because rIBASE is caller save and we need to reload it.
11171 *
11172 * Note that unlike in the Arm implementation, we should never arrive
11173 * here with a zero breakFlag because we always refresh rIBASE on
11174 * return.
11175 */
11176    EXPORT_PC
11177    movl   rSELF, %eax
11178    movl   rPC, OUT_ARG0(%esp)
11179    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11180    movl   rFP, OUT_ARG1(%esp)
11181    je     1f                                # reload rIBASE & resume if not
11182    movl   %eax, OUT_ARG2(%esp)
11183    call   dvmCheckBefore                    # (dPC, dFP, self)
11184    movl   rSELF, %eax
111851:
11186    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11187    jmp    *dvmAsmInstructionStart+(124*4)
11188
11189/* ------------------------------ */
11190.L_ALT_OP_NEG_LONG: /* 0x7d */
11191/* File: x86/alt_stub.S */
11192/*
11193 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11194 * any interesting requests and then jump to the real instruction
11195 * handler.  Unlike the Arm handler, we can't do this as a tail call
11196 * because rIBASE is caller save and we need to reload it.
11197 *
11198 * Note that unlike in the Arm implementation, we should never arrive
11199 * here with a zero breakFlag because we always refresh rIBASE on
11200 * return.
11201 */
11202    EXPORT_PC
11203    movl   rSELF, %eax
11204    movl   rPC, OUT_ARG0(%esp)
11205    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11206    movl   rFP, OUT_ARG1(%esp)
11207    je     1f                                # reload rIBASE & resume if not
11208    movl   %eax, OUT_ARG2(%esp)
11209    call   dvmCheckBefore                    # (dPC, dFP, self)
11210    movl   rSELF, %eax
112111:
11212    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11213    jmp    *dvmAsmInstructionStart+(125*4)
11214
11215/* ------------------------------ */
11216.L_ALT_OP_NOT_LONG: /* 0x7e */
11217/* File: x86/alt_stub.S */
11218/*
11219 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11220 * any interesting requests and then jump to the real instruction
11221 * handler.  Unlike the Arm handler, we can't do this as a tail call
11222 * because rIBASE is caller save and we need to reload it.
11223 *
11224 * Note that unlike in the Arm implementation, we should never arrive
11225 * here with a zero breakFlag because we always refresh rIBASE on
11226 * return.
11227 */
11228    EXPORT_PC
11229    movl   rSELF, %eax
11230    movl   rPC, OUT_ARG0(%esp)
11231    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11232    movl   rFP, OUT_ARG1(%esp)
11233    je     1f                                # reload rIBASE & resume if not
11234    movl   %eax, OUT_ARG2(%esp)
11235    call   dvmCheckBefore                    # (dPC, dFP, self)
11236    movl   rSELF, %eax
112371:
11238    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11239    jmp    *dvmAsmInstructionStart+(126*4)
11240
11241/* ------------------------------ */
11242.L_ALT_OP_NEG_FLOAT: /* 0x7f */
11243/* File: x86/alt_stub.S */
11244/*
11245 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11246 * any interesting requests and then jump to the real instruction
11247 * handler.  Unlike the Arm handler, we can't do this as a tail call
11248 * because rIBASE is caller save and we need to reload it.
11249 *
11250 * Note that unlike in the Arm implementation, we should never arrive
11251 * here with a zero breakFlag because we always refresh rIBASE on
11252 * return.
11253 */
11254    EXPORT_PC
11255    movl   rSELF, %eax
11256    movl   rPC, OUT_ARG0(%esp)
11257    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11258    movl   rFP, OUT_ARG1(%esp)
11259    je     1f                                # reload rIBASE & resume if not
11260    movl   %eax, OUT_ARG2(%esp)
11261    call   dvmCheckBefore                    # (dPC, dFP, self)
11262    movl   rSELF, %eax
112631:
11264    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11265    jmp    *dvmAsmInstructionStart+(127*4)
11266
11267/* ------------------------------ */
11268.L_ALT_OP_NEG_DOUBLE: /* 0x80 */
11269/* File: x86/alt_stub.S */
11270/*
11271 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11272 * any interesting requests and then jump to the real instruction
11273 * handler.  Unlike the Arm handler, we can't do this as a tail call
11274 * because rIBASE is caller save and we need to reload it.
11275 *
11276 * Note that unlike in the Arm implementation, we should never arrive
11277 * here with a zero breakFlag because we always refresh rIBASE on
11278 * return.
11279 */
11280    EXPORT_PC
11281    movl   rSELF, %eax
11282    movl   rPC, OUT_ARG0(%esp)
11283    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11284    movl   rFP, OUT_ARG1(%esp)
11285    je     1f                                # reload rIBASE & resume if not
11286    movl   %eax, OUT_ARG2(%esp)
11287    call   dvmCheckBefore                    # (dPC, dFP, self)
11288    movl   rSELF, %eax
112891:
11290    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11291    jmp    *dvmAsmInstructionStart+(128*4)
11292
11293/* ------------------------------ */
11294.L_ALT_OP_INT_TO_LONG: /* 0x81 */
11295/* File: x86/alt_stub.S */
11296/*
11297 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11298 * any interesting requests and then jump to the real instruction
11299 * handler.  Unlike the Arm handler, we can't do this as a tail call
11300 * because rIBASE is caller save and we need to reload it.
11301 *
11302 * Note that unlike in the Arm implementation, we should never arrive
11303 * here with a zero breakFlag because we always refresh rIBASE on
11304 * return.
11305 */
11306    EXPORT_PC
11307    movl   rSELF, %eax
11308    movl   rPC, OUT_ARG0(%esp)
11309    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11310    movl   rFP, OUT_ARG1(%esp)
11311    je     1f                                # reload rIBASE & resume if not
11312    movl   %eax, OUT_ARG2(%esp)
11313    call   dvmCheckBefore                    # (dPC, dFP, self)
11314    movl   rSELF, %eax
113151:
11316    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11317    jmp    *dvmAsmInstructionStart+(129*4)
11318
11319/* ------------------------------ */
11320.L_ALT_OP_INT_TO_FLOAT: /* 0x82 */
11321/* File: x86/alt_stub.S */
11322/*
11323 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11324 * any interesting requests and then jump to the real instruction
11325 * handler.  Unlike the Arm handler, we can't do this as a tail call
11326 * because rIBASE is caller save and we need to reload it.
11327 *
11328 * Note that unlike in the Arm implementation, we should never arrive
11329 * here with a zero breakFlag because we always refresh rIBASE on
11330 * return.
11331 */
11332    EXPORT_PC
11333    movl   rSELF, %eax
11334    movl   rPC, OUT_ARG0(%esp)
11335    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11336    movl   rFP, OUT_ARG1(%esp)
11337    je     1f                                # reload rIBASE & resume if not
11338    movl   %eax, OUT_ARG2(%esp)
11339    call   dvmCheckBefore                    # (dPC, dFP, self)
11340    movl   rSELF, %eax
113411:
11342    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11343    jmp    *dvmAsmInstructionStart+(130*4)
11344
11345/* ------------------------------ */
11346.L_ALT_OP_INT_TO_DOUBLE: /* 0x83 */
11347/* File: x86/alt_stub.S */
11348/*
11349 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11350 * any interesting requests and then jump to the real instruction
11351 * handler.  Unlike the Arm handler, we can't do this as a tail call
11352 * because rIBASE is caller save and we need to reload it.
11353 *
11354 * Note that unlike in the Arm implementation, we should never arrive
11355 * here with a zero breakFlag because we always refresh rIBASE on
11356 * return.
11357 */
11358    EXPORT_PC
11359    movl   rSELF, %eax
11360    movl   rPC, OUT_ARG0(%esp)
11361    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11362    movl   rFP, OUT_ARG1(%esp)
11363    je     1f                                # reload rIBASE & resume if not
11364    movl   %eax, OUT_ARG2(%esp)
11365    call   dvmCheckBefore                    # (dPC, dFP, self)
11366    movl   rSELF, %eax
113671:
11368    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11369    jmp    *dvmAsmInstructionStart+(131*4)
11370
11371/* ------------------------------ */
11372.L_ALT_OP_LONG_TO_INT: /* 0x84 */
11373/* File: x86/alt_stub.S */
11374/*
11375 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11376 * any interesting requests and then jump to the real instruction
11377 * handler.  Unlike the Arm handler, we can't do this as a tail call
11378 * because rIBASE is caller save and we need to reload it.
11379 *
11380 * Note that unlike in the Arm implementation, we should never arrive
11381 * here with a zero breakFlag because we always refresh rIBASE on
11382 * return.
11383 */
11384    EXPORT_PC
11385    movl   rSELF, %eax
11386    movl   rPC, OUT_ARG0(%esp)
11387    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11388    movl   rFP, OUT_ARG1(%esp)
11389    je     1f                                # reload rIBASE & resume if not
11390    movl   %eax, OUT_ARG2(%esp)
11391    call   dvmCheckBefore                    # (dPC, dFP, self)
11392    movl   rSELF, %eax
113931:
11394    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11395    jmp    *dvmAsmInstructionStart+(132*4)
11396
11397/* ------------------------------ */
11398.L_ALT_OP_LONG_TO_FLOAT: /* 0x85 */
11399/* File: x86/alt_stub.S */
11400/*
11401 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11402 * any interesting requests and then jump to the real instruction
11403 * handler.  Unlike the Arm handler, we can't do this as a tail call
11404 * because rIBASE is caller save and we need to reload it.
11405 *
11406 * Note that unlike in the Arm implementation, we should never arrive
11407 * here with a zero breakFlag because we always refresh rIBASE on
11408 * return.
11409 */
11410    EXPORT_PC
11411    movl   rSELF, %eax
11412    movl   rPC, OUT_ARG0(%esp)
11413    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11414    movl   rFP, OUT_ARG1(%esp)
11415    je     1f                                # reload rIBASE & resume if not
11416    movl   %eax, OUT_ARG2(%esp)
11417    call   dvmCheckBefore                    # (dPC, dFP, self)
11418    movl   rSELF, %eax
114191:
11420    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11421    jmp    *dvmAsmInstructionStart+(133*4)
11422
11423/* ------------------------------ */
11424.L_ALT_OP_LONG_TO_DOUBLE: /* 0x86 */
11425/* File: x86/alt_stub.S */
11426/*
11427 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11428 * any interesting requests and then jump to the real instruction
11429 * handler.  Unlike the Arm handler, we can't do this as a tail call
11430 * because rIBASE is caller save and we need to reload it.
11431 *
11432 * Note that unlike in the Arm implementation, we should never arrive
11433 * here with a zero breakFlag because we always refresh rIBASE on
11434 * return.
11435 */
11436    EXPORT_PC
11437    movl   rSELF, %eax
11438    movl   rPC, OUT_ARG0(%esp)
11439    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11440    movl   rFP, OUT_ARG1(%esp)
11441    je     1f                                # reload rIBASE & resume if not
11442    movl   %eax, OUT_ARG2(%esp)
11443    call   dvmCheckBefore                    # (dPC, dFP, self)
11444    movl   rSELF, %eax
114451:
11446    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11447    jmp    *dvmAsmInstructionStart+(134*4)
11448
11449/* ------------------------------ */
11450.L_ALT_OP_FLOAT_TO_INT: /* 0x87 */
11451/* File: x86/alt_stub.S */
11452/*
11453 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11454 * any interesting requests and then jump to the real instruction
11455 * handler.  Unlike the Arm handler, we can't do this as a tail call
11456 * because rIBASE is caller save and we need to reload it.
11457 *
11458 * Note that unlike in the Arm implementation, we should never arrive
11459 * here with a zero breakFlag because we always refresh rIBASE on
11460 * return.
11461 */
11462    EXPORT_PC
11463    movl   rSELF, %eax
11464    movl   rPC, OUT_ARG0(%esp)
11465    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11466    movl   rFP, OUT_ARG1(%esp)
11467    je     1f                                # reload rIBASE & resume if not
11468    movl   %eax, OUT_ARG2(%esp)
11469    call   dvmCheckBefore                    # (dPC, dFP, self)
11470    movl   rSELF, %eax
114711:
11472    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11473    jmp    *dvmAsmInstructionStart+(135*4)
11474
11475/* ------------------------------ */
11476.L_ALT_OP_FLOAT_TO_LONG: /* 0x88 */
11477/* File: x86/alt_stub.S */
11478/*
11479 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11480 * any interesting requests and then jump to the real instruction
11481 * handler.  Unlike the Arm handler, we can't do this as a tail call
11482 * because rIBASE is caller save and we need to reload it.
11483 *
11484 * Note that unlike in the Arm implementation, we should never arrive
11485 * here with a zero breakFlag because we always refresh rIBASE on
11486 * return.
11487 */
11488    EXPORT_PC
11489    movl   rSELF, %eax
11490    movl   rPC, OUT_ARG0(%esp)
11491    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11492    movl   rFP, OUT_ARG1(%esp)
11493    je     1f                                # reload rIBASE & resume if not
11494    movl   %eax, OUT_ARG2(%esp)
11495    call   dvmCheckBefore                    # (dPC, dFP, self)
11496    movl   rSELF, %eax
114971:
11498    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11499    jmp    *dvmAsmInstructionStart+(136*4)
11500
11501/* ------------------------------ */
11502.L_ALT_OP_FLOAT_TO_DOUBLE: /* 0x89 */
11503/* File: x86/alt_stub.S */
11504/*
11505 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11506 * any interesting requests and then jump to the real instruction
11507 * handler.  Unlike the Arm handler, we can't do this as a tail call
11508 * because rIBASE is caller save and we need to reload it.
11509 *
11510 * Note that unlike in the Arm implementation, we should never arrive
11511 * here with a zero breakFlag because we always refresh rIBASE on
11512 * return.
11513 */
11514    EXPORT_PC
11515    movl   rSELF, %eax
11516    movl   rPC, OUT_ARG0(%esp)
11517    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11518    movl   rFP, OUT_ARG1(%esp)
11519    je     1f                                # reload rIBASE & resume if not
11520    movl   %eax, OUT_ARG2(%esp)
11521    call   dvmCheckBefore                    # (dPC, dFP, self)
11522    movl   rSELF, %eax
115231:
11524    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11525    jmp    *dvmAsmInstructionStart+(137*4)
11526
11527/* ------------------------------ */
11528.L_ALT_OP_DOUBLE_TO_INT: /* 0x8a */
11529/* File: x86/alt_stub.S */
11530/*
11531 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11532 * any interesting requests and then jump to the real instruction
11533 * handler.  Unlike the Arm handler, we can't do this as a tail call
11534 * because rIBASE is caller save and we need to reload it.
11535 *
11536 * Note that unlike in the Arm implementation, we should never arrive
11537 * here with a zero breakFlag because we always refresh rIBASE on
11538 * return.
11539 */
11540    EXPORT_PC
11541    movl   rSELF, %eax
11542    movl   rPC, OUT_ARG0(%esp)
11543    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11544    movl   rFP, OUT_ARG1(%esp)
11545    je     1f                                # reload rIBASE & resume if not
11546    movl   %eax, OUT_ARG2(%esp)
11547    call   dvmCheckBefore                    # (dPC, dFP, self)
11548    movl   rSELF, %eax
115491:
11550    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11551    jmp    *dvmAsmInstructionStart+(138*4)
11552
11553/* ------------------------------ */
11554.L_ALT_OP_DOUBLE_TO_LONG: /* 0x8b */
11555/* File: x86/alt_stub.S */
11556/*
11557 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11558 * any interesting requests and then jump to the real instruction
11559 * handler.  Unlike the Arm handler, we can't do this as a tail call
11560 * because rIBASE is caller save and we need to reload it.
11561 *
11562 * Note that unlike in the Arm implementation, we should never arrive
11563 * here with a zero breakFlag because we always refresh rIBASE on
11564 * return.
11565 */
11566    EXPORT_PC
11567    movl   rSELF, %eax
11568    movl   rPC, OUT_ARG0(%esp)
11569    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11570    movl   rFP, OUT_ARG1(%esp)
11571    je     1f                                # reload rIBASE & resume if not
11572    movl   %eax, OUT_ARG2(%esp)
11573    call   dvmCheckBefore                    # (dPC, dFP, self)
11574    movl   rSELF, %eax
115751:
11576    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11577    jmp    *dvmAsmInstructionStart+(139*4)
11578
11579/* ------------------------------ */
11580.L_ALT_OP_DOUBLE_TO_FLOAT: /* 0x8c */
11581/* File: x86/alt_stub.S */
11582/*
11583 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11584 * any interesting requests and then jump to the real instruction
11585 * handler.  Unlike the Arm handler, we can't do this as a tail call
11586 * because rIBASE is caller save and we need to reload it.
11587 *
11588 * Note that unlike in the Arm implementation, we should never arrive
11589 * here with a zero breakFlag because we always refresh rIBASE on
11590 * return.
11591 */
11592    EXPORT_PC
11593    movl   rSELF, %eax
11594    movl   rPC, OUT_ARG0(%esp)
11595    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11596    movl   rFP, OUT_ARG1(%esp)
11597    je     1f                                # reload rIBASE & resume if not
11598    movl   %eax, OUT_ARG2(%esp)
11599    call   dvmCheckBefore                    # (dPC, dFP, self)
11600    movl   rSELF, %eax
116011:
11602    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11603    jmp    *dvmAsmInstructionStart+(140*4)
11604
11605/* ------------------------------ */
11606.L_ALT_OP_INT_TO_BYTE: /* 0x8d */
11607/* File: x86/alt_stub.S */
11608/*
11609 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11610 * any interesting requests and then jump to the real instruction
11611 * handler.  Unlike the Arm handler, we can't do this as a tail call
11612 * because rIBASE is caller save and we need to reload it.
11613 *
11614 * Note that unlike in the Arm implementation, we should never arrive
11615 * here with a zero breakFlag because we always refresh rIBASE on
11616 * return.
11617 */
11618    EXPORT_PC
11619    movl   rSELF, %eax
11620    movl   rPC, OUT_ARG0(%esp)
11621    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11622    movl   rFP, OUT_ARG1(%esp)
11623    je     1f                                # reload rIBASE & resume if not
11624    movl   %eax, OUT_ARG2(%esp)
11625    call   dvmCheckBefore                    # (dPC, dFP, self)
11626    movl   rSELF, %eax
116271:
11628    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11629    jmp    *dvmAsmInstructionStart+(141*4)
11630
11631/* ------------------------------ */
11632.L_ALT_OP_INT_TO_CHAR: /* 0x8e */
11633/* File: x86/alt_stub.S */
11634/*
11635 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11636 * any interesting requests and then jump to the real instruction
11637 * handler.  Unlike the Arm handler, we can't do this as a tail call
11638 * because rIBASE is caller save and we need to reload it.
11639 *
11640 * Note that unlike in the Arm implementation, we should never arrive
11641 * here with a zero breakFlag because we always refresh rIBASE on
11642 * return.
11643 */
11644    EXPORT_PC
11645    movl   rSELF, %eax
11646    movl   rPC, OUT_ARG0(%esp)
11647    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11648    movl   rFP, OUT_ARG1(%esp)
11649    je     1f                                # reload rIBASE & resume if not
11650    movl   %eax, OUT_ARG2(%esp)
11651    call   dvmCheckBefore                    # (dPC, dFP, self)
11652    movl   rSELF, %eax
116531:
11654    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11655    jmp    *dvmAsmInstructionStart+(142*4)
11656
11657/* ------------------------------ */
11658.L_ALT_OP_INT_TO_SHORT: /* 0x8f */
11659/* File: x86/alt_stub.S */
11660/*
11661 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11662 * any interesting requests and then jump to the real instruction
11663 * handler.  Unlike the Arm handler, we can't do this as a tail call
11664 * because rIBASE is caller save and we need to reload it.
11665 *
11666 * Note that unlike in the Arm implementation, we should never arrive
11667 * here with a zero breakFlag because we always refresh rIBASE on
11668 * return.
11669 */
11670    EXPORT_PC
11671    movl   rSELF, %eax
11672    movl   rPC, OUT_ARG0(%esp)
11673    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11674    movl   rFP, OUT_ARG1(%esp)
11675    je     1f                                # reload rIBASE & resume if not
11676    movl   %eax, OUT_ARG2(%esp)
11677    call   dvmCheckBefore                    # (dPC, dFP, self)
11678    movl   rSELF, %eax
116791:
11680    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11681    jmp    *dvmAsmInstructionStart+(143*4)
11682
11683/* ------------------------------ */
11684.L_ALT_OP_ADD_INT: /* 0x90 */
11685/* File: x86/alt_stub.S */
11686/*
11687 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11688 * any interesting requests and then jump to the real instruction
11689 * handler.  Unlike the Arm handler, we can't do this as a tail call
11690 * because rIBASE is caller save and we need to reload it.
11691 *
11692 * Note that unlike in the Arm implementation, we should never arrive
11693 * here with a zero breakFlag because we always refresh rIBASE on
11694 * return.
11695 */
11696    EXPORT_PC
11697    movl   rSELF, %eax
11698    movl   rPC, OUT_ARG0(%esp)
11699    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11700    movl   rFP, OUT_ARG1(%esp)
11701    je     1f                                # reload rIBASE & resume if not
11702    movl   %eax, OUT_ARG2(%esp)
11703    call   dvmCheckBefore                    # (dPC, dFP, self)
11704    movl   rSELF, %eax
117051:
11706    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11707    jmp    *dvmAsmInstructionStart+(144*4)
11708
11709/* ------------------------------ */
11710.L_ALT_OP_SUB_INT: /* 0x91 */
11711/* File: x86/alt_stub.S */
11712/*
11713 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11714 * any interesting requests and then jump to the real instruction
11715 * handler.  Unlike the Arm handler, we can't do this as a tail call
11716 * because rIBASE is caller save and we need to reload it.
11717 *
11718 * Note that unlike in the Arm implementation, we should never arrive
11719 * here with a zero breakFlag because we always refresh rIBASE on
11720 * return.
11721 */
11722    EXPORT_PC
11723    movl   rSELF, %eax
11724    movl   rPC, OUT_ARG0(%esp)
11725    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11726    movl   rFP, OUT_ARG1(%esp)
11727    je     1f                                # reload rIBASE & resume if not
11728    movl   %eax, OUT_ARG2(%esp)
11729    call   dvmCheckBefore                    # (dPC, dFP, self)
11730    movl   rSELF, %eax
117311:
11732    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11733    jmp    *dvmAsmInstructionStart+(145*4)
11734
11735/* ------------------------------ */
11736.L_ALT_OP_MUL_INT: /* 0x92 */
11737/* File: x86/alt_stub.S */
11738/*
11739 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11740 * any interesting requests and then jump to the real instruction
11741 * handler.  Unlike the Arm handler, we can't do this as a tail call
11742 * because rIBASE is caller save and we need to reload it.
11743 *
11744 * Note that unlike in the Arm implementation, we should never arrive
11745 * here with a zero breakFlag because we always refresh rIBASE on
11746 * return.
11747 */
11748    EXPORT_PC
11749    movl   rSELF, %eax
11750    movl   rPC, OUT_ARG0(%esp)
11751    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11752    movl   rFP, OUT_ARG1(%esp)
11753    je     1f                                # reload rIBASE & resume if not
11754    movl   %eax, OUT_ARG2(%esp)
11755    call   dvmCheckBefore                    # (dPC, dFP, self)
11756    movl   rSELF, %eax
117571:
11758    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11759    jmp    *dvmAsmInstructionStart+(146*4)
11760
11761/* ------------------------------ */
11762.L_ALT_OP_DIV_INT: /* 0x93 */
11763/* File: x86/alt_stub.S */
11764/*
11765 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11766 * any interesting requests and then jump to the real instruction
11767 * handler.  Unlike the Arm handler, we can't do this as a tail call
11768 * because rIBASE is caller save and we need to reload it.
11769 *
11770 * Note that unlike in the Arm implementation, we should never arrive
11771 * here with a zero breakFlag because we always refresh rIBASE on
11772 * return.
11773 */
11774    EXPORT_PC
11775    movl   rSELF, %eax
11776    movl   rPC, OUT_ARG0(%esp)
11777    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11778    movl   rFP, OUT_ARG1(%esp)
11779    je     1f                                # reload rIBASE & resume if not
11780    movl   %eax, OUT_ARG2(%esp)
11781    call   dvmCheckBefore                    # (dPC, dFP, self)
11782    movl   rSELF, %eax
117831:
11784    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11785    jmp    *dvmAsmInstructionStart+(147*4)
11786
11787/* ------------------------------ */
11788.L_ALT_OP_REM_INT: /* 0x94 */
11789/* File: x86/alt_stub.S */
11790/*
11791 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11792 * any interesting requests and then jump to the real instruction
11793 * handler.  Unlike the Arm handler, we can't do this as a tail call
11794 * because rIBASE is caller save and we need to reload it.
11795 *
11796 * Note that unlike in the Arm implementation, we should never arrive
11797 * here with a zero breakFlag because we always refresh rIBASE on
11798 * return.
11799 */
11800    EXPORT_PC
11801    movl   rSELF, %eax
11802    movl   rPC, OUT_ARG0(%esp)
11803    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11804    movl   rFP, OUT_ARG1(%esp)
11805    je     1f                                # reload rIBASE & resume if not
11806    movl   %eax, OUT_ARG2(%esp)
11807    call   dvmCheckBefore                    # (dPC, dFP, self)
11808    movl   rSELF, %eax
118091:
11810    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11811    jmp    *dvmAsmInstructionStart+(148*4)
11812
11813/* ------------------------------ */
11814.L_ALT_OP_AND_INT: /* 0x95 */
11815/* File: x86/alt_stub.S */
11816/*
11817 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11818 * any interesting requests and then jump to the real instruction
11819 * handler.  Unlike the Arm handler, we can't do this as a tail call
11820 * because rIBASE is caller save and we need to reload it.
11821 *
11822 * Note that unlike in the Arm implementation, we should never arrive
11823 * here with a zero breakFlag because we always refresh rIBASE on
11824 * return.
11825 */
11826    EXPORT_PC
11827    movl   rSELF, %eax
11828    movl   rPC, OUT_ARG0(%esp)
11829    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11830    movl   rFP, OUT_ARG1(%esp)
11831    je     1f                                # reload rIBASE & resume if not
11832    movl   %eax, OUT_ARG2(%esp)
11833    call   dvmCheckBefore                    # (dPC, dFP, self)
11834    movl   rSELF, %eax
118351:
11836    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11837    jmp    *dvmAsmInstructionStart+(149*4)
11838
11839/* ------------------------------ */
11840.L_ALT_OP_OR_INT: /* 0x96 */
11841/* File: x86/alt_stub.S */
11842/*
11843 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11844 * any interesting requests and then jump to the real instruction
11845 * handler.  Unlike the Arm handler, we can't do this as a tail call
11846 * because rIBASE is caller save and we need to reload it.
11847 *
11848 * Note that unlike in the Arm implementation, we should never arrive
11849 * here with a zero breakFlag because we always refresh rIBASE on
11850 * return.
11851 */
11852    EXPORT_PC
11853    movl   rSELF, %eax
11854    movl   rPC, OUT_ARG0(%esp)
11855    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11856    movl   rFP, OUT_ARG1(%esp)
11857    je     1f                                # reload rIBASE & resume if not
11858    movl   %eax, OUT_ARG2(%esp)
11859    call   dvmCheckBefore                    # (dPC, dFP, self)
11860    movl   rSELF, %eax
118611:
11862    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11863    jmp    *dvmAsmInstructionStart+(150*4)
11864
11865/* ------------------------------ */
11866.L_ALT_OP_XOR_INT: /* 0x97 */
11867/* File: x86/alt_stub.S */
11868/*
11869 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11870 * any interesting requests and then jump to the real instruction
11871 * handler.  Unlike the Arm handler, we can't do this as a tail call
11872 * because rIBASE is caller save and we need to reload it.
11873 *
11874 * Note that unlike in the Arm implementation, we should never arrive
11875 * here with a zero breakFlag because we always refresh rIBASE on
11876 * return.
11877 */
11878    EXPORT_PC
11879    movl   rSELF, %eax
11880    movl   rPC, OUT_ARG0(%esp)
11881    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11882    movl   rFP, OUT_ARG1(%esp)
11883    je     1f                                # reload rIBASE & resume if not
11884    movl   %eax, OUT_ARG2(%esp)
11885    call   dvmCheckBefore                    # (dPC, dFP, self)
11886    movl   rSELF, %eax
118871:
11888    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11889    jmp    *dvmAsmInstructionStart+(151*4)
11890
11891/* ------------------------------ */
11892.L_ALT_OP_SHL_INT: /* 0x98 */
11893/* File: x86/alt_stub.S */
11894/*
11895 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11896 * any interesting requests and then jump to the real instruction
11897 * handler.  Unlike the Arm handler, we can't do this as a tail call
11898 * because rIBASE is caller save and we need to reload it.
11899 *
11900 * Note that unlike in the Arm implementation, we should never arrive
11901 * here with a zero breakFlag because we always refresh rIBASE on
11902 * return.
11903 */
11904    EXPORT_PC
11905    movl   rSELF, %eax
11906    movl   rPC, OUT_ARG0(%esp)
11907    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11908    movl   rFP, OUT_ARG1(%esp)
11909    je     1f                                # reload rIBASE & resume if not
11910    movl   %eax, OUT_ARG2(%esp)
11911    call   dvmCheckBefore                    # (dPC, dFP, self)
11912    movl   rSELF, %eax
119131:
11914    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11915    jmp    *dvmAsmInstructionStart+(152*4)
11916
11917/* ------------------------------ */
11918.L_ALT_OP_SHR_INT: /* 0x99 */
11919/* File: x86/alt_stub.S */
11920/*
11921 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11922 * any interesting requests and then jump to the real instruction
11923 * handler.  Unlike the Arm handler, we can't do this as a tail call
11924 * because rIBASE is caller save and we need to reload it.
11925 *
11926 * Note that unlike in the Arm implementation, we should never arrive
11927 * here with a zero breakFlag because we always refresh rIBASE on
11928 * return.
11929 */
11930    EXPORT_PC
11931    movl   rSELF, %eax
11932    movl   rPC, OUT_ARG0(%esp)
11933    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11934    movl   rFP, OUT_ARG1(%esp)
11935    je     1f                                # reload rIBASE & resume if not
11936    movl   %eax, OUT_ARG2(%esp)
11937    call   dvmCheckBefore                    # (dPC, dFP, self)
11938    movl   rSELF, %eax
119391:
11940    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11941    jmp    *dvmAsmInstructionStart+(153*4)
11942
11943/* ------------------------------ */
11944.L_ALT_OP_USHR_INT: /* 0x9a */
11945/* File: x86/alt_stub.S */
11946/*
11947 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11948 * any interesting requests and then jump to the real instruction
11949 * handler.  Unlike the Arm handler, we can't do this as a tail call
11950 * because rIBASE is caller save and we need to reload it.
11951 *
11952 * Note that unlike in the Arm implementation, we should never arrive
11953 * here with a zero breakFlag because we always refresh rIBASE on
11954 * return.
11955 */
11956    EXPORT_PC
11957    movl   rSELF, %eax
11958    movl   rPC, OUT_ARG0(%esp)
11959    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11960    movl   rFP, OUT_ARG1(%esp)
11961    je     1f                                # reload rIBASE & resume if not
11962    movl   %eax, OUT_ARG2(%esp)
11963    call   dvmCheckBefore                    # (dPC, dFP, self)
11964    movl   rSELF, %eax
119651:
11966    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11967    jmp    *dvmAsmInstructionStart+(154*4)
11968
11969/* ------------------------------ */
11970.L_ALT_OP_ADD_LONG: /* 0x9b */
11971/* File: x86/alt_stub.S */
11972/*
11973 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11974 * any interesting requests and then jump to the real instruction
11975 * handler.  Unlike the Arm handler, we can't do this as a tail call
11976 * because rIBASE is caller save and we need to reload it.
11977 *
11978 * Note that unlike in the Arm implementation, we should never arrive
11979 * here with a zero breakFlag because we always refresh rIBASE on
11980 * return.
11981 */
11982    EXPORT_PC
11983    movl   rSELF, %eax
11984    movl   rPC, OUT_ARG0(%esp)
11985    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11986    movl   rFP, OUT_ARG1(%esp)
11987    je     1f                                # reload rIBASE & resume if not
11988    movl   %eax, OUT_ARG2(%esp)
11989    call   dvmCheckBefore                    # (dPC, dFP, self)
11990    movl   rSELF, %eax
119911:
11992    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11993    jmp    *dvmAsmInstructionStart+(155*4)
11994
11995/* ------------------------------ */
11996.L_ALT_OP_SUB_LONG: /* 0x9c */
11997/* File: x86/alt_stub.S */
11998/*
11999 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12000 * any interesting requests and then jump to the real instruction
12001 * handler.  Unlike the Arm handler, we can't do this as a tail call
12002 * because rIBASE is caller save and we need to reload it.
12003 *
12004 * Note that unlike in the Arm implementation, we should never arrive
12005 * here with a zero breakFlag because we always refresh rIBASE on
12006 * return.
12007 */
12008    EXPORT_PC
12009    movl   rSELF, %eax
12010    movl   rPC, OUT_ARG0(%esp)
12011    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12012    movl   rFP, OUT_ARG1(%esp)
12013    je     1f                                # reload rIBASE & resume if not
12014    movl   %eax, OUT_ARG2(%esp)
12015    call   dvmCheckBefore                    # (dPC, dFP, self)
12016    movl   rSELF, %eax
120171:
12018    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12019    jmp    *dvmAsmInstructionStart+(156*4)
12020
12021/* ------------------------------ */
12022.L_ALT_OP_MUL_LONG: /* 0x9d */
12023/* File: x86/alt_stub.S */
12024/*
12025 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12026 * any interesting requests and then jump to the real instruction
12027 * handler.  Unlike the Arm handler, we can't do this as a tail call
12028 * because rIBASE is caller save and we need to reload it.
12029 *
12030 * Note that unlike in the Arm implementation, we should never arrive
12031 * here with a zero breakFlag because we always refresh rIBASE on
12032 * return.
12033 */
12034    EXPORT_PC
12035    movl   rSELF, %eax
12036    movl   rPC, OUT_ARG0(%esp)
12037    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12038    movl   rFP, OUT_ARG1(%esp)
12039    je     1f                                # reload rIBASE & resume if not
12040    movl   %eax, OUT_ARG2(%esp)
12041    call   dvmCheckBefore                    # (dPC, dFP, self)
12042    movl   rSELF, %eax
120431:
12044    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12045    jmp    *dvmAsmInstructionStart+(157*4)
12046
12047/* ------------------------------ */
12048.L_ALT_OP_DIV_LONG: /* 0x9e */
12049/* File: x86/alt_stub.S */
12050/*
12051 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12052 * any interesting requests and then jump to the real instruction
12053 * handler.  Unlike the Arm handler, we can't do this as a tail call
12054 * because rIBASE is caller save and we need to reload it.
12055 *
12056 * Note that unlike in the Arm implementation, we should never arrive
12057 * here with a zero breakFlag because we always refresh rIBASE on
12058 * return.
12059 */
12060    EXPORT_PC
12061    movl   rSELF, %eax
12062    movl   rPC, OUT_ARG0(%esp)
12063    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12064    movl   rFP, OUT_ARG1(%esp)
12065    je     1f                                # reload rIBASE & resume if not
12066    movl   %eax, OUT_ARG2(%esp)
12067    call   dvmCheckBefore                    # (dPC, dFP, self)
12068    movl   rSELF, %eax
120691:
12070    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12071    jmp    *dvmAsmInstructionStart+(158*4)
12072
12073/* ------------------------------ */
12074.L_ALT_OP_REM_LONG: /* 0x9f */
12075/* File: x86/alt_stub.S */
12076/*
12077 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12078 * any interesting requests and then jump to the real instruction
12079 * handler.  Unlike the Arm handler, we can't do this as a tail call
12080 * because rIBASE is caller save and we need to reload it.
12081 *
12082 * Note that unlike in the Arm implementation, we should never arrive
12083 * here with a zero breakFlag because we always refresh rIBASE on
12084 * return.
12085 */
12086    EXPORT_PC
12087    movl   rSELF, %eax
12088    movl   rPC, OUT_ARG0(%esp)
12089    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12090    movl   rFP, OUT_ARG1(%esp)
12091    je     1f                                # reload rIBASE & resume if not
12092    movl   %eax, OUT_ARG2(%esp)
12093    call   dvmCheckBefore                    # (dPC, dFP, self)
12094    movl   rSELF, %eax
120951:
12096    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12097    jmp    *dvmAsmInstructionStart+(159*4)
12098
12099/* ------------------------------ */
12100.L_ALT_OP_AND_LONG: /* 0xa0 */
12101/* File: x86/alt_stub.S */
12102/*
12103 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12104 * any interesting requests and then jump to the real instruction
12105 * handler.  Unlike the Arm handler, we can't do this as a tail call
12106 * because rIBASE is caller save and we need to reload it.
12107 *
12108 * Note that unlike in the Arm implementation, we should never arrive
12109 * here with a zero breakFlag because we always refresh rIBASE on
12110 * return.
12111 */
12112    EXPORT_PC
12113    movl   rSELF, %eax
12114    movl   rPC, OUT_ARG0(%esp)
12115    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12116    movl   rFP, OUT_ARG1(%esp)
12117    je     1f                                # reload rIBASE & resume if not
12118    movl   %eax, OUT_ARG2(%esp)
12119    call   dvmCheckBefore                    # (dPC, dFP, self)
12120    movl   rSELF, %eax
121211:
12122    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12123    jmp    *dvmAsmInstructionStart+(160*4)
12124
12125/* ------------------------------ */
12126.L_ALT_OP_OR_LONG: /* 0xa1 */
12127/* File: x86/alt_stub.S */
12128/*
12129 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12130 * any interesting requests and then jump to the real instruction
12131 * handler.  Unlike the Arm handler, we can't do this as a tail call
12132 * because rIBASE is caller save and we need to reload it.
12133 *
12134 * Note that unlike in the Arm implementation, we should never arrive
12135 * here with a zero breakFlag because we always refresh rIBASE on
12136 * return.
12137 */
12138    EXPORT_PC
12139    movl   rSELF, %eax
12140    movl   rPC, OUT_ARG0(%esp)
12141    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12142    movl   rFP, OUT_ARG1(%esp)
12143    je     1f                                # reload rIBASE & resume if not
12144    movl   %eax, OUT_ARG2(%esp)
12145    call   dvmCheckBefore                    # (dPC, dFP, self)
12146    movl   rSELF, %eax
121471:
12148    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12149    jmp    *dvmAsmInstructionStart+(161*4)
12150
12151/* ------------------------------ */
12152.L_ALT_OP_XOR_LONG: /* 0xa2 */
12153/* File: x86/alt_stub.S */
12154/*
12155 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12156 * any interesting requests and then jump to the real instruction
12157 * handler.  Unlike the Arm handler, we can't do this as a tail call
12158 * because rIBASE is caller save and we need to reload it.
12159 *
12160 * Note that unlike in the Arm implementation, we should never arrive
12161 * here with a zero breakFlag because we always refresh rIBASE on
12162 * return.
12163 */
12164    EXPORT_PC
12165    movl   rSELF, %eax
12166    movl   rPC, OUT_ARG0(%esp)
12167    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12168    movl   rFP, OUT_ARG1(%esp)
12169    je     1f                                # reload rIBASE & resume if not
12170    movl   %eax, OUT_ARG2(%esp)
12171    call   dvmCheckBefore                    # (dPC, dFP, self)
12172    movl   rSELF, %eax
121731:
12174    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12175    jmp    *dvmAsmInstructionStart+(162*4)
12176
12177/* ------------------------------ */
12178.L_ALT_OP_SHL_LONG: /* 0xa3 */
12179/* File: x86/alt_stub.S */
12180/*
12181 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12182 * any interesting requests and then jump to the real instruction
12183 * handler.  Unlike the Arm handler, we can't do this as a tail call
12184 * because rIBASE is caller save and we need to reload it.
12185 *
12186 * Note that unlike in the Arm implementation, we should never arrive
12187 * here with a zero breakFlag because we always refresh rIBASE on
12188 * return.
12189 */
12190    EXPORT_PC
12191    movl   rSELF, %eax
12192    movl   rPC, OUT_ARG0(%esp)
12193    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12194    movl   rFP, OUT_ARG1(%esp)
12195    je     1f                                # reload rIBASE & resume if not
12196    movl   %eax, OUT_ARG2(%esp)
12197    call   dvmCheckBefore                    # (dPC, dFP, self)
12198    movl   rSELF, %eax
121991:
12200    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12201    jmp    *dvmAsmInstructionStart+(163*4)
12202
12203/* ------------------------------ */
12204.L_ALT_OP_SHR_LONG: /* 0xa4 */
12205/* File: x86/alt_stub.S */
12206/*
12207 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12208 * any interesting requests and then jump to the real instruction
12209 * handler.  Unlike the Arm handler, we can't do this as a tail call
12210 * because rIBASE is caller save and we need to reload it.
12211 *
12212 * Note that unlike in the Arm implementation, we should never arrive
12213 * here with a zero breakFlag because we always refresh rIBASE on
12214 * return.
12215 */
12216    EXPORT_PC
12217    movl   rSELF, %eax
12218    movl   rPC, OUT_ARG0(%esp)
12219    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12220    movl   rFP, OUT_ARG1(%esp)
12221    je     1f                                # reload rIBASE & resume if not
12222    movl   %eax, OUT_ARG2(%esp)
12223    call   dvmCheckBefore                    # (dPC, dFP, self)
12224    movl   rSELF, %eax
122251:
12226    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12227    jmp    *dvmAsmInstructionStart+(164*4)
12228
12229/* ------------------------------ */
12230.L_ALT_OP_USHR_LONG: /* 0xa5 */
12231/* File: x86/alt_stub.S */
12232/*
12233 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12234 * any interesting requests and then jump to the real instruction
12235 * handler.  Unlike the Arm handler, we can't do this as a tail call
12236 * because rIBASE is caller save and we need to reload it.
12237 *
12238 * Note that unlike in the Arm implementation, we should never arrive
12239 * here with a zero breakFlag because we always refresh rIBASE on
12240 * return.
12241 */
12242    EXPORT_PC
12243    movl   rSELF, %eax
12244    movl   rPC, OUT_ARG0(%esp)
12245    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12246    movl   rFP, OUT_ARG1(%esp)
12247    je     1f                                # reload rIBASE & resume if not
12248    movl   %eax, OUT_ARG2(%esp)
12249    call   dvmCheckBefore                    # (dPC, dFP, self)
12250    movl   rSELF, %eax
122511:
12252    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12253    jmp    *dvmAsmInstructionStart+(165*4)
12254
12255/* ------------------------------ */
12256.L_ALT_OP_ADD_FLOAT: /* 0xa6 */
12257/* File: x86/alt_stub.S */
12258/*
12259 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12260 * any interesting requests and then jump to the real instruction
12261 * handler.  Unlike the Arm handler, we can't do this as a tail call
12262 * because rIBASE is caller save and we need to reload it.
12263 *
12264 * Note that unlike in the Arm implementation, we should never arrive
12265 * here with a zero breakFlag because we always refresh rIBASE on
12266 * return.
12267 */
12268    EXPORT_PC
12269    movl   rSELF, %eax
12270    movl   rPC, OUT_ARG0(%esp)
12271    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12272    movl   rFP, OUT_ARG1(%esp)
12273    je     1f                                # reload rIBASE & resume if not
12274    movl   %eax, OUT_ARG2(%esp)
12275    call   dvmCheckBefore                    # (dPC, dFP, self)
12276    movl   rSELF, %eax
122771:
12278    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12279    jmp    *dvmAsmInstructionStart+(166*4)
12280
12281/* ------------------------------ */
12282.L_ALT_OP_SUB_FLOAT: /* 0xa7 */
12283/* File: x86/alt_stub.S */
12284/*
12285 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12286 * any interesting requests and then jump to the real instruction
12287 * handler.  Unlike the Arm handler, we can't do this as a tail call
12288 * because rIBASE is caller save and we need to reload it.
12289 *
12290 * Note that unlike in the Arm implementation, we should never arrive
12291 * here with a zero breakFlag because we always refresh rIBASE on
12292 * return.
12293 */
12294    EXPORT_PC
12295    movl   rSELF, %eax
12296    movl   rPC, OUT_ARG0(%esp)
12297    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12298    movl   rFP, OUT_ARG1(%esp)
12299    je     1f                                # reload rIBASE & resume if not
12300    movl   %eax, OUT_ARG2(%esp)
12301    call   dvmCheckBefore                    # (dPC, dFP, self)
12302    movl   rSELF, %eax
123031:
12304    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12305    jmp    *dvmAsmInstructionStart+(167*4)
12306
12307/* ------------------------------ */
12308.L_ALT_OP_MUL_FLOAT: /* 0xa8 */
12309/* File: x86/alt_stub.S */
12310/*
12311 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12312 * any interesting requests and then jump to the real instruction
12313 * handler.  Unlike the Arm handler, we can't do this as a tail call
12314 * because rIBASE is caller save and we need to reload it.
12315 *
12316 * Note that unlike in the Arm implementation, we should never arrive
12317 * here with a zero breakFlag because we always refresh rIBASE on
12318 * return.
12319 */
12320    EXPORT_PC
12321    movl   rSELF, %eax
12322    movl   rPC, OUT_ARG0(%esp)
12323    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12324    movl   rFP, OUT_ARG1(%esp)
12325    je     1f                                # reload rIBASE & resume if not
12326    movl   %eax, OUT_ARG2(%esp)
12327    call   dvmCheckBefore                    # (dPC, dFP, self)
12328    movl   rSELF, %eax
123291:
12330    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12331    jmp    *dvmAsmInstructionStart+(168*4)
12332
12333/* ------------------------------ */
12334.L_ALT_OP_DIV_FLOAT: /* 0xa9 */
12335/* File: x86/alt_stub.S */
12336/*
12337 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12338 * any interesting requests and then jump to the real instruction
12339 * handler.  Unlike the Arm handler, we can't do this as a tail call
12340 * because rIBASE is caller save and we need to reload it.
12341 *
12342 * Note that unlike in the Arm implementation, we should never arrive
12343 * here with a zero breakFlag because we always refresh rIBASE on
12344 * return.
12345 */
12346    EXPORT_PC
12347    movl   rSELF, %eax
12348    movl   rPC, OUT_ARG0(%esp)
12349    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12350    movl   rFP, OUT_ARG1(%esp)
12351    je     1f                                # reload rIBASE & resume if not
12352    movl   %eax, OUT_ARG2(%esp)
12353    call   dvmCheckBefore                    # (dPC, dFP, self)
12354    movl   rSELF, %eax
123551:
12356    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12357    jmp    *dvmAsmInstructionStart+(169*4)
12358
12359/* ------------------------------ */
12360.L_ALT_OP_REM_FLOAT: /* 0xaa */
12361/* File: x86/alt_stub.S */
12362/*
12363 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12364 * any interesting requests and then jump to the real instruction
12365 * handler.  Unlike the Arm handler, we can't do this as a tail call
12366 * because rIBASE is caller save and we need to reload it.
12367 *
12368 * Note that unlike in the Arm implementation, we should never arrive
12369 * here with a zero breakFlag because we always refresh rIBASE on
12370 * return.
12371 */
12372    EXPORT_PC
12373    movl   rSELF, %eax
12374    movl   rPC, OUT_ARG0(%esp)
12375    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12376    movl   rFP, OUT_ARG1(%esp)
12377    je     1f                                # reload rIBASE & resume if not
12378    movl   %eax, OUT_ARG2(%esp)
12379    call   dvmCheckBefore                    # (dPC, dFP, self)
12380    movl   rSELF, %eax
123811:
12382    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12383    jmp    *dvmAsmInstructionStart+(170*4)
12384
12385/* ------------------------------ */
12386.L_ALT_OP_ADD_DOUBLE: /* 0xab */
12387/* File: x86/alt_stub.S */
12388/*
12389 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12390 * any interesting requests and then jump to the real instruction
12391 * handler.  Unlike the Arm handler, we can't do this as a tail call
12392 * because rIBASE is caller save and we need to reload it.
12393 *
12394 * Note that unlike in the Arm implementation, we should never arrive
12395 * here with a zero breakFlag because we always refresh rIBASE on
12396 * return.
12397 */
12398    EXPORT_PC
12399    movl   rSELF, %eax
12400    movl   rPC, OUT_ARG0(%esp)
12401    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12402    movl   rFP, OUT_ARG1(%esp)
12403    je     1f                                # reload rIBASE & resume if not
12404    movl   %eax, OUT_ARG2(%esp)
12405    call   dvmCheckBefore                    # (dPC, dFP, self)
12406    movl   rSELF, %eax
124071:
12408    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12409    jmp    *dvmAsmInstructionStart+(171*4)
12410
12411/* ------------------------------ */
12412.L_ALT_OP_SUB_DOUBLE: /* 0xac */
12413/* File: x86/alt_stub.S */
12414/*
12415 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12416 * any interesting requests and then jump to the real instruction
12417 * handler.  Unlike the Arm handler, we can't do this as a tail call
12418 * because rIBASE is caller save and we need to reload it.
12419 *
12420 * Note that unlike in the Arm implementation, we should never arrive
12421 * here with a zero breakFlag because we always refresh rIBASE on
12422 * return.
12423 */
12424    EXPORT_PC
12425    movl   rSELF, %eax
12426    movl   rPC, OUT_ARG0(%esp)
12427    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12428    movl   rFP, OUT_ARG1(%esp)
12429    je     1f                                # reload rIBASE & resume if not
12430    movl   %eax, OUT_ARG2(%esp)
12431    call   dvmCheckBefore                    # (dPC, dFP, self)
12432    movl   rSELF, %eax
124331:
12434    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12435    jmp    *dvmAsmInstructionStart+(172*4)
12436
12437/* ------------------------------ */
12438.L_ALT_OP_MUL_DOUBLE: /* 0xad */
12439/* File: x86/alt_stub.S */
12440/*
12441 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12442 * any interesting requests and then jump to the real instruction
12443 * handler.  Unlike the Arm handler, we can't do this as a tail call
12444 * because rIBASE is caller save and we need to reload it.
12445 *
12446 * Note that unlike in the Arm implementation, we should never arrive
12447 * here with a zero breakFlag because we always refresh rIBASE on
12448 * return.
12449 */
12450    EXPORT_PC
12451    movl   rSELF, %eax
12452    movl   rPC, OUT_ARG0(%esp)
12453    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12454    movl   rFP, OUT_ARG1(%esp)
12455    je     1f                                # reload rIBASE & resume if not
12456    movl   %eax, OUT_ARG2(%esp)
12457    call   dvmCheckBefore                    # (dPC, dFP, self)
12458    movl   rSELF, %eax
124591:
12460    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12461    jmp    *dvmAsmInstructionStart+(173*4)
12462
12463/* ------------------------------ */
12464.L_ALT_OP_DIV_DOUBLE: /* 0xae */
12465/* File: x86/alt_stub.S */
12466/*
12467 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12468 * any interesting requests and then jump to the real instruction
12469 * handler.  Unlike the Arm handler, we can't do this as a tail call
12470 * because rIBASE is caller save and we need to reload it.
12471 *
12472 * Note that unlike in the Arm implementation, we should never arrive
12473 * here with a zero breakFlag because we always refresh rIBASE on
12474 * return.
12475 */
12476    EXPORT_PC
12477    movl   rSELF, %eax
12478    movl   rPC, OUT_ARG0(%esp)
12479    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12480    movl   rFP, OUT_ARG1(%esp)
12481    je     1f                                # reload rIBASE & resume if not
12482    movl   %eax, OUT_ARG2(%esp)
12483    call   dvmCheckBefore                    # (dPC, dFP, self)
12484    movl   rSELF, %eax
124851:
12486    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12487    jmp    *dvmAsmInstructionStart+(174*4)
12488
12489/* ------------------------------ */
12490.L_ALT_OP_REM_DOUBLE: /* 0xaf */
12491/* File: x86/alt_stub.S */
12492/*
12493 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12494 * any interesting requests and then jump to the real instruction
12495 * handler.  Unlike the Arm handler, we can't do this as a tail call
12496 * because rIBASE is caller save and we need to reload it.
12497 *
12498 * Note that unlike in the Arm implementation, we should never arrive
12499 * here with a zero breakFlag because we always refresh rIBASE on
12500 * return.
12501 */
12502    EXPORT_PC
12503    movl   rSELF, %eax
12504    movl   rPC, OUT_ARG0(%esp)
12505    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12506    movl   rFP, OUT_ARG1(%esp)
12507    je     1f                                # reload rIBASE & resume if not
12508    movl   %eax, OUT_ARG2(%esp)
12509    call   dvmCheckBefore                    # (dPC, dFP, self)
12510    movl   rSELF, %eax
125111:
12512    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12513    jmp    *dvmAsmInstructionStart+(175*4)
12514
12515/* ------------------------------ */
12516.L_ALT_OP_ADD_INT_2ADDR: /* 0xb0 */
12517/* File: x86/alt_stub.S */
12518/*
12519 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12520 * any interesting requests and then jump to the real instruction
12521 * handler.  Unlike the Arm handler, we can't do this as a tail call
12522 * because rIBASE is caller save and we need to reload it.
12523 *
12524 * Note that unlike in the Arm implementation, we should never arrive
12525 * here with a zero breakFlag because we always refresh rIBASE on
12526 * return.
12527 */
12528    EXPORT_PC
12529    movl   rSELF, %eax
12530    movl   rPC, OUT_ARG0(%esp)
12531    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12532    movl   rFP, OUT_ARG1(%esp)
12533    je     1f                                # reload rIBASE & resume if not
12534    movl   %eax, OUT_ARG2(%esp)
12535    call   dvmCheckBefore                    # (dPC, dFP, self)
12536    movl   rSELF, %eax
125371:
12538    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12539    jmp    *dvmAsmInstructionStart+(176*4)
12540
12541/* ------------------------------ */
12542.L_ALT_OP_SUB_INT_2ADDR: /* 0xb1 */
12543/* File: x86/alt_stub.S */
12544/*
12545 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12546 * any interesting requests and then jump to the real instruction
12547 * handler.  Unlike the Arm handler, we can't do this as a tail call
12548 * because rIBASE is caller save and we need to reload it.
12549 *
12550 * Note that unlike in the Arm implementation, we should never arrive
12551 * here with a zero breakFlag because we always refresh rIBASE on
12552 * return.
12553 */
12554    EXPORT_PC
12555    movl   rSELF, %eax
12556    movl   rPC, OUT_ARG0(%esp)
12557    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12558    movl   rFP, OUT_ARG1(%esp)
12559    je     1f                                # reload rIBASE & resume if not
12560    movl   %eax, OUT_ARG2(%esp)
12561    call   dvmCheckBefore                    # (dPC, dFP, self)
12562    movl   rSELF, %eax
125631:
12564    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12565    jmp    *dvmAsmInstructionStart+(177*4)
12566
12567/* ------------------------------ */
12568.L_ALT_OP_MUL_INT_2ADDR: /* 0xb2 */
12569/* File: x86/alt_stub.S */
12570/*
12571 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12572 * any interesting requests and then jump to the real instruction
12573 * handler.  Unlike the Arm handler, we can't do this as a tail call
12574 * because rIBASE is caller save and we need to reload it.
12575 *
12576 * Note that unlike in the Arm implementation, we should never arrive
12577 * here with a zero breakFlag because we always refresh rIBASE on
12578 * return.
12579 */
12580    EXPORT_PC
12581    movl   rSELF, %eax
12582    movl   rPC, OUT_ARG0(%esp)
12583    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12584    movl   rFP, OUT_ARG1(%esp)
12585    je     1f                                # reload rIBASE & resume if not
12586    movl   %eax, OUT_ARG2(%esp)
12587    call   dvmCheckBefore                    # (dPC, dFP, self)
12588    movl   rSELF, %eax
125891:
12590    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12591    jmp    *dvmAsmInstructionStart+(178*4)
12592
12593/* ------------------------------ */
12594.L_ALT_OP_DIV_INT_2ADDR: /* 0xb3 */
12595/* File: x86/alt_stub.S */
12596/*
12597 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12598 * any interesting requests and then jump to the real instruction
12599 * handler.  Unlike the Arm handler, we can't do this as a tail call
12600 * because rIBASE is caller save and we need to reload it.
12601 *
12602 * Note that unlike in the Arm implementation, we should never arrive
12603 * here with a zero breakFlag because we always refresh rIBASE on
12604 * return.
12605 */
12606    EXPORT_PC
12607    movl   rSELF, %eax
12608    movl   rPC, OUT_ARG0(%esp)
12609    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12610    movl   rFP, OUT_ARG1(%esp)
12611    je     1f                                # reload rIBASE & resume if not
12612    movl   %eax, OUT_ARG2(%esp)
12613    call   dvmCheckBefore                    # (dPC, dFP, self)
12614    movl   rSELF, %eax
126151:
12616    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12617    jmp    *dvmAsmInstructionStart+(179*4)
12618
12619/* ------------------------------ */
12620.L_ALT_OP_REM_INT_2ADDR: /* 0xb4 */
12621/* File: x86/alt_stub.S */
12622/*
12623 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12624 * any interesting requests and then jump to the real instruction
12625 * handler.  Unlike the Arm handler, we can't do this as a tail call
12626 * because rIBASE is caller save and we need to reload it.
12627 *
12628 * Note that unlike in the Arm implementation, we should never arrive
12629 * here with a zero breakFlag because we always refresh rIBASE on
12630 * return.
12631 */
12632    EXPORT_PC
12633    movl   rSELF, %eax
12634    movl   rPC, OUT_ARG0(%esp)
12635    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12636    movl   rFP, OUT_ARG1(%esp)
12637    je     1f                                # reload rIBASE & resume if not
12638    movl   %eax, OUT_ARG2(%esp)
12639    call   dvmCheckBefore                    # (dPC, dFP, self)
12640    movl   rSELF, %eax
126411:
12642    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12643    jmp    *dvmAsmInstructionStart+(180*4)
12644
12645/* ------------------------------ */
12646.L_ALT_OP_AND_INT_2ADDR: /* 0xb5 */
12647/* File: x86/alt_stub.S */
12648/*
12649 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12650 * any interesting requests and then jump to the real instruction
12651 * handler.  Unlike the Arm handler, we can't do this as a tail call
12652 * because rIBASE is caller save and we need to reload it.
12653 *
12654 * Note that unlike in the Arm implementation, we should never arrive
12655 * here with a zero breakFlag because we always refresh rIBASE on
12656 * return.
12657 */
12658    EXPORT_PC
12659    movl   rSELF, %eax
12660    movl   rPC, OUT_ARG0(%esp)
12661    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12662    movl   rFP, OUT_ARG1(%esp)
12663    je     1f                                # reload rIBASE & resume if not
12664    movl   %eax, OUT_ARG2(%esp)
12665    call   dvmCheckBefore                    # (dPC, dFP, self)
12666    movl   rSELF, %eax
126671:
12668    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12669    jmp    *dvmAsmInstructionStart+(181*4)
12670
12671/* ------------------------------ */
12672.L_ALT_OP_OR_INT_2ADDR: /* 0xb6 */
12673/* File: x86/alt_stub.S */
12674/*
12675 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12676 * any interesting requests and then jump to the real instruction
12677 * handler.  Unlike the Arm handler, we can't do this as a tail call
12678 * because rIBASE is caller save and we need to reload it.
12679 *
12680 * Note that unlike in the Arm implementation, we should never arrive
12681 * here with a zero breakFlag because we always refresh rIBASE on
12682 * return.
12683 */
12684    EXPORT_PC
12685    movl   rSELF, %eax
12686    movl   rPC, OUT_ARG0(%esp)
12687    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12688    movl   rFP, OUT_ARG1(%esp)
12689    je     1f                                # reload rIBASE & resume if not
12690    movl   %eax, OUT_ARG2(%esp)
12691    call   dvmCheckBefore                    # (dPC, dFP, self)
12692    movl   rSELF, %eax
126931:
12694    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12695    jmp    *dvmAsmInstructionStart+(182*4)
12696
12697/* ------------------------------ */
12698.L_ALT_OP_XOR_INT_2ADDR: /* 0xb7 */
12699/* File: x86/alt_stub.S */
12700/*
12701 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12702 * any interesting requests and then jump to the real instruction
12703 * handler.  Unlike the Arm handler, we can't do this as a tail call
12704 * because rIBASE is caller save and we need to reload it.
12705 *
12706 * Note that unlike in the Arm implementation, we should never arrive
12707 * here with a zero breakFlag because we always refresh rIBASE on
12708 * return.
12709 */
12710    EXPORT_PC
12711    movl   rSELF, %eax
12712    movl   rPC, OUT_ARG0(%esp)
12713    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12714    movl   rFP, OUT_ARG1(%esp)
12715    je     1f                                # reload rIBASE & resume if not
12716    movl   %eax, OUT_ARG2(%esp)
12717    call   dvmCheckBefore                    # (dPC, dFP, self)
12718    movl   rSELF, %eax
127191:
12720    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12721    jmp    *dvmAsmInstructionStart+(183*4)
12722
12723/* ------------------------------ */
12724.L_ALT_OP_SHL_INT_2ADDR: /* 0xb8 */
12725/* File: x86/alt_stub.S */
12726/*
12727 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12728 * any interesting requests and then jump to the real instruction
12729 * handler.  Unlike the Arm handler, we can't do this as a tail call
12730 * because rIBASE is caller save and we need to reload it.
12731 *
12732 * Note that unlike in the Arm implementation, we should never arrive
12733 * here with a zero breakFlag because we always refresh rIBASE on
12734 * return.
12735 */
12736    EXPORT_PC
12737    movl   rSELF, %eax
12738    movl   rPC, OUT_ARG0(%esp)
12739    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12740    movl   rFP, OUT_ARG1(%esp)
12741    je     1f                                # reload rIBASE & resume if not
12742    movl   %eax, OUT_ARG2(%esp)
12743    call   dvmCheckBefore                    # (dPC, dFP, self)
12744    movl   rSELF, %eax
127451:
12746    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12747    jmp    *dvmAsmInstructionStart+(184*4)
12748
12749/* ------------------------------ */
12750.L_ALT_OP_SHR_INT_2ADDR: /* 0xb9 */
12751/* File: x86/alt_stub.S */
12752/*
12753 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12754 * any interesting requests and then jump to the real instruction
12755 * handler.  Unlike the Arm handler, we can't do this as a tail call
12756 * because rIBASE is caller save and we need to reload it.
12757 *
12758 * Note that unlike in the Arm implementation, we should never arrive
12759 * here with a zero breakFlag because we always refresh rIBASE on
12760 * return.
12761 */
12762    EXPORT_PC
12763    movl   rSELF, %eax
12764    movl   rPC, OUT_ARG0(%esp)
12765    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12766    movl   rFP, OUT_ARG1(%esp)
12767    je     1f                                # reload rIBASE & resume if not
12768    movl   %eax, OUT_ARG2(%esp)
12769    call   dvmCheckBefore                    # (dPC, dFP, self)
12770    movl   rSELF, %eax
127711:
12772    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12773    jmp    *dvmAsmInstructionStart+(185*4)
12774
12775/* ------------------------------ */
12776.L_ALT_OP_USHR_INT_2ADDR: /* 0xba */
12777/* File: x86/alt_stub.S */
12778/*
12779 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12780 * any interesting requests and then jump to the real instruction
12781 * handler.  Unlike the Arm handler, we can't do this as a tail call
12782 * because rIBASE is caller save and we need to reload it.
12783 *
12784 * Note that unlike in the Arm implementation, we should never arrive
12785 * here with a zero breakFlag because we always refresh rIBASE on
12786 * return.
12787 */
12788    EXPORT_PC
12789    movl   rSELF, %eax
12790    movl   rPC, OUT_ARG0(%esp)
12791    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12792    movl   rFP, OUT_ARG1(%esp)
12793    je     1f                                # reload rIBASE & resume if not
12794    movl   %eax, OUT_ARG2(%esp)
12795    call   dvmCheckBefore                    # (dPC, dFP, self)
12796    movl   rSELF, %eax
127971:
12798    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12799    jmp    *dvmAsmInstructionStart+(186*4)
12800
12801/* ------------------------------ */
12802.L_ALT_OP_ADD_LONG_2ADDR: /* 0xbb */
12803/* File: x86/alt_stub.S */
12804/*
12805 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12806 * any interesting requests and then jump to the real instruction
12807 * handler.  Unlike the Arm handler, we can't do this as a tail call
12808 * because rIBASE is caller save and we need to reload it.
12809 *
12810 * Note that unlike in the Arm implementation, we should never arrive
12811 * here with a zero breakFlag because we always refresh rIBASE on
12812 * return.
12813 */
12814    EXPORT_PC
12815    movl   rSELF, %eax
12816    movl   rPC, OUT_ARG0(%esp)
12817    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12818    movl   rFP, OUT_ARG1(%esp)
12819    je     1f                                # reload rIBASE & resume if not
12820    movl   %eax, OUT_ARG2(%esp)
12821    call   dvmCheckBefore                    # (dPC, dFP, self)
12822    movl   rSELF, %eax
128231:
12824    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12825    jmp    *dvmAsmInstructionStart+(187*4)
12826
12827/* ------------------------------ */
12828.L_ALT_OP_SUB_LONG_2ADDR: /* 0xbc */
12829/* File: x86/alt_stub.S */
12830/*
12831 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12832 * any interesting requests and then jump to the real instruction
12833 * handler.  Unlike the Arm handler, we can't do this as a tail call
12834 * because rIBASE is caller save and we need to reload it.
12835 *
12836 * Note that unlike in the Arm implementation, we should never arrive
12837 * here with a zero breakFlag because we always refresh rIBASE on
12838 * return.
12839 */
12840    EXPORT_PC
12841    movl   rSELF, %eax
12842    movl   rPC, OUT_ARG0(%esp)
12843    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12844    movl   rFP, OUT_ARG1(%esp)
12845    je     1f                                # reload rIBASE & resume if not
12846    movl   %eax, OUT_ARG2(%esp)
12847    call   dvmCheckBefore                    # (dPC, dFP, self)
12848    movl   rSELF, %eax
128491:
12850    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12851    jmp    *dvmAsmInstructionStart+(188*4)
12852
12853/* ------------------------------ */
12854.L_ALT_OP_MUL_LONG_2ADDR: /* 0xbd */
12855/* File: x86/alt_stub.S */
12856/*
12857 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12858 * any interesting requests and then jump to the real instruction
12859 * handler.  Unlike the Arm handler, we can't do this as a tail call
12860 * because rIBASE is caller save and we need to reload it.
12861 *
12862 * Note that unlike in the Arm implementation, we should never arrive
12863 * here with a zero breakFlag because we always refresh rIBASE on
12864 * return.
12865 */
12866    EXPORT_PC
12867    movl   rSELF, %eax
12868    movl   rPC, OUT_ARG0(%esp)
12869    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12870    movl   rFP, OUT_ARG1(%esp)
12871    je     1f                                # reload rIBASE & resume if not
12872    movl   %eax, OUT_ARG2(%esp)
12873    call   dvmCheckBefore                    # (dPC, dFP, self)
12874    movl   rSELF, %eax
128751:
12876    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12877    jmp    *dvmAsmInstructionStart+(189*4)
12878
12879/* ------------------------------ */
12880.L_ALT_OP_DIV_LONG_2ADDR: /* 0xbe */
12881/* File: x86/alt_stub.S */
12882/*
12883 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12884 * any interesting requests and then jump to the real instruction
12885 * handler.  Unlike the Arm handler, we can't do this as a tail call
12886 * because rIBASE is caller save and we need to reload it.
12887 *
12888 * Note that unlike in the Arm implementation, we should never arrive
12889 * here with a zero breakFlag because we always refresh rIBASE on
12890 * return.
12891 */
12892    EXPORT_PC
12893    movl   rSELF, %eax
12894    movl   rPC, OUT_ARG0(%esp)
12895    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12896    movl   rFP, OUT_ARG1(%esp)
12897    je     1f                                # reload rIBASE & resume if not
12898    movl   %eax, OUT_ARG2(%esp)
12899    call   dvmCheckBefore                    # (dPC, dFP, self)
12900    movl   rSELF, %eax
129011:
12902    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12903    jmp    *dvmAsmInstructionStart+(190*4)
12904
12905/* ------------------------------ */
12906.L_ALT_OP_REM_LONG_2ADDR: /* 0xbf */
12907/* File: x86/alt_stub.S */
12908/*
12909 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12910 * any interesting requests and then jump to the real instruction
12911 * handler.  Unlike the Arm handler, we can't do this as a tail call
12912 * because rIBASE is caller save and we need to reload it.
12913 *
12914 * Note that unlike in the Arm implementation, we should never arrive
12915 * here with a zero breakFlag because we always refresh rIBASE on
12916 * return.
12917 */
12918    EXPORT_PC
12919    movl   rSELF, %eax
12920    movl   rPC, OUT_ARG0(%esp)
12921    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12922    movl   rFP, OUT_ARG1(%esp)
12923    je     1f                                # reload rIBASE & resume if not
12924    movl   %eax, OUT_ARG2(%esp)
12925    call   dvmCheckBefore                    # (dPC, dFP, self)
12926    movl   rSELF, %eax
129271:
12928    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12929    jmp    *dvmAsmInstructionStart+(191*4)
12930
12931/* ------------------------------ */
12932.L_ALT_OP_AND_LONG_2ADDR: /* 0xc0 */
12933/* File: x86/alt_stub.S */
12934/*
12935 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12936 * any interesting requests and then jump to the real instruction
12937 * handler.  Unlike the Arm handler, we can't do this as a tail call
12938 * because rIBASE is caller save and we need to reload it.
12939 *
12940 * Note that unlike in the Arm implementation, we should never arrive
12941 * here with a zero breakFlag because we always refresh rIBASE on
12942 * return.
12943 */
12944    EXPORT_PC
12945    movl   rSELF, %eax
12946    movl   rPC, OUT_ARG0(%esp)
12947    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12948    movl   rFP, OUT_ARG1(%esp)
12949    je     1f                                # reload rIBASE & resume if not
12950    movl   %eax, OUT_ARG2(%esp)
12951    call   dvmCheckBefore                    # (dPC, dFP, self)
12952    movl   rSELF, %eax
129531:
12954    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12955    jmp    *dvmAsmInstructionStart+(192*4)
12956
12957/* ------------------------------ */
12958.L_ALT_OP_OR_LONG_2ADDR: /* 0xc1 */
12959/* File: x86/alt_stub.S */
12960/*
12961 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12962 * any interesting requests and then jump to the real instruction
12963 * handler.  Unlike the Arm handler, we can't do this as a tail call
12964 * because rIBASE is caller save and we need to reload it.
12965 *
12966 * Note that unlike in the Arm implementation, we should never arrive
12967 * here with a zero breakFlag because we always refresh rIBASE on
12968 * return.
12969 */
12970    EXPORT_PC
12971    movl   rSELF, %eax
12972    movl   rPC, OUT_ARG0(%esp)
12973    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12974    movl   rFP, OUT_ARG1(%esp)
12975    je     1f                                # reload rIBASE & resume if not
12976    movl   %eax, OUT_ARG2(%esp)
12977    call   dvmCheckBefore                    # (dPC, dFP, self)
12978    movl   rSELF, %eax
129791:
12980    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12981    jmp    *dvmAsmInstructionStart+(193*4)
12982
12983/* ------------------------------ */
12984.L_ALT_OP_XOR_LONG_2ADDR: /* 0xc2 */
12985/* File: x86/alt_stub.S */
12986/*
12987 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12988 * any interesting requests and then jump to the real instruction
12989 * handler.  Unlike the Arm handler, we can't do this as a tail call
12990 * because rIBASE is caller save and we need to reload it.
12991 *
12992 * Note that unlike in the Arm implementation, we should never arrive
12993 * here with a zero breakFlag because we always refresh rIBASE on
12994 * return.
12995 */
12996    EXPORT_PC
12997    movl   rSELF, %eax
12998    movl   rPC, OUT_ARG0(%esp)
12999    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13000    movl   rFP, OUT_ARG1(%esp)
13001    je     1f                                # reload rIBASE & resume if not
13002    movl   %eax, OUT_ARG2(%esp)
13003    call   dvmCheckBefore                    # (dPC, dFP, self)
13004    movl   rSELF, %eax
130051:
13006    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13007    jmp    *dvmAsmInstructionStart+(194*4)
13008
13009/* ------------------------------ */
13010.L_ALT_OP_SHL_LONG_2ADDR: /* 0xc3 */
13011/* File: x86/alt_stub.S */
13012/*
13013 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13014 * any interesting requests and then jump to the real instruction
13015 * handler.  Unlike the Arm handler, we can't do this as a tail call
13016 * because rIBASE is caller save and we need to reload it.
13017 *
13018 * Note that unlike in the Arm implementation, we should never arrive
13019 * here with a zero breakFlag because we always refresh rIBASE on
13020 * return.
13021 */
13022    EXPORT_PC
13023    movl   rSELF, %eax
13024    movl   rPC, OUT_ARG0(%esp)
13025    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13026    movl   rFP, OUT_ARG1(%esp)
13027    je     1f                                # reload rIBASE & resume if not
13028    movl   %eax, OUT_ARG2(%esp)
13029    call   dvmCheckBefore                    # (dPC, dFP, self)
13030    movl   rSELF, %eax
130311:
13032    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13033    jmp    *dvmAsmInstructionStart+(195*4)
13034
13035/* ------------------------------ */
13036.L_ALT_OP_SHR_LONG_2ADDR: /* 0xc4 */
13037/* File: x86/alt_stub.S */
13038/*
13039 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13040 * any interesting requests and then jump to the real instruction
13041 * handler.  Unlike the Arm handler, we can't do this as a tail call
13042 * because rIBASE is caller save and we need to reload it.
13043 *
13044 * Note that unlike in the Arm implementation, we should never arrive
13045 * here with a zero breakFlag because we always refresh rIBASE on
13046 * return.
13047 */
13048    EXPORT_PC
13049    movl   rSELF, %eax
13050    movl   rPC, OUT_ARG0(%esp)
13051    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13052    movl   rFP, OUT_ARG1(%esp)
13053    je     1f                                # reload rIBASE & resume if not
13054    movl   %eax, OUT_ARG2(%esp)
13055    call   dvmCheckBefore                    # (dPC, dFP, self)
13056    movl   rSELF, %eax
130571:
13058    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13059    jmp    *dvmAsmInstructionStart+(196*4)
13060
13061/* ------------------------------ */
13062.L_ALT_OP_USHR_LONG_2ADDR: /* 0xc5 */
13063/* File: x86/alt_stub.S */
13064/*
13065 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13066 * any interesting requests and then jump to the real instruction
13067 * handler.  Unlike the Arm handler, we can't do this as a tail call
13068 * because rIBASE is caller save and we need to reload it.
13069 *
13070 * Note that unlike in the Arm implementation, we should never arrive
13071 * here with a zero breakFlag because we always refresh rIBASE on
13072 * return.
13073 */
13074    EXPORT_PC
13075    movl   rSELF, %eax
13076    movl   rPC, OUT_ARG0(%esp)
13077    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13078    movl   rFP, OUT_ARG1(%esp)
13079    je     1f                                # reload rIBASE & resume if not
13080    movl   %eax, OUT_ARG2(%esp)
13081    call   dvmCheckBefore                    # (dPC, dFP, self)
13082    movl   rSELF, %eax
130831:
13084    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13085    jmp    *dvmAsmInstructionStart+(197*4)
13086
13087/* ------------------------------ */
13088.L_ALT_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
13089/* File: x86/alt_stub.S */
13090/*
13091 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13092 * any interesting requests and then jump to the real instruction
13093 * handler.  Unlike the Arm handler, we can't do this as a tail call
13094 * because rIBASE is caller save and we need to reload it.
13095 *
13096 * Note that unlike in the Arm implementation, we should never arrive
13097 * here with a zero breakFlag because we always refresh rIBASE on
13098 * return.
13099 */
13100    EXPORT_PC
13101    movl   rSELF, %eax
13102    movl   rPC, OUT_ARG0(%esp)
13103    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13104    movl   rFP, OUT_ARG1(%esp)
13105    je     1f                                # reload rIBASE & resume if not
13106    movl   %eax, OUT_ARG2(%esp)
13107    call   dvmCheckBefore                    # (dPC, dFP, self)
13108    movl   rSELF, %eax
131091:
13110    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13111    jmp    *dvmAsmInstructionStart+(198*4)
13112
13113/* ------------------------------ */
13114.L_ALT_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
13115/* File: x86/alt_stub.S */
13116/*
13117 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13118 * any interesting requests and then jump to the real instruction
13119 * handler.  Unlike the Arm handler, we can't do this as a tail call
13120 * because rIBASE is caller save and we need to reload it.
13121 *
13122 * Note that unlike in the Arm implementation, we should never arrive
13123 * here with a zero breakFlag because we always refresh rIBASE on
13124 * return.
13125 */
13126    EXPORT_PC
13127    movl   rSELF, %eax
13128    movl   rPC, OUT_ARG0(%esp)
13129    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13130    movl   rFP, OUT_ARG1(%esp)
13131    je     1f                                # reload rIBASE & resume if not
13132    movl   %eax, OUT_ARG2(%esp)
13133    call   dvmCheckBefore                    # (dPC, dFP, self)
13134    movl   rSELF, %eax
131351:
13136    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13137    jmp    *dvmAsmInstructionStart+(199*4)
13138
13139/* ------------------------------ */
13140.L_ALT_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
13141/* File: x86/alt_stub.S */
13142/*
13143 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13144 * any interesting requests and then jump to the real instruction
13145 * handler.  Unlike the Arm handler, we can't do this as a tail call
13146 * because rIBASE is caller save and we need to reload it.
13147 *
13148 * Note that unlike in the Arm implementation, we should never arrive
13149 * here with a zero breakFlag because we always refresh rIBASE on
13150 * return.
13151 */
13152    EXPORT_PC
13153    movl   rSELF, %eax
13154    movl   rPC, OUT_ARG0(%esp)
13155    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13156    movl   rFP, OUT_ARG1(%esp)
13157    je     1f                                # reload rIBASE & resume if not
13158    movl   %eax, OUT_ARG2(%esp)
13159    call   dvmCheckBefore                    # (dPC, dFP, self)
13160    movl   rSELF, %eax
131611:
13162    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13163    jmp    *dvmAsmInstructionStart+(200*4)
13164
13165/* ------------------------------ */
13166.L_ALT_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
13167/* File: x86/alt_stub.S */
13168/*
13169 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13170 * any interesting requests and then jump to the real instruction
13171 * handler.  Unlike the Arm handler, we can't do this as a tail call
13172 * because rIBASE is caller save and we need to reload it.
13173 *
13174 * Note that unlike in the Arm implementation, we should never arrive
13175 * here with a zero breakFlag because we always refresh rIBASE on
13176 * return.
13177 */
13178    EXPORT_PC
13179    movl   rSELF, %eax
13180    movl   rPC, OUT_ARG0(%esp)
13181    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13182    movl   rFP, OUT_ARG1(%esp)
13183    je     1f                                # reload rIBASE & resume if not
13184    movl   %eax, OUT_ARG2(%esp)
13185    call   dvmCheckBefore                    # (dPC, dFP, self)
13186    movl   rSELF, %eax
131871:
13188    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13189    jmp    *dvmAsmInstructionStart+(201*4)
13190
13191/* ------------------------------ */
13192.L_ALT_OP_REM_FLOAT_2ADDR: /* 0xca */
13193/* File: x86/alt_stub.S */
13194/*
13195 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13196 * any interesting requests and then jump to the real instruction
13197 * handler.  Unlike the Arm handler, we can't do this as a tail call
13198 * because rIBASE is caller save and we need to reload it.
13199 *
13200 * Note that unlike in the Arm implementation, we should never arrive
13201 * here with a zero breakFlag because we always refresh rIBASE on
13202 * return.
13203 */
13204    EXPORT_PC
13205    movl   rSELF, %eax
13206    movl   rPC, OUT_ARG0(%esp)
13207    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13208    movl   rFP, OUT_ARG1(%esp)
13209    je     1f                                # reload rIBASE & resume if not
13210    movl   %eax, OUT_ARG2(%esp)
13211    call   dvmCheckBefore                    # (dPC, dFP, self)
13212    movl   rSELF, %eax
132131:
13214    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13215    jmp    *dvmAsmInstructionStart+(202*4)
13216
13217/* ------------------------------ */
13218.L_ALT_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
13219/* File: x86/alt_stub.S */
13220/*
13221 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13222 * any interesting requests and then jump to the real instruction
13223 * handler.  Unlike the Arm handler, we can't do this as a tail call
13224 * because rIBASE is caller save and we need to reload it.
13225 *
13226 * Note that unlike in the Arm implementation, we should never arrive
13227 * here with a zero breakFlag because we always refresh rIBASE on
13228 * return.
13229 */
13230    EXPORT_PC
13231    movl   rSELF, %eax
13232    movl   rPC, OUT_ARG0(%esp)
13233    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13234    movl   rFP, OUT_ARG1(%esp)
13235    je     1f                                # reload rIBASE & resume if not
13236    movl   %eax, OUT_ARG2(%esp)
13237    call   dvmCheckBefore                    # (dPC, dFP, self)
13238    movl   rSELF, %eax
132391:
13240    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13241    jmp    *dvmAsmInstructionStart+(203*4)
13242
13243/* ------------------------------ */
13244.L_ALT_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
13245/* File: x86/alt_stub.S */
13246/*
13247 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13248 * any interesting requests and then jump to the real instruction
13249 * handler.  Unlike the Arm handler, we can't do this as a tail call
13250 * because rIBASE is caller save and we need to reload it.
13251 *
13252 * Note that unlike in the Arm implementation, we should never arrive
13253 * here with a zero breakFlag because we always refresh rIBASE on
13254 * return.
13255 */
13256    EXPORT_PC
13257    movl   rSELF, %eax
13258    movl   rPC, OUT_ARG0(%esp)
13259    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13260    movl   rFP, OUT_ARG1(%esp)
13261    je     1f                                # reload rIBASE & resume if not
13262    movl   %eax, OUT_ARG2(%esp)
13263    call   dvmCheckBefore                    # (dPC, dFP, self)
13264    movl   rSELF, %eax
132651:
13266    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13267    jmp    *dvmAsmInstructionStart+(204*4)
13268
13269/* ------------------------------ */
13270.L_ALT_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
13271/* File: x86/alt_stub.S */
13272/*
13273 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13274 * any interesting requests and then jump to the real instruction
13275 * handler.  Unlike the Arm handler, we can't do this as a tail call
13276 * because rIBASE is caller save and we need to reload it.
13277 *
13278 * Note that unlike in the Arm implementation, we should never arrive
13279 * here with a zero breakFlag because we always refresh rIBASE on
13280 * return.
13281 */
13282    EXPORT_PC
13283    movl   rSELF, %eax
13284    movl   rPC, OUT_ARG0(%esp)
13285    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13286    movl   rFP, OUT_ARG1(%esp)
13287    je     1f                                # reload rIBASE & resume if not
13288    movl   %eax, OUT_ARG2(%esp)
13289    call   dvmCheckBefore                    # (dPC, dFP, self)
13290    movl   rSELF, %eax
132911:
13292    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13293    jmp    *dvmAsmInstructionStart+(205*4)
13294
13295/* ------------------------------ */
13296.L_ALT_OP_DIV_DOUBLE_2ADDR: /* 0xce */
13297/* File: x86/alt_stub.S */
13298/*
13299 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13300 * any interesting requests and then jump to the real instruction
13301 * handler.  Unlike the Arm handler, we can't do this as a tail call
13302 * because rIBASE is caller save and we need to reload it.
13303 *
13304 * Note that unlike in the Arm implementation, we should never arrive
13305 * here with a zero breakFlag because we always refresh rIBASE on
13306 * return.
13307 */
13308    EXPORT_PC
13309    movl   rSELF, %eax
13310    movl   rPC, OUT_ARG0(%esp)
13311    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13312    movl   rFP, OUT_ARG1(%esp)
13313    je     1f                                # reload rIBASE & resume if not
13314    movl   %eax, OUT_ARG2(%esp)
13315    call   dvmCheckBefore                    # (dPC, dFP, self)
13316    movl   rSELF, %eax
133171:
13318    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13319    jmp    *dvmAsmInstructionStart+(206*4)
13320
13321/* ------------------------------ */
13322.L_ALT_OP_REM_DOUBLE_2ADDR: /* 0xcf */
13323/* File: x86/alt_stub.S */
13324/*
13325 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13326 * any interesting requests and then jump to the real instruction
13327 * handler.  Unlike the Arm handler, we can't do this as a tail call
13328 * because rIBASE is caller save and we need to reload it.
13329 *
13330 * Note that unlike in the Arm implementation, we should never arrive
13331 * here with a zero breakFlag because we always refresh rIBASE on
13332 * return.
13333 */
13334    EXPORT_PC
13335    movl   rSELF, %eax
13336    movl   rPC, OUT_ARG0(%esp)
13337    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13338    movl   rFP, OUT_ARG1(%esp)
13339    je     1f                                # reload rIBASE & resume if not
13340    movl   %eax, OUT_ARG2(%esp)
13341    call   dvmCheckBefore                    # (dPC, dFP, self)
13342    movl   rSELF, %eax
133431:
13344    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13345    jmp    *dvmAsmInstructionStart+(207*4)
13346
13347/* ------------------------------ */
13348.L_ALT_OP_ADD_INT_LIT16: /* 0xd0 */
13349/* File: x86/alt_stub.S */
13350/*
13351 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13352 * any interesting requests and then jump to the real instruction
13353 * handler.  Unlike the Arm handler, we can't do this as a tail call
13354 * because rIBASE is caller save and we need to reload it.
13355 *
13356 * Note that unlike in the Arm implementation, we should never arrive
13357 * here with a zero breakFlag because we always refresh rIBASE on
13358 * return.
13359 */
13360    EXPORT_PC
13361    movl   rSELF, %eax
13362    movl   rPC, OUT_ARG0(%esp)
13363    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13364    movl   rFP, OUT_ARG1(%esp)
13365    je     1f                                # reload rIBASE & resume if not
13366    movl   %eax, OUT_ARG2(%esp)
13367    call   dvmCheckBefore                    # (dPC, dFP, self)
13368    movl   rSELF, %eax
133691:
13370    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13371    jmp    *dvmAsmInstructionStart+(208*4)
13372
13373/* ------------------------------ */
13374.L_ALT_OP_RSUB_INT: /* 0xd1 */
13375/* File: x86/alt_stub.S */
13376/*
13377 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13378 * any interesting requests and then jump to the real instruction
13379 * handler.  Unlike the Arm handler, we can't do this as a tail call
13380 * because rIBASE is caller save and we need to reload it.
13381 *
13382 * Note that unlike in the Arm implementation, we should never arrive
13383 * here with a zero breakFlag because we always refresh rIBASE on
13384 * return.
13385 */
13386    EXPORT_PC
13387    movl   rSELF, %eax
13388    movl   rPC, OUT_ARG0(%esp)
13389    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13390    movl   rFP, OUT_ARG1(%esp)
13391    je     1f                                # reload rIBASE & resume if not
13392    movl   %eax, OUT_ARG2(%esp)
13393    call   dvmCheckBefore                    # (dPC, dFP, self)
13394    movl   rSELF, %eax
133951:
13396    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13397    jmp    *dvmAsmInstructionStart+(209*4)
13398
13399/* ------------------------------ */
13400.L_ALT_OP_MUL_INT_LIT16: /* 0xd2 */
13401/* File: x86/alt_stub.S */
13402/*
13403 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13404 * any interesting requests and then jump to the real instruction
13405 * handler.  Unlike the Arm handler, we can't do this as a tail call
13406 * because rIBASE is caller save and we need to reload it.
13407 *
13408 * Note that unlike in the Arm implementation, we should never arrive
13409 * here with a zero breakFlag because we always refresh rIBASE on
13410 * return.
13411 */
13412    EXPORT_PC
13413    movl   rSELF, %eax
13414    movl   rPC, OUT_ARG0(%esp)
13415    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13416    movl   rFP, OUT_ARG1(%esp)
13417    je     1f                                # reload rIBASE & resume if not
13418    movl   %eax, OUT_ARG2(%esp)
13419    call   dvmCheckBefore                    # (dPC, dFP, self)
13420    movl   rSELF, %eax
134211:
13422    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13423    jmp    *dvmAsmInstructionStart+(210*4)
13424
13425/* ------------------------------ */
13426.L_ALT_OP_DIV_INT_LIT16: /* 0xd3 */
13427/* File: x86/alt_stub.S */
13428/*
13429 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13430 * any interesting requests and then jump to the real instruction
13431 * handler.  Unlike the Arm handler, we can't do this as a tail call
13432 * because rIBASE is caller save and we need to reload it.
13433 *
13434 * Note that unlike in the Arm implementation, we should never arrive
13435 * here with a zero breakFlag because we always refresh rIBASE on
13436 * return.
13437 */
13438    EXPORT_PC
13439    movl   rSELF, %eax
13440    movl   rPC, OUT_ARG0(%esp)
13441    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13442    movl   rFP, OUT_ARG1(%esp)
13443    je     1f                                # reload rIBASE & resume if not
13444    movl   %eax, OUT_ARG2(%esp)
13445    call   dvmCheckBefore                    # (dPC, dFP, self)
13446    movl   rSELF, %eax
134471:
13448    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13449    jmp    *dvmAsmInstructionStart+(211*4)
13450
13451/* ------------------------------ */
13452.L_ALT_OP_REM_INT_LIT16: /* 0xd4 */
13453/* File: x86/alt_stub.S */
13454/*
13455 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13456 * any interesting requests and then jump to the real instruction
13457 * handler.  Unlike the Arm handler, we can't do this as a tail call
13458 * because rIBASE is caller save and we need to reload it.
13459 *
13460 * Note that unlike in the Arm implementation, we should never arrive
13461 * here with a zero breakFlag because we always refresh rIBASE on
13462 * return.
13463 */
13464    EXPORT_PC
13465    movl   rSELF, %eax
13466    movl   rPC, OUT_ARG0(%esp)
13467    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13468    movl   rFP, OUT_ARG1(%esp)
13469    je     1f                                # reload rIBASE & resume if not
13470    movl   %eax, OUT_ARG2(%esp)
13471    call   dvmCheckBefore                    # (dPC, dFP, self)
13472    movl   rSELF, %eax
134731:
13474    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13475    jmp    *dvmAsmInstructionStart+(212*4)
13476
13477/* ------------------------------ */
13478.L_ALT_OP_AND_INT_LIT16: /* 0xd5 */
13479/* File: x86/alt_stub.S */
13480/*
13481 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13482 * any interesting requests and then jump to the real instruction
13483 * handler.  Unlike the Arm handler, we can't do this as a tail call
13484 * because rIBASE is caller save and we need to reload it.
13485 *
13486 * Note that unlike in the Arm implementation, we should never arrive
13487 * here with a zero breakFlag because we always refresh rIBASE on
13488 * return.
13489 */
13490    EXPORT_PC
13491    movl   rSELF, %eax
13492    movl   rPC, OUT_ARG0(%esp)
13493    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13494    movl   rFP, OUT_ARG1(%esp)
13495    je     1f                                # reload rIBASE & resume if not
13496    movl   %eax, OUT_ARG2(%esp)
13497    call   dvmCheckBefore                    # (dPC, dFP, self)
13498    movl   rSELF, %eax
134991:
13500    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13501    jmp    *dvmAsmInstructionStart+(213*4)
13502
13503/* ------------------------------ */
13504.L_ALT_OP_OR_INT_LIT16: /* 0xd6 */
13505/* File: x86/alt_stub.S */
13506/*
13507 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13508 * any interesting requests and then jump to the real instruction
13509 * handler.  Unlike the Arm handler, we can't do this as a tail call
13510 * because rIBASE is caller save and we need to reload it.
13511 *
13512 * Note that unlike in the Arm implementation, we should never arrive
13513 * here with a zero breakFlag because we always refresh rIBASE on
13514 * return.
13515 */
13516    EXPORT_PC
13517    movl   rSELF, %eax
13518    movl   rPC, OUT_ARG0(%esp)
13519    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13520    movl   rFP, OUT_ARG1(%esp)
13521    je     1f                                # reload rIBASE & resume if not
13522    movl   %eax, OUT_ARG2(%esp)
13523    call   dvmCheckBefore                    # (dPC, dFP, self)
13524    movl   rSELF, %eax
135251:
13526    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13527    jmp    *dvmAsmInstructionStart+(214*4)
13528
13529/* ------------------------------ */
13530.L_ALT_OP_XOR_INT_LIT16: /* 0xd7 */
13531/* File: x86/alt_stub.S */
13532/*
13533 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13534 * any interesting requests and then jump to the real instruction
13535 * handler.  Unlike the Arm handler, we can't do this as a tail call
13536 * because rIBASE is caller save and we need to reload it.
13537 *
13538 * Note that unlike in the Arm implementation, we should never arrive
13539 * here with a zero breakFlag because we always refresh rIBASE on
13540 * return.
13541 */
13542    EXPORT_PC
13543    movl   rSELF, %eax
13544    movl   rPC, OUT_ARG0(%esp)
13545    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13546    movl   rFP, OUT_ARG1(%esp)
13547    je     1f                                # reload rIBASE & resume if not
13548    movl   %eax, OUT_ARG2(%esp)
13549    call   dvmCheckBefore                    # (dPC, dFP, self)
13550    movl   rSELF, %eax
135511:
13552    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13553    jmp    *dvmAsmInstructionStart+(215*4)
13554
13555/* ------------------------------ */
13556.L_ALT_OP_ADD_INT_LIT8: /* 0xd8 */
13557/* File: x86/alt_stub.S */
13558/*
13559 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13560 * any interesting requests and then jump to the real instruction
13561 * handler.  Unlike the Arm handler, we can't do this as a tail call
13562 * because rIBASE is caller save and we need to reload it.
13563 *
13564 * Note that unlike in the Arm implementation, we should never arrive
13565 * here with a zero breakFlag because we always refresh rIBASE on
13566 * return.
13567 */
13568    EXPORT_PC
13569    movl   rSELF, %eax
13570    movl   rPC, OUT_ARG0(%esp)
13571    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13572    movl   rFP, OUT_ARG1(%esp)
13573    je     1f                                # reload rIBASE & resume if not
13574    movl   %eax, OUT_ARG2(%esp)
13575    call   dvmCheckBefore                    # (dPC, dFP, self)
13576    movl   rSELF, %eax
135771:
13578    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13579    jmp    *dvmAsmInstructionStart+(216*4)
13580
13581/* ------------------------------ */
13582.L_ALT_OP_RSUB_INT_LIT8: /* 0xd9 */
13583/* File: x86/alt_stub.S */
13584/*
13585 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13586 * any interesting requests and then jump to the real instruction
13587 * handler.  Unlike the Arm handler, we can't do this as a tail call
13588 * because rIBASE is caller save and we need to reload it.
13589 *
13590 * Note that unlike in the Arm implementation, we should never arrive
13591 * here with a zero breakFlag because we always refresh rIBASE on
13592 * return.
13593 */
13594    EXPORT_PC
13595    movl   rSELF, %eax
13596    movl   rPC, OUT_ARG0(%esp)
13597    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13598    movl   rFP, OUT_ARG1(%esp)
13599    je     1f                                # reload rIBASE & resume if not
13600    movl   %eax, OUT_ARG2(%esp)
13601    call   dvmCheckBefore                    # (dPC, dFP, self)
13602    movl   rSELF, %eax
136031:
13604    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13605    jmp    *dvmAsmInstructionStart+(217*4)
13606
13607/* ------------------------------ */
13608.L_ALT_OP_MUL_INT_LIT8: /* 0xda */
13609/* File: x86/alt_stub.S */
13610/*
13611 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13612 * any interesting requests and then jump to the real instruction
13613 * handler.  Unlike the Arm handler, we can't do this as a tail call
13614 * because rIBASE is caller save and we need to reload it.
13615 *
13616 * Note that unlike in the Arm implementation, we should never arrive
13617 * here with a zero breakFlag because we always refresh rIBASE on
13618 * return.
13619 */
13620    EXPORT_PC
13621    movl   rSELF, %eax
13622    movl   rPC, OUT_ARG0(%esp)
13623    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13624    movl   rFP, OUT_ARG1(%esp)
13625    je     1f                                # reload rIBASE & resume if not
13626    movl   %eax, OUT_ARG2(%esp)
13627    call   dvmCheckBefore                    # (dPC, dFP, self)
13628    movl   rSELF, %eax
136291:
13630    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13631    jmp    *dvmAsmInstructionStart+(218*4)
13632
13633/* ------------------------------ */
13634.L_ALT_OP_DIV_INT_LIT8: /* 0xdb */
13635/* File: x86/alt_stub.S */
13636/*
13637 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13638 * any interesting requests and then jump to the real instruction
13639 * handler.  Unlike the Arm handler, we can't do this as a tail call
13640 * because rIBASE is caller save and we need to reload it.
13641 *
13642 * Note that unlike in the Arm implementation, we should never arrive
13643 * here with a zero breakFlag because we always refresh rIBASE on
13644 * return.
13645 */
13646    EXPORT_PC
13647    movl   rSELF, %eax
13648    movl   rPC, OUT_ARG0(%esp)
13649    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13650    movl   rFP, OUT_ARG1(%esp)
13651    je     1f                                # reload rIBASE & resume if not
13652    movl   %eax, OUT_ARG2(%esp)
13653    call   dvmCheckBefore                    # (dPC, dFP, self)
13654    movl   rSELF, %eax
136551:
13656    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13657    jmp    *dvmAsmInstructionStart+(219*4)
13658
13659/* ------------------------------ */
13660.L_ALT_OP_REM_INT_LIT8: /* 0xdc */
13661/* File: x86/alt_stub.S */
13662/*
13663 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13664 * any interesting requests and then jump to the real instruction
13665 * handler.  Unlike the Arm handler, we can't do this as a tail call
13666 * because rIBASE is caller save and we need to reload it.
13667 *
13668 * Note that unlike in the Arm implementation, we should never arrive
13669 * here with a zero breakFlag because we always refresh rIBASE on
13670 * return.
13671 */
13672    EXPORT_PC
13673    movl   rSELF, %eax
13674    movl   rPC, OUT_ARG0(%esp)
13675    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13676    movl   rFP, OUT_ARG1(%esp)
13677    je     1f                                # reload rIBASE & resume if not
13678    movl   %eax, OUT_ARG2(%esp)
13679    call   dvmCheckBefore                    # (dPC, dFP, self)
13680    movl   rSELF, %eax
136811:
13682    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13683    jmp    *dvmAsmInstructionStart+(220*4)
13684
13685/* ------------------------------ */
13686.L_ALT_OP_AND_INT_LIT8: /* 0xdd */
13687/* File: x86/alt_stub.S */
13688/*
13689 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13690 * any interesting requests and then jump to the real instruction
13691 * handler.  Unlike the Arm handler, we can't do this as a tail call
13692 * because rIBASE is caller save and we need to reload it.
13693 *
13694 * Note that unlike in the Arm implementation, we should never arrive
13695 * here with a zero breakFlag because we always refresh rIBASE on
13696 * return.
13697 */
13698    EXPORT_PC
13699    movl   rSELF, %eax
13700    movl   rPC, OUT_ARG0(%esp)
13701    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13702    movl   rFP, OUT_ARG1(%esp)
13703    je     1f                                # reload rIBASE & resume if not
13704    movl   %eax, OUT_ARG2(%esp)
13705    call   dvmCheckBefore                    # (dPC, dFP, self)
13706    movl   rSELF, %eax
137071:
13708    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13709    jmp    *dvmAsmInstructionStart+(221*4)
13710
13711/* ------------------------------ */
13712.L_ALT_OP_OR_INT_LIT8: /* 0xde */
13713/* File: x86/alt_stub.S */
13714/*
13715 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13716 * any interesting requests and then jump to the real instruction
13717 * handler.  Unlike the Arm handler, we can't do this as a tail call
13718 * because rIBASE is caller save and we need to reload it.
13719 *
13720 * Note that unlike in the Arm implementation, we should never arrive
13721 * here with a zero breakFlag because we always refresh rIBASE on
13722 * return.
13723 */
13724    EXPORT_PC
13725    movl   rSELF, %eax
13726    movl   rPC, OUT_ARG0(%esp)
13727    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13728    movl   rFP, OUT_ARG1(%esp)
13729    je     1f                                # reload rIBASE & resume if not
13730    movl   %eax, OUT_ARG2(%esp)
13731    call   dvmCheckBefore                    # (dPC, dFP, self)
13732    movl   rSELF, %eax
137331:
13734    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13735    jmp    *dvmAsmInstructionStart+(222*4)
13736
13737/* ------------------------------ */
13738.L_ALT_OP_XOR_INT_LIT8: /* 0xdf */
13739/* File: x86/alt_stub.S */
13740/*
13741 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13742 * any interesting requests and then jump to the real instruction
13743 * handler.  Unlike the Arm handler, we can't do this as a tail call
13744 * because rIBASE is caller save and we need to reload it.
13745 *
13746 * Note that unlike in the Arm implementation, we should never arrive
13747 * here with a zero breakFlag because we always refresh rIBASE on
13748 * return.
13749 */
13750    EXPORT_PC
13751    movl   rSELF, %eax
13752    movl   rPC, OUT_ARG0(%esp)
13753    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13754    movl   rFP, OUT_ARG1(%esp)
13755    je     1f                                # reload rIBASE & resume if not
13756    movl   %eax, OUT_ARG2(%esp)
13757    call   dvmCheckBefore                    # (dPC, dFP, self)
13758    movl   rSELF, %eax
137591:
13760    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13761    jmp    *dvmAsmInstructionStart+(223*4)
13762
13763/* ------------------------------ */
13764.L_ALT_OP_SHL_INT_LIT8: /* 0xe0 */
13765/* File: x86/alt_stub.S */
13766/*
13767 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13768 * any interesting requests and then jump to the real instruction
13769 * handler.  Unlike the Arm handler, we can't do this as a tail call
13770 * because rIBASE is caller save and we need to reload it.
13771 *
13772 * Note that unlike in the Arm implementation, we should never arrive
13773 * here with a zero breakFlag because we always refresh rIBASE on
13774 * return.
13775 */
13776    EXPORT_PC
13777    movl   rSELF, %eax
13778    movl   rPC, OUT_ARG0(%esp)
13779    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13780    movl   rFP, OUT_ARG1(%esp)
13781    je     1f                                # reload rIBASE & resume if not
13782    movl   %eax, OUT_ARG2(%esp)
13783    call   dvmCheckBefore                    # (dPC, dFP, self)
13784    movl   rSELF, %eax
137851:
13786    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13787    jmp    *dvmAsmInstructionStart+(224*4)
13788
13789/* ------------------------------ */
13790.L_ALT_OP_SHR_INT_LIT8: /* 0xe1 */
13791/* File: x86/alt_stub.S */
13792/*
13793 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13794 * any interesting requests and then jump to the real instruction
13795 * handler.  Unlike the Arm handler, we can't do this as a tail call
13796 * because rIBASE is caller save and we need to reload it.
13797 *
13798 * Note that unlike in the Arm implementation, we should never arrive
13799 * here with a zero breakFlag because we always refresh rIBASE on
13800 * return.
13801 */
13802    EXPORT_PC
13803    movl   rSELF, %eax
13804    movl   rPC, OUT_ARG0(%esp)
13805    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13806    movl   rFP, OUT_ARG1(%esp)
13807    je     1f                                # reload rIBASE & resume if not
13808    movl   %eax, OUT_ARG2(%esp)
13809    call   dvmCheckBefore                    # (dPC, dFP, self)
13810    movl   rSELF, %eax
138111:
13812    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13813    jmp    *dvmAsmInstructionStart+(225*4)
13814
13815/* ------------------------------ */
13816.L_ALT_OP_USHR_INT_LIT8: /* 0xe2 */
13817/* File: x86/alt_stub.S */
13818/*
13819 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13820 * any interesting requests and then jump to the real instruction
13821 * handler.  Unlike the Arm handler, we can't do this as a tail call
13822 * because rIBASE is caller save and we need to reload it.
13823 *
13824 * Note that unlike in the Arm implementation, we should never arrive
13825 * here with a zero breakFlag because we always refresh rIBASE on
13826 * return.
13827 */
13828    EXPORT_PC
13829    movl   rSELF, %eax
13830    movl   rPC, OUT_ARG0(%esp)
13831    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13832    movl   rFP, OUT_ARG1(%esp)
13833    je     1f                                # reload rIBASE & resume if not
13834    movl   %eax, OUT_ARG2(%esp)
13835    call   dvmCheckBefore                    # (dPC, dFP, self)
13836    movl   rSELF, %eax
138371:
13838    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13839    jmp    *dvmAsmInstructionStart+(226*4)
13840
13841/* ------------------------------ */
13842.L_ALT_OP_IGET_VOLATILE: /* 0xe3 */
13843/* File: x86/alt_stub.S */
13844/*
13845 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13846 * any interesting requests and then jump to the real instruction
13847 * handler.  Unlike the Arm handler, we can't do this as a tail call
13848 * because rIBASE is caller save and we need to reload it.
13849 *
13850 * Note that unlike in the Arm implementation, we should never arrive
13851 * here with a zero breakFlag because we always refresh rIBASE on
13852 * return.
13853 */
13854    EXPORT_PC
13855    movl   rSELF, %eax
13856    movl   rPC, OUT_ARG0(%esp)
13857    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13858    movl   rFP, OUT_ARG1(%esp)
13859    je     1f                                # reload rIBASE & resume if not
13860    movl   %eax, OUT_ARG2(%esp)
13861    call   dvmCheckBefore                    # (dPC, dFP, self)
13862    movl   rSELF, %eax
138631:
13864    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13865    jmp    *dvmAsmInstructionStart+(227*4)
13866
13867/* ------------------------------ */
13868.L_ALT_OP_IPUT_VOLATILE: /* 0xe4 */
13869/* File: x86/alt_stub.S */
13870/*
13871 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13872 * any interesting requests and then jump to the real instruction
13873 * handler.  Unlike the Arm handler, we can't do this as a tail call
13874 * because rIBASE is caller save and we need to reload it.
13875 *
13876 * Note that unlike in the Arm implementation, we should never arrive
13877 * here with a zero breakFlag because we always refresh rIBASE on
13878 * return.
13879 */
13880    EXPORT_PC
13881    movl   rSELF, %eax
13882    movl   rPC, OUT_ARG0(%esp)
13883    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13884    movl   rFP, OUT_ARG1(%esp)
13885    je     1f                                # reload rIBASE & resume if not
13886    movl   %eax, OUT_ARG2(%esp)
13887    call   dvmCheckBefore                    # (dPC, dFP, self)
13888    movl   rSELF, %eax
138891:
13890    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13891    jmp    *dvmAsmInstructionStart+(228*4)
13892
13893/* ------------------------------ */
13894.L_ALT_OP_SGET_VOLATILE: /* 0xe5 */
13895/* File: x86/alt_stub.S */
13896/*
13897 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13898 * any interesting requests and then jump to the real instruction
13899 * handler.  Unlike the Arm handler, we can't do this as a tail call
13900 * because rIBASE is caller save and we need to reload it.
13901 *
13902 * Note that unlike in the Arm implementation, we should never arrive
13903 * here with a zero breakFlag because we always refresh rIBASE on
13904 * return.
13905 */
13906    EXPORT_PC
13907    movl   rSELF, %eax
13908    movl   rPC, OUT_ARG0(%esp)
13909    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13910    movl   rFP, OUT_ARG1(%esp)
13911    je     1f                                # reload rIBASE & resume if not
13912    movl   %eax, OUT_ARG2(%esp)
13913    call   dvmCheckBefore                    # (dPC, dFP, self)
13914    movl   rSELF, %eax
139151:
13916    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13917    jmp    *dvmAsmInstructionStart+(229*4)
13918
13919/* ------------------------------ */
13920.L_ALT_OP_SPUT_VOLATILE: /* 0xe6 */
13921/* File: x86/alt_stub.S */
13922/*
13923 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13924 * any interesting requests and then jump to the real instruction
13925 * handler.  Unlike the Arm handler, we can't do this as a tail call
13926 * because rIBASE is caller save and we need to reload it.
13927 *
13928 * Note that unlike in the Arm implementation, we should never arrive
13929 * here with a zero breakFlag because we always refresh rIBASE on
13930 * return.
13931 */
13932    EXPORT_PC
13933    movl   rSELF, %eax
13934    movl   rPC, OUT_ARG0(%esp)
13935    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13936    movl   rFP, OUT_ARG1(%esp)
13937    je     1f                                # reload rIBASE & resume if not
13938    movl   %eax, OUT_ARG2(%esp)
13939    call   dvmCheckBefore                    # (dPC, dFP, self)
13940    movl   rSELF, %eax
139411:
13942    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13943    jmp    *dvmAsmInstructionStart+(230*4)
13944
13945/* ------------------------------ */
13946.L_ALT_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
13947/* File: x86/alt_stub.S */
13948/*
13949 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13950 * any interesting requests and then jump to the real instruction
13951 * handler.  Unlike the Arm handler, we can't do this as a tail call
13952 * because rIBASE is caller save and we need to reload it.
13953 *
13954 * Note that unlike in the Arm implementation, we should never arrive
13955 * here with a zero breakFlag because we always refresh rIBASE on
13956 * return.
13957 */
13958    EXPORT_PC
13959    movl   rSELF, %eax
13960    movl   rPC, OUT_ARG0(%esp)
13961    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13962    movl   rFP, OUT_ARG1(%esp)
13963    je     1f                                # reload rIBASE & resume if not
13964    movl   %eax, OUT_ARG2(%esp)
13965    call   dvmCheckBefore                    # (dPC, dFP, self)
13966    movl   rSELF, %eax
139671:
13968    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13969    jmp    *dvmAsmInstructionStart+(231*4)
13970
13971/* ------------------------------ */
13972.L_ALT_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
13973/* File: x86/alt_stub.S */
13974/*
13975 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13976 * any interesting requests and then jump to the real instruction
13977 * handler.  Unlike the Arm handler, we can't do this as a tail call
13978 * because rIBASE is caller save and we need to reload it.
13979 *
13980 * Note that unlike in the Arm implementation, we should never arrive
13981 * here with a zero breakFlag because we always refresh rIBASE on
13982 * return.
13983 */
13984    EXPORT_PC
13985    movl   rSELF, %eax
13986    movl   rPC, OUT_ARG0(%esp)
13987    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13988    movl   rFP, OUT_ARG1(%esp)
13989    je     1f                                # reload rIBASE & resume if not
13990    movl   %eax, OUT_ARG2(%esp)
13991    call   dvmCheckBefore                    # (dPC, dFP, self)
13992    movl   rSELF, %eax
139931:
13994    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13995    jmp    *dvmAsmInstructionStart+(232*4)
13996
13997/* ------------------------------ */
13998.L_ALT_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
13999/* File: x86/alt_stub.S */
14000/*
14001 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14002 * any interesting requests and then jump to the real instruction
14003 * handler.  Unlike the Arm handler, we can't do this as a tail call
14004 * because rIBASE is caller save and we need to reload it.
14005 *
14006 * Note that unlike in the Arm implementation, we should never arrive
14007 * here with a zero breakFlag because we always refresh rIBASE on
14008 * return.
14009 */
14010    EXPORT_PC
14011    movl   rSELF, %eax
14012    movl   rPC, OUT_ARG0(%esp)
14013    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14014    movl   rFP, OUT_ARG1(%esp)
14015    je     1f                                # reload rIBASE & resume if not
14016    movl   %eax, OUT_ARG2(%esp)
14017    call   dvmCheckBefore                    # (dPC, dFP, self)
14018    movl   rSELF, %eax
140191:
14020    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14021    jmp    *dvmAsmInstructionStart+(233*4)
14022
14023/* ------------------------------ */
14024.L_ALT_OP_SGET_WIDE_VOLATILE: /* 0xea */
14025/* File: x86/alt_stub.S */
14026/*
14027 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14028 * any interesting requests and then jump to the real instruction
14029 * handler.  Unlike the Arm handler, we can't do this as a tail call
14030 * because rIBASE is caller save and we need to reload it.
14031 *
14032 * Note that unlike in the Arm implementation, we should never arrive
14033 * here with a zero breakFlag because we always refresh rIBASE on
14034 * return.
14035 */
14036    EXPORT_PC
14037    movl   rSELF, %eax
14038    movl   rPC, OUT_ARG0(%esp)
14039    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14040    movl   rFP, OUT_ARG1(%esp)
14041    je     1f                                # reload rIBASE & resume if not
14042    movl   %eax, OUT_ARG2(%esp)
14043    call   dvmCheckBefore                    # (dPC, dFP, self)
14044    movl   rSELF, %eax
140451:
14046    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14047    jmp    *dvmAsmInstructionStart+(234*4)
14048
14049/* ------------------------------ */
14050.L_ALT_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
14051/* File: x86/alt_stub.S */
14052/*
14053 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14054 * any interesting requests and then jump to the real instruction
14055 * handler.  Unlike the Arm handler, we can't do this as a tail call
14056 * because rIBASE is caller save and we need to reload it.
14057 *
14058 * Note that unlike in the Arm implementation, we should never arrive
14059 * here with a zero breakFlag because we always refresh rIBASE on
14060 * return.
14061 */
14062    EXPORT_PC
14063    movl   rSELF, %eax
14064    movl   rPC, OUT_ARG0(%esp)
14065    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14066    movl   rFP, OUT_ARG1(%esp)
14067    je     1f                                # reload rIBASE & resume if not
14068    movl   %eax, OUT_ARG2(%esp)
14069    call   dvmCheckBefore                    # (dPC, dFP, self)
14070    movl   rSELF, %eax
140711:
14072    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14073    jmp    *dvmAsmInstructionStart+(235*4)
14074
14075/* ------------------------------ */
14076.L_ALT_OP_BREAKPOINT: /* 0xec */
14077/* File: x86/alt_stub.S */
14078/*
14079 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14080 * any interesting requests and then jump to the real instruction
14081 * handler.  Unlike the Arm handler, we can't do this as a tail call
14082 * because rIBASE is caller save and we need to reload it.
14083 *
14084 * Note that unlike in the Arm implementation, we should never arrive
14085 * here with a zero breakFlag because we always refresh rIBASE on
14086 * return.
14087 */
14088    EXPORT_PC
14089    movl   rSELF, %eax
14090    movl   rPC, OUT_ARG0(%esp)
14091    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14092    movl   rFP, OUT_ARG1(%esp)
14093    je     1f                                # reload rIBASE & resume if not
14094    movl   %eax, OUT_ARG2(%esp)
14095    call   dvmCheckBefore                    # (dPC, dFP, self)
14096    movl   rSELF, %eax
140971:
14098    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14099    jmp    *dvmAsmInstructionStart+(236*4)
14100
14101/* ------------------------------ */
14102.L_ALT_OP_THROW_VERIFICATION_ERROR: /* 0xed */
14103/* File: x86/alt_stub.S */
14104/*
14105 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14106 * any interesting requests and then jump to the real instruction
14107 * handler.  Unlike the Arm handler, we can't do this as a tail call
14108 * because rIBASE is caller save and we need to reload it.
14109 *
14110 * Note that unlike in the Arm implementation, we should never arrive
14111 * here with a zero breakFlag because we always refresh rIBASE on
14112 * return.
14113 */
14114    EXPORT_PC
14115    movl   rSELF, %eax
14116    movl   rPC, OUT_ARG0(%esp)
14117    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14118    movl   rFP, OUT_ARG1(%esp)
14119    je     1f                                # reload rIBASE & resume if not
14120    movl   %eax, OUT_ARG2(%esp)
14121    call   dvmCheckBefore                    # (dPC, dFP, self)
14122    movl   rSELF, %eax
141231:
14124    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14125    jmp    *dvmAsmInstructionStart+(237*4)
14126
14127/* ------------------------------ */
14128.L_ALT_OP_EXECUTE_INLINE: /* 0xee */
14129/* File: x86/alt_stub.S */
14130/*
14131 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14132 * any interesting requests and then jump to the real instruction
14133 * handler.  Unlike the Arm handler, we can't do this as a tail call
14134 * because rIBASE is caller save and we need to reload it.
14135 *
14136 * Note that unlike in the Arm implementation, we should never arrive
14137 * here with a zero breakFlag because we always refresh rIBASE on
14138 * return.
14139 */
14140    EXPORT_PC
14141    movl   rSELF, %eax
14142    movl   rPC, OUT_ARG0(%esp)
14143    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14144    movl   rFP, OUT_ARG1(%esp)
14145    je     1f                                # reload rIBASE & resume if not
14146    movl   %eax, OUT_ARG2(%esp)
14147    call   dvmCheckBefore                    # (dPC, dFP, self)
14148    movl   rSELF, %eax
141491:
14150    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14151    jmp    *dvmAsmInstructionStart+(238*4)
14152
14153/* ------------------------------ */
14154.L_ALT_OP_EXECUTE_INLINE_RANGE: /* 0xef */
14155/* File: x86/alt_stub.S */
14156/*
14157 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14158 * any interesting requests and then jump to the real instruction
14159 * handler.  Unlike the Arm handler, we can't do this as a tail call
14160 * because rIBASE is caller save and we need to reload it.
14161 *
14162 * Note that unlike in the Arm implementation, we should never arrive
14163 * here with a zero breakFlag because we always refresh rIBASE on
14164 * return.
14165 */
14166    EXPORT_PC
14167    movl   rSELF, %eax
14168    movl   rPC, OUT_ARG0(%esp)
14169    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14170    movl   rFP, OUT_ARG1(%esp)
14171    je     1f                                # reload rIBASE & resume if not
14172    movl   %eax, OUT_ARG2(%esp)
14173    call   dvmCheckBefore                    # (dPC, dFP, self)
14174    movl   rSELF, %eax
141751:
14176    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14177    jmp    *dvmAsmInstructionStart+(239*4)
14178
14179/* ------------------------------ */
14180.L_ALT_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */
14181/* File: x86/alt_stub.S */
14182/*
14183 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14184 * any interesting requests and then jump to the real instruction
14185 * handler.  Unlike the Arm handler, we can't do this as a tail call
14186 * because rIBASE is caller save and we need to reload it.
14187 *
14188 * Note that unlike in the Arm implementation, we should never arrive
14189 * here with a zero breakFlag because we always refresh rIBASE on
14190 * return.
14191 */
14192    EXPORT_PC
14193    movl   rSELF, %eax
14194    movl   rPC, OUT_ARG0(%esp)
14195    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14196    movl   rFP, OUT_ARG1(%esp)
14197    je     1f                                # reload rIBASE & resume if not
14198    movl   %eax, OUT_ARG2(%esp)
14199    call   dvmCheckBefore                    # (dPC, dFP, self)
14200    movl   rSELF, %eax
142011:
14202    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14203    jmp    *dvmAsmInstructionStart+(240*4)
14204
14205/* ------------------------------ */
14206.L_ALT_OP_RETURN_VOID_BARRIER: /* 0xf1 */
14207/* File: x86/alt_stub.S */
14208/*
14209 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14210 * any interesting requests and then jump to the real instruction
14211 * handler.  Unlike the Arm handler, we can't do this as a tail call
14212 * because rIBASE is caller save and we need to reload it.
14213 *
14214 * Note that unlike in the Arm implementation, we should never arrive
14215 * here with a zero breakFlag because we always refresh rIBASE on
14216 * return.
14217 */
14218    EXPORT_PC
14219    movl   rSELF, %eax
14220    movl   rPC, OUT_ARG0(%esp)
14221    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14222    movl   rFP, OUT_ARG1(%esp)
14223    je     1f                                # reload rIBASE & resume if not
14224    movl   %eax, OUT_ARG2(%esp)
14225    call   dvmCheckBefore                    # (dPC, dFP, self)
14226    movl   rSELF, %eax
142271:
14228    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14229    jmp    *dvmAsmInstructionStart+(241*4)
14230
14231/* ------------------------------ */
14232.L_ALT_OP_IGET_QUICK: /* 0xf2 */
14233/* File: x86/alt_stub.S */
14234/*
14235 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14236 * any interesting requests and then jump to the real instruction
14237 * handler.  Unlike the Arm handler, we can't do this as a tail call
14238 * because rIBASE is caller save and we need to reload it.
14239 *
14240 * Note that unlike in the Arm implementation, we should never arrive
14241 * here with a zero breakFlag because we always refresh rIBASE on
14242 * return.
14243 */
14244    EXPORT_PC
14245    movl   rSELF, %eax
14246    movl   rPC, OUT_ARG0(%esp)
14247    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14248    movl   rFP, OUT_ARG1(%esp)
14249    je     1f                                # reload rIBASE & resume if not
14250    movl   %eax, OUT_ARG2(%esp)
14251    call   dvmCheckBefore                    # (dPC, dFP, self)
14252    movl   rSELF, %eax
142531:
14254    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14255    jmp    *dvmAsmInstructionStart+(242*4)
14256
14257/* ------------------------------ */
14258.L_ALT_OP_IGET_WIDE_QUICK: /* 0xf3 */
14259/* File: x86/alt_stub.S */
14260/*
14261 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14262 * any interesting requests and then jump to the real instruction
14263 * handler.  Unlike the Arm handler, we can't do this as a tail call
14264 * because rIBASE is caller save and we need to reload it.
14265 *
14266 * Note that unlike in the Arm implementation, we should never arrive
14267 * here with a zero breakFlag because we always refresh rIBASE on
14268 * return.
14269 */
14270    EXPORT_PC
14271    movl   rSELF, %eax
14272    movl   rPC, OUT_ARG0(%esp)
14273    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14274    movl   rFP, OUT_ARG1(%esp)
14275    je     1f                                # reload rIBASE & resume if not
14276    movl   %eax, OUT_ARG2(%esp)
14277    call   dvmCheckBefore                    # (dPC, dFP, self)
14278    movl   rSELF, %eax
142791:
14280    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14281    jmp    *dvmAsmInstructionStart+(243*4)
14282
14283/* ------------------------------ */
14284.L_ALT_OP_IGET_OBJECT_QUICK: /* 0xf4 */
14285/* File: x86/alt_stub.S */
14286/*
14287 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14288 * any interesting requests and then jump to the real instruction
14289 * handler.  Unlike the Arm handler, we can't do this as a tail call
14290 * because rIBASE is caller save and we need to reload it.
14291 *
14292 * Note that unlike in the Arm implementation, we should never arrive
14293 * here with a zero breakFlag because we always refresh rIBASE on
14294 * return.
14295 */
14296    EXPORT_PC
14297    movl   rSELF, %eax
14298    movl   rPC, OUT_ARG0(%esp)
14299    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14300    movl   rFP, OUT_ARG1(%esp)
14301    je     1f                                # reload rIBASE & resume if not
14302    movl   %eax, OUT_ARG2(%esp)
14303    call   dvmCheckBefore                    # (dPC, dFP, self)
14304    movl   rSELF, %eax
143051:
14306    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14307    jmp    *dvmAsmInstructionStart+(244*4)
14308
14309/* ------------------------------ */
14310.L_ALT_OP_IPUT_QUICK: /* 0xf5 */
14311/* File: x86/alt_stub.S */
14312/*
14313 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14314 * any interesting requests and then jump to the real instruction
14315 * handler.  Unlike the Arm handler, we can't do this as a tail call
14316 * because rIBASE is caller save and we need to reload it.
14317 *
14318 * Note that unlike in the Arm implementation, we should never arrive
14319 * here with a zero breakFlag because we always refresh rIBASE on
14320 * return.
14321 */
14322    EXPORT_PC
14323    movl   rSELF, %eax
14324    movl   rPC, OUT_ARG0(%esp)
14325    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14326    movl   rFP, OUT_ARG1(%esp)
14327    je     1f                                # reload rIBASE & resume if not
14328    movl   %eax, OUT_ARG2(%esp)
14329    call   dvmCheckBefore                    # (dPC, dFP, self)
14330    movl   rSELF, %eax
143311:
14332    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14333    jmp    *dvmAsmInstructionStart+(245*4)
14334
14335/* ------------------------------ */
14336.L_ALT_OP_IPUT_WIDE_QUICK: /* 0xf6 */
14337/* File: x86/alt_stub.S */
14338/*
14339 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14340 * any interesting requests and then jump to the real instruction
14341 * handler.  Unlike the Arm handler, we can't do this as a tail call
14342 * because rIBASE is caller save and we need to reload it.
14343 *
14344 * Note that unlike in the Arm implementation, we should never arrive
14345 * here with a zero breakFlag because we always refresh rIBASE on
14346 * return.
14347 */
14348    EXPORT_PC
14349    movl   rSELF, %eax
14350    movl   rPC, OUT_ARG0(%esp)
14351    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14352    movl   rFP, OUT_ARG1(%esp)
14353    je     1f                                # reload rIBASE & resume if not
14354    movl   %eax, OUT_ARG2(%esp)
14355    call   dvmCheckBefore                    # (dPC, dFP, self)
14356    movl   rSELF, %eax
143571:
14358    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14359    jmp    *dvmAsmInstructionStart+(246*4)
14360
14361/* ------------------------------ */
14362.L_ALT_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
14363/* File: x86/alt_stub.S */
14364/*
14365 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14366 * any interesting requests and then jump to the real instruction
14367 * handler.  Unlike the Arm handler, we can't do this as a tail call
14368 * because rIBASE is caller save and we need to reload it.
14369 *
14370 * Note that unlike in the Arm implementation, we should never arrive
14371 * here with a zero breakFlag because we always refresh rIBASE on
14372 * return.
14373 */
14374    EXPORT_PC
14375    movl   rSELF, %eax
14376    movl   rPC, OUT_ARG0(%esp)
14377    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14378    movl   rFP, OUT_ARG1(%esp)
14379    je     1f                                # reload rIBASE & resume if not
14380    movl   %eax, OUT_ARG2(%esp)
14381    call   dvmCheckBefore                    # (dPC, dFP, self)
14382    movl   rSELF, %eax
143831:
14384    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14385    jmp    *dvmAsmInstructionStart+(247*4)
14386
14387/* ------------------------------ */
14388.L_ALT_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
14389/* File: x86/alt_stub.S */
14390/*
14391 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14392 * any interesting requests and then jump to the real instruction
14393 * handler.  Unlike the Arm handler, we can't do this as a tail call
14394 * because rIBASE is caller save and we need to reload it.
14395 *
14396 * Note that unlike in the Arm implementation, we should never arrive
14397 * here with a zero breakFlag because we always refresh rIBASE on
14398 * return.
14399 */
14400    EXPORT_PC
14401    movl   rSELF, %eax
14402    movl   rPC, OUT_ARG0(%esp)
14403    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14404    movl   rFP, OUT_ARG1(%esp)
14405    je     1f                                # reload rIBASE & resume if not
14406    movl   %eax, OUT_ARG2(%esp)
14407    call   dvmCheckBefore                    # (dPC, dFP, self)
14408    movl   rSELF, %eax
144091:
14410    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14411    jmp    *dvmAsmInstructionStart+(248*4)
14412
14413/* ------------------------------ */
14414.L_ALT_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
14415/* File: x86/alt_stub.S */
14416/*
14417 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14418 * any interesting requests and then jump to the real instruction
14419 * handler.  Unlike the Arm handler, we can't do this as a tail call
14420 * because rIBASE is caller save and we need to reload it.
14421 *
14422 * Note that unlike in the Arm implementation, we should never arrive
14423 * here with a zero breakFlag because we always refresh rIBASE on
14424 * return.
14425 */
14426    EXPORT_PC
14427    movl   rSELF, %eax
14428    movl   rPC, OUT_ARG0(%esp)
14429    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14430    movl   rFP, OUT_ARG1(%esp)
14431    je     1f                                # reload rIBASE & resume if not
14432    movl   %eax, OUT_ARG2(%esp)
14433    call   dvmCheckBefore                    # (dPC, dFP, self)
14434    movl   rSELF, %eax
144351:
14436    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14437    jmp    *dvmAsmInstructionStart+(249*4)
14438
14439/* ------------------------------ */
14440.L_ALT_OP_INVOKE_SUPER_QUICK: /* 0xfa */
14441/* File: x86/alt_stub.S */
14442/*
14443 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14444 * any interesting requests and then jump to the real instruction
14445 * handler.  Unlike the Arm handler, we can't do this as a tail call
14446 * because rIBASE is caller save and we need to reload it.
14447 *
14448 * Note that unlike in the Arm implementation, we should never arrive
14449 * here with a zero breakFlag because we always refresh rIBASE on
14450 * return.
14451 */
14452    EXPORT_PC
14453    movl   rSELF, %eax
14454    movl   rPC, OUT_ARG0(%esp)
14455    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14456    movl   rFP, OUT_ARG1(%esp)
14457    je     1f                                # reload rIBASE & resume if not
14458    movl   %eax, OUT_ARG2(%esp)
14459    call   dvmCheckBefore                    # (dPC, dFP, self)
14460    movl   rSELF, %eax
144611:
14462    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14463    jmp    *dvmAsmInstructionStart+(250*4)
14464
14465/* ------------------------------ */
14466.L_ALT_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
14467/* File: x86/alt_stub.S */
14468/*
14469 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14470 * any interesting requests and then jump to the real instruction
14471 * handler.  Unlike the Arm handler, we can't do this as a tail call
14472 * because rIBASE is caller save and we need to reload it.
14473 *
14474 * Note that unlike in the Arm implementation, we should never arrive
14475 * here with a zero breakFlag because we always refresh rIBASE on
14476 * return.
14477 */
14478    EXPORT_PC
14479    movl   rSELF, %eax
14480    movl   rPC, OUT_ARG0(%esp)
14481    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14482    movl   rFP, OUT_ARG1(%esp)
14483    je     1f                                # reload rIBASE & resume if not
14484    movl   %eax, OUT_ARG2(%esp)
14485    call   dvmCheckBefore                    # (dPC, dFP, self)
14486    movl   rSELF, %eax
144871:
14488    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14489    jmp    *dvmAsmInstructionStart+(251*4)
14490
14491/* ------------------------------ */
14492.L_ALT_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
14493/* File: x86/alt_stub.S */
14494/*
14495 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14496 * any interesting requests and then jump to the real instruction
14497 * handler.  Unlike the Arm handler, we can't do this as a tail call
14498 * because rIBASE is caller save and we need to reload it.
14499 *
14500 * Note that unlike in the Arm implementation, we should never arrive
14501 * here with a zero breakFlag because we always refresh rIBASE on
14502 * return.
14503 */
14504    EXPORT_PC
14505    movl   rSELF, %eax
14506    movl   rPC, OUT_ARG0(%esp)
14507    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14508    movl   rFP, OUT_ARG1(%esp)
14509    je     1f                                # reload rIBASE & resume if not
14510    movl   %eax, OUT_ARG2(%esp)
14511    call   dvmCheckBefore                    # (dPC, dFP, self)
14512    movl   rSELF, %eax
145131:
14514    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14515    jmp    *dvmAsmInstructionStart+(252*4)
14516
14517/* ------------------------------ */
14518.L_ALT_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
14519/* File: x86/alt_stub.S */
14520/*
14521 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14522 * any interesting requests and then jump to the real instruction
14523 * handler.  Unlike the Arm handler, we can't do this as a tail call
14524 * because rIBASE is caller save and we need to reload it.
14525 *
14526 * Note that unlike in the Arm implementation, we should never arrive
14527 * here with a zero breakFlag because we always refresh rIBASE on
14528 * return.
14529 */
14530    EXPORT_PC
14531    movl   rSELF, %eax
14532    movl   rPC, OUT_ARG0(%esp)
14533    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14534    movl   rFP, OUT_ARG1(%esp)
14535    je     1f                                # reload rIBASE & resume if not
14536    movl   %eax, OUT_ARG2(%esp)
14537    call   dvmCheckBefore                    # (dPC, dFP, self)
14538    movl   rSELF, %eax
145391:
14540    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14541    jmp    *dvmAsmInstructionStart+(253*4)
14542
14543/* ------------------------------ */
14544.L_ALT_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
14545/* File: x86/alt_stub.S */
14546/*
14547 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14548 * any interesting requests and then jump to the real instruction
14549 * handler.  Unlike the Arm handler, we can't do this as a tail call
14550 * because rIBASE is caller save and we need to reload it.
14551 *
14552 * Note that unlike in the Arm implementation, we should never arrive
14553 * here with a zero breakFlag because we always refresh rIBASE on
14554 * return.
14555 */
14556    EXPORT_PC
14557    movl   rSELF, %eax
14558    movl   rPC, OUT_ARG0(%esp)
14559    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14560    movl   rFP, OUT_ARG1(%esp)
14561    je     1f                                # reload rIBASE & resume if not
14562    movl   %eax, OUT_ARG2(%esp)
14563    call   dvmCheckBefore                    # (dPC, dFP, self)
14564    movl   rSELF, %eax
145651:
14566    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14567    jmp    *dvmAsmInstructionStart+(254*4)
14568
14569/* ------------------------------ */
14570.L_ALT_OP_UNUSED_FF: /* 0xff */
14571/* File: x86/alt_stub.S */
14572/*
14573 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14574 * any interesting requests and then jump to the real instruction
14575 * handler.  Unlike the Arm handler, we can't do this as a tail call
14576 * because rIBASE is caller save and we need to reload it.
14577 *
14578 * Note that unlike in the Arm implementation, we should never arrive
14579 * here with a zero breakFlag because we always refresh rIBASE on
14580 * return.
14581 */
14582    EXPORT_PC
14583    movl   rSELF, %eax
14584    movl   rPC, OUT_ARG0(%esp)
14585    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14586    movl   rFP, OUT_ARG1(%esp)
14587    je     1f                                # reload rIBASE & resume if not
14588    movl   %eax, OUT_ARG2(%esp)
14589    call   dvmCheckBefore                    # (dPC, dFP, self)
14590    movl   rSELF, %eax
145911:
14592    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14593    jmp    *dvmAsmInstructionStart+(255*4)
14594
14595    .size   dvmAsmAltInstructionStartCode, .-dvmAsmAltInstructionStartCode
14596    .global dvmAsmAltInstructionEndCode
14597dvmAsmAltInstructionEndCode:
14598
14599    .global dvmAsmInstructionStart
14600    .text
14601dvmAsmInstructionStart:
14602    .long .L_OP_NOP /* 0x00 */
14603    .long .L_OP_MOVE /* 0x01 */
14604    .long .L_OP_MOVE_FROM16 /* 0x02 */
14605    .long .L_OP_MOVE_16 /* 0x03 */
14606    .long .L_OP_MOVE_WIDE /* 0x04 */
14607    .long .L_OP_MOVE_WIDE_FROM16 /* 0x05 */
14608    .long .L_OP_MOVE_WIDE_16 /* 0x06 */
14609    .long .L_OP_MOVE_OBJECT /* 0x07 */
14610    .long .L_OP_MOVE_OBJECT_FROM16 /* 0x08 */
14611    .long .L_OP_MOVE_OBJECT_16 /* 0x09 */
14612    .long .L_OP_MOVE_RESULT /* 0x0a */
14613    .long .L_OP_MOVE_RESULT_WIDE /* 0x0b */
14614    .long .L_OP_MOVE_RESULT_OBJECT /* 0x0c */
14615    .long .L_OP_MOVE_EXCEPTION /* 0x0d */
14616    .long .L_OP_RETURN_VOID /* 0x0e */
14617    .long .L_OP_RETURN /* 0x0f */
14618    .long .L_OP_RETURN_WIDE /* 0x10 */
14619    .long .L_OP_RETURN_OBJECT /* 0x11 */
14620    .long .L_OP_CONST_4 /* 0x12 */
14621    .long .L_OP_CONST_16 /* 0x13 */
14622    .long .L_OP_CONST /* 0x14 */
14623    .long .L_OP_CONST_HIGH16 /* 0x15 */
14624    .long .L_OP_CONST_WIDE_16 /* 0x16 */
14625    .long .L_OP_CONST_WIDE_32 /* 0x17 */
14626    .long .L_OP_CONST_WIDE /* 0x18 */
14627    .long .L_OP_CONST_WIDE_HIGH16 /* 0x19 */
14628    .long .L_OP_CONST_STRING /* 0x1a */
14629    .long .L_OP_CONST_STRING_JUMBO /* 0x1b */
14630    .long .L_OP_CONST_CLASS /* 0x1c */
14631    .long .L_OP_MONITOR_ENTER /* 0x1d */
14632    .long .L_OP_MONITOR_EXIT /* 0x1e */
14633    .long .L_OP_CHECK_CAST /* 0x1f */
14634    .long .L_OP_INSTANCE_OF /* 0x20 */
14635    .long .L_OP_ARRAY_LENGTH /* 0x21 */
14636    .long .L_OP_NEW_INSTANCE /* 0x22 */
14637    .long .L_OP_NEW_ARRAY /* 0x23 */
14638    .long .L_OP_FILLED_NEW_ARRAY /* 0x24 */
14639    .long .L_OP_FILLED_NEW_ARRAY_RANGE /* 0x25 */
14640    .long .L_OP_FILL_ARRAY_DATA /* 0x26 */
14641    .long .L_OP_THROW /* 0x27 */
14642    .long .L_OP_GOTO /* 0x28 */
14643    .long .L_OP_GOTO_16 /* 0x29 */
14644    .long .L_OP_GOTO_32 /* 0x2a */
14645    .long .L_OP_PACKED_SWITCH /* 0x2b */
14646    .long .L_OP_SPARSE_SWITCH /* 0x2c */
14647    .long .L_OP_CMPL_FLOAT /* 0x2d */
14648    .long .L_OP_CMPG_FLOAT /* 0x2e */
14649    .long .L_OP_CMPL_DOUBLE /* 0x2f */
14650    .long .L_OP_CMPG_DOUBLE /* 0x30 */
14651    .long .L_OP_CMP_LONG /* 0x31 */
14652    .long .L_OP_IF_EQ /* 0x32 */
14653    .long .L_OP_IF_NE /* 0x33 */
14654    .long .L_OP_IF_LT /* 0x34 */
14655    .long .L_OP_IF_GE /* 0x35 */
14656    .long .L_OP_IF_GT /* 0x36 */
14657    .long .L_OP_IF_LE /* 0x37 */
14658    .long .L_OP_IF_EQZ /* 0x38 */
14659    .long .L_OP_IF_NEZ /* 0x39 */
14660    .long .L_OP_IF_LTZ /* 0x3a */
14661    .long .L_OP_IF_GEZ /* 0x3b */
14662    .long .L_OP_IF_GTZ /* 0x3c */
14663    .long .L_OP_IF_LEZ /* 0x3d */
14664    .long .L_OP_UNUSED_3E /* 0x3e */
14665    .long .L_OP_UNUSED_3F /* 0x3f */
14666    .long .L_OP_UNUSED_40 /* 0x40 */
14667    .long .L_OP_UNUSED_41 /* 0x41 */
14668    .long .L_OP_UNUSED_42 /* 0x42 */
14669    .long .L_OP_UNUSED_43 /* 0x43 */
14670    .long .L_OP_AGET /* 0x44 */
14671    .long .L_OP_AGET_WIDE /* 0x45 */
14672    .long .L_OP_AGET_OBJECT /* 0x46 */
14673    .long .L_OP_AGET_BOOLEAN /* 0x47 */
14674    .long .L_OP_AGET_BYTE /* 0x48 */
14675    .long .L_OP_AGET_CHAR /* 0x49 */
14676    .long .L_OP_AGET_SHORT /* 0x4a */
14677    .long .L_OP_APUT /* 0x4b */
14678    .long .L_OP_APUT_WIDE /* 0x4c */
14679    .long .L_OP_APUT_OBJECT /* 0x4d */
14680    .long .L_OP_APUT_BOOLEAN /* 0x4e */
14681    .long .L_OP_APUT_BYTE /* 0x4f */
14682    .long .L_OP_APUT_CHAR /* 0x50 */
14683    .long .L_OP_APUT_SHORT /* 0x51 */
14684    .long .L_OP_IGET /* 0x52 */
14685    .long .L_OP_IGET_WIDE /* 0x53 */
14686    .long .L_OP_IGET_OBJECT /* 0x54 */
14687    .long .L_OP_IGET_BOOLEAN /* 0x55 */
14688    .long .L_OP_IGET_BYTE /* 0x56 */
14689    .long .L_OP_IGET_CHAR /* 0x57 */
14690    .long .L_OP_IGET_SHORT /* 0x58 */
14691    .long .L_OP_IPUT /* 0x59 */
14692    .long .L_OP_IPUT_WIDE /* 0x5a */
14693    .long .L_OP_IPUT_OBJECT /* 0x5b */
14694    .long .L_OP_IPUT_BOOLEAN /* 0x5c */
14695    .long .L_OP_IPUT_BYTE /* 0x5d */
14696    .long .L_OP_IPUT_CHAR /* 0x5e */
14697    .long .L_OP_IPUT_SHORT /* 0x5f */
14698    .long .L_OP_SGET /* 0x60 */
14699    .long .L_OP_SGET_WIDE /* 0x61 */
14700    .long .L_OP_SGET_OBJECT /* 0x62 */
14701    .long .L_OP_SGET_BOOLEAN /* 0x63 */
14702    .long .L_OP_SGET_BYTE /* 0x64 */
14703    .long .L_OP_SGET_CHAR /* 0x65 */
14704    .long .L_OP_SGET_SHORT /* 0x66 */
14705    .long .L_OP_SPUT /* 0x67 */
14706    .long .L_OP_SPUT_WIDE /* 0x68 */
14707    .long .L_OP_SPUT_OBJECT /* 0x69 */
14708    .long .L_OP_SPUT_BOOLEAN /* 0x6a */
14709    .long .L_OP_SPUT_BYTE /* 0x6b */
14710    .long .L_OP_SPUT_CHAR /* 0x6c */
14711    .long .L_OP_SPUT_SHORT /* 0x6d */
14712    .long .L_OP_INVOKE_VIRTUAL /* 0x6e */
14713    .long .L_OP_INVOKE_SUPER /* 0x6f */
14714    .long .L_OP_INVOKE_DIRECT /* 0x70 */
14715    .long .L_OP_INVOKE_STATIC /* 0x71 */
14716    .long .L_OP_INVOKE_INTERFACE /* 0x72 */
14717    .long .L_OP_UNUSED_73 /* 0x73 */
14718    .long .L_OP_INVOKE_VIRTUAL_RANGE /* 0x74 */
14719    .long .L_OP_INVOKE_SUPER_RANGE /* 0x75 */
14720    .long .L_OP_INVOKE_DIRECT_RANGE /* 0x76 */
14721    .long .L_OP_INVOKE_STATIC_RANGE /* 0x77 */
14722    .long .L_OP_INVOKE_INTERFACE_RANGE /* 0x78 */
14723    .long .L_OP_UNUSED_79 /* 0x79 */
14724    .long .L_OP_UNUSED_7A /* 0x7a */
14725    .long .L_OP_NEG_INT /* 0x7b */
14726    .long .L_OP_NOT_INT /* 0x7c */
14727    .long .L_OP_NEG_LONG /* 0x7d */
14728    .long .L_OP_NOT_LONG /* 0x7e */
14729    .long .L_OP_NEG_FLOAT /* 0x7f */
14730    .long .L_OP_NEG_DOUBLE /* 0x80 */
14731    .long .L_OP_INT_TO_LONG /* 0x81 */
14732    .long .L_OP_INT_TO_FLOAT /* 0x82 */
14733    .long .L_OP_INT_TO_DOUBLE /* 0x83 */
14734    .long .L_OP_LONG_TO_INT /* 0x84 */
14735    .long .L_OP_LONG_TO_FLOAT /* 0x85 */
14736    .long .L_OP_LONG_TO_DOUBLE /* 0x86 */
14737    .long .L_OP_FLOAT_TO_INT /* 0x87 */
14738    .long .L_OP_FLOAT_TO_LONG /* 0x88 */
14739    .long .L_OP_FLOAT_TO_DOUBLE /* 0x89 */
14740    .long .L_OP_DOUBLE_TO_INT /* 0x8a */
14741    .long .L_OP_DOUBLE_TO_LONG /* 0x8b */
14742    .long .L_OP_DOUBLE_TO_FLOAT /* 0x8c */
14743    .long .L_OP_INT_TO_BYTE /* 0x8d */
14744    .long .L_OP_INT_TO_CHAR /* 0x8e */
14745    .long .L_OP_INT_TO_SHORT /* 0x8f */
14746    .long .L_OP_ADD_INT /* 0x90 */
14747    .long .L_OP_SUB_INT /* 0x91 */
14748    .long .L_OP_MUL_INT /* 0x92 */
14749    .long .L_OP_DIV_INT /* 0x93 */
14750    .long .L_OP_REM_INT /* 0x94 */
14751    .long .L_OP_AND_INT /* 0x95 */
14752    .long .L_OP_OR_INT /* 0x96 */
14753    .long .L_OP_XOR_INT /* 0x97 */
14754    .long .L_OP_SHL_INT /* 0x98 */
14755    .long .L_OP_SHR_INT /* 0x99 */
14756    .long .L_OP_USHR_INT /* 0x9a */
14757    .long .L_OP_ADD_LONG /* 0x9b */
14758    .long .L_OP_SUB_LONG /* 0x9c */
14759    .long .L_OP_MUL_LONG /* 0x9d */
14760    .long .L_OP_DIV_LONG /* 0x9e */
14761    .long .L_OP_REM_LONG /* 0x9f */
14762    .long .L_OP_AND_LONG /* 0xa0 */
14763    .long .L_OP_OR_LONG /* 0xa1 */
14764    .long .L_OP_XOR_LONG /* 0xa2 */
14765    .long .L_OP_SHL_LONG /* 0xa3 */
14766    .long .L_OP_SHR_LONG /* 0xa4 */
14767    .long .L_OP_USHR_LONG /* 0xa5 */
14768    .long .L_OP_ADD_FLOAT /* 0xa6 */
14769    .long .L_OP_SUB_FLOAT /* 0xa7 */
14770    .long .L_OP_MUL_FLOAT /* 0xa8 */
14771    .long .L_OP_DIV_FLOAT /* 0xa9 */
14772    .long .L_OP_REM_FLOAT /* 0xaa */
14773    .long .L_OP_ADD_DOUBLE /* 0xab */
14774    .long .L_OP_SUB_DOUBLE /* 0xac */
14775    .long .L_OP_MUL_DOUBLE /* 0xad */
14776    .long .L_OP_DIV_DOUBLE /* 0xae */
14777    .long .L_OP_REM_DOUBLE /* 0xaf */
14778    .long .L_OP_ADD_INT_2ADDR /* 0xb0 */
14779    .long .L_OP_SUB_INT_2ADDR /* 0xb1 */
14780    .long .L_OP_MUL_INT_2ADDR /* 0xb2 */
14781    .long .L_OP_DIV_INT_2ADDR /* 0xb3 */
14782    .long .L_OP_REM_INT_2ADDR /* 0xb4 */
14783    .long .L_OP_AND_INT_2ADDR /* 0xb5 */
14784    .long .L_OP_OR_INT_2ADDR /* 0xb6 */
14785    .long .L_OP_XOR_INT_2ADDR /* 0xb7 */
14786    .long .L_OP_SHL_INT_2ADDR /* 0xb8 */
14787    .long .L_OP_SHR_INT_2ADDR /* 0xb9 */
14788    .long .L_OP_USHR_INT_2ADDR /* 0xba */
14789    .long .L_OP_ADD_LONG_2ADDR /* 0xbb */
14790    .long .L_OP_SUB_LONG_2ADDR /* 0xbc */
14791    .long .L_OP_MUL_LONG_2ADDR /* 0xbd */
14792    .long .L_OP_DIV_LONG_2ADDR /* 0xbe */
14793    .long .L_OP_REM_LONG_2ADDR /* 0xbf */
14794    .long .L_OP_AND_LONG_2ADDR /* 0xc0 */
14795    .long .L_OP_OR_LONG_2ADDR /* 0xc1 */
14796    .long .L_OP_XOR_LONG_2ADDR /* 0xc2 */
14797    .long .L_OP_SHL_LONG_2ADDR /* 0xc3 */
14798    .long .L_OP_SHR_LONG_2ADDR /* 0xc4 */
14799    .long .L_OP_USHR_LONG_2ADDR /* 0xc5 */
14800    .long .L_OP_ADD_FLOAT_2ADDR /* 0xc6 */
14801    .long .L_OP_SUB_FLOAT_2ADDR /* 0xc7 */
14802    .long .L_OP_MUL_FLOAT_2ADDR /* 0xc8 */
14803    .long .L_OP_DIV_FLOAT_2ADDR /* 0xc9 */
14804    .long .L_OP_REM_FLOAT_2ADDR /* 0xca */
14805    .long .L_OP_ADD_DOUBLE_2ADDR /* 0xcb */
14806    .long .L_OP_SUB_DOUBLE_2ADDR /* 0xcc */
14807    .long .L_OP_MUL_DOUBLE_2ADDR /* 0xcd */
14808    .long .L_OP_DIV_DOUBLE_2ADDR /* 0xce */
14809    .long .L_OP_REM_DOUBLE_2ADDR /* 0xcf */
14810    .long .L_OP_ADD_INT_LIT16 /* 0xd0 */
14811    .long .L_OP_RSUB_INT /* 0xd1 */
14812    .long .L_OP_MUL_INT_LIT16 /* 0xd2 */
14813    .long .L_OP_DIV_INT_LIT16 /* 0xd3 */
14814    .long .L_OP_REM_INT_LIT16 /* 0xd4 */
14815    .long .L_OP_AND_INT_LIT16 /* 0xd5 */
14816    .long .L_OP_OR_INT_LIT16 /* 0xd6 */
14817    .long .L_OP_XOR_INT_LIT16 /* 0xd7 */
14818    .long .L_OP_ADD_INT_LIT8 /* 0xd8 */
14819    .long .L_OP_RSUB_INT_LIT8 /* 0xd9 */
14820    .long .L_OP_MUL_INT_LIT8 /* 0xda */
14821    .long .L_OP_DIV_INT_LIT8 /* 0xdb */
14822    .long .L_OP_REM_INT_LIT8 /* 0xdc */
14823    .long .L_OP_AND_INT_LIT8 /* 0xdd */
14824    .long .L_OP_OR_INT_LIT8 /* 0xde */
14825    .long .L_OP_XOR_INT_LIT8 /* 0xdf */
14826    .long .L_OP_SHL_INT_LIT8 /* 0xe0 */
14827    .long .L_OP_SHR_INT_LIT8 /* 0xe1 */
14828    .long .L_OP_USHR_INT_LIT8 /* 0xe2 */
14829    .long .L_OP_IGET_VOLATILE /* 0xe3 */
14830    .long .L_OP_IPUT_VOLATILE /* 0xe4 */
14831    .long .L_OP_SGET_VOLATILE /* 0xe5 */
14832    .long .L_OP_SPUT_VOLATILE /* 0xe6 */
14833    .long .L_OP_IGET_OBJECT_VOLATILE /* 0xe7 */
14834    .long .L_OP_IGET_WIDE_VOLATILE /* 0xe8 */
14835    .long .L_OP_IPUT_WIDE_VOLATILE /* 0xe9 */
14836    .long .L_OP_SGET_WIDE_VOLATILE /* 0xea */
14837    .long .L_OP_SPUT_WIDE_VOLATILE /* 0xeb */
14838    .long .L_OP_BREAKPOINT /* 0xec */
14839    .long .L_OP_THROW_VERIFICATION_ERROR /* 0xed */
14840    .long .L_OP_EXECUTE_INLINE /* 0xee */
14841    .long .L_OP_EXECUTE_INLINE_RANGE /* 0xef */
14842    .long .L_OP_INVOKE_OBJECT_INIT_RANGE /* 0xf0 */
14843    .long .L_OP_RETURN_VOID_BARRIER /* 0xf1 */
14844    .long .L_OP_IGET_QUICK /* 0xf2 */
14845    .long .L_OP_IGET_WIDE_QUICK /* 0xf3 */
14846    .long .L_OP_IGET_OBJECT_QUICK /* 0xf4 */
14847    .long .L_OP_IPUT_QUICK /* 0xf5 */
14848    .long .L_OP_IPUT_WIDE_QUICK /* 0xf6 */
14849    .long .L_OP_IPUT_OBJECT_QUICK /* 0xf7 */
14850    .long .L_OP_INVOKE_VIRTUAL_QUICK /* 0xf8 */
14851    .long .L_OP_INVOKE_VIRTUAL_QUICK_RANGE /* 0xf9 */
14852    .long .L_OP_INVOKE_SUPER_QUICK /* 0xfa */
14853    .long .L_OP_INVOKE_SUPER_QUICK_RANGE /* 0xfb */
14854    .long .L_OP_IPUT_OBJECT_VOLATILE /* 0xfc */
14855    .long .L_OP_SGET_OBJECT_VOLATILE /* 0xfd */
14856    .long .L_OP_SPUT_OBJECT_VOLATILE /* 0xfe */
14857    .long .L_OP_UNUSED_FF /* 0xff */
14858
14859    .global dvmAsmAltInstructionStart
14860    .text
14861dvmAsmAltInstructionStart:
14862    .long .L_ALT_OP_NOP /* 0x00 */
14863    .long .L_ALT_OP_MOVE /* 0x01 */
14864    .long .L_ALT_OP_MOVE_FROM16 /* 0x02 */
14865    .long .L_ALT_OP_MOVE_16 /* 0x03 */
14866    .long .L_ALT_OP_MOVE_WIDE /* 0x04 */
14867    .long .L_ALT_OP_MOVE_WIDE_FROM16 /* 0x05 */
14868    .long .L_ALT_OP_MOVE_WIDE_16 /* 0x06 */
14869    .long .L_ALT_OP_MOVE_OBJECT /* 0x07 */
14870    .long .L_ALT_OP_MOVE_OBJECT_FROM16 /* 0x08 */
14871    .long .L_ALT_OP_MOVE_OBJECT_16 /* 0x09 */
14872    .long .L_ALT_OP_MOVE_RESULT /* 0x0a */
14873    .long .L_ALT_OP_MOVE_RESULT_WIDE /* 0x0b */
14874    .long .L_ALT_OP_MOVE_RESULT_OBJECT /* 0x0c */
14875    .long .L_ALT_OP_MOVE_EXCEPTION /* 0x0d */
14876    .long .L_ALT_OP_RETURN_VOID /* 0x0e */
14877    .long .L_ALT_OP_RETURN /* 0x0f */
14878    .long .L_ALT_OP_RETURN_WIDE /* 0x10 */
14879    .long .L_ALT_OP_RETURN_OBJECT /* 0x11 */
14880    .long .L_ALT_OP_CONST_4 /* 0x12 */
14881    .long .L_ALT_OP_CONST_16 /* 0x13 */
14882    .long .L_ALT_OP_CONST /* 0x14 */
14883    .long .L_ALT_OP_CONST_HIGH16 /* 0x15 */
14884    .long .L_ALT_OP_CONST_WIDE_16 /* 0x16 */
14885    .long .L_ALT_OP_CONST_WIDE_32 /* 0x17 */
14886    .long .L_ALT_OP_CONST_WIDE /* 0x18 */
14887    .long .L_ALT_OP_CONST_WIDE_HIGH16 /* 0x19 */
14888    .long .L_ALT_OP_CONST_STRING /* 0x1a */
14889    .long .L_ALT_OP_CONST_STRING_JUMBO /* 0x1b */
14890    .long .L_ALT_OP_CONST_CLASS /* 0x1c */
14891    .long .L_ALT_OP_MONITOR_ENTER /* 0x1d */
14892    .long .L_ALT_OP_MONITOR_EXIT /* 0x1e */
14893    .long .L_ALT_OP_CHECK_CAST /* 0x1f */
14894    .long .L_ALT_OP_INSTANCE_OF /* 0x20 */
14895    .long .L_ALT_OP_ARRAY_LENGTH /* 0x21 */
14896    .long .L_ALT_OP_NEW_INSTANCE /* 0x22 */
14897    .long .L_ALT_OP_NEW_ARRAY /* 0x23 */
14898    .long .L_ALT_OP_FILLED_NEW_ARRAY /* 0x24 */
14899    .long .L_ALT_OP_FILLED_NEW_ARRAY_RANGE /* 0x25 */
14900    .long .L_ALT_OP_FILL_ARRAY_DATA /* 0x26 */
14901    .long .L_ALT_OP_THROW /* 0x27 */
14902    .long .L_ALT_OP_GOTO /* 0x28 */
14903    .long .L_ALT_OP_GOTO_16 /* 0x29 */
14904    .long .L_ALT_OP_GOTO_32 /* 0x2a */
14905    .long .L_ALT_OP_PACKED_SWITCH /* 0x2b */
14906    .long .L_ALT_OP_SPARSE_SWITCH /* 0x2c */
14907    .long .L_ALT_OP_CMPL_FLOAT /* 0x2d */
14908    .long .L_ALT_OP_CMPG_FLOAT /* 0x2e */
14909    .long .L_ALT_OP_CMPL_DOUBLE /* 0x2f */
14910    .long .L_ALT_OP_CMPG_DOUBLE /* 0x30 */
14911    .long .L_ALT_OP_CMP_LONG /* 0x31 */
14912    .long .L_ALT_OP_IF_EQ /* 0x32 */
14913    .long .L_ALT_OP_IF_NE /* 0x33 */
14914    .long .L_ALT_OP_IF_LT /* 0x34 */
14915    .long .L_ALT_OP_IF_GE /* 0x35 */
14916    .long .L_ALT_OP_IF_GT /* 0x36 */
14917    .long .L_ALT_OP_IF_LE /* 0x37 */
14918    .long .L_ALT_OP_IF_EQZ /* 0x38 */
14919    .long .L_ALT_OP_IF_NEZ /* 0x39 */
14920    .long .L_ALT_OP_IF_LTZ /* 0x3a */
14921    .long .L_ALT_OP_IF_GEZ /* 0x3b */
14922    .long .L_ALT_OP_IF_GTZ /* 0x3c */
14923    .long .L_ALT_OP_IF_LEZ /* 0x3d */
14924    .long .L_ALT_OP_UNUSED_3E /* 0x3e */
14925    .long .L_ALT_OP_UNUSED_3F /* 0x3f */
14926    .long .L_ALT_OP_UNUSED_40 /* 0x40 */
14927    .long .L_ALT_OP_UNUSED_41 /* 0x41 */
14928    .long .L_ALT_OP_UNUSED_42 /* 0x42 */
14929    .long .L_ALT_OP_UNUSED_43 /* 0x43 */
14930    .long .L_ALT_OP_AGET /* 0x44 */
14931    .long .L_ALT_OP_AGET_WIDE /* 0x45 */
14932    .long .L_ALT_OP_AGET_OBJECT /* 0x46 */
14933    .long .L_ALT_OP_AGET_BOOLEAN /* 0x47 */
14934    .long .L_ALT_OP_AGET_BYTE /* 0x48 */
14935    .long .L_ALT_OP_AGET_CHAR /* 0x49 */
14936    .long .L_ALT_OP_AGET_SHORT /* 0x4a */
14937    .long .L_ALT_OP_APUT /* 0x4b */
14938    .long .L_ALT_OP_APUT_WIDE /* 0x4c */
14939    .long .L_ALT_OP_APUT_OBJECT /* 0x4d */
14940    .long .L_ALT_OP_APUT_BOOLEAN /* 0x4e */
14941    .long .L_ALT_OP_APUT_BYTE /* 0x4f */
14942    .long .L_ALT_OP_APUT_CHAR /* 0x50 */
14943    .long .L_ALT_OP_APUT_SHORT /* 0x51 */
14944    .long .L_ALT_OP_IGET /* 0x52 */
14945    .long .L_ALT_OP_IGET_WIDE /* 0x53 */
14946    .long .L_ALT_OP_IGET_OBJECT /* 0x54 */
14947    .long .L_ALT_OP_IGET_BOOLEAN /* 0x55 */
14948    .long .L_ALT_OP_IGET_BYTE /* 0x56 */
14949    .long .L_ALT_OP_IGET_CHAR /* 0x57 */
14950    .long .L_ALT_OP_IGET_SHORT /* 0x58 */
14951    .long .L_ALT_OP_IPUT /* 0x59 */
14952    .long .L_ALT_OP_IPUT_WIDE /* 0x5a */
14953    .long .L_ALT_OP_IPUT_OBJECT /* 0x5b */
14954    .long .L_ALT_OP_IPUT_BOOLEAN /* 0x5c */
14955    .long .L_ALT_OP_IPUT_BYTE /* 0x5d */
14956    .long .L_ALT_OP_IPUT_CHAR /* 0x5e */
14957    .long .L_ALT_OP_IPUT_SHORT /* 0x5f */
14958    .long .L_ALT_OP_SGET /* 0x60 */
14959    .long .L_ALT_OP_SGET_WIDE /* 0x61 */
14960    .long .L_ALT_OP_SGET_OBJECT /* 0x62 */
14961    .long .L_ALT_OP_SGET_BOOLEAN /* 0x63 */
14962    .long .L_ALT_OP_SGET_BYTE /* 0x64 */
14963    .long .L_ALT_OP_SGET_CHAR /* 0x65 */
14964    .long .L_ALT_OP_SGET_SHORT /* 0x66 */
14965    .long .L_ALT_OP_SPUT /* 0x67 */
14966    .long .L_ALT_OP_SPUT_WIDE /* 0x68 */
14967    .long .L_ALT_OP_SPUT_OBJECT /* 0x69 */
14968    .long .L_ALT_OP_SPUT_BOOLEAN /* 0x6a */
14969    .long .L_ALT_OP_SPUT_BYTE /* 0x6b */
14970    .long .L_ALT_OP_SPUT_CHAR /* 0x6c */
14971    .long .L_ALT_OP_SPUT_SHORT /* 0x6d */
14972    .long .L_ALT_OP_INVOKE_VIRTUAL /* 0x6e */
14973    .long .L_ALT_OP_INVOKE_SUPER /* 0x6f */
14974    .long .L_ALT_OP_INVOKE_DIRECT /* 0x70 */
14975    .long .L_ALT_OP_INVOKE_STATIC /* 0x71 */
14976    .long .L_ALT_OP_INVOKE_INTERFACE /* 0x72 */
14977    .long .L_ALT_OP_UNUSED_73 /* 0x73 */
14978    .long .L_ALT_OP_INVOKE_VIRTUAL_RANGE /* 0x74 */
14979    .long .L_ALT_OP_INVOKE_SUPER_RANGE /* 0x75 */
14980    .long .L_ALT_OP_INVOKE_DIRECT_RANGE /* 0x76 */
14981    .long .L_ALT_OP_INVOKE_STATIC_RANGE /* 0x77 */
14982    .long .L_ALT_OP_INVOKE_INTERFACE_RANGE /* 0x78 */
14983    .long .L_ALT_OP_UNUSED_79 /* 0x79 */
14984    .long .L_ALT_OP_UNUSED_7A /* 0x7a */
14985    .long .L_ALT_OP_NEG_INT /* 0x7b */
14986    .long .L_ALT_OP_NOT_INT /* 0x7c */
14987    .long .L_ALT_OP_NEG_LONG /* 0x7d */
14988    .long .L_ALT_OP_NOT_LONG /* 0x7e */
14989    .long .L_ALT_OP_NEG_FLOAT /* 0x7f */
14990    .long .L_ALT_OP_NEG_DOUBLE /* 0x80 */
14991    .long .L_ALT_OP_INT_TO_LONG /* 0x81 */
14992    .long .L_ALT_OP_INT_TO_FLOAT /* 0x82 */
14993    .long .L_ALT_OP_INT_TO_DOUBLE /* 0x83 */
14994    .long .L_ALT_OP_LONG_TO_INT /* 0x84 */
14995    .long .L_ALT_OP_LONG_TO_FLOAT /* 0x85 */
14996    .long .L_ALT_OP_LONG_TO_DOUBLE /* 0x86 */
14997    .long .L_ALT_OP_FLOAT_TO_INT /* 0x87 */
14998    .long .L_ALT_OP_FLOAT_TO_LONG /* 0x88 */
14999    .long .L_ALT_OP_FLOAT_TO_DOUBLE /* 0x89 */
15000    .long .L_ALT_OP_DOUBLE_TO_INT /* 0x8a */
15001    .long .L_ALT_OP_DOUBLE_TO_LONG /* 0x8b */
15002    .long .L_ALT_OP_DOUBLE_TO_FLOAT /* 0x8c */
15003    .long .L_ALT_OP_INT_TO_BYTE /* 0x8d */
15004    .long .L_ALT_OP_INT_TO_CHAR /* 0x8e */
15005    .long .L_ALT_OP_INT_TO_SHORT /* 0x8f */
15006    .long .L_ALT_OP_ADD_INT /* 0x90 */
15007    .long .L_ALT_OP_SUB_INT /* 0x91 */
15008    .long .L_ALT_OP_MUL_INT /* 0x92 */
15009    .long .L_ALT_OP_DIV_INT /* 0x93 */
15010    .long .L_ALT_OP_REM_INT /* 0x94 */
15011    .long .L_ALT_OP_AND_INT /* 0x95 */
15012    .long .L_ALT_OP_OR_INT /* 0x96 */
15013    .long .L_ALT_OP_XOR_INT /* 0x97 */
15014    .long .L_ALT_OP_SHL_INT /* 0x98 */
15015    .long .L_ALT_OP_SHR_INT /* 0x99 */
15016    .long .L_ALT_OP_USHR_INT /* 0x9a */
15017    .long .L_ALT_OP_ADD_LONG /* 0x9b */
15018    .long .L_ALT_OP_SUB_LONG /* 0x9c */
15019    .long .L_ALT_OP_MUL_LONG /* 0x9d */
15020    .long .L_ALT_OP_DIV_LONG /* 0x9e */
15021    .long .L_ALT_OP_REM_LONG /* 0x9f */
15022    .long .L_ALT_OP_AND_LONG /* 0xa0 */
15023    .long .L_ALT_OP_OR_LONG /* 0xa1 */
15024    .long .L_ALT_OP_XOR_LONG /* 0xa2 */
15025    .long .L_ALT_OP_SHL_LONG /* 0xa3 */
15026    .long .L_ALT_OP_SHR_LONG /* 0xa4 */
15027    .long .L_ALT_OP_USHR_LONG /* 0xa5 */
15028    .long .L_ALT_OP_ADD_FLOAT /* 0xa6 */
15029    .long .L_ALT_OP_SUB_FLOAT /* 0xa7 */
15030    .long .L_ALT_OP_MUL_FLOAT /* 0xa8 */
15031    .long .L_ALT_OP_DIV_FLOAT /* 0xa9 */
15032    .long .L_ALT_OP_REM_FLOAT /* 0xaa */
15033    .long .L_ALT_OP_ADD_DOUBLE /* 0xab */
15034    .long .L_ALT_OP_SUB_DOUBLE /* 0xac */
15035    .long .L_ALT_OP_MUL_DOUBLE /* 0xad */
15036    .long .L_ALT_OP_DIV_DOUBLE /* 0xae */
15037    .long .L_ALT_OP_REM_DOUBLE /* 0xaf */
15038    .long .L_ALT_OP_ADD_INT_2ADDR /* 0xb0 */
15039    .long .L_ALT_OP_SUB_INT_2ADDR /* 0xb1 */
15040    .long .L_ALT_OP_MUL_INT_2ADDR /* 0xb2 */
15041    .long .L_ALT_OP_DIV_INT_2ADDR /* 0xb3 */
15042    .long .L_ALT_OP_REM_INT_2ADDR /* 0xb4 */
15043    .long .L_ALT_OP_AND_INT_2ADDR /* 0xb5 */
15044    .long .L_ALT_OP_OR_INT_2ADDR /* 0xb6 */
15045    .long .L_ALT_OP_XOR_INT_2ADDR /* 0xb7 */
15046    .long .L_ALT_OP_SHL_INT_2ADDR /* 0xb8 */
15047    .long .L_ALT_OP_SHR_INT_2ADDR /* 0xb9 */
15048    .long .L_ALT_OP_USHR_INT_2ADDR /* 0xba */
15049    .long .L_ALT_OP_ADD_LONG_2ADDR /* 0xbb */
15050    .long .L_ALT_OP_SUB_LONG_2ADDR /* 0xbc */
15051    .long .L_ALT_OP_MUL_LONG_2ADDR /* 0xbd */
15052    .long .L_ALT_OP_DIV_LONG_2ADDR /* 0xbe */
15053    .long .L_ALT_OP_REM_LONG_2ADDR /* 0xbf */
15054    .long .L_ALT_OP_AND_LONG_2ADDR /* 0xc0 */
15055    .long .L_ALT_OP_OR_LONG_2ADDR /* 0xc1 */
15056    .long .L_ALT_OP_XOR_LONG_2ADDR /* 0xc2 */
15057    .long .L_ALT_OP_SHL_LONG_2ADDR /* 0xc3 */
15058    .long .L_ALT_OP_SHR_LONG_2ADDR /* 0xc4 */
15059    .long .L_ALT_OP_USHR_LONG_2ADDR /* 0xc5 */
15060    .long .L_ALT_OP_ADD_FLOAT_2ADDR /* 0xc6 */
15061    .long .L_ALT_OP_SUB_FLOAT_2ADDR /* 0xc7 */
15062    .long .L_ALT_OP_MUL_FLOAT_2ADDR /* 0xc8 */
15063    .long .L_ALT_OP_DIV_FLOAT_2ADDR /* 0xc9 */
15064    .long .L_ALT_OP_REM_FLOAT_2ADDR /* 0xca */
15065    .long .L_ALT_OP_ADD_DOUBLE_2ADDR /* 0xcb */
15066    .long .L_ALT_OP_SUB_DOUBLE_2ADDR /* 0xcc */
15067    .long .L_ALT_OP_MUL_DOUBLE_2ADDR /* 0xcd */
15068    .long .L_ALT_OP_DIV_DOUBLE_2ADDR /* 0xce */
15069    .long .L_ALT_OP_REM_DOUBLE_2ADDR /* 0xcf */
15070    .long .L_ALT_OP_ADD_INT_LIT16 /* 0xd0 */
15071    .long .L_ALT_OP_RSUB_INT /* 0xd1 */
15072    .long .L_ALT_OP_MUL_INT_LIT16 /* 0xd2 */
15073    .long .L_ALT_OP_DIV_INT_LIT16 /* 0xd3 */
15074    .long .L_ALT_OP_REM_INT_LIT16 /* 0xd4 */
15075    .long .L_ALT_OP_AND_INT_LIT16 /* 0xd5 */
15076    .long .L_ALT_OP_OR_INT_LIT16 /* 0xd6 */
15077    .long .L_ALT_OP_XOR_INT_LIT16 /* 0xd7 */
15078    .long .L_ALT_OP_ADD_INT_LIT8 /* 0xd8 */
15079    .long .L_ALT_OP_RSUB_INT_LIT8 /* 0xd9 */
15080    .long .L_ALT_OP_MUL_INT_LIT8 /* 0xda */
15081    .long .L_ALT_OP_DIV_INT_LIT8 /* 0xdb */
15082    .long .L_ALT_OP_REM_INT_LIT8 /* 0xdc */
15083    .long .L_ALT_OP_AND_INT_LIT8 /* 0xdd */
15084    .long .L_ALT_OP_OR_INT_LIT8 /* 0xde */
15085    .long .L_ALT_OP_XOR_INT_LIT8 /* 0xdf */
15086    .long .L_ALT_OP_SHL_INT_LIT8 /* 0xe0 */
15087    .long .L_ALT_OP_SHR_INT_LIT8 /* 0xe1 */
15088    .long .L_ALT_OP_USHR_INT_LIT8 /* 0xe2 */
15089    .long .L_ALT_OP_IGET_VOLATILE /* 0xe3 */
15090    .long .L_ALT_OP_IPUT_VOLATILE /* 0xe4 */
15091    .long .L_ALT_OP_SGET_VOLATILE /* 0xe5 */
15092    .long .L_ALT_OP_SPUT_VOLATILE /* 0xe6 */
15093    .long .L_ALT_OP_IGET_OBJECT_VOLATILE /* 0xe7 */
15094    .long .L_ALT_OP_IGET_WIDE_VOLATILE /* 0xe8 */
15095    .long .L_ALT_OP_IPUT_WIDE_VOLATILE /* 0xe9 */
15096    .long .L_ALT_OP_SGET_WIDE_VOLATILE /* 0xea */
15097    .long .L_ALT_OP_SPUT_WIDE_VOLATILE /* 0xeb */
15098    .long .L_ALT_OP_BREAKPOINT /* 0xec */
15099    .long .L_ALT_OP_THROW_VERIFICATION_ERROR /* 0xed */
15100    .long .L_ALT_OP_EXECUTE_INLINE /* 0xee */
15101    .long .L_ALT_OP_EXECUTE_INLINE_RANGE /* 0xef */
15102    .long .L_ALT_OP_INVOKE_OBJECT_INIT_RANGE /* 0xf0 */
15103    .long .L_ALT_OP_RETURN_VOID_BARRIER /* 0xf1 */
15104    .long .L_ALT_OP_IGET_QUICK /* 0xf2 */
15105    .long .L_ALT_OP_IGET_WIDE_QUICK /* 0xf3 */
15106    .long .L_ALT_OP_IGET_OBJECT_QUICK /* 0xf4 */
15107    .long .L_ALT_OP_IPUT_QUICK /* 0xf5 */
15108    .long .L_ALT_OP_IPUT_WIDE_QUICK /* 0xf6 */
15109    .long .L_ALT_OP_IPUT_OBJECT_QUICK /* 0xf7 */
15110    .long .L_ALT_OP_INVOKE_VIRTUAL_QUICK /* 0xf8 */
15111    .long .L_ALT_OP_INVOKE_VIRTUAL_QUICK_RANGE /* 0xf9 */
15112    .long .L_ALT_OP_INVOKE_SUPER_QUICK /* 0xfa */
15113    .long .L_ALT_OP_INVOKE_SUPER_QUICK_RANGE /* 0xfb */
15114    .long .L_ALT_OP_IPUT_OBJECT_VOLATILE /* 0xfc */
15115    .long .L_ALT_OP_SGET_OBJECT_VOLATILE /* 0xfd */
15116    .long .L_ALT_OP_SPUT_OBJECT_VOLATILE /* 0xfe */
15117    .long .L_ALT_OP_UNUSED_FF /* 0xff */
15118/* File: x86/entry.S */
15119/*
15120 * Copyright (C) 2008 The Android Open Source Project
15121 *
15122 * Licensed under the Apache License, Version 2.0 (the "License");
15123 * you may not use this file except in compliance with the License.
15124 * You may obtain a copy of the License at
15125 *
15126 *      http://www.apache.org/licenses/LICENSE-2.0
15127 *
15128 * Unless required by applicable law or agreed to in writing, software
15129 * distributed under the License is distributed on an "AS IS" BASIS,
15130 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15131 * See the License for the specific language governing permissions and
15132 * limitations under the License.
15133 */
15134
15135
15136    .text
15137    .global dvmMterpStdRun
15138    .type   dvmMterpStdRun, %function
15139/*
15140 * bool dvmMterpStdRun(Thread* self)
15141 *
15142 * Interpreter entry point.  Returns changeInterp.
15143 *
15144 */
15145dvmMterpStdRun:
15146    push    %ebp                 # save caller base pointer
15147    movl    %esp, %ebp           # set our %ebp
15148    movl    rSELF, %ecx          # get incoming rSELF
15149/*
15150 * At this point we've allocated one slot on the stack
15151 * via push and stack is 8-byte aligned.  Allocate space
15152 * for 9 spill slots, 4 local slots, 5 arg slots to bring
15153 * us to 16-byte alignment
15154 */
15155    subl    $(FRAME_SIZE-4), %esp
15156
15157/* Spill callee save regs */
15158    movl    %edi,EDI_SPILL(%ebp)
15159    movl    %esi,ESI_SPILL(%ebp)
15160    movl    %ebx,EBX_SPILL(%ebp)
15161
15162/* Set up "named" registers */
15163    movl    offThread_pc(%ecx),rPC
15164    movl    offThread_curFrame(%ecx),rFP
15165    movl    offThread_curHandlerTable(%ecx),rIBASE
15166
15167/* Remember %esp for future "longjmp" */
15168    movl    %esp,offThread_bailPtr(%ecx)
15169
15170   /* Normal case: start executing the instruction at rPC */
15171    FETCH_INST
15172    GOTO_NEXT
15173
15174    .global dvmMterpStdBail
15175    .type   dvmMterpStdBail, %function
15176/*
15177 * void dvmMterpStdBail(Thread* self, bool changeInterp)
15178 *
15179 * Restore the stack pointer and PC from the save point established on entry.
15180 * This is essentially the same as a longjmp, but should be cheaper.  The
15181 * last instruction causes us to return to whoever called dvmMterpStdRun.
15182 *
15183 * We're not going to build a standard frame here, so the arg accesses will
15184 * look a little strange.
15185 *
15186 * On entry:
15187 *  esp+4 (arg0)  Thread* self
15188 *  esp+8 (arg1)  bool changeInterp
15189 */
15190dvmMterpStdBail:
15191    movl    4(%esp),%ecx                 # grab self
15192    movl    8(%esp),%eax                 # changeInterp to return reg
15193    movl    offThread_bailPtr(%ecx),%esp   # Restore "setjmp" esp
15194    movl    %esp,%ebp
15195    addl    $(FRAME_SIZE-4), %ebp       # Restore %ebp at point of setjmp
15196    movl    EDI_SPILL(%ebp),%edi
15197    movl    ESI_SPILL(%ebp),%esi
15198    movl    EBX_SPILL(%ebp),%ebx
15199    movl    %ebp, %esp                   # strip frame
15200    pop     %ebp                         # restore caller's ebp
15201    ret                                  # return to dvmMterpStdRun's caller
15202
15203
15204/*
15205 * Strings
15206 */
15207    .section    .rodata
15208.LstrBadEntryPoint:
15209    .asciz  "Bad entry point %d\n"
15210
15211
15212/* File: x86/footer.S */
15213/*
15214 * Copyright (C) 2008 The Android Open Source Project
15215 *
15216 * Licensed under the Apache License, Version 2.0 (the "License");
15217 * you may not use this file except in compliance with the License.
15218 * You may obtain a copy of the License at
15219 *
15220 *      http://www.apache.org/licenses/LICENSE-2.0
15221 *
15222 * Unless required by applicable law or agreed to in writing, software
15223 * distributed under the License is distributed on an "AS IS" BASIS,
15224 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15225 * See the License for the specific language governing permissions and
15226 * limitations under the License.
15227 */
15228/*
15229 * Common subroutines and data.
15230 */
15231
15232#if defined(WITH_JIT)
15233/*
15234 * JIT-related re-entries into the interpreter.  In general, if the
15235 * exit from a translation can at some point be chained, the entry
15236 * here requires that control arrived via a call, and that the "rp"
15237 * on TOS is actually a pointer to a 32-bit cell containing the Dalvik PC
15238 * of the next insn to handle.  If no chaining will happen, the entry
15239 * should be reached via a direct jump and rPC set beforehand.
15240 */
15241
15242    .global dvmJitToInterpPunt
15243/*
15244 * The compiler will generate a jump to this entry point when it is
15245 * having difficulty translating a Dalvik instruction.  We must skip
15246 * the code cache lookup & prevent chaining to avoid bouncing between
15247 * the interpreter and code cache. rPC must be set on entry.
15248 */
15249dvmJitToInterpPunt:
15250#if defined(WITH_JIT_TUNING)
15251    movl   rPC, OUT_ARG0(%esp)
15252    call   dvmBumpPunt
15253#endif
15254    movl   rSELF, %ecx
15255    movl   offThread_curHandlerTable(%ecx),rIBASE
15256    FETCH_INST_R %ecx
15257    GOTO_NEXT_R %ecx
15258
15259    .global dvmJitToInterpSingleStep
15260/*
15261 * Return to the interpreter to handle a single instruction.
15262 * Should be reached via a call.
15263 * On entry:
15264 *   0(%esp)          <= native return address within trace
15265 *   rPC              <= Dalvik PC of this instruction
15266 *   OUT_ARG0+4(%esp) <= Dalvik PC of next instruction
15267 */
15268dvmJitToInterpSingleStep:
15269/* TODO */
15270    call     dvmAbort
15271#if 0
15272    pop    %eax
15273    movl   rSELF, %ecx
15274    movl   OUT_ARG0(%esp), %edx
15275    movl   %eax,offThread_jitResumeNPC(%ecx)
15276    movl   %edx,offThread_jitResumeDPC(%ecx)
15277    movl   $kInterpEntryInstr,offThread_entryPoint(%ecx)
15278    movl   $1,rINST     # changeInterp <= true
15279    jmp    common_gotoBail
15280#endif
15281
15282    .global dvmJitToInterpNoChainNoProfile
15283/*
15284 * Return from the translation cache to the interpreter to do method
15285 * invocation.  Check if the translation exists for the callee, but don't
15286 * chain to it. rPC must be set on entry.
15287 */
15288dvmJitToInterpNoChainNoProfile:
15289#if defined(WITH_JIT_TUNING)
15290    call   dvmBumpNoChain
15291#endif
15292    movl   rSELF, %eax
15293    movl   rPC,OUT_ARG0(%esp)
15294    movl   %eax,OUT_ARG1(%esp)
15295    call   dvmJitGetTraceAddrThread        # (pc, self)
15296    movl   rSELF,%ecx                # ecx <- self
15297    movl   %eax,offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
15298    cmpl   $0, %eax
15299    jz     1f
15300    call   *%eax                     # exec translation if we've got one
15301    # won't return
153021:
15303    movl   rSELF, %ecx
15304    movl   offThread_curHandlerTable(%ecx),rIBASE
15305    FETCH_INST_R %ecx
15306    GOTO_NEXT_R %ecx
15307
15308/*
15309 * Return from the translation cache and immediately request a
15310 * translation fro the exit target, but don't attempt to chain.
15311 * rPC set on entry.
15312 */
15313    .global dvmJitToInterpTraceSelectNoChain
15314dvmJitToInterpTraceSelectNoChain:
15315#if defined(WITH_JIT_TUNING)
15316    call   dvmBumpNoChain
15317#endif
15318    movl   rSELF, %eax
15319    movl   rPC,OUT_ARG0(%esp)
15320    movl   %eax,OUT_ARG1(%esp)
15321    call   dvmJitGetTraceAddrThread # (pc, self)
15322    movl   rSELF,%ecx
15323    cmpl   $0,%eax
15324    movl   %eax,offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
15325    jz     1f
15326    call   *%eax              # jump to tranlation
15327    # won't return
15328
15329/* No Translation - request one */
153301:
15331    GET_JIT_PROF_TABLE %ecx %eax
15332    cmpl   $0, %eax          # JIT enabled?
15333    jnz    2f                 # Request one if so
15334    movl   rSELF, %ecx
15335    movl   offThread_curHandlerTable(%ecx),rIBASE
15336    FETCH_INST_R %ecx         # Continue interpreting if not
15337    GOTO_NEXT_R %ecx
153382:
15339    movl   $kJitTSelectRequestHot,rINST  # ask for trace select
15340    jmp    common_selectTrace
15341
15342/*
15343 * Return from the translation cache and immediately request a
15344 * translation for the exit target.  Reached via a call, and
15345 * (TOS)->rPC.
15346 */
15347    .global dvmJitToInterpTraceSelect
15348dvmJitToInterpTraceSelect:
15349    pop    rINST           # save chain cell address in callee save reg
15350    movl   (rINST),rPC
15351    movl   rSELF, %eax
15352    movl   rPC,OUT_ARG0(%esp)
15353    movl   %eax,OUT_ARG1(%esp)
15354    call   dvmJitGetTraceAddrThread # (pc, self)
15355    cmpl   $0,%eax
15356    jz     1b                 # no - ask for one
15357    movl   %eax,OUT_ARG0(%esp)
15358# TODO - need to adjust rINST to beginning of sequence
15359    movl   rINST,OUT_ARG1(%esp)
15360    call   dvmJitChain        # Attempt dvmJitChain(codeAddr,chainAddr)
15361    cmpl   $0,%eax           # Success?
15362    jz     toInterpreter      # didn't chain - interpret
15363    call   *%eax
15364    # won't return
15365
15366/*
15367 * Placeholder entries for x86 JIT
15368 */
15369    .global dvmJitToInterpBackwardBranch
15370dvmJitToInterpBackwardBranch:
15371    .global dvmJitToInterpNormal
15372dvmJitToInterpNormal:
15373    .global dvmJitToInterpNoChain
15374dvmJitToInterpNoChain:
15375toInterpreter:
15376    jmp  common_abort
15377
15378common_updateProfile:
15379    # quick & dirty hash
15380    movl   rPC, %eax
15381    shrl   $12, %eax
15382    xorl   rPC, %eax
15383    andl   $((1<<JIT_PROF_SIZE_LOG_2)-1),%eax
15384    decb   (%edx,%eax)
15385    jz     2f
153861:
15387    GOTO_NEXT
153882:
15389/*
15390 * Here, we switch to the debug interpreter to request
15391 * trace selection.  First, though, check to see if there
15392 * is already a native translation in place (and, if so,
15393 * jump to it now.
15394 */
15395    GET_JIT_THRESHOLD %ecx rINST  # leaves rSELF in %ecx
15396    EXPORT_PC
15397    movb   rINSTbl,(%edx,%eax)   # reset counter
15398    movl   %ecx,rINST            # preserve rSELF
15399    movl   rSELF, %eax
15400    movl   rPC,OUT_ARG0(%esp)
15401    movl   %eax,OUT_ARG1(%esp)
15402    call   dvmJitGetTraceAddr  # (pc, self)
15403    movl   %eax,offThread_inJitCodeCache(rINST)   # set the inJitCodeCache flag
15404    cmpl   $0,%eax
15405    jz     1f
15406    call   *%eax        # TODO: decide call vs/ jmp!.  No return either way
154071:
15408    movl   $kJitTSelectRequest,%eax
15409    # On entry, eax<- jitState, rPC valid
15410common_selectTrace:
15411/* TODO */
15412    call   dvmAbort
15413#if 0
15414    movl   rSELF,%ecx
15415    movl   %eax,offThread_jitState(%ecx)
15416    movl   $kInterpEntryInstr,offThread_entryPoint(%ecx)
15417    movl   $1,rINST
15418    jmp    common_gotoBail
15419#endif
15420#endif
15421
15422
15423
15424/*
15425 * Common code for method invocation with range.
15426 *
15427 * On entry:
15428 *   eax = Method* methodToCall
15429 *   rINSTw trashed, must reload
15430 *   rIBASE trashed, must reload before resuming interpreter
15431 */
15432
15433common_invokeMethodRange:
15434.LinvokeNewRange:
15435
15436   /*
15437    * prepare to copy args to "outs" area of current frame
15438    */
15439
15440    movzbl      1(rPC),rINST       # rINST<- AA
15441    movzwl      4(rPC), %ecx            # %ecx<- CCCC
15442    SAVEAREA_FROM_FP %edx               # %edx<- &StackSaveArea
15443    test        rINST, rINST
15444    movl        rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- AA
15445    jz          .LinvokeArgsDone        # no args; jump to args done
15446
15447
15448   /*
15449    * %eax=methodToCall, %ecx=CCCC, LOCAL0_OFFSET(%ebp)=count,
15450    * %edx=&outs (&stackSaveArea).  (very few methods have > 10 args;
15451    * could unroll for common cases)
15452    */
15453
15454.LinvokeRangeArgs:
15455    movl        %ebx, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- save %ebx
15456    lea         (rFP, %ecx, 4), %ecx    # %ecx<- &vCCCC
15457    shll        $2, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- offset
15458    subl        LOCAL0_OFFSET(%ebp), %edx       # %edx<- update &outs
15459    shrl        $2, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- offset
154601:
15461    movl        (%ecx), %ebx            # %ebx<- vCCCC
15462    lea         4(%ecx), %ecx           # %ecx<- &vCCCC++
15463    subl        $1, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET<- LOCAL0_OFFSET--
15464    movl        %ebx, (%edx)            # *outs<- vCCCC
15465    lea         4(%edx), %edx           # outs++
15466    jne         1b                      # loop if count (LOCAL0_OFFSET(%ebp)) not zero
15467    movl        LOCAL1_OFFSET(%ebp), %ebx       # %ebx<- restore %ebx
15468    jmp         .LinvokeArgsDone        # continue
15469
15470   /*
15471    * %eax is "Method* methodToCall", the method we're trying to call
15472    * prepare to copy args to "outs" area of current frame
15473    * rIBASE trashed, must reload before resuming interpreter
15474    */
15475
15476common_invokeMethodNoRange:
15477.LinvokeNewNoRange:
15478    movzbl      1(rPC),rINST       # rINST<- BA
15479    movl        rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- BA
15480    shrl        $4, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- B
15481    je          .LinvokeArgsDone        # no args; jump to args done
15482    movzwl      4(rPC), %ecx            # %ecx<- GFED
15483    SAVEAREA_FROM_FP %edx               # %edx<- &StackSaveArea
15484
15485   /*
15486    * %eax=methodToCall, %ecx=GFED, LOCAL0_OFFSET(%ebp)=count, %edx=outs
15487    */
15488
15489.LinvokeNonRange:
15490    cmp         $2, LOCAL0_OFFSET(%ebp)        # compare LOCAL0_OFFSET(%ebp) to 2
15491    movl        %ecx, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- GFED
15492    jl          1f                      # handle 1 arg
15493    je          2f                      # handle 2 args
15494    cmp         $4, LOCAL0_OFFSET(%ebp)        # compare LOCAL0_OFFSET(%ebp) to 4
15495    jl          3f                      # handle 3 args
15496    je          4f                      # handle 4 args
154975:
15498    andl        $15, rINST             # rINSTw<- A
15499    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
15500    movl        (rFP, rINST, 4), %ecx   # %ecx<- vA
15501    movl        %ecx, (%edx)            # *outs<- vA
15502    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
155034:
15504    shr         $12, %ecx              # %ecx<- G
15505    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
15506    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vG
15507    movl        %ecx, (%edx)            # *outs<- vG
15508    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
155093:
15510    and         $0x0f00, %ecx          # %ecx<- 0F00
15511    shr         $8, %ecx               # %ecx<- F
15512    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
15513    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vF
15514    movl        %ecx, (%edx)            # *outs<- vF
15515    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
155162:
15517    and         $0x00f0, %ecx          # %ecx<- 00E0
15518    shr         $4, %ecx               # %ecx<- E
15519    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
15520    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vE
15521    movl        %ecx, (%edx)            # *outs<- vE
15522    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
155231:
15524    and         $0x000f, %ecx          # %ecx<- 000D
15525    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vD
15526    movl        %ecx, -4(%edx)          # *--outs<- vD
155270:
15528
15529   /*
15530    * %eax is "Method* methodToCall", the method we're trying to call
15531    * find space for the new stack frame, check for overflow
15532    */
15533
15534.LinvokeArgsDone:
15535    movzwl      offMethod_registersSize(%eax), %edx # %edx<- methodToCall->regsSize
15536    movzwl      offMethod_outsSize(%eax), %ecx # %ecx<- methodToCall->outsSize
15537    movl        %eax, LOCAL0_OFFSET(%ebp)       # LOCAL0_OFFSET<- methodToCall
15538    shl         $2, %edx               # %edx<- update offset
15539    SAVEAREA_FROM_FP %eax               # %eax<- &StackSaveArea
15540    subl        %edx, %eax              # %eax<- newFP; (old savearea - regsSize)
15541    movl        rSELF,%edx              # %edx<- pthread
15542    movl        %eax, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- &outs
15543    subl        $sizeofStackSaveArea, %eax # %eax<- newSaveArea (stack save area using newFP)
15544    movl        offThread_interpStackEnd(%edx), %edx # %edx<- self->interpStackEnd
15545    movl        %edx, TMP_SPILL1(%ebp)  # spill self->interpStackEnd
15546    shl         $2, %ecx               # %ecx<- update offset for outsSize
15547    movl        %eax, %edx              # %edx<- newSaveArea
15548    sub         %ecx, %eax              # %eax<- bottom; (newSaveArea - outsSize)
15549    cmp         TMP_SPILL1(%ebp), %eax  # compare interpStackEnd and bottom
15550    movl        LOCAL0_OFFSET(%ebp), %eax       # %eax<- restore methodToCall
15551    jl          .LstackOverflow         # handle frame overflow
15552
15553   /*
15554    * set up newSaveArea
15555    */
15556
15557#ifdef EASY_GDB
15558    SAVEAREA_FROM_FP %ecx               # %ecx<- &StackSaveArea
15559    movl        %ecx, offStackSaveArea_prevSave(%edx) # newSaveArea->prevSave<- &outs
15560#endif
15561    movl        rSELF,%ecx              # %ecx<- pthread
15562    movl        rFP, offStackSaveArea_prevFrame(%edx) # newSaveArea->prevFrame<- rFP
15563    movl        rPC, offStackSaveArea_savedPc(%edx) # newSaveArea->savedPc<- rPC
15564
15565    /* Any special actions to take? */
15566    cmpw        $0, offThread_subMode(%ecx)
15567    jne         2f                     # Yes - handle them
155681:
15569    testl       $ACC_NATIVE, offMethod_accessFlags(%eax) # check for native call
15570    movl        %eax, offStackSaveArea_method(%edx) # newSaveArea->method<- method to call
15571    jne         .LinvokeNative          # handle native call
15572
15573   /*
15574    * Update "self" values for the new method
15575    * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFp
15576    */
15577    movl        offMethod_clazz(%eax), %edx # %edx<- method->clazz
15578    movl        offClassObject_pDvmDex(%edx), %edx # %edx<- method->clazz->pDvmDex
15579    movl        %eax, offThread_method(%ecx) # self->method<- methodToCall
15580    movl        %edx, offThread_methodClassDex(%ecx) # self->methodClassDex<- method->clazz->pDvmDex
15581    movl        offMethod_insns(%eax), rPC # rPC<- methodToCall->insns
15582    movl        $1, offThread_debugIsMethodEntry(%ecx)
15583    movl        LOCAL1_OFFSET(%ebp), rFP # rFP<- newFP
15584    movl        rFP, offThread_curFrame(%ecx) # curFrame<-newFP
15585    movl        offThread_curHandlerTable(%ecx),rIBASE
15586    FETCH_INST
15587    GOTO_NEXT                           # jump to methodToCall->insns
15588
155892:
15590    /*
15591     * On entry, preserve all:
15592     *  %eax: method
15593     *  %ecx: self
15594     *  %edx: new save area
15595     */
15596    SPILL_TMP1(%eax)                   # preserve methodToCall
15597    SPILL_TMP2(%edx)                   # preserve newSaveArea
15598    movl        rPC, offThread_pc(%ecx) # update interpSave.pc
15599    movl        %ecx, OUT_ARG0(%esp)
15600    movl        %eax, OUT_ARG1(%esp)
15601    call        dvmReportInvoke        # (self, method)
15602    UNSPILL_TMP1(%eax)
15603    UNSPILL_TMP2(%edx)
15604    movl        rSELF,%ecx             # restore rSELF
15605    jmp         1b
15606
15607   /*
15608    * Prep for the native call
15609    * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFP, %edx=newSaveArea, %ecx=self
15610    */
15611
15612.LinvokeNative:
15613    movl        offThread_jniLocal_topCookie(%ecx), rINST # rINST<- self->localRef->...
15614    movl        rINST, offStackSaveArea_localRefCookie(%edx) # newSaveArea->localRefCookie<- top
15615    movl        %edx, LOCAL2_OFFSET(%ebp)  # save newSaveArea
15616    movl        LOCAL1_OFFSET(%ebp), rINST # rINST<- newFP
15617    movl        rINST, offThread_curFrame(%ecx)  # curFrame<- newFP
15618    cmpw        $0, offThread_subMode(%ecx)  # Anything special going on?
15619    jne         11f                     # yes - handle it
15620    movl        %ecx, OUT_ARG3(%esp)    # push parameter self
15621    movl        %eax, OUT_ARG2(%esp)    # push parameter methodToCall
15622    lea         offThread_retval(%ecx), %ecx # %ecx<- &retval
15623    movl        %ecx, OUT_ARG1(%esp)    # push parameter &retval
15624    movl        rINST, OUT_ARG0(%esp)    # push parameter newFP
15625    call        *offMethod_nativeFunc(%eax) # call methodToCall->nativeFunc
156267:
15627    movl        LOCAL2_OFFSET(%ebp), %ecx    # %ecx<- newSaveArea
15628    movl        rSELF, %eax             # %eax<- self
15629    movl        offStackSaveArea_localRefCookie(%ecx), %edx # %edx<- old top
15630    cmp         $0, offThread_exception(%eax) # check for exception
15631    movl        rFP, offThread_curFrame(%eax) # curFrame<- rFP
15632    movl        %edx, offThread_jniLocal_topCookie(%eax) # new top <- old top
15633    jne         common_exceptionThrown  # handle exception
15634    movl        offThread_curHandlerTable(%eax),rIBASE
15635    FETCH_INST_OPCODE 3 %ecx
15636    ADVANCE_PC 3
15637    GOTO_NEXT_R %ecx                    # jump to next instruction
15638
1563911:
15640    /*
15641     * Handle any special subMode actions
15642     * %eax=methodToCall, rINST=newFP, %ecx=self
15643     */
15644    SPILL_TMP1(%eax)                    # save methodTocall
15645    movl        rPC, offThread_pc(%ecx)
15646    movl        %eax, OUT_ARG0(%esp)
15647    movl        %ecx, OUT_ARG1(%esp)
15648    movl        rFP, OUT_ARG2(%esp)
15649    call        dvmReportPreNativeInvoke # (methodToCall, self, fp)
15650    UNSPILL_TMP1(%eax)                  # restore methodToCall
15651    movl        rSELF,%ecx              # restore self
15652
15653    /* Do the native call */
15654    movl        %ecx, OUT_ARG3(%esp)    # push parameter self
15655    lea         offThread_retval(%ecx), %ecx # %ecx<- &retval
15656    movl        %eax, OUT_ARG2(%esp)    # push parameter methodToCall
15657    movl        %ecx, OUT_ARG1(%esp)    # push parameter &retval
15658    movl        rINST, OUT_ARG0(%esp)   # push parameter newFP
15659    call        *offMethod_nativeFunc(%eax) # call methodToCall->nativeFunc
15660
15661    UNSPILL_TMP1(%eax)                  # restore methodToCall
15662    movl        rSELF, %ecx
15663    movl        %eax, OUT_ARG0(%esp)
15664    movl        %ecx, OUT_ARG1(%esp)
15665    movl        rFP, OUT_ARG2(%esp)
15666    call        dvmReportPostNativeInvoke # (methodToCall, self, fp)
15667    jmp         7b                      # rejoin
15668
15669.LstackOverflow:    # eax=methodToCall
15670    movl        %eax, OUT_ARG1(%esp)    # push parameter methodToCall
15671    movl        rSELF,%eax              # %eax<- self
15672    movl        %eax, OUT_ARG0(%esp)    # push parameter self
15673    call        dvmHandleStackOverflow  # call: (Thread* self, Method* meth)
15674    jmp         common_exceptionThrown  # handle exception
15675
15676
15677/*
15678 * Common code for handling a return instruction
15679 */
15680common_returnFromMethod:
15681    movl    rSELF,%ecx
15682    SAVEAREA_FROM_FP %eax                         # eax<- saveArea (old)
15683    cmpw    $0, offThread_subMode(%ecx)          # special action needed?
15684    jne     19f                                   # go if so
1568514:
15686    movl    offStackSaveArea_prevFrame(%eax),rFP  # rFP<- prevFrame
15687    movl    (offStackSaveArea_method-sizeofStackSaveArea)(rFP),rINST
15688    cmpl    $0,rINST                             # break?
15689    je      common_gotoBail    # break frame, bail out completely
15690
15691    movl    offStackSaveArea_savedPc(%eax),rPC # pc<- saveArea->savedPC
15692    movl    rINST,offThread_method(%ecx)       # self->method = newSave->meethod
15693    movl    rFP,offThread_curFrame(%ecx)       # curFrame = fp
15694    movl    offMethod_clazz(rINST),%eax        # eax<- method->clazz
15695    movl    offThread_curHandlerTable(%ecx),rIBASE
15696    movl    offClassObject_pDvmDex(%eax),rINST # rINST<- method->clazz->pDvmDex
15697    FETCH_INST_OPCODE 3 %eax
15698    movl    rINST,offThread_methodClassDex(%ecx)
15699    ADVANCE_PC 3
15700    GOTO_NEXT_R %eax
15701
1570219:
15703    /*
15704     * Handle special subMode actions
15705     * On entry, rFP: prevFP, %ecx: self, %eax: saveArea
15706     */
15707    movl     rFP, offThread_curFrame(%ecx)    # update interpSave.curFrame
15708    movl     rPC, offThread_pc(%ecx)          # update interpSave.pc
15709    movl     %ecx, OUT_ARG0(%esp)             # parameter self
15710    call     dvmReportReturn                  # (self)
15711    movl     rSELF, %ecx                      # restore self
15712    SAVEAREA_FROM_FP %eax                     # restore saveArea
15713    jmp      14b
15714
15715
15716/*
15717 * Prepare to strip the current frame and "longjump" back to caller of
15718 * dvmMterpStdRun.
15719 *
15720 * on entry:
15721 *    rINST holds changeInterp
15722 *    ecx holds self pointer
15723 *
15724 * expected profile: dvmMterpStdBail(Thread *self, bool changeInterp)
15725 */
15726common_gotoBail:
15727    movl   rPC,offThread_pc(%ecx)     # export state to self
15728    movl   rFP,offThread_curFrame(%ecx)
15729    movl   %ecx,OUT_ARG0(%esp)      # self in arg0
15730    movl   rINST,OUT_ARG1(%esp)     # changeInterp in arg1
15731    call   dvmMterpStdBail          # bail out....
15732
15733
15734/*
15735 * After returning from a "selfd" function, pull out the updated values
15736 * and start executing at the next instruction.
15737 */
15738 common_resumeAfterGlueCall:
15739     movl  rSELF, %eax
15740     movl  offThread_pc(%eax),rPC
15741     movl  offThread_curFrame(%eax),rFP
15742     movl  offThread_curHandlerTable(%eax),rIBASE
15743     FETCH_INST
15744     GOTO_NEXT
15745
15746/*
15747 * Integer divide or mod by zero
15748 */
15749common_errDivideByZero:
15750    EXPORT_PC
15751    movl    $.LstrDivideByZero,%eax
15752    movl    %eax,OUT_ARG0(%esp)
15753    call    dvmThrowArithmeticException
15754    jmp     common_exceptionThrown
15755
15756/*
15757 * Attempt to allocate an array with a negative size.
15758 * On entry, len in eax
15759 */
15760common_errNegativeArraySize:
15761    EXPORT_PC
15762    movl    %eax,OUT_ARG0(%esp)                  # arg0<- len
15763    call    dvmThrowNegativeArraySizeException   # (len)
15764    jmp     common_exceptionThrown
15765
15766/*
15767 * Attempt to allocate an array with a negative size.
15768 * On entry, method name in eax
15769 */
15770common_errNoSuchMethod:
15771
15772    EXPORT_PC
15773    movl    %eax,OUT_ARG0(%esp)
15774    call    dvmThrowNoSuchMethodError
15775    jmp     common_exceptionThrown
15776
15777/*
15778 * Hit a null object when we weren't expecting one.  Export the PC, throw a
15779 * NullPointerException and goto the exception processing code.
15780 */
15781common_errNullObject:
15782    EXPORT_PC
15783    xorl    %eax,%eax
15784    movl    %eax,OUT_ARG0(%esp)
15785    call    dvmThrowNullPointerException
15786    jmp     common_exceptionThrown
15787
15788/*
15789 * Array index exceeds max.
15790 * On entry:
15791 *    eax <- array object
15792 *    ecx <- index
15793 */
15794common_errArrayIndex:
15795    EXPORT_PC
15796    movl    offArrayObject_length(%eax), %eax
15797    movl    %eax,OUT_ARG0(%esp)
15798    movl    %ecx,OUT_ARG1(%esp)
15799    call    dvmThrowArrayIndexOutOfBoundsException   # args (length, index)
15800    jmp     common_exceptionThrown
15801
15802/*
15803 * Somebody has thrown an exception.  Handle it.
15804 *
15805 * If the exception processing code returns to us (instead of falling
15806 * out of the interpreter), continue with whatever the next instruction
15807 * now happens to be.
15808 *
15809 * NOTE: special subMode handling done in dvmMterp_exceptionThrown
15810 *
15811 * This does not return.
15812 */
15813common_exceptionThrown:
15814    movl    rSELF,%ecx
15815    movl    rPC,offThread_pc(%ecx)
15816    movl    rFP,offThread_curFrame(%ecx)
15817    movl    %ecx,OUT_ARG0(%esp)
15818    call    dvmMterp_exceptionThrown
15819    jmp     common_resumeAfterGlueCall
15820
15821common_abort:
15822    movl    $0xdeadf00d,%eax
15823    call     *%eax
15824
15825
15826/*
15827 * Strings
15828 */
15829
15830    .section     .rodata
15831.LstrDivideByZero:
15832    .asciz  "divide by zero"
15833.LstrFilledNewArrayNotImplA:
15834    .asciz  "filled-new-array only implemented for 'int'"
15835
15836