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      esi   interpreted program counter, used for fetching instructions
62  rFP      edi   interpreted frame pointer, used for accessing locals and args
63  rINSTw   bx    first 16-bit code of current instruction
64  rINSTbl  bl    opcode portion of instruction word
65  rINSTbh  bh    high byte of inst word, usually contains src/tgt reg names
66  rIBASE   edx   base of instruction handler table
67
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#if defined(WITH_JIT)
110/* for spill region: increase size by 48 (to keep 16-byte alignment) */
111/* 76 + 48 = 124 */
112#define JIT_SPILL      (-56)
113#define FRAME_SIZE     124
114#else
115#define FRAME_SIZE     76
116#endif
117
118#define SPILL(reg) movl reg##,reg##_SPILL(%ebp)
119#define UNSPILL(reg) movl reg##_SPILL(%ebp),reg
120#define SPILL_TMP1(reg) movl reg,TMP_SPILL1(%ebp)
121#define UNSPILL_TMP1(reg) movl TMP_SPILL1(%ebp),reg
122#define SPILL_TMP2(reg) movl reg,TMP_SPILL2(%ebp)
123#define UNSPILL_TMP2(reg) movl TMP_SPILL2(%ebp),reg
124#define SPILL_TMP3(reg) movl reg,TMP_SPILL3(%ebp)
125#define UNSPILL_TMP3(reg) movl TMP_SPILL3(%ebp),reg
126
127#if defined(WITH_JIT)
128.macro GET_JIT_PROF_TABLE _self _reg
129    movl    offThread_pJitProfTable(\_self),\_reg
130.endm
131.macro GET_JIT_THRESHOLD _self _reg
132    movl    offThread_jitThreshold(\_self),\_reg
133.endm
134#endif
135
136/* save/restore the PC and/or FP from the self struct */
137.macro SAVE_PC_FP_TO_SELF _reg
138    movl     rSELF,\_reg
139    movl     rPC,offThread_pc(\_reg)
140    movl     rFP,offThread_curFrame(\_reg)
141.endm
142
143.macro LOAD_PC_FP_FROM_SELF
144    movl    rSELF,rFP
145    movl    offThread_pc(rFP),rPC
146    movl    offThread_curFrame(rFP),rFP
147.endm
148
149/* The interpreter assumes a properly aligned stack on entry, and
150 * will preserve 16-byte alignment.
151 */
152
153/*
154 * "export" the PC to the interpreted stack frame, f/b/o future exception
155 * objects.  Must be done *before* something throws.
156 *
157 * In C this is "SAVEAREA_FROM_FP(fp)->xtra.currentPc = pc", i.e.
158 * fp - sizeof(StackSaveArea) + offsetof(SaveArea, xtra.currentPc)
159 *
160 * It's okay to do this more than once.
161 */
162.macro EXPORT_PC
163    movl     rPC, (-sizeofStackSaveArea + offStackSaveArea_currentPc)(rFP)
164.endm
165
166.macro GET_PC
167    movl     (-sizeofStackSaveArea + offStackSaveArea_currentPc)(rFP), rPC
168.endm
169
170/*
171 * Given a frame pointer, find the stack save area.
172 *
173 * In C this is "((StackSaveArea*)(_fp) -1)".
174 */
175.macro SAVEAREA_FROM_FP _reg
176    leal    -sizeofStackSaveArea(rFP), \_reg
177.endm
178
179/*
180 * Fetch the next instruction from rPC into rINSTw.  Does not advance rPC.
181 */
182.macro FETCH_INST
183    movzwl    (rPC),rINST
184.endm
185
186/*
187 * Fetch the opcode byte and zero-extend it into _reg.  Must be used
188 * in conjunction with GOTO_NEXT_R
189 */
190.macro FETCH_INST_R _reg
191    movzbl    (rPC),\_reg
192.endm
193
194/*
195 * Fetch the opcode byte at _count words offset from rPC and zero-extend
196 * it into _reg.  Must be used in conjunction with GOTO_NEXT_R
197 */
198.macro FETCH_INST_OPCODE _count _reg
199    movzbl  \_count*2(rPC),\_reg
200.endm
201
202/*
203 * Fetch the nth instruction word from rPC into rINSTw.  Does not advance
204 * rPC, and _count is in words
205 */
206.macro FETCH_INST_WORD _count
207    movzwl  \_count*2(rPC),rINST
208.endm
209
210/*
211 * Fetch instruction word indexed (used for branching).
212 * Index is in instruction word units.
213 */
214.macro FETCH_INST_INDEXED _reg
215    movzwl  (rPC,\_reg,2),rINST
216.endm
217
218/*
219 * Advance rPC by instruction count
220 */
221.macro ADVANCE_PC _count
222    leal  2*\_count(rPC),rPC
223.endm
224
225/*
226 * Advance rPC by branch offset in register
227 */
228.macro ADVANCE_PC_INDEXED _reg
229    leal (rPC,\_reg,2),rPC
230.endm
231
232.macro GOTO_NEXT
233     movzx   rINSTbl,%eax
234     movzbl  rINSTbh,rINST
235     jmp     *(rIBASE,%eax,4)
236.endm
237
238   /*
239    * Version of GOTO_NEXT that assumes _reg preloaded with opcode.
240    * Should be paired with FETCH_INST_R
241    */
242.macro GOTO_NEXT_R _reg
243     movzbl  1(rPC),rINST
244     jmp     *(rIBASE,\_reg,4)
245.endm
246
247/*
248 * Get/set the 32-bit value from a Dalvik register.
249 */
250.macro GET_VREG_R _reg _vreg
251    movl     (rFP,\_vreg,4),\_reg
252.endm
253
254.macro SET_VREG _reg _vreg
255    movl     \_reg,(rFP,\_vreg,4)
256.endm
257
258.macro GET_VREG_WORD _reg _vreg _offset
259    movl     4*(\_offset)(rFP,\_vreg,4),\_reg
260.endm
261
262.macro SET_VREG_WORD _reg _vreg _offset
263    movl     \_reg,4*(\_offset)(rFP,\_vreg,4)
264.endm
265
266#define sReg0 LOCAL0_OFFSET(%ebp)
267#define sReg1 LOCAL1_OFFSET(%ebp)
268#define sReg2 LOCAL2_OFFSET(%ebp)
269
270   /*
271    * x86 JIT Helpers
272    */
273
274    .macro dumpSwitch _regData _regScratch1 _regScratch2
275    .endm
276
277   /*
278    * Hard coded helper values.
279    */
280
281.balign 16
282
283.LdoubNeg:
284    .quad       0x8000000000000000
285
286.L64bits:
287    .quad       0xFFFFFFFFFFFFFFFF
288
289.LshiftMask2:
290    .quad       0x0000000000000000
291.LshiftMask:
292    .quad       0x000000000000003F
293
294.Lvalue64:
295    .quad       0x0000000000000040
296
297.LvaluePosInfLong:
298    .quad       0x7FFFFFFFFFFFFFFF
299
300.LvalueNegInfLong:
301    .quad       0x8000000000000000
302
303.LvalueNanLong:
304    .quad       0x0000000000000000
305
306.LintMin:
307.long   0x80000000
308
309.LintMax:
310.long   0x7FFFFFFF
311
312
313/*
314 * This is a #include, not a %include, because we want the C pre-processor
315 * to expand the macros into assembler assignment statements.
316 */
317#include "../common/asm-constants.h"
318
319#if defined(WITH_JIT)
320#include "../common/jit-config.h"
321#endif
322
323
324    .global dvmAsmInstructionStartCode
325    .type   dvmAsmInstructionStartCode, %function
326dvmAsmInstructionStartCode = .L_OP_NOP
327    .text
328
329/* ------------------------------ */
330.L_OP_NOP: /* 0x00 */
331/* File: x86/OP_NOP.S */
332    FETCH_INST_OPCODE 1 %ecx
333    ADVANCE_PC 1
334    GOTO_NEXT_R %ecx
335
336/* ------------------------------ */
337.L_OP_MOVE: /* 0x01 */
338/* File: x86/OP_MOVE.S */
339    /* for move, move-object, long-to-int */
340    /* op vA, vB */
341    movzbl rINSTbl,%eax          # eax<- BA
342    andb   $0xf,%al             # eax<- A
343    shrl   $4,rINST            # rINST<- B
344    GET_VREG_R rINST rINST
345    FETCH_INST_OPCODE 1 %ecx
346    ADVANCE_PC 1
347    SET_VREG rINST %eax           # fp[A]<-fp[B]
348    GOTO_NEXT_R %ecx
349
350/* ------------------------------ */
351.L_OP_MOVE_FROM16: /* 0x02 */
352/* File: x86/OP_MOVE_FROM16.S */
353    /* for: move/from16, move-object/from16 */
354    /* op vAA, vBBBB */
355    movzx    rINSTbl,%eax              # eax <= AA
356    movw     2(rPC),rINSTw             # rINSTw <= BBBB
357    GET_VREG_R rINST rINST             # rINST- fp[BBBB]
358    FETCH_INST_OPCODE 2 %ecx
359    ADVANCE_PC 2
360    SET_VREG rINST %eax                # fp[AA]<- ecx]
361    GOTO_NEXT_R %ecx
362
363/* ------------------------------ */
364.L_OP_MOVE_16: /* 0x03 */
365/* File: x86/OP_MOVE_16.S */
366    /* for: move/16, move-object/16 */
367    /* op vAAAA, vBBBB */
368    movzwl    4(rPC),%ecx              # ecx<- BBBB
369    movzwl    2(rPC),%eax              # eax<- AAAA
370    GET_VREG_R  rINST %ecx
371    FETCH_INST_OPCODE 3 %ecx
372    ADVANCE_PC 3
373    SET_VREG  rINST %eax
374    GOTO_NEXT_R %ecx
375
376/* ------------------------------ */
377.L_OP_MOVE_WIDE: /* 0x04 */
378/* File: x86/OP_MOVE_WIDE.S */
379    /* move-wide vA, vB */
380    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
381    movzbl    rINSTbl,%ecx                # ecx <- BA
382    sarl      $4,rINST                   # rINST<- B
383    GET_VREG_WORD %eax rINST 0            # eax<- v[B+0]
384    GET_VREG_WORD rINST rINST 1           # rINST<- v[B+1]
385    andb      $0xf,%cl                   # ecx <- A
386    SET_VREG_WORD rINST %ecx 1            # v[A+1]<- rINST
387    SET_VREG_WORD %eax %ecx 0             # v[A+0]<- eax
388    FETCH_INST_OPCODE 1 %ecx
389    ADVANCE_PC 1
390    GOTO_NEXT_R %ecx
391
392/* ------------------------------ */
393.L_OP_MOVE_WIDE_FROM16: /* 0x05 */
394/* File: x86/OP_MOVE_WIDE_FROM16.S */
395    /* move-wide/from16 vAA, vBBBB */
396    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
397    movzwl    2(rPC),%ecx              # ecx<- BBBB
398    movzbl    rINSTbl,%eax             # eax<- AAAA
399    GET_VREG_WORD rINST %ecx 0         # rINST<- v[BBBB+0]
400    GET_VREG_WORD %ecx %ecx 1          # ecx<- v[BBBB+1]
401    SET_VREG_WORD rINST %eax 0         # v[AAAA+0]<- rINST
402    SET_VREG_WORD %ecx %eax 1          # v[AAAA+1]<- eax
403    FETCH_INST_OPCODE 2 %ecx
404    ADVANCE_PC 2
405    GOTO_NEXT_R %ecx
406
407/* ------------------------------ */
408.L_OP_MOVE_WIDE_16: /* 0x06 */
409/* File: x86/OP_MOVE_WIDE_16.S */
410    /* move-wide/16 vAAAA, vBBBB */
411    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
412    movzwl    4(rPC),%ecx            # ecx<- BBBB
413    movzwl    2(rPC),%eax            # eax<- AAAA
414    GET_VREG_WORD rINST %ecx 0       # rINSTw_WORD<- v[BBBB+0]
415    GET_VREG_WORD %ecx %ecx 1        # ecx<- v[BBBB+1]
416    SET_VREG_WORD rINST %eax 0       # v[AAAA+0]<- rINST
417    SET_VREG_WORD %ecx %eax 1        # v[AAAA+1]<- ecx
418    FETCH_INST_OPCODE 3 %ecx
419    ADVANCE_PC 3
420    GOTO_NEXT_R %ecx
421
422/* ------------------------------ */
423.L_OP_MOVE_OBJECT: /* 0x07 */
424/* File: x86/OP_MOVE_OBJECT.S */
425/* File: x86/OP_MOVE.S */
426    /* for move, move-object, long-to-int */
427    /* op vA, vB */
428    movzbl rINSTbl,%eax          # eax<- BA
429    andb   $0xf,%al             # eax<- A
430    shrl   $4,rINST            # rINST<- B
431    GET_VREG_R rINST rINST
432    FETCH_INST_OPCODE 1 %ecx
433    ADVANCE_PC 1
434    SET_VREG rINST %eax           # fp[A]<-fp[B]
435    GOTO_NEXT_R %ecx
436
437
438/* ------------------------------ */
439.L_OP_MOVE_OBJECT_FROM16: /* 0x08 */
440/* File: x86/OP_MOVE_OBJECT_FROM16.S */
441/* File: x86/OP_MOVE_FROM16.S */
442    /* for: move/from16, move-object/from16 */
443    /* op vAA, vBBBB */
444    movzx    rINSTbl,%eax              # eax <= AA
445    movw     2(rPC),rINSTw             # rINSTw <= BBBB
446    GET_VREG_R rINST rINST             # rINST- fp[BBBB]
447    FETCH_INST_OPCODE 2 %ecx
448    ADVANCE_PC 2
449    SET_VREG rINST %eax                # fp[AA]<- ecx]
450    GOTO_NEXT_R %ecx
451
452
453/* ------------------------------ */
454.L_OP_MOVE_OBJECT_16: /* 0x09 */
455/* File: x86/OP_MOVE_OBJECT_16.S */
456/* File: x86/OP_MOVE_16.S */
457    /* for: move/16, move-object/16 */
458    /* op vAAAA, vBBBB */
459    movzwl    4(rPC),%ecx              # ecx<- BBBB
460    movzwl    2(rPC),%eax              # eax<- AAAA
461    GET_VREG_R  rINST %ecx
462    FETCH_INST_OPCODE 3 %ecx
463    ADVANCE_PC 3
464    SET_VREG  rINST %eax
465    GOTO_NEXT_R %ecx
466
467
468/* ------------------------------ */
469.L_OP_MOVE_RESULT: /* 0x0a */
470/* File: x86/OP_MOVE_RESULT.S */
471    /* for: move-result, move-result-object */
472    /* op vAA */
473    movl     rSELF,%eax                    # eax<- rSELF
474    movl     offThread_retval(%eax),%eax   # eax<- self->retval.l
475    FETCH_INST_OPCODE 1 %ecx
476    ADVANCE_PC 1
477    SET_VREG  %eax rINST                   # fp[AA]<- retval.l
478    GOTO_NEXT_R %ecx
479
480/* ------------------------------ */
481.L_OP_MOVE_RESULT_WIDE: /* 0x0b */
482/* File: x86/OP_MOVE_RESULT_WIDE.S */
483    /* move-result-wide vAA */
484    movl    rSELF,%ecx
485    movl    offThread_retval(%ecx),%eax
486    movl    4+offThread_retval(%ecx),%ecx
487    SET_VREG_WORD %eax rINST 0     # v[AA+0] <- eax
488    SET_VREG_WORD %ecx rINST 1     # v[AA+1] <- ecx
489    FETCH_INST_OPCODE 1 %ecx
490    ADVANCE_PC 1
491    GOTO_NEXT_R %ecx
492
493/* ------------------------------ */
494.L_OP_MOVE_RESULT_OBJECT: /* 0x0c */
495/* File: x86/OP_MOVE_RESULT_OBJECT.S */
496/* File: x86/OP_MOVE_RESULT.S */
497    /* for: move-result, move-result-object */
498    /* op vAA */
499    movl     rSELF,%eax                    # eax<- rSELF
500    movl     offThread_retval(%eax),%eax   # eax<- self->retval.l
501    FETCH_INST_OPCODE 1 %ecx
502    ADVANCE_PC 1
503    SET_VREG  %eax rINST                   # fp[AA]<- retval.l
504    GOTO_NEXT_R %ecx
505
506
507/* ------------------------------ */
508.L_OP_MOVE_EXCEPTION: /* 0x0d */
509/* File: x86/OP_MOVE_EXCEPTION.S */
510    /* move-exception vAA */
511    movl    rSELF,%ecx
512    movl    offThread_exception(%ecx),%eax # eax<- dvmGetException bypass
513    SET_VREG %eax rINST                # fp[AA]<- exception object
514    FETCH_INST_OPCODE 1 %eax
515    ADVANCE_PC 1
516    movl    $0,offThread_exception(%ecx) # dvmClearException bypass
517    GOTO_NEXT_R %eax
518
519/* ------------------------------ */
520.L_OP_RETURN_VOID: /* 0x0e */
521/* File: x86/OP_RETURN_VOID.S */
522    jmp       common_returnFromMethod
523
524/* ------------------------------ */
525.L_OP_RETURN: /* 0x0f */
526/* File: x86/OP_RETURN.S */
527    /*
528     * Return a 32-bit value.  Copies the return value into the "self"
529     * structure, then jumps to the return handler.
530     *
531     * for: return, return-object
532     */
533    /* op vAA */
534    movl    rSELF,%ecx
535    GET_VREG_R %eax rINST               # eax<- vAA
536    movl    %eax,offThread_retval(%ecx)   # retval.i <- AA
537    jmp     common_returnFromMethod
538
539/* ------------------------------ */
540.L_OP_RETURN_WIDE: /* 0x10 */
541/* File: x86/OP_RETURN_WIDE.S */
542    /*
543     * Return a 64-bit value.  Copies the return value into the "self"
544     * structure, then jumps to the return handler.
545     */
546    /* return-wide vAA */
547    movl    rSELF,%ecx
548    GET_VREG_WORD %eax rINST 0       # eax<- v[AA+0]
549    GET_VREG_WORD rINST rINST 1      # rINST<- v[AA+1]
550    movl    %eax,offThread_retval(%ecx)
551    movl    rINST,4+offThread_retval(%ecx)
552    jmp     common_returnFromMethod
553
554/* ------------------------------ */
555.L_OP_RETURN_OBJECT: /* 0x11 */
556/* File: x86/OP_RETURN_OBJECT.S */
557/* File: x86/OP_RETURN.S */
558    /*
559     * Return a 32-bit value.  Copies the return value into the "self"
560     * structure, then jumps to the return handler.
561     *
562     * for: return, return-object
563     */
564    /* op vAA */
565    movl    rSELF,%ecx
566    GET_VREG_R %eax rINST               # eax<- vAA
567    movl    %eax,offThread_retval(%ecx)   # retval.i <- AA
568    jmp     common_returnFromMethod
569
570
571/* ------------------------------ */
572.L_OP_CONST_4: /* 0x12 */
573/* File: x86/OP_CONST_4.S */
574    /* const/4 vA, #+B */
575    movsx   rINSTbl,%eax              # eax<-ssssssBx
576    movl    $0xf,rINST
577    andl    %eax,rINST                # rINST<- A
578    FETCH_INST_OPCODE 1 %ecx
579    ADVANCE_PC 1
580    sarl    $4,%eax
581    SET_VREG %eax rINST
582    GOTO_NEXT_R %ecx
583
584/* ------------------------------ */
585.L_OP_CONST_16: /* 0x13 */
586/* File: x86/OP_CONST_16.S */
587    /* const/16 vAA, #+BBBB */
588    movswl  2(rPC),%ecx                # ecx<- ssssBBBB
589    FETCH_INST_OPCODE 2 %eax
590    ADVANCE_PC 2
591    SET_VREG %ecx rINST                # vAA<- ssssBBBB
592    GOTO_NEXT_R %eax
593
594/* ------------------------------ */
595.L_OP_CONST: /* 0x14 */
596/* File: x86/OP_CONST.S */
597    /* const vAA, #+BBBBbbbb */
598    movl      2(rPC),%eax             # grab all 32 bits at once
599    movl      rINST,rINST             # rINST<- AA
600    FETCH_INST_OPCODE 3 %ecx
601    ADVANCE_PC 3
602    SET_VREG %eax rINST               # vAA<- eax
603    GOTO_NEXT_R %ecx
604
605/* ------------------------------ */
606.L_OP_CONST_HIGH16: /* 0x15 */
607/* File: x86/OP_CONST_HIGH16.S */
608    /* const/high16 vAA, #+BBBB0000 */
609    movzwl     2(rPC),%eax                # eax<- 0000BBBB
610    FETCH_INST_OPCODE 2 %ecx
611    ADVANCE_PC 2
612    sall       $16,%eax                  # eax<- BBBB0000
613    SET_VREG %eax rINST                   # vAA<- eax
614    GOTO_NEXT_R %ecx
615
616/* ------------------------------ */
617.L_OP_CONST_WIDE_16: /* 0x16 */
618/* File: x86/OP_CONST_WIDE_16.S */
619    /* const-wide/16 vAA, #+BBBB */
620    movswl    2(rPC),%eax               # eax<- ssssBBBB
621    SPILL(rIBASE)                       # preserve rIBASE (cltd trashes it)
622    cltd                                # rIBASE:eax<- ssssssssssssBBBB
623    SET_VREG_WORD rIBASE rINST 1        # store msw
624    FETCH_INST_OPCODE 2 %ecx
625    UNSPILL(rIBASE)                     # restore rIBASE
626    SET_VREG_WORD %eax rINST 0          # store lsw
627    ADVANCE_PC 2
628    GOTO_NEXT_R %ecx
629
630/* ------------------------------ */
631.L_OP_CONST_WIDE_32: /* 0x17 */
632/* File: x86/OP_CONST_WIDE_32.S */
633    /* const-wide/32 vAA, #+BBBBbbbb */
634    movl     2(rPC),%eax                # eax<- BBBBbbbb
635    SPILL(rIBASE)                       # save rIBASE (cltd trashes it)
636    cltd                                # rIBASE:eax<- ssssssssssssBBBB
637    SET_VREG_WORD rIBASE rINST,1        # store msw
638    FETCH_INST_OPCODE 3 %ecx
639    UNSPILL(rIBASE)                     # restore rIBASE
640    SET_VREG_WORD %eax rINST 0          # store lsw
641    ADVANCE_PC 3
642    GOTO_NEXT_R %ecx
643
644/* ------------------------------ */
645.L_OP_CONST_WIDE: /* 0x18 */
646/* File: x86/OP_CONST_WIDE.S */
647    /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
648    movl      2(rPC),%eax         # eax<- lsw
649    movzbl    rINSTbl,%ecx        # ecx<- AA
650    movl      6(rPC),rINST        # rINST<- msw
651    leal      (rFP,%ecx,4),%ecx   # dst addr
652    movl      rINST,4(%ecx)
653    movl      %eax,(%ecx)
654    FETCH_INST_OPCODE 5 %ecx
655    ADVANCE_PC 5
656    GOTO_NEXT_R %ecx
657
658/* ------------------------------ */
659.L_OP_CONST_WIDE_HIGH16: /* 0x19 */
660/* File: x86/OP_CONST_WIDE_HIGH16.S */
661    /* const-wide/high16 vAA, #+BBBB000000000000 */
662    movzwl     2(rPC),%eax                # eax<- 0000BBBB
663    FETCH_INST_OPCODE 2 %ecx
664    ADVANCE_PC 2
665    sall       $16,%eax                  # eax<- BBBB0000
666    SET_VREG_WORD %eax rINST 1            # v[AA+1]<- eax
667    xorl       %eax,%eax
668    SET_VREG_WORD %eax rINST 0            # v[AA+0]<- eax
669    GOTO_NEXT_R %ecx
670
671/* ------------------------------ */
672.L_OP_CONST_STRING: /* 0x1a */
673/* File: x86/OP_CONST_STRING.S */
674
675    /* const/string vAA, String@BBBB */
676    movl      rSELF,%ecx
677    movzwl    2(rPC),%eax              # eax<- BBBB
678    movl      offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex
679    movl      offDvmDex_pResStrings(%ecx),%ecx # ecx<- dvmDex->pResStrings
680    movl      (%ecx,%eax,4),%eax       # eax<- rResString[BBBB]
681    FETCH_INST_OPCODE 2 %ecx
682    testl     %eax,%eax                # resolved yet?
683    je        .LOP_CONST_STRING_resolve
684    SET_VREG  %eax rINST               # vAA<- rResString[BBBB]
685    ADVANCE_PC 2
686    GOTO_NEXT_R %ecx
687
688/* This is the less common path, so we'll redo some work
689   here rather than force spills on the common path */
690.LOP_CONST_STRING_resolve:
691    movl     rSELF,%eax
692    EXPORT_PC
693    movl     offThread_method(%eax),%eax # eax<- self->method
694    movzwl   2(rPC),%ecx               # ecx<- BBBB
695    movl     offMethod_clazz(%eax),%eax
696    movl     %ecx,OUT_ARG1(%esp)
697    movl     %eax,OUT_ARG0(%esp)
698    SPILL(rIBASE)
699    call     dvmResolveString          # go resolve
700    UNSPILL(rIBASE)
701    testl    %eax,%eax                 # failed?
702    je       common_exceptionThrown
703    FETCH_INST_OPCODE 2 %ecx
704    SET_VREG %eax rINST
705    ADVANCE_PC 2
706    GOTO_NEXT_R %ecx
707
708/* ------------------------------ */
709.L_OP_CONST_STRING_JUMBO: /* 0x1b */
710/* File: x86/OP_CONST_STRING_JUMBO.S */
711
712    /* const/string vAA, String@BBBBBBBB */
713    movl      rSELF,%ecx
714    movl      2(rPC),%eax              # eax<- BBBBBBBB
715    movl      offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex
716    movl      offDvmDex_pResStrings(%ecx),%ecx # ecx<- dvmDex->pResStrings
717    movl      (%ecx,%eax,4),%eax       # eax<- rResString[BBBB]
718    FETCH_INST_OPCODE 3 %ecx
719    testl     %eax,%eax                # resolved yet?
720    je        .LOP_CONST_STRING_JUMBO_resolve
721    SET_VREG  %eax rINST               # vAA<- rResString[BBBB]
722    ADVANCE_PC 3
723    GOTO_NEXT_R %ecx
724
725/* This is the less common path, so we'll redo some work
726   here rather than force spills on the common path */
727.LOP_CONST_STRING_JUMBO_resolve:
728    movl     rSELF,%eax
729    EXPORT_PC
730    movl     offThread_method(%eax),%eax # eax<- self->method
731    movl     2(rPC),%ecx               # ecx<- BBBBBBBB
732    movl     offMethod_clazz(%eax),%eax
733    movl     %ecx,OUT_ARG1(%esp)
734    movl     %eax,OUT_ARG0(%esp)
735    SPILL(rIBASE)
736    call     dvmResolveString          # go resolve
737    UNSPILL(rIBASE)
738    testl    %eax,%eax                 # failed?
739    je       common_exceptionThrown
740    FETCH_INST_OPCODE 3 %ecx
741    SET_VREG %eax rINST
742    ADVANCE_PC 3
743    GOTO_NEXT_R %ecx
744
745/* ------------------------------ */
746.L_OP_CONST_CLASS: /* 0x1c */
747/* File: x86/OP_CONST_CLASS.S */
748
749    /* const/class vAA, Class@BBBB */
750    movl      rSELF,%ecx
751    movzwl    2(rPC),%eax              # eax<- BBBB
752    movl      offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex
753    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- dvmDex->pResClasses
754    movl      (%ecx,%eax,4),%eax       # eax<- rResClasses[BBBB]
755    testl     %eax,%eax                # resolved yet?
756    je        .LOP_CONST_CLASS_resolve
757    FETCH_INST_OPCODE 2 %ecx
758    SET_VREG  %eax rINST               # vAA<- rResClasses[BBBB]
759    ADVANCE_PC 2
760    GOTO_NEXT_R %ecx
761
762/* This is the less common path, so we'll redo some work
763   here rather than force spills on the common path */
764.LOP_CONST_CLASS_resolve:
765    movl     rSELF,%eax
766    EXPORT_PC
767    movl     offThread_method(%eax),%eax # eax<- self->method
768    movl     $1,OUT_ARG2(%esp)        # true
769    movzwl   2(rPC),%ecx               # ecx<- BBBB
770    movl     offMethod_clazz(%eax),%eax
771    movl     %ecx,OUT_ARG1(%esp)
772    movl     %eax,OUT_ARG0(%esp)
773    SPILL(rIBASE)
774    call     dvmResolveClass           # go resolve
775    UNSPILL(rIBASE)
776    testl    %eax,%eax                 # failed?
777    je       common_exceptionThrown
778    FETCH_INST_OPCODE 2 %ecx
779    SET_VREG %eax rINST
780    ADVANCE_PC 2
781    GOTO_NEXT_R %ecx
782
783/* ------------------------------ */
784.L_OP_MONITOR_ENTER: /* 0x1d */
785/* File: x86/OP_MONITOR_ENTER.S */
786    /*
787     * Synchronize on an object.
788     */
789    /* monitor-enter vAA */
790    movl    rSELF,%ecx
791    GET_VREG_R %eax rINST               # eax<- vAA
792    FETCH_INST_WORD 1
793    testl   %eax,%eax                   # null object?
794    EXPORT_PC                           # need for precise GC
795    je     common_errNullObject
796    movl    %ecx,OUT_ARG0(%esp)
797    movl    %eax,OUT_ARG1(%esp)
798    SPILL(rIBASE)
799    call    dvmLockObject               # dvmLockObject(self,object)
800    UNSPILL(rIBASE)
801    FETCH_INST_OPCODE 1 %ecx
802    ADVANCE_PC 1
803    GOTO_NEXT_R %ecx
804
805/* ------------------------------ */
806.L_OP_MONITOR_EXIT: /* 0x1e */
807/* File: x86/OP_MONITOR_EXIT.S */
808    /*
809     * Unlock an object.
810     *
811     * Exceptions that occur when unlocking a monitor need to appear as
812     * if they happened at the following instruction.  See the Dalvik
813     * instruction spec.
814     */
815    /* monitor-exit vAA */
816    GET_VREG_R %eax rINST
817    movl    rSELF,%ecx
818    EXPORT_PC
819    testl   %eax,%eax                   # null object?
820    je      .LOP_MONITOR_EXIT_errNullObject   # go if so
821    movl    %eax,OUT_ARG1(%esp)
822    movl    %ecx,OUT_ARG0(%esp)
823    SPILL(rIBASE)
824    call    dvmUnlockObject             # unlock(self,obj)
825    UNSPILL(rIBASE)
826    FETCH_INST_OPCODE 1 %ecx
827    testl   %eax,%eax                   # success?
828    ADVANCE_PC 1
829    je      common_exceptionThrown      # no, exception pending
830    GOTO_NEXT_R %ecx
831.LOP_MONITOR_EXIT_errNullObject:
832    ADVANCE_PC 1                        # advance before throw
833    jmp     common_errNullObject
834
835/* ------------------------------ */
836.L_OP_CHECK_CAST: /* 0x1f */
837/* File: x86/OP_CHECK_CAST.S */
838    /*
839     * Check to see if a cast from one class to another is allowed.
840     */
841    /* check-cast vAA, class@BBBB */
842    movl      rSELF,%ecx
843    GET_VREG_R  rINST,rINST             # rINST<- vAA (object)
844    movzwl    2(rPC),%eax               # eax<- BBBB
845    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
846    testl     rINST,rINST               # is oject null?
847    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
848    je        .LOP_CHECK_CAST_okay          # null obj, cast always succeeds
849    movl      (%ecx,%eax,4),%eax        # eax<- resolved class
850    movl      offObject_clazz(rINST),%ecx # ecx<- obj->clazz
851    testl     %eax,%eax                 # have we resolved this before?
852    je        .LOP_CHECK_CAST_resolve       # no, go do it now
853.LOP_CHECK_CAST_resolved:
854    cmpl      %eax,%ecx                 # same class (trivial success)?
855    jne       .LOP_CHECK_CAST_fullcheck     # no, do full check
856.LOP_CHECK_CAST_okay:
857    FETCH_INST_OPCODE 2 %ecx
858    ADVANCE_PC 2
859    GOTO_NEXT_R %ecx
860
861    /*
862     * Trivial test failed, need to perform full check.  This is common.
863     *  ecx holds obj->clazz
864     *  eax holds class resolved from BBBB
865     *  rINST holds object
866     */
867.LOP_CHECK_CAST_fullcheck:
868    movl    %eax,sReg0                 # we'll need the desired class on failure
869    movl    %eax,OUT_ARG1(%esp)
870    movl    %ecx,OUT_ARG0(%esp)
871    SPILL(rIBASE)
872    call    dvmInstanceofNonTrivial    # eax<- boolean result
873    UNSPILL(rIBASE)
874    testl   %eax,%eax                  # failed?
875    jne     .LOP_CHECK_CAST_okay           # no, success
876
877    # A cast has failed.  We need to throw a ClassCastException.
878    EXPORT_PC
879    movl    offObject_clazz(rINST),%eax
880    movl    %eax,OUT_ARG0(%esp)                 # arg0<- obj->clazz
881    movl    sReg0,%ecx
882    movl    %ecx,OUT_ARG1(%esp)                 # arg1<- desired class
883    call    dvmThrowClassCastException
884    jmp     common_exceptionThrown
885
886    /*
887     * Resolution required.  This is the least-likely path, and we're
888     * going to have to recreate some data.
889     *
890     *  rINST holds object
891     */
892.LOP_CHECK_CAST_resolve:
893    movl    rSELF,%ecx
894    EXPORT_PC
895    movzwl  2(rPC),%eax                # eax<- BBBB
896    movl    offThread_method(%ecx),%ecx  # ecx<- self->method
897    movl    %eax,OUT_ARG1(%esp)        # arg1<- BBBB
898    movl    offMethod_clazz(%ecx),%ecx # ecx<- metho->clazz
899    movl    $0,OUT_ARG2(%esp)         # arg2<- false
900    movl    %ecx,OUT_ARG0(%esp)        # arg0<- method->clazz
901    SPILL(rIBASE)
902    call    dvmResolveClass            # eax<- resolved ClassObject ptr
903    UNSPILL(rIBASE)
904    testl   %eax,%eax                  # got null?
905    je      common_exceptionThrown     # yes, handle exception
906    movl    offObject_clazz(rINST),%ecx  # ecx<- obj->clazz
907    jmp     .LOP_CHECK_CAST_resolved       # pick up where we left off
908
909/* ------------------------------ */
910.L_OP_INSTANCE_OF: /* 0x20 */
911/* File: x86/OP_INSTANCE_OF.S */
912    /*
913     * Check to see if an object reference is an instance of a class.
914     *
915     * Most common situation is a non-null object, being compared against
916     * an already-resolved class.
917     */
918    /* instance-of vA, vB, class@CCCC */
919    movl    rINST,%eax                  # eax<- BA
920    sarl    $4,%eax                    # eax<- B
921    GET_VREG_R %eax %eax                # eax<- vB (obj)
922    movl    rSELF,%ecx
923    testl   %eax,%eax                   # object null?
924    movl    offThread_methodClassDex(%ecx),%ecx  # ecx<- pDvmDex
925    SPILL(rIBASE)                       # preserve rIBASE
926    je      .LOP_INSTANCE_OF_store           # null obj, not instance, store it
927    movzwl  2(rPC),rIBASE               # rIBASE<- CCCC
928    movl    offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
929    movl    (%ecx,rIBASE,4),%ecx        # ecx<- resolved class
930    movl    offObject_clazz(%eax),%eax  # eax<- obj->clazz
931    testl   %ecx,%ecx                   # have we resolved this before?
932    je      .LOP_INSTANCE_OF_resolve         # not resolved, do it now
933.LOP_INSTANCE_OF_resolved:  # eax<- obj->clazz, ecx<- resolved class
934    cmpl    %eax,%ecx                   # same class (trivial success)?
935    je      .LOP_INSTANCE_OF_trivial         # yes, trivial finish
936    /*
937     * Trivial test failed, need to perform full check.  This is common.
938     *  eax holds obj->clazz
939     *  ecx holds class resolved from BBBB
940     *  rINST has BA
941     */
942    movl    %eax,OUT_ARG0(%esp)
943    movl    %ecx,OUT_ARG1(%esp)
944    call    dvmInstanceofNonTrivial     # eax<- boolean result
945    # fall through to OP_INSTANCE_OF_store
946
947    /*
948     * eax holds boolean result
949     * rINST holds BA
950     */
951.LOP_INSTANCE_OF_store:
952    FETCH_INST_OPCODE 2 %ecx
953    UNSPILL(rIBASE)
954    andb    $0xf,rINSTbl               # <- A
955    ADVANCE_PC 2
956    SET_VREG %eax rINST                 # vA<- eax
957    GOTO_NEXT_R %ecx
958
959    /*
960     * Trivial test succeeded, save and bail.
961     *  r9 holds A
962     */
963.LOP_INSTANCE_OF_trivial:
964    FETCH_INST_OPCODE 2 %ecx
965    UNSPILL(rIBASE)
966    andb    $0xf,rINSTbl               # <- A
967    ADVANCE_PC 2
968    movl    $1,%eax
969    SET_VREG %eax rINST                 # vA<- true
970    GOTO_NEXT_R %ecx
971
972    /*
973     * Resolution required.  This is the least-likely path.
974     *
975     *  rIBASE holds BBBB
976     *  rINST holds BA
977     */
978.LOP_INSTANCE_OF_resolve:
979    movl    rIBASE,OUT_ARG1(%esp)         # arg1<- BBBB
980    movl    rSELF,%ecx
981    movl    offThread_method(%ecx),%ecx
982    movl    $1,OUT_ARG2(%esp)          # arg2<- true
983    movl    offMethod_clazz(%ecx),%ecx  # ecx<- method->clazz
984    EXPORT_PC
985    movl    %ecx,OUT_ARG0(%esp)         # arg0<- method->clazz
986    call    dvmResolveClass             # eax<- resolved ClassObject ptr
987    testl   %eax,%eax                   # success?
988    je      common_exceptionThrown      # no, handle exception
989/* Now, we need to sync up with fast path.  We need eax to
990 * hold the obj->clazz, and ecx to hold the resolved class
991 */
992    movl    %eax,%ecx                   # ecx<- resolved class
993    movl    rINST,%eax                  # eax<- BA
994    sarl    $4,%eax                    # eax<- B
995    GET_VREG_R %eax %eax                # eax<- vB (obj)
996    movl    offObject_clazz(%eax),%eax  # eax<- obj->clazz
997    jmp     .LOP_INSTANCE_OF_resolved
998
999/* ------------------------------ */
1000.L_OP_ARRAY_LENGTH: /* 0x21 */
1001/* File: x86/OP_ARRAY_LENGTH.S */
1002    /*
1003     * Return the length of an array.
1004     */
1005   mov      rINST,%eax                # eax<- BA
1006   sarl     $4,rINST                 # rINST<- B
1007   GET_VREG_R %ecx rINST              # ecx<- vB (object ref)
1008   andb     $0xf,%al                 # eax<- A
1009   testl    %ecx,%ecx                 # is null?
1010   je       common_errNullObject
1011   movl     offArrayObject_length(%ecx),rINST
1012   FETCH_INST_OPCODE 1 %ecx
1013   ADVANCE_PC 1
1014   SET_VREG rINST %eax
1015   GOTO_NEXT_R %ecx
1016
1017/* ------------------------------ */
1018.L_OP_NEW_INSTANCE: /* 0x22 */
1019/* File: x86/OP_NEW_INSTANCE.S */
1020    /*
1021     * Create a new instance of a class.
1022     */
1023    /* new-instance vAA, class@BBBB */
1024    movl      rSELF,%ecx
1025    movzwl    2(rPC),%eax               # eax<- BBBB
1026    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- pDvmDex
1027    SPILL(rIBASE)
1028    SPILL_TMP2(%ebx)
1029    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
1030    EXPORT_PC
1031#if defined(WITH_JIT)
1032    lea       (%ecx,%eax,4),%ebx        # ebx <- &resolved class
1033#endif
1034    movl      (%ecx,%eax,4),%ecx        # ecx<- resolved class
1035    testl     %ecx,%ecx                 # resolved?
1036    je        .LOP_NEW_INSTANCE_resolve       # no, go do it
1037.LOP_NEW_INSTANCE_resolved:  # on entry, ecx<- class
1038    cmpb      $CLASS_INITIALIZED,offClassObject_status(%ecx)
1039    jne       .LOP_NEW_INSTANCE_needinit
1040.LOP_NEW_INSTANCE_initialized:  # on entry, ecx<- class
1041    movl      $ALLOC_DONT_TRACK,OUT_ARG1(%esp)
1042    movl     %ecx,OUT_ARG0(%esp)
1043    call     dvmAllocObject             # eax<- new object
1044    testl    %eax,%eax                  # success?
1045    je       common_exceptionThrown     # no, bail out
1046#if defined(WITH_JIT)
1047        /*
1048     * The JIT needs the class to be fully resolved before it can
1049     * include this instruction in a trace.
1050     */
1051    movl    rSELF, %ecx
1052    movl    offThread_subMode(%ecx), %ecx
1053    andl    $kSubModeJitTraceBuild, %ecx # under construction?
1054    jne     .LOP_NEW_INSTANCE_jitCheck
1055#endif
1056.LOP_NEW_INSTANCE_end:
1057    UNSPILL_TMP2(%ebx)
1058    SET_VREG %eax rINST
1059    UNSPILL(rIBASE)
1060    FETCH_INST_OPCODE 2 %ecx
1061    ADVANCE_PC 2
1062    GOTO_NEXT_R %ecx
1063
1064#if defined(WITH_JIT)
1065    /*
1066     * Check to see if we need to stop the trace building early.
1067     * eax: new object
1068     */
1069.LOP_NEW_INSTANCE_jitCheck:
1070    cmp     $0, (%ebx)                   # okay?
1071    jne     .LOP_NEW_INSTANCE_end        # yes, finish
1072    SPILL_TMP1(%eax)                     # preserve new object
1073    movl    rSELF, %ecx
1074    movl    %ecx, OUT_ARG0(%esp)
1075    movl    rPC, OUT_ARG1(%esp)
1076    call    dvmJitEndTraceSelect         # (self, pc)
1077    UNSPILL_TMP1(%eax)
1078    UNSPILL_TMP2(%ebx)
1079    SET_VREG %eax rINST                  # vAA <- new object
1080    UNSPILL(rIBASE)
1081    FETCH_INST_OPCODE 2 %ecx
1082    ADVANCE_PC 2
1083    GOTO_NEXT_R %ecx
1084#endif
1085
1086    /*
1087     * Class initialization required.
1088     *
1089     *  ecx holds class object
1090     */
1091.LOP_NEW_INSTANCE_needinit:
1092    SPILL_TMP1(%ecx)                    # save object
1093    movl    %ecx,OUT_ARG0(%esp)
1094    call    dvmInitClass                # initialize class
1095    UNSPILL_TMP1(%ecx)                  # restore object
1096    testl   %eax,%eax                   # success?
1097    jne     .LOP_NEW_INSTANCE_initialized     # success, continue
1098    jmp     common_exceptionThrown      # go deal with init exception
1099
1100    /*
1101     * Resolution required.  This is the least-likely path.
1102     *
1103     */
1104.LOP_NEW_INSTANCE_resolve:
1105    movl    rSELF,%ecx
1106    movzwl  2(rPC),%eax
1107    movl    offThread_method(%ecx),%ecx   # ecx<- self->method
1108    movl    %eax,OUT_ARG1(%esp)
1109    movl    offMethod_clazz(%ecx),%ecx  # ecx<- method->clazz
1110    movl    $0,OUT_ARG2(%esp)
1111    movl    %ecx,OUT_ARG0(%esp)
1112    call    dvmResolveClass             # call(clazz,off,flags)
1113    movl    %eax,%ecx                   # ecx<- resolved ClassObject ptr
1114    testl   %ecx,%ecx                   # success?
1115    jne     .LOP_NEW_INSTANCE_resolved        # good to go
1116    jmp     common_exceptionThrown      # no, handle exception
1117
1118/* ------------------------------ */
1119.L_OP_NEW_ARRAY: /* 0x23 */
1120/* File: x86/OP_NEW_ARRAY.S */
1121    /*
1122     * Allocate an array of objects, specified with the array class
1123     * and a count.
1124     *
1125     * The verifier guarantees that this is an array class, so we don't
1126     * check for it here.
1127     */
1128    /* new-array vA, vB, class@CCCC */
1129    movl    rSELF,%ecx
1130    EXPORT_PC
1131    movl    offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
1132    movzwl  2(rPC),%eax                       # eax<- CCCC
1133    movl    offDvmDex_pResClasses(%ecx),%ecx  # ecx<- pDvmDex->pResClasses
1134    SPILL(rIBASE)
1135    movl    (%ecx,%eax,4),%ecx                # ecx<- resolved class
1136    movzbl  rINSTbl,%eax
1137    sarl    $4,%eax                          # eax<- B
1138    GET_VREG_R %eax %eax                      # eax<- vB (array length)
1139    andb    $0xf,rINSTbl                     # rINST<- A
1140    testl   %eax,%eax
1141    js      common_errNegativeArraySize       # bail, passing len in eax
1142    testl   %ecx,%ecx                         # already resolved?
1143    jne     .LOP_NEW_ARRAY_finish                # yes, fast path
1144    /*
1145     * Resolve class.  (This is an uncommon case.)
1146     *  ecx holds class (null here)
1147     *  eax holds array length (vB)
1148     */
1149    movl    rSELF,%ecx
1150    SPILL_TMP1(%eax)                   # save array length
1151    movl    offThread_method(%ecx),%ecx  # ecx<- self->method
1152    movzwl  2(rPC),%eax                # eax<- CCCC
1153    movl    offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
1154    movl    %eax,OUT_ARG1(%esp)
1155    movl    $0,OUT_ARG2(%esp)
1156    movl    %ecx,OUT_ARG0(%esp)
1157    call    dvmResolveClass            # eax<- call(clazz,ref,flag)
1158    movl    %eax,%ecx
1159    UNSPILL_TMP1(%eax)
1160    testl   %ecx,%ecx                  # successful resolution?
1161    je      common_exceptionThrown     # no, bail.
1162# fall through to OP_NEW_ARRAY_finish
1163
1164    /*
1165     * Finish allocation
1166     *
1167     * ecx holds class
1168     * eax holds array length (vB)
1169     */
1170.LOP_NEW_ARRAY_finish:
1171    movl    %ecx,OUT_ARG0(%esp)
1172    movl    %eax,OUT_ARG1(%esp)
1173    movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)
1174    call    dvmAllocArrayByClass    # eax<- call(clazz,length,flags)
1175    FETCH_INST_OPCODE 2 %ecx
1176    UNSPILL(rIBASE)
1177    testl   %eax,%eax               # failed?
1178    je      common_exceptionThrown  # yup - go handle
1179    SET_VREG %eax rINST
1180    ADVANCE_PC 2
1181    GOTO_NEXT_R %ecx
1182
1183/* ------------------------------ */
1184.L_OP_FILLED_NEW_ARRAY: /* 0x24 */
1185/* File: x86/OP_FILLED_NEW_ARRAY.S */
1186    /*
1187     * Create a new array with elements filled from registers.
1188     *
1189     * for: filled-new-array, filled-new-array/range
1190     */
1191    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1192    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1193    movl    rSELF,%eax
1194    movl    offThread_methodClassDex(%eax),%eax # eax<- pDvmDex
1195    movzwl  2(rPC),%ecx                       # ecx<- BBBB
1196    movl    offDvmDex_pResClasses(%eax),%eax  # eax<- pDvmDex->pResClasses
1197    SPILL(rIBASE)                             # preserve rIBASE
1198    movl    (%eax,%ecx,4),%eax                # eax<- resolved class
1199    EXPORT_PC
1200    testl   %eax,%eax                         # already resolved?
1201    jne     .LOP_FILLED_NEW_ARRAY_continue              # yes, continue
1202    # less frequent path, so we'll redo some work
1203    movl    rSELF,%eax
1204    movl    $0,OUT_ARG2(%esp)                # arg2<- false
1205    movl    %ecx,OUT_ARG1(%esp)               # arg1<- BBBB
1206    movl    offThread_method(%eax),%eax         # eax<- self->method
1207    movl    offMethod_clazz(%eax),%eax        # eax<- method->clazz
1208    movl    %eax,OUT_ARG0(%esp)               # arg0<- clazz
1209    call    dvmResolveClass                   # eax<- call(clazz,ref,flag)
1210    testl   %eax,%eax                         # null?
1211    je      common_exceptionThrown            # yes, handle it
1212
1213       # note: fall through to .LOP_FILLED_NEW_ARRAY_continue
1214
1215    /*
1216     * On entry:
1217     *    eax holds array class [r0]
1218     *    rINST holds AA or BB [r10]
1219     *    ecx is scratch
1220     */
1221.LOP_FILLED_NEW_ARRAY_continue:
1222    movl    offClassObject_descriptor(%eax),%ecx  # ecx<- arrayClass->descriptor
1223    movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)     # arg2<- flags
1224    movzbl  1(%ecx),%ecx                          # ecx<- descriptor[1]
1225    movl    %eax,OUT_ARG0(%esp)                   # arg0<- arrayClass
1226    movl    rSELF,%eax
1227    cmpb    $'I',%cl                             # supported?
1228    je      1f
1229    cmpb    $'L',%cl
1230    je      1f
1231    cmpb    $'[',%cl
1232    jne      .LOP_FILLED_NEW_ARRAY_notimpl                  # no, not handled yet
12331:
1234    movl    %ecx,offThread_retval+4(%eax)           # save type
1235    .if      (!0)
1236    SPILL_TMP1(rINST)                              # save copy, need "B" later
1237    sarl    $4,rINST
1238    .endif
1239    movl    rINST,OUT_ARG1(%esp)                  # arg1<- A or AA (length)
1240    call    dvmAllocArrayByClass     # eax<- call(arrayClass, length, flags)
1241    movl    rSELF,%ecx
1242    testl   %eax,%eax                             # alloc successful?
1243    je      common_exceptionThrown                # no, handle exception
1244    movl    %eax,offThread_retval(%ecx)             # retval.l<- new array
1245    movzwl  4(rPC),%ecx                           # ecx<- FEDC or CCCC
1246    leal    offArrayObject_contents(%eax),%eax    # eax<- newArray->contents
1247
1248/* at this point:
1249 *     eax is pointer to tgt
1250 *     rINST is length
1251 *     ecx is FEDC or CCCC
1252 *     TMP_SPILL1 is BA
1253 *  We now need to copy values from registers into the array
1254 */
1255
1256    .if 0
1257    # set up src pointer
1258    SPILL_TMP2(%esi)
1259    SPILL_TMP3(%edi)
1260    leal    (rFP,%ecx,4),%esi # set up src ptr
1261    movl    %eax,%edi         # set up dst ptr
1262    movl    rINST,%ecx        # load count register
1263    rep
1264    movsd
1265    UNSPILL_TMP2(%esi)
1266    UNSPILL_TMP3(%edi)
1267    movl    rSELF,%ecx
1268    movl    offThread_retval+4(%ecx),%eax      # eax<- type
1269    .else
1270    testl  rINST,rINST
1271    je     4f
1272    UNSPILL_TMP1(rIBASE)      # restore "BA"
1273    andl   $0x0f,rIBASE      # rIBASE<- 0000000A
1274    sall   $16,rIBASE        # rIBASE<- 000A0000
1275    orl    %ecx,rIBASE        # rIBASE<- 000AFEDC
12763:
1277    movl   $0xf,%ecx
1278    andl   rIBASE,%ecx        # ecx<- next reg to load
1279    GET_VREG_R %ecx %ecx
1280    shrl   $4,rIBASE
1281    leal   4(%eax),%eax
1282    movl   %ecx,-4(%eax)
1283    sub    $1,rINST
1284    jne    3b
12854:
1286    movl   rSELF,%ecx
1287    movl    offThread_retval+4(%ecx),%eax      # eax<- type
1288    .endif
1289
1290    cmpb    $'I',%al                        # Int array?
1291    je      5f                               # skip card mark if so
1292    movl    offThread_retval(%ecx),%eax        # eax<- object head
1293    movl    offThread_cardTable(%ecx),%ecx     # card table base
1294    shrl    $GC_CARD_SHIFT,%eax             # convert to card num
1295    movb    %cl,(%ecx,%eax)                  # mark card based on object head
12965:
1297    UNSPILL(rIBASE)                          # restore rIBASE
1298    FETCH_INST_OPCODE 3 %ecx
1299    ADVANCE_PC 3
1300    GOTO_NEXT_R %ecx
1301
1302
1303    /*
1304     * Throw an exception indicating that we have not implemented this
1305     * mode of filled-new-array.
1306     */
1307.LOP_FILLED_NEW_ARRAY_notimpl:
1308    movl    $.LstrFilledNewArrayNotImplA,%eax
1309    movl    %eax,OUT_ARG0(%esp)
1310    call    dvmThrowInternalError
1311    jmp     common_exceptionThrown
1312
1313/* ------------------------------ */
1314.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
1315/* File: x86/OP_FILLED_NEW_ARRAY_RANGE.S */
1316/* File: x86/OP_FILLED_NEW_ARRAY.S */
1317    /*
1318     * Create a new array with elements filled from registers.
1319     *
1320     * for: filled-new-array, filled-new-array/range
1321     */
1322    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1323    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1324    movl    rSELF,%eax
1325    movl    offThread_methodClassDex(%eax),%eax # eax<- pDvmDex
1326    movzwl  2(rPC),%ecx                       # ecx<- BBBB
1327    movl    offDvmDex_pResClasses(%eax),%eax  # eax<- pDvmDex->pResClasses
1328    SPILL(rIBASE)                             # preserve rIBASE
1329    movl    (%eax,%ecx,4),%eax                # eax<- resolved class
1330    EXPORT_PC
1331    testl   %eax,%eax                         # already resolved?
1332    jne     .LOP_FILLED_NEW_ARRAY_RANGE_continue              # yes, continue
1333    # less frequent path, so we'll redo some work
1334    movl    rSELF,%eax
1335    movl    $0,OUT_ARG2(%esp)                # arg2<- false
1336    movl    %ecx,OUT_ARG1(%esp)               # arg1<- BBBB
1337    movl    offThread_method(%eax),%eax         # eax<- self->method
1338    movl    offMethod_clazz(%eax),%eax        # eax<- method->clazz
1339    movl    %eax,OUT_ARG0(%esp)               # arg0<- clazz
1340    call    dvmResolveClass                   # eax<- call(clazz,ref,flag)
1341    testl   %eax,%eax                         # null?
1342    je      common_exceptionThrown            # yes, handle it
1343
1344       # note: fall through to .LOP_FILLED_NEW_ARRAY_RANGE_continue
1345
1346    /*
1347     * On entry:
1348     *    eax holds array class [r0]
1349     *    rINST holds AA or BB [r10]
1350     *    ecx is scratch
1351     */
1352.LOP_FILLED_NEW_ARRAY_RANGE_continue:
1353    movl    offClassObject_descriptor(%eax),%ecx  # ecx<- arrayClass->descriptor
1354    movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)     # arg2<- flags
1355    movzbl  1(%ecx),%ecx                          # ecx<- descriptor[1]
1356    movl    %eax,OUT_ARG0(%esp)                   # arg0<- arrayClass
1357    movl    rSELF,%eax
1358    cmpb    $'I',%cl                             # supported?
1359    je      1f
1360    cmpb    $'L',%cl
1361    je      1f
1362    cmpb    $'[',%cl
1363    jne      .LOP_FILLED_NEW_ARRAY_RANGE_notimpl                  # no, not handled yet
13641:
1365    movl    %ecx,offThread_retval+4(%eax)           # save type
1366    .if      (!1)
1367    SPILL_TMP1(rINST)                              # save copy, need "B" later
1368    sarl    $4,rINST
1369    .endif
1370    movl    rINST,OUT_ARG1(%esp)                  # arg1<- A or AA (length)
1371    call    dvmAllocArrayByClass     # eax<- call(arrayClass, length, flags)
1372    movl    rSELF,%ecx
1373    testl   %eax,%eax                             # alloc successful?
1374    je      common_exceptionThrown                # no, handle exception
1375    movl    %eax,offThread_retval(%ecx)             # retval.l<- new array
1376    movzwl  4(rPC),%ecx                           # ecx<- FEDC or CCCC
1377    leal    offArrayObject_contents(%eax),%eax    # eax<- newArray->contents
1378
1379/* at this point:
1380 *     eax is pointer to tgt
1381 *     rINST is length
1382 *     ecx is FEDC or CCCC
1383 *     TMP_SPILL1 is BA
1384 *  We now need to copy values from registers into the array
1385 */
1386
1387    .if 1
1388    # set up src pointer
1389    SPILL_TMP2(%esi)
1390    SPILL_TMP3(%edi)
1391    leal    (rFP,%ecx,4),%esi # set up src ptr
1392    movl    %eax,%edi         # set up dst ptr
1393    movl    rINST,%ecx        # load count register
1394    rep
1395    movsd
1396    UNSPILL_TMP2(%esi)
1397    UNSPILL_TMP3(%edi)
1398    movl    rSELF,%ecx
1399    movl    offThread_retval+4(%ecx),%eax      # eax<- type
1400    .else
1401    testl  rINST,rINST
1402    je     4f
1403    UNSPILL_TMP1(rIBASE)      # restore "BA"
1404    andl   $0x0f,rIBASE      # rIBASE<- 0000000A
1405    sall   $16,rIBASE        # rIBASE<- 000A0000
1406    orl    %ecx,rIBASE        # rIBASE<- 000AFEDC
14073:
1408    movl   $0xf,%ecx
1409    andl   rIBASE,%ecx        # ecx<- next reg to load
1410    GET_VREG_R %ecx %ecx
1411    shrl   $4,rIBASE
1412    leal   4(%eax),%eax
1413    movl   %ecx,-4(%eax)
1414    sub    $1,rINST
1415    jne    3b
14164:
1417    movl   rSELF,%ecx
1418    movl    offThread_retval+4(%ecx),%eax      # eax<- type
1419    .endif
1420
1421    cmpb    $'I',%al                        # Int array?
1422    je      5f                               # skip card mark if so
1423    movl    offThread_retval(%ecx),%eax        # eax<- object head
1424    movl    offThread_cardTable(%ecx),%ecx     # card table base
1425    shrl    $GC_CARD_SHIFT,%eax             # convert to card num
1426    movb    %cl,(%ecx,%eax)                  # mark card based on object head
14275:
1428    UNSPILL(rIBASE)                          # restore rIBASE
1429    FETCH_INST_OPCODE 3 %ecx
1430    ADVANCE_PC 3
1431    GOTO_NEXT_R %ecx
1432
1433
1434    /*
1435     * Throw an exception indicating that we have not implemented this
1436     * mode of filled-new-array.
1437     */
1438.LOP_FILLED_NEW_ARRAY_RANGE_notimpl:
1439    movl    $.LstrFilledNewArrayNotImplA,%eax
1440    movl    %eax,OUT_ARG0(%esp)
1441    call    dvmThrowInternalError
1442    jmp     common_exceptionThrown
1443
1444
1445/* ------------------------------ */
1446.L_OP_FILL_ARRAY_DATA: /* 0x26 */
1447/* File: x86/OP_FILL_ARRAY_DATA.S */
1448    /* fill-array-data vAA, +BBBBBBBB */
1449    movl    2(rPC),%ecx                # ecx<- BBBBbbbb
1450    leal    (rPC,%ecx,2),%ecx          # ecx<- PC + BBBBbbbb*2
1451    GET_VREG_R %eax rINST
1452    EXPORT_PC
1453    movl    %eax,OUT_ARG0(%esp)
1454    movl    %ecx,OUT_ARG1(%esp)
1455    SPILL(rIBASE)
1456    call    dvmInterpHandleFillArrayData
1457    UNSPILL(rIBASE)
1458    FETCH_INST_OPCODE 3 %ecx
1459    testl   %eax,%eax                   # exception thrown?
1460    je      common_exceptionThrown
1461    ADVANCE_PC 3
1462    GOTO_NEXT_R %ecx
1463
1464/* ------------------------------ */
1465.L_OP_THROW: /* 0x27 */
1466/* File: x86/OP_THROW.S */
1467    /*
1468     * Throw an exception object in the current thread.
1469     */
1470    /* throw vAA */
1471    EXPORT_PC
1472    GET_VREG_R %eax rINST              # eax<- exception object
1473    movl     rSELF,%ecx                # ecx<- self
1474    testl    %eax,%eax                 # null object?
1475    je       common_errNullObject
1476    movl     %eax,offThread_exception(%ecx) # thread->exception<- obj
1477    jmp      common_exceptionThrown
1478
1479/* ------------------------------ */
1480.L_OP_GOTO: /* 0x28 */
1481/* File: x86/OP_GOTO.S */
1482    /*
1483     * Unconditional branch, 8-bit offset.
1484     *
1485     * The branch distance is a signed code-unit offset, which we need to
1486     * double to get a byte offset.
1487     */
1488    /* goto +AA */
1489    movl    rSELF,%ecx
1490    movsbl  rINSTbl,%eax          # eax<- ssssssAA
1491    movl    offThread_curHandlerTable(%ecx),rIBASE
1492    FETCH_INST_INDEXED %eax
1493    ADVANCE_PC_INDEXED %eax
1494#if defined(WITH_JIT)
1495    GET_JIT_PROF_TABLE %ecx %eax
1496    cmp         $0, %eax
1497    jne         common_updateProfile # set up %ebx & %edx & rPC
1498#endif
1499    GOTO_NEXT
1500
1501/* ------------------------------ */
1502.L_OP_GOTO_16: /* 0x29 */
1503/* File: x86/OP_GOTO_16.S */
1504    /*
1505     * Unconditional branch, 16-bit offset.
1506     *
1507     * The branch distance is a signed code-unit offset
1508     */
1509    /* goto/16 +AAAA */
1510    movl    rSELF,%ecx
1511    movswl  2(rPC),%eax            # eax<- ssssAAAA
1512    movl    offThread_curHandlerTable(%ecx),rIBASE
1513    FETCH_INST_INDEXED %eax
1514    ADVANCE_PC_INDEXED %eax
1515#if defined(WITH_JIT)
1516    GET_JIT_PROF_TABLE %ecx %eax
1517    cmp         $0, %eax
1518    jne         common_updateProfile # set up %ebx & %edx & rPC
1519#endif
1520    GOTO_NEXT
1521
1522/* ------------------------------ */
1523.L_OP_GOTO_32: /* 0x2a */
1524/* File: x86/OP_GOTO_32.S */
1525    /*
1526     * Unconditional branch, 32-bit offset.
1527     *
1528     * The branch distance is a signed code-unit offset.
1529     */
1530    /* goto/32 AAAAAAAA */
1531    movl    rSELF,%ecx
1532    movl    2(rPC),%eax            # eax<- AAAAAAAA
1533    movl    offThread_curHandlerTable(%ecx),rIBASE
1534    FETCH_INST_INDEXED %eax
1535    ADVANCE_PC_INDEXED %eax
1536#if defined(WITH_JIT)
1537    GET_JIT_PROF_TABLE %ecx %eax
1538    cmp         $0, %eax
1539    jne         common_updateProfile # set up %ebx & %edx & rPC
1540#endif
1541    GOTO_NEXT
1542
1543/* ------------------------------ */
1544.L_OP_PACKED_SWITCH: /* 0x2b */
1545/* File: x86/OP_PACKED_SWITCH.S */
1546    /*
1547     * Handle a packed-switch or sparse-switch instruction.  In both cases
1548     * we decode it and hand it off to a helper function.
1549     *
1550     * We don't really expect backward branches in a switch statement, but
1551     * they're perfectly legal, so we check for them here.
1552     *
1553     * for: packed-switch, sparse-switch
1554     */
1555    /* op vAA, +BBBB */
1556    movl    2(rPC),%ecx           # ecx<- BBBBbbbb
1557    GET_VREG_R %eax rINST         # eax<- vAA
1558    leal    (rPC,%ecx,2),%ecx     # ecx<- PC + BBBBbbbb*2
1559    movl    %eax,OUT_ARG1(%esp)   # ARG1<- vAA
1560    movl    %ecx,OUT_ARG0(%esp)   # ARG0<- switchData
1561    call    dvmInterpHandlePackedSwitch
1562    movl    rSELF,%ecx
1563    ADVANCE_PC_INDEXED %eax
1564    movl    offThread_curHandlerTable(%ecx),rIBASE
1565    FETCH_INST
1566#if defined(WITH_JIT)
1567    GET_JIT_PROF_TABLE %ecx %eax
1568    cmp         $0, %eax
1569    jne         common_updateProfile # set up %ebx & %edx & rPC
1570#endif
1571    GOTO_NEXT
1572
1573/* ------------------------------ */
1574.L_OP_SPARSE_SWITCH: /* 0x2c */
1575/* File: x86/OP_SPARSE_SWITCH.S */
1576/* File: x86/OP_PACKED_SWITCH.S */
1577    /*
1578     * Handle a packed-switch or sparse-switch instruction.  In both cases
1579     * we decode it and hand it off to a helper function.
1580     *
1581     * We don't really expect backward branches in a switch statement, but
1582     * they're perfectly legal, so we check for them here.
1583     *
1584     * for: packed-switch, sparse-switch
1585     */
1586    /* op vAA, +BBBB */
1587    movl    2(rPC),%ecx           # ecx<- BBBBbbbb
1588    GET_VREG_R %eax rINST         # eax<- vAA
1589    leal    (rPC,%ecx,2),%ecx     # ecx<- PC + BBBBbbbb*2
1590    movl    %eax,OUT_ARG1(%esp)   # ARG1<- vAA
1591    movl    %ecx,OUT_ARG0(%esp)   # ARG0<- switchData
1592    call    dvmInterpHandleSparseSwitch
1593    movl    rSELF,%ecx
1594    ADVANCE_PC_INDEXED %eax
1595    movl    offThread_curHandlerTable(%ecx),rIBASE
1596    FETCH_INST
1597#if defined(WITH_JIT)
1598    GET_JIT_PROF_TABLE %ecx %eax
1599    cmp         $0, %eax
1600    jne         common_updateProfile # set up %ebx & %edx & rPC
1601#endif
1602    GOTO_NEXT
1603
1604
1605/* ------------------------------ */
1606.L_OP_CMPL_FLOAT: /* 0x2d */
1607/* File: x86/OP_CMPL_FLOAT.S */
1608/* File: x86/OP_CMPG_DOUBLE.S */
1609    /* float/double_cmp[gl] vAA, vBB, vCC */
1610    movzbl    3(rPC),%eax             # eax<- CC
1611    movzbl    2(rPC),%ecx             # ecx<- BB
1612    .if 0
1613    fldl     (rFP,%eax,4)
1614    fldl     (rFP,%ecx,4)
1615    .else
1616    flds     (rFP,%eax,4)
1617    flds     (rFP,%ecx,4)
1618    .endif
1619    xorl     %ecx,%ecx
1620    fucompp     # z if equal, p set if NaN, c set if st0 < st1
1621    fnstsw   %ax
1622    sahf
1623    FETCH_INST_OPCODE 2 %eax
1624    jp       .LOP_CMPL_FLOAT_isNaN
1625    je       .LOP_CMPL_FLOAT_finish
1626    sbbl     %ecx,%ecx
1627    jb       .LOP_CMPL_FLOAT_finish
1628    incl     %ecx
1629.LOP_CMPL_FLOAT_finish:
1630    SET_VREG %ecx rINST
1631    ADVANCE_PC 2
1632    GOTO_NEXT_R %eax
1633
1634.LOP_CMPL_FLOAT_isNaN:
1635    movl      $-1,%ecx
1636    jmp       .LOP_CMPL_FLOAT_finish
1637
1638
1639/* ------------------------------ */
1640.L_OP_CMPG_FLOAT: /* 0x2e */
1641/* File: x86/OP_CMPG_FLOAT.S */
1642/* File: x86/OP_CMPG_DOUBLE.S */
1643    /* float/double_cmp[gl] vAA, vBB, vCC */
1644    movzbl    3(rPC),%eax             # eax<- CC
1645    movzbl    2(rPC),%ecx             # ecx<- BB
1646    .if 0
1647    fldl     (rFP,%eax,4)
1648    fldl     (rFP,%ecx,4)
1649    .else
1650    flds     (rFP,%eax,4)
1651    flds     (rFP,%ecx,4)
1652    .endif
1653    xorl     %ecx,%ecx
1654    fucompp     # z if equal, p set if NaN, c set if st0 < st1
1655    fnstsw   %ax
1656    sahf
1657    FETCH_INST_OPCODE 2 %eax
1658    jp       .LOP_CMPG_FLOAT_isNaN
1659    je       .LOP_CMPG_FLOAT_finish
1660    sbbl     %ecx,%ecx
1661    jb       .LOP_CMPG_FLOAT_finish
1662    incl     %ecx
1663.LOP_CMPG_FLOAT_finish:
1664    SET_VREG %ecx rINST
1665    ADVANCE_PC 2
1666    GOTO_NEXT_R %eax
1667
1668.LOP_CMPG_FLOAT_isNaN:
1669    movl      $1,%ecx
1670    jmp       .LOP_CMPG_FLOAT_finish
1671
1672
1673/* ------------------------------ */
1674.L_OP_CMPL_DOUBLE: /* 0x2f */
1675/* File: x86/OP_CMPL_DOUBLE.S */
1676/* File: x86/OP_CMPG_DOUBLE.S */
1677    /* float/double_cmp[gl] vAA, vBB, vCC */
1678    movzbl    3(rPC),%eax             # eax<- CC
1679    movzbl    2(rPC),%ecx             # ecx<- BB
1680    .if 1
1681    fldl     (rFP,%eax,4)
1682    fldl     (rFP,%ecx,4)
1683    .else
1684    flds     (rFP,%eax,4)
1685    flds     (rFP,%ecx,4)
1686    .endif
1687    xorl     %ecx,%ecx
1688    fucompp     # z if equal, p set if NaN, c set if st0 < st1
1689    fnstsw   %ax
1690    sahf
1691    FETCH_INST_OPCODE 2 %eax
1692    jp       .LOP_CMPL_DOUBLE_isNaN
1693    je       .LOP_CMPL_DOUBLE_finish
1694    sbbl     %ecx,%ecx
1695    jb       .LOP_CMPL_DOUBLE_finish
1696    incl     %ecx
1697.LOP_CMPL_DOUBLE_finish:
1698    SET_VREG %ecx rINST
1699    ADVANCE_PC 2
1700    GOTO_NEXT_R %eax
1701
1702.LOP_CMPL_DOUBLE_isNaN:
1703    movl      $-1,%ecx
1704    jmp       .LOP_CMPL_DOUBLE_finish
1705
1706
1707/* ------------------------------ */
1708.L_OP_CMPG_DOUBLE: /* 0x30 */
1709/* File: x86/OP_CMPG_DOUBLE.S */
1710    /* float/double_cmp[gl] vAA, vBB, vCC */
1711    movzbl    3(rPC),%eax             # eax<- CC
1712    movzbl    2(rPC),%ecx             # ecx<- BB
1713    .if 1
1714    fldl     (rFP,%eax,4)
1715    fldl     (rFP,%ecx,4)
1716    .else
1717    flds     (rFP,%eax,4)
1718    flds     (rFP,%ecx,4)
1719    .endif
1720    xorl     %ecx,%ecx
1721    fucompp     # z if equal, p set if NaN, c set if st0 < st1
1722    fnstsw   %ax
1723    sahf
1724    FETCH_INST_OPCODE 2 %eax
1725    jp       .LOP_CMPG_DOUBLE_isNaN
1726    je       .LOP_CMPG_DOUBLE_finish
1727    sbbl     %ecx,%ecx
1728    jb       .LOP_CMPG_DOUBLE_finish
1729    incl     %ecx
1730.LOP_CMPG_DOUBLE_finish:
1731    SET_VREG %ecx rINST
1732    ADVANCE_PC 2
1733    GOTO_NEXT_R %eax
1734
1735.LOP_CMPG_DOUBLE_isNaN:
1736    movl      $1,%ecx
1737    jmp       .LOP_CMPG_DOUBLE_finish
1738
1739/* ------------------------------ */
1740.L_OP_CMP_LONG: /* 0x31 */
1741/* File: x86/OP_CMP_LONG.S */
1742    /*
1743     * Compare two 64-bit values.  Puts 0, 1, or -1 into the destination
1744     * register based on the results of the comparison.
1745     */
1746    // TUNING: rework to avoid rIBASE spill
1747    /* cmp-long vAA, vBB, vCC */
1748    movzbl    2(rPC),%ecx              # ecx<- BB
1749    SPILL(rIBASE)
1750    movzbl    3(rPC),rIBASE            # rIBASE- CC
1751    GET_VREG_WORD %eax %ecx,1          # eax<- v[BB+1]
1752    GET_VREG_WORD %ecx %ecx 0          # ecx<- v[BB+0]
1753    cmpl      4(rFP,rIBASE,4),%eax
1754    jl        .LOP_CMP_LONG_smaller
1755    jg        .LOP_CMP_LONG_bigger
1756    sub       (rFP,rIBASE,4),%ecx
1757    ja        .LOP_CMP_LONG_bigger
1758    jb        .LOP_CMP_LONG_smaller
1759    SET_VREG %ecx rINST
1760    FETCH_INST_OPCODE 2 %ecx
1761    UNSPILL(rIBASE)
1762    ADVANCE_PC 2
1763    GOTO_NEXT_R %ecx
1764
1765.LOP_CMP_LONG_bigger:
1766    movl      $1,%ecx
1767    SET_VREG %ecx rINST
1768    FETCH_INST_OPCODE 2 %ecx
1769    UNSPILL(rIBASE)
1770    ADVANCE_PC 2
1771    GOTO_NEXT_R %ecx
1772
1773.LOP_CMP_LONG_smaller:
1774    movl      $-1,%ecx
1775    SET_VREG %ecx rINST
1776    FETCH_INST_OPCODE 2 %ecx
1777    UNSPILL(rIBASE)
1778    ADVANCE_PC 2
1779    GOTO_NEXT_R %ecx
1780
1781/* ------------------------------ */
1782.L_OP_IF_EQ: /* 0x32 */
1783/* File: x86/OP_IF_EQ.S */
1784/* File: x86/bincmp.S */
1785    /*
1786     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1787     * fragment that specifies the *reverse* comparison to perform, e.g.
1788     * for "if-le" you would use "gt".
1789     *
1790     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1791     */
1792    /* if-cmp vA, vB, +CCCC */
1793    movzx    rINSTbl,%ecx          # ecx <- A+
1794    andb     $0xf,%cl             # ecx <- A
1795    GET_VREG_R %eax %ecx           # eax <- vA
1796    sarl     $4,rINST             # rINST<- B
1797    movl     rSELF,%ecx
1798    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1799    movl     $2,%eax              # assume not taken
1800    jne   1f
1801    movswl   2(rPC),%eax           # Get signed branch offset
18021:
1803    movl     offThread_curHandlerTable(%ecx),rIBASE
1804    FETCH_INST_INDEXED %eax
1805    ADVANCE_PC_INDEXED %eax
1806#if defined(WITH_JIT)
1807    GET_JIT_PROF_TABLE %ecx %eax
1808    cmp         $0, %eax
1809    jne         common_updateProfile # set up %ebx & %edx & rPC
1810#endif
1811    GOTO_NEXT
1812
1813
1814/* ------------------------------ */
1815.L_OP_IF_NE: /* 0x33 */
1816/* File: x86/OP_IF_NE.S */
1817/* File: x86/bincmp.S */
1818    /*
1819     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1820     * fragment that specifies the *reverse* comparison to perform, e.g.
1821     * for "if-le" you would use "gt".
1822     *
1823     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1824     */
1825    /* if-cmp vA, vB, +CCCC */
1826    movzx    rINSTbl,%ecx          # ecx <- A+
1827    andb     $0xf,%cl             # ecx <- A
1828    GET_VREG_R %eax %ecx           # eax <- vA
1829    sarl     $4,rINST             # rINST<- B
1830    movl     rSELF,%ecx
1831    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1832    movl     $2,%eax              # assume not taken
1833    je   1f
1834    movswl   2(rPC),%eax           # Get signed branch offset
18351:
1836    movl     offThread_curHandlerTable(%ecx),rIBASE
1837    FETCH_INST_INDEXED %eax
1838    ADVANCE_PC_INDEXED %eax
1839#if defined(WITH_JIT)
1840    GET_JIT_PROF_TABLE %ecx %eax
1841    cmp         $0, %eax
1842    jne         common_updateProfile # set up %ebx & %edx & rPC
1843#endif
1844    GOTO_NEXT
1845
1846
1847/* ------------------------------ */
1848.L_OP_IF_LT: /* 0x34 */
1849/* File: x86/OP_IF_LT.S */
1850/* File: x86/bincmp.S */
1851    /*
1852     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1853     * fragment that specifies the *reverse* comparison to perform, e.g.
1854     * for "if-le" you would use "gt".
1855     *
1856     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1857     */
1858    /* if-cmp vA, vB, +CCCC */
1859    movzx    rINSTbl,%ecx          # ecx <- A+
1860    andb     $0xf,%cl             # ecx <- A
1861    GET_VREG_R %eax %ecx           # eax <- vA
1862    sarl     $4,rINST             # rINST<- B
1863    movl     rSELF,%ecx
1864    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1865    movl     $2,%eax              # assume not taken
1866    jge   1f
1867    movswl   2(rPC),%eax           # Get signed branch offset
18681:
1869    movl     offThread_curHandlerTable(%ecx),rIBASE
1870    FETCH_INST_INDEXED %eax
1871    ADVANCE_PC_INDEXED %eax
1872#if defined(WITH_JIT)
1873    GET_JIT_PROF_TABLE %ecx %eax
1874    cmp         $0, %eax
1875    jne         common_updateProfile # set up %ebx & %edx & rPC
1876#endif
1877    GOTO_NEXT
1878
1879
1880/* ------------------------------ */
1881.L_OP_IF_GE: /* 0x35 */
1882/* File: x86/OP_IF_GE.S */
1883/* File: x86/bincmp.S */
1884    /*
1885     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1886     * fragment that specifies the *reverse* comparison to perform, e.g.
1887     * for "if-le" you would use "gt".
1888     *
1889     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1890     */
1891    /* if-cmp vA, vB, +CCCC */
1892    movzx    rINSTbl,%ecx          # ecx <- A+
1893    andb     $0xf,%cl             # ecx <- A
1894    GET_VREG_R %eax %ecx           # eax <- vA
1895    sarl     $4,rINST             # rINST<- B
1896    movl     rSELF,%ecx
1897    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1898    movl     $2,%eax              # assume not taken
1899    jl   1f
1900    movswl   2(rPC),%eax           # Get signed branch offset
19011:
1902    movl     offThread_curHandlerTable(%ecx),rIBASE
1903    FETCH_INST_INDEXED %eax
1904    ADVANCE_PC_INDEXED %eax
1905#if defined(WITH_JIT)
1906    GET_JIT_PROF_TABLE %ecx %eax
1907    cmp         $0, %eax
1908    jne         common_updateProfile # set up %ebx & %edx & rPC
1909#endif
1910    GOTO_NEXT
1911
1912
1913/* ------------------------------ */
1914.L_OP_IF_GT: /* 0x36 */
1915/* File: x86/OP_IF_GT.S */
1916/* File: x86/bincmp.S */
1917    /*
1918     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1919     * fragment that specifies the *reverse* comparison to perform, e.g.
1920     * for "if-le" you would use "gt".
1921     *
1922     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1923     */
1924    /* if-cmp vA, vB, +CCCC */
1925    movzx    rINSTbl,%ecx          # ecx <- A+
1926    andb     $0xf,%cl             # ecx <- A
1927    GET_VREG_R %eax %ecx           # eax <- vA
1928    sarl     $4,rINST             # rINST<- B
1929    movl     rSELF,%ecx
1930    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1931    movl     $2,%eax              # assume not taken
1932    jle   1f
1933    movswl   2(rPC),%eax           # Get signed branch offset
19341:
1935    movl     offThread_curHandlerTable(%ecx),rIBASE
1936    FETCH_INST_INDEXED %eax
1937    ADVANCE_PC_INDEXED %eax
1938#if defined(WITH_JIT)
1939    GET_JIT_PROF_TABLE %ecx %eax
1940    cmp         $0, %eax
1941    jne         common_updateProfile # set up %ebx & %edx & rPC
1942#endif
1943    GOTO_NEXT
1944
1945
1946/* ------------------------------ */
1947.L_OP_IF_LE: /* 0x37 */
1948/* File: x86/OP_IF_LE.S */
1949/* File: x86/bincmp.S */
1950    /*
1951     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1952     * fragment that specifies the *reverse* comparison to perform, e.g.
1953     * for "if-le" you would use "gt".
1954     *
1955     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1956     */
1957    /* if-cmp vA, vB, +CCCC */
1958    movzx    rINSTbl,%ecx          # ecx <- A+
1959    andb     $0xf,%cl             # ecx <- A
1960    GET_VREG_R %eax %ecx           # eax <- vA
1961    sarl     $4,rINST             # rINST<- B
1962    movl     rSELF,%ecx
1963    cmpl     (rFP,rINST,4),%eax    # compare (vA, vB)
1964    movl     $2,%eax              # assume not taken
1965    jg   1f
1966    movswl   2(rPC),%eax           # Get signed branch offset
19671:
1968    movl     offThread_curHandlerTable(%ecx),rIBASE
1969    FETCH_INST_INDEXED %eax
1970    ADVANCE_PC_INDEXED %eax
1971#if defined(WITH_JIT)
1972    GET_JIT_PROF_TABLE %ecx %eax
1973    cmp         $0, %eax
1974    jne         common_updateProfile # set up %ebx & %edx & rPC
1975#endif
1976    GOTO_NEXT
1977
1978
1979/* ------------------------------ */
1980.L_OP_IF_EQZ: /* 0x38 */
1981/* File: x86/OP_IF_EQZ.S */
1982/* File: x86/zcmp.S */
1983    /*
1984     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1985     * fragment that specifies the *reverse* comparison to perform, e.g.
1986     * for "if-le" you would use "gt".
1987     *
1988     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1989     */
1990    /* if-cmp vAA, +BBBB */
1991    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
1992    movl     rSELF,%ecx
1993    movl     $2,%eax              # assume branch not taken
1994    jne   1f
1995    movswl   2(rPC),%eax           # fetch signed displacement
1996    movl     offThread_curHandlerTable(%ecx),rIBASE
19971:
1998    FETCH_INST_INDEXED %eax
1999    ADVANCE_PC_INDEXED %eax
2000#if defined(WITH_JIT)
2001    GET_JIT_PROF_TABLE %ecx %eax
2002    cmp         $0, %eax
2003    jne         common_updateProfile # set up %ebx & %edx & rPC
2004#endif
2005    GOTO_NEXT
2006
2007
2008/* ------------------------------ */
2009.L_OP_IF_NEZ: /* 0x39 */
2010/* File: x86/OP_IF_NEZ.S */
2011/* File: x86/zcmp.S */
2012    /*
2013     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
2014     * fragment that specifies the *reverse* comparison to perform, e.g.
2015     * for "if-le" you would use "gt".
2016     *
2017     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
2018     */
2019    /* if-cmp vAA, +BBBB */
2020    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
2021    movl     rSELF,%ecx
2022    movl     $2,%eax              # assume branch not taken
2023    je   1f
2024    movswl   2(rPC),%eax           # fetch signed displacement
2025    movl     offThread_curHandlerTable(%ecx),rIBASE
20261:
2027    FETCH_INST_INDEXED %eax
2028    ADVANCE_PC_INDEXED %eax
2029#if defined(WITH_JIT)
2030    GET_JIT_PROF_TABLE %ecx %eax
2031    cmp         $0, %eax
2032    jne         common_updateProfile # set up %ebx & %edx & rPC
2033#endif
2034    GOTO_NEXT
2035
2036
2037/* ------------------------------ */
2038.L_OP_IF_LTZ: /* 0x3a */
2039/* File: x86/OP_IF_LTZ.S */
2040/* File: x86/zcmp.S */
2041    /*
2042     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
2043     * fragment that specifies the *reverse* comparison to perform, e.g.
2044     * for "if-le" you would use "gt".
2045     *
2046     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
2047     */
2048    /* if-cmp vAA, +BBBB */
2049    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
2050    movl     rSELF,%ecx
2051    movl     $2,%eax              # assume branch not taken
2052    jge   1f
2053    movswl   2(rPC),%eax           # fetch signed displacement
2054    movl     offThread_curHandlerTable(%ecx),rIBASE
20551:
2056    FETCH_INST_INDEXED %eax
2057    ADVANCE_PC_INDEXED %eax
2058#if defined(WITH_JIT)
2059    GET_JIT_PROF_TABLE %ecx %eax
2060    cmp         $0, %eax
2061    jne         common_updateProfile # set up %ebx & %edx & rPC
2062#endif
2063    GOTO_NEXT
2064
2065
2066/* ------------------------------ */
2067.L_OP_IF_GEZ: /* 0x3b */
2068/* File: x86/OP_IF_GEZ.S */
2069/* File: x86/zcmp.S */
2070    /*
2071     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
2072     * fragment that specifies the *reverse* comparison to perform, e.g.
2073     * for "if-le" you would use "gt".
2074     *
2075     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
2076     */
2077    /* if-cmp vAA, +BBBB */
2078    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
2079    movl     rSELF,%ecx
2080    movl     $2,%eax              # assume branch not taken
2081    jl   1f
2082    movswl   2(rPC),%eax           # fetch signed displacement
2083    movl     offThread_curHandlerTable(%ecx),rIBASE
20841:
2085    FETCH_INST_INDEXED %eax
2086    ADVANCE_PC_INDEXED %eax
2087#if defined(WITH_JIT)
2088    GET_JIT_PROF_TABLE %ecx %eax
2089    cmp         $0, %eax
2090    jne         common_updateProfile # set up %ebx & %edx & rPC
2091#endif
2092    GOTO_NEXT
2093
2094
2095/* ------------------------------ */
2096.L_OP_IF_GTZ: /* 0x3c */
2097/* File: x86/OP_IF_GTZ.S */
2098/* File: x86/zcmp.S */
2099    /*
2100     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
2101     * fragment that specifies the *reverse* comparison to perform, e.g.
2102     * for "if-le" you would use "gt".
2103     *
2104     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
2105     */
2106    /* if-cmp vAA, +BBBB */
2107    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
2108    movl     rSELF,%ecx
2109    movl     $2,%eax              # assume branch not taken
2110    jle   1f
2111    movswl   2(rPC),%eax           # fetch signed displacement
2112    movl     offThread_curHandlerTable(%ecx),rIBASE
21131:
2114    FETCH_INST_INDEXED %eax
2115    ADVANCE_PC_INDEXED %eax
2116#if defined(WITH_JIT)
2117    GET_JIT_PROF_TABLE %ecx %eax
2118    cmp         $0, %eax
2119    jne         common_updateProfile # set up %ebx & %edx & rPC
2120#endif
2121    GOTO_NEXT
2122
2123
2124/* ------------------------------ */
2125.L_OP_IF_LEZ: /* 0x3d */
2126/* File: x86/OP_IF_LEZ.S */
2127/* File: x86/zcmp.S */
2128    /*
2129     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
2130     * fragment that specifies the *reverse* comparison to perform, e.g.
2131     * for "if-le" you would use "gt".
2132     *
2133     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
2134     */
2135    /* if-cmp vAA, +BBBB */
2136    cmpl     $0,(rFP,rINST,4)     # compare (vA, 0)
2137    movl     rSELF,%ecx
2138    movl     $2,%eax              # assume branch not taken
2139    jg   1f
2140    movswl   2(rPC),%eax           # fetch signed displacement
2141    movl     offThread_curHandlerTable(%ecx),rIBASE
21421:
2143    FETCH_INST_INDEXED %eax
2144    ADVANCE_PC_INDEXED %eax
2145#if defined(WITH_JIT)
2146    GET_JIT_PROF_TABLE %ecx %eax
2147    cmp         $0, %eax
2148    jne         common_updateProfile # set up %ebx & %edx & rPC
2149#endif
2150    GOTO_NEXT
2151
2152
2153/* ------------------------------ */
2154.L_OP_UNUSED_3E: /* 0x3e */
2155/* File: x86/OP_UNUSED_3E.S */
2156/* File: x86/unused.S */
2157    jmp     common_abort
2158
2159
2160/* ------------------------------ */
2161.L_OP_UNUSED_3F: /* 0x3f */
2162/* File: x86/OP_UNUSED_3F.S */
2163/* File: x86/unused.S */
2164    jmp     common_abort
2165
2166
2167/* ------------------------------ */
2168.L_OP_UNUSED_40: /* 0x40 */
2169/* File: x86/OP_UNUSED_40.S */
2170/* File: x86/unused.S */
2171    jmp     common_abort
2172
2173
2174/* ------------------------------ */
2175.L_OP_UNUSED_41: /* 0x41 */
2176/* File: x86/OP_UNUSED_41.S */
2177/* File: x86/unused.S */
2178    jmp     common_abort
2179
2180
2181/* ------------------------------ */
2182.L_OP_UNUSED_42: /* 0x42 */
2183/* File: x86/OP_UNUSED_42.S */
2184/* File: x86/unused.S */
2185    jmp     common_abort
2186
2187
2188/* ------------------------------ */
2189.L_OP_UNUSED_43: /* 0x43 */
2190/* File: x86/OP_UNUSED_43.S */
2191/* File: x86/unused.S */
2192    jmp     common_abort
2193
2194
2195/* ------------------------------ */
2196.L_OP_AGET: /* 0x44 */
2197/* File: x86/OP_AGET.S */
2198    /*
2199     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2200     *
2201     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2202     */
2203    /* op vAA, vBB, vCC */
2204    movzbl    2(rPC),%eax               # eax<- BB
2205    movzbl    3(rPC),%ecx               # ecx<- CC
2206    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2207    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2208    testl     %eax,%eax                 # null array object?
2209    je        common_errNullObject      # bail if so
2210    cmpl      offArrayObject_length(%eax),%ecx
2211    jae       common_errArrayIndex      # index >= length, bail.  Expects
2212                                        #    arrayObj in eax
2213                                        #    index in ecx
2214    movl     offArrayObject_contents(%eax,%ecx,4),%eax
2215.LOP_AGET_finish:
2216    FETCH_INST_OPCODE 2 %ecx
2217    SET_VREG  %eax rINST
2218    ADVANCE_PC 2
2219    GOTO_NEXT_R %ecx
2220
2221/* ------------------------------ */
2222.L_OP_AGET_WIDE: /* 0x45 */
2223/* File: x86/OP_AGET_WIDE.S */
2224    /*
2225     * Array get, 64 bits.  vAA <- vBB[vCC].
2226     *
2227     */
2228    /* op vAA, vBB, vCC */
2229    movzbl    2(rPC),%eax               # eax<- BB
2230    movzbl    3(rPC),%ecx               # ecx<- CC
2231    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2232    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2233    testl     %eax,%eax                 # null array object?
2234    je        common_errNullObject      # bail if so
2235    cmpl      offArrayObject_length(%eax),%ecx
2236    jae       common_errArrayIndex      # index >= length, bail.  Expects
2237                                        #    arrayObj in eax
2238                                        #    index in ecx
2239    leal      offArrayObject_contents(%eax,%ecx,8),%eax
2240    movl      (%eax),%ecx
2241    movl      4(%eax),%eax
2242    SET_VREG_WORD %ecx rINST 0
2243    SET_VREG_WORD %eax rINST 1
2244    FETCH_INST_OPCODE 2 %ecx
2245    ADVANCE_PC 2
2246    GOTO_NEXT_R %ecx
2247
2248/* ------------------------------ */
2249.L_OP_AGET_OBJECT: /* 0x46 */
2250/* File: x86/OP_AGET_OBJECT.S */
2251/* File: x86/OP_AGET.S */
2252    /*
2253     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2254     *
2255     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2256     */
2257    /* op vAA, vBB, vCC */
2258    movzbl    2(rPC),%eax               # eax<- BB
2259    movzbl    3(rPC),%ecx               # ecx<- CC
2260    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2261    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2262    testl     %eax,%eax                 # null array object?
2263    je        common_errNullObject      # bail if so
2264    cmpl      offArrayObject_length(%eax),%ecx
2265    jae       common_errArrayIndex      # index >= length, bail.  Expects
2266                                        #    arrayObj in eax
2267                                        #    index in ecx
2268    movl     offArrayObject_contents(%eax,%ecx,4),%eax
2269.LOP_AGET_OBJECT_finish:
2270    FETCH_INST_OPCODE 2 %ecx
2271    SET_VREG  %eax rINST
2272    ADVANCE_PC 2
2273    GOTO_NEXT_R %ecx
2274
2275
2276/* ------------------------------ */
2277.L_OP_AGET_BOOLEAN: /* 0x47 */
2278/* File: x86/OP_AGET_BOOLEAN.S */
2279/* File: x86/OP_AGET.S */
2280    /*
2281     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2282     *
2283     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2284     */
2285    /* op vAA, vBB, vCC */
2286    movzbl    2(rPC),%eax               # eax<- BB
2287    movzbl    3(rPC),%ecx               # ecx<- CC
2288    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2289    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2290    testl     %eax,%eax                 # null array object?
2291    je        common_errNullObject      # bail if so
2292    cmpl      offArrayObject_length(%eax),%ecx
2293    jae       common_errArrayIndex      # index >= length, bail.  Expects
2294                                        #    arrayObj in eax
2295                                        #    index in ecx
2296    movzbl     offArrayObject_contents(%eax,%ecx,1),%eax
2297.LOP_AGET_BOOLEAN_finish:
2298    FETCH_INST_OPCODE 2 %ecx
2299    SET_VREG  %eax rINST
2300    ADVANCE_PC 2
2301    GOTO_NEXT_R %ecx
2302
2303
2304/* ------------------------------ */
2305.L_OP_AGET_BYTE: /* 0x48 */
2306/* File: x86/OP_AGET_BYTE.S */
2307/* File: x86/OP_AGET.S */
2308    /*
2309     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2310     *
2311     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2312     */
2313    /* op vAA, vBB, vCC */
2314    movzbl    2(rPC),%eax               # eax<- BB
2315    movzbl    3(rPC),%ecx               # ecx<- CC
2316    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2317    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2318    testl     %eax,%eax                 # null array object?
2319    je        common_errNullObject      # bail if so
2320    cmpl      offArrayObject_length(%eax),%ecx
2321    jae       common_errArrayIndex      # index >= length, bail.  Expects
2322                                        #    arrayObj in eax
2323                                        #    index in ecx
2324    movsbl     offArrayObject_contents(%eax,%ecx,1),%eax
2325.LOP_AGET_BYTE_finish:
2326    FETCH_INST_OPCODE 2 %ecx
2327    SET_VREG  %eax rINST
2328    ADVANCE_PC 2
2329    GOTO_NEXT_R %ecx
2330
2331
2332/* ------------------------------ */
2333.L_OP_AGET_CHAR: /* 0x49 */
2334/* File: x86/OP_AGET_CHAR.S */
2335/* File: x86/OP_AGET.S */
2336    /*
2337     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2338     *
2339     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2340     */
2341    /* op vAA, vBB, vCC */
2342    movzbl    2(rPC),%eax               # eax<- BB
2343    movzbl    3(rPC),%ecx               # ecx<- CC
2344    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2345    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2346    testl     %eax,%eax                 # null array object?
2347    je        common_errNullObject      # bail if so
2348    cmpl      offArrayObject_length(%eax),%ecx
2349    jae       common_errArrayIndex      # index >= length, bail.  Expects
2350                                        #    arrayObj in eax
2351                                        #    index in ecx
2352    movzwl     offArrayObject_contents(%eax,%ecx,2),%eax
2353.LOP_AGET_CHAR_finish:
2354    FETCH_INST_OPCODE 2 %ecx
2355    SET_VREG  %eax rINST
2356    ADVANCE_PC 2
2357    GOTO_NEXT_R %ecx
2358
2359
2360/* ------------------------------ */
2361.L_OP_AGET_SHORT: /* 0x4a */
2362/* File: x86/OP_AGET_SHORT.S */
2363/* File: x86/OP_AGET.S */
2364    /*
2365     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2366     *
2367     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2368     */
2369    /* op vAA, vBB, vCC */
2370    movzbl    2(rPC),%eax               # eax<- BB
2371    movzbl    3(rPC),%ecx               # ecx<- CC
2372    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2373    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2374    testl     %eax,%eax                 # null array object?
2375    je        common_errNullObject      # bail if so
2376    cmpl      offArrayObject_length(%eax),%ecx
2377    jae       common_errArrayIndex      # index >= length, bail.  Expects
2378                                        #    arrayObj in eax
2379                                        #    index in ecx
2380    movswl     offArrayObject_contents(%eax,%ecx,2),%eax
2381.LOP_AGET_SHORT_finish:
2382    FETCH_INST_OPCODE 2 %ecx
2383    SET_VREG  %eax rINST
2384    ADVANCE_PC 2
2385    GOTO_NEXT_R %ecx
2386
2387
2388/* ------------------------------ */
2389.L_OP_APUT: /* 0x4b */
2390/* File: x86/OP_APUT.S */
2391    /*
2392     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2393     *
2394     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2395     */
2396    /* op vAA, vBB, vCC */
2397    movzbl    2(rPC),%eax               # eax<- BB
2398    movzbl    3(rPC),%ecx               # ecx<- CC
2399    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2400    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2401    testl     %eax,%eax                 # null array object?
2402    je        common_errNullObject      # bail if so
2403    cmpl      offArrayObject_length(%eax),%ecx
2404    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2405                                        #   arrayObj in eax
2406                                        #   index in ecx
2407    leal      offArrayObject_contents(%eax,%ecx,4),%eax
2408.LOP_APUT_finish:
2409    GET_VREG_R  rINST rINST
2410    FETCH_INST_OPCODE 2 %ecx
2411    movl     rINST,(%eax)
2412    ADVANCE_PC 2
2413    GOTO_NEXT_R %ecx
2414
2415/* ------------------------------ */
2416.L_OP_APUT_WIDE: /* 0x4c */
2417/* File: x86/OP_APUT_WIDE.S */
2418    /*
2419     * Array put, 64 bits.  vBB[vCC]<-vAA.
2420     *
2421     */
2422    /* op vAA, vBB, vCC */
2423    movzbl    2(rPC),%eax               # eax<- BB
2424    movzbl    3(rPC),%ecx               # ecx<- CC
2425    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2426    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2427    testl     %eax,%eax                 # null array object?
2428    je        common_errNullObject      # bail if so
2429    cmpl      offArrayObject_length(%eax),%ecx
2430    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2431                                        #   arrayObj in eax
2432                                        #   index in ecx
2433    leal      offArrayObject_contents(%eax,%ecx,8),%eax
2434    GET_VREG_WORD %ecx rINST 0
2435    GET_VREG_WORD rINST rINST 1
2436    movl      %ecx,(%eax)
2437    FETCH_INST_OPCODE 2 %ecx
2438    movl      rINST,4(%eax)
2439    ADVANCE_PC 2
2440    GOTO_NEXT_R %ecx
2441
2442/* ------------------------------ */
2443.L_OP_APUT_OBJECT: /* 0x4d */
2444/* File: x86/OP_APUT_OBJECT.S */
2445    /*
2446     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2447     *
2448     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2449     */
2450    /* op vAA, vBB, vCC */
2451    movzbl    2(rPC),%eax               # eax<- BB
2452    movzbl    3(rPC),%ecx               # ecx<- CC
2453    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2454    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2455    GET_VREG_R  rINST rINST             # rINST<- vAA
2456    testl     %eax,%eax                 # null array object?
2457    je        common_errNullObject      # bail if so
2458    cmpl      offArrayObject_length(%eax),%ecx
2459    jae       common_errArrayIndex      # index >= length, bail.  Expects
2460                                        #    arrayObj in eax
2461                                        #    index in ecx
2462    /* On entry:
2463     *   eax<- array object
2464     *   ecx<- index
2465     *   rINST<- vAA
2466     */
2467    leal      offArrayObject_contents(%eax,%ecx,4),%ecx
2468    testl     rINST,rINST                    # storing null reference?
2469    je        .LOP_APUT_OBJECT_skip_check
2470    SPILL_TMP1(%ecx)                         # save target address
2471    SPILL_TMP2(%eax)                         # save object head
2472    movl      offObject_clazz(%eax),%eax     # eax<- arrayObj->clazz
2473    movl      offObject_clazz(rINST),%ecx    # ecx<- obj->clazz
2474    movl      %eax,OUT_ARG1(%esp)
2475    movl      %ecx,OUT_ARG0(%esp)
2476    movl      %ecx,sReg0                     # store the two classes for later
2477    movl      %eax,sReg1
2478    SPILL(rIBASE)
2479    call      dvmCanPutArrayElement          # test object type vs. array type
2480    UNSPILL(rIBASE)
2481    UNSPILL_TMP1(%ecx)                       # recover target address
2482    testl     %eax,%eax
2483    movl      rSELF,%eax
2484    jne       .LOP_APUT_OBJECT_types_okay
2485
2486    # The types don't match.  We need to throw an ArrayStoreException.
2487    EXPORT_PC
2488    movl      sReg0,%eax                     # restore the two classes...
2489    movl      %eax,OUT_ARG0(%esp)
2490    movl      sReg1,%ecx
2491    movl      %ecx,OUT_ARG1(%esp)
2492    call      dvmThrowArrayStoreExceptionIncompatibleElement # ...and throw
2493    jmp       common_exceptionThrown
2494
2495.LOP_APUT_OBJECT_types_okay:
2496    movl      offThread_cardTable(%eax),%eax   # get card table base
2497    movl      rINST,(%ecx)                   # store into array
2498    UNSPILL_TMP2(rINST)                      # recover object head
2499    FETCH_INST_OPCODE 2 %ecx
2500    shrl      $GC_CARD_SHIFT,rINST          # object head to card number
2501    movb      %al,(%eax,rINST)               # mark card using object head
2502    ADVANCE_PC 2
2503    GOTO_NEXT_R %ecx
2504
2505.LOP_APUT_OBJECT_skip_check:
2506    movl      rINST,(%ecx)
2507    FETCH_INST_OPCODE 2 %ecx
2508    ADVANCE_PC 2
2509    GOTO_NEXT_R %ecx
2510
2511/* ------------------------------ */
2512.L_OP_APUT_BOOLEAN: /* 0x4e */
2513/* File: x86/OP_APUT_BOOLEAN.S */
2514/* File: x86/OP_APUT.S */
2515    /*
2516     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2517     *
2518     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2519     */
2520    /* op vAA, vBB, vCC */
2521    movzbl    2(rPC),%eax               # eax<- BB
2522    movzbl    3(rPC),%ecx               # ecx<- CC
2523    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2524    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2525    testl     %eax,%eax                 # null array object?
2526    je        common_errNullObject      # bail if so
2527    cmpl      offArrayObject_length(%eax),%ecx
2528    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2529                                        #   arrayObj in eax
2530                                        #   index in ecx
2531    leal      offArrayObject_contents(%eax,%ecx,1),%eax
2532.LOP_APUT_BOOLEAN_finish:
2533    GET_VREG_R  rINST rINST
2534    FETCH_INST_OPCODE 2 %ecx
2535    movb     rINSTbl,(%eax)
2536    ADVANCE_PC 2
2537    GOTO_NEXT_R %ecx
2538
2539
2540/* ------------------------------ */
2541.L_OP_APUT_BYTE: /* 0x4f */
2542/* File: x86/OP_APUT_BYTE.S */
2543/* File: x86/OP_APUT.S */
2544    /*
2545     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2546     *
2547     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2548     */
2549    /* op vAA, vBB, vCC */
2550    movzbl    2(rPC),%eax               # eax<- BB
2551    movzbl    3(rPC),%ecx               # ecx<- CC
2552    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2553    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2554    testl     %eax,%eax                 # null array object?
2555    je        common_errNullObject      # bail if so
2556    cmpl      offArrayObject_length(%eax),%ecx
2557    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2558                                        #   arrayObj in eax
2559                                        #   index in ecx
2560    leal      offArrayObject_contents(%eax,%ecx,1),%eax
2561.LOP_APUT_BYTE_finish:
2562    GET_VREG_R  rINST rINST
2563    FETCH_INST_OPCODE 2 %ecx
2564    movb     rINSTbl,(%eax)
2565    ADVANCE_PC 2
2566    GOTO_NEXT_R %ecx
2567
2568
2569/* ------------------------------ */
2570.L_OP_APUT_CHAR: /* 0x50 */
2571/* File: x86/OP_APUT_CHAR.S */
2572/* File: x86/OP_APUT.S */
2573    /*
2574     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2575     *
2576     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2577     */
2578    /* op vAA, vBB, vCC */
2579    movzbl    2(rPC),%eax               # eax<- BB
2580    movzbl    3(rPC),%ecx               # ecx<- CC
2581    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2582    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2583    testl     %eax,%eax                 # null array object?
2584    je        common_errNullObject      # bail if so
2585    cmpl      offArrayObject_length(%eax),%ecx
2586    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2587                                        #   arrayObj in eax
2588                                        #   index in ecx
2589    leal      offArrayObject_contents(%eax,%ecx,2),%eax
2590.LOP_APUT_CHAR_finish:
2591    GET_VREG_R  rINST rINST
2592    FETCH_INST_OPCODE 2 %ecx
2593    movw     rINSTw,(%eax)
2594    ADVANCE_PC 2
2595    GOTO_NEXT_R %ecx
2596
2597
2598/* ------------------------------ */
2599.L_OP_APUT_SHORT: /* 0x51 */
2600/* File: x86/OP_APUT_SHORT.S */
2601/* File: x86/OP_APUT.S */
2602    /*
2603     * Array put, 32 bits or less.  vBB[vCC] <- vAA
2604     *
2605     * for: aput, aput-object, aput-boolean, aput-byte, aput-char, aput-short
2606     */
2607    /* op vAA, vBB, vCC */
2608    movzbl    2(rPC),%eax               # eax<- BB
2609    movzbl    3(rPC),%ecx               # ecx<- CC
2610    GET_VREG_R  %eax %eax               # eax<- vBB (array object)
2611    GET_VREG_R  %ecx %ecx               # ecs<- vCC (requested index)
2612    testl     %eax,%eax                 # null array object?
2613    je        common_errNullObject      # bail if so
2614    cmpl      offArrayObject_length(%eax),%ecx
2615    jae       common_errArrayIndex      # index >= length, bail.  Expects:
2616                                        #   arrayObj in eax
2617                                        #   index in ecx
2618    leal      offArrayObject_contents(%eax,%ecx,2),%eax
2619.LOP_APUT_SHORT_finish:
2620    GET_VREG_R  rINST rINST
2621    FETCH_INST_OPCODE 2 %ecx
2622    movw     rINSTw,(%eax)
2623    ADVANCE_PC 2
2624    GOTO_NEXT_R %ecx
2625
2626
2627/* ------------------------------ */
2628.L_OP_IGET: /* 0x52 */
2629/* File: x86/OP_IGET.S */
2630    /*
2631     * General 32-bit instance field get.
2632     *
2633     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2634     */
2635    /* op vA, vB, field@CCCC */
2636    movl    rSELF,%ecx
2637    SPILL(rIBASE)                               # preserve rIBASE
2638    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
2639    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
2640    movzbl  rINSTbl,%ecx                        # ecx<- BA
2641    sarl    $4,%ecx                            # ecx<- B
2642    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2643    andb    $0xf,rINSTbl                       # rINST<- A
2644    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2645    movl    (%eax,rIBASE,4),%eax                # resolved entry
2646    testl   %eax,%eax                           # is resolved entry null?
2647    jne     .LOP_IGET_finish                  # no, already resolved
2648    movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
2649    movl    rSELF,rIBASE
2650    EXPORT_PC
2651    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
2652    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
2653    SPILL_TMP1(%ecx)                            # save obj pointer across call
2654    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
2655    call    dvmResolveInstField                 #  ... to dvmResolveInstField
2656    UNSPILL_TMP1(%ecx)
2657    testl   %eax,%eax                           #  returns InstrField ptr
2658    jne     .LOP_IGET_finish
2659    jmp     common_exceptionThrown
2660
2661.LOP_IGET_finish:
2662    /*
2663     * Currently:
2664     *   eax holds resolved field
2665     *   ecx holds object
2666     *   rINST holds A
2667     */
2668    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
2669    testl   %ecx,%ecx                           # object null?
2670    je      common_errNullObject                # object was null
2671    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
2672    FETCH_INST_OPCODE 2 %eax
2673    UNSPILL(rIBASE)
2674    SET_VREG %ecx rINST
2675    ADVANCE_PC 2
2676    GOTO_NEXT_R %eax
2677
2678/* ------------------------------ */
2679.L_OP_IGET_WIDE: /* 0x53 */
2680/* File: x86/OP_IGET_WIDE.S */
2681    /*
2682     * 64-bit instance field get.
2683     *
2684     */
2685    /* op vA, vB, field@CCCC */
2686    movl    rSELF,%ecx
2687    SPILL(rIBASE)                               # preserve rIBASE
2688    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
2689    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
2690    movzbl  rINSTbl,%ecx                        # ecx<- BA
2691    sarl    $4,%ecx                            # ecx<- B
2692    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2693    andb    $0xf,rINSTbl                       # rINST<- A
2694    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2695    movl    (%eax,rIBASE,4),%eax                # resolved entry
2696    testl   %eax,%eax                           # is resolved entry null?
2697    jne     .LOP_IGET_WIDE_finish                  # no, already resolved
2698    movl    rIBASE,OUT_ARG1(%esp)               # for dvmResolveInstField
2699    movl    rSELF,rIBASE
2700    EXPORT_PC
2701    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
2702    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
2703    SPILL_TMP1(%ecx)                            # save objpointer across call
2704    movl    rPC,OUT_ARG0(%esp)                  # pass in method->clazz
2705    call    dvmResolveInstField                 #  ... to dvmResolveInstField
2706    UNSPILL_TMP1(%ecx)
2707    testl   %eax,%eax                           # returns InstrField ptr
2708    jne     .LOP_IGET_WIDE_finish
2709    jmp     common_exceptionThrown
2710
2711.LOP_IGET_WIDE_finish:
2712    /*
2713     * Currently:
2714     *   eax holds resolved field
2715     *   ecx holds object
2716     *   rINST holds A
2717     */
2718    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
2719    testl   %ecx,%ecx                           # object null?
2720    je      common_errNullObject                # object was null
2721    leal    (%ecx,%eax,1),%eax                  # eax<- address of field
2722    movl    (%eax),%ecx                         # ecx<- lsw
2723    movl    4(%eax),%eax                        # eax<- msw
2724    SET_VREG_WORD %ecx rINST 0
2725    FETCH_INST_OPCODE 2 %ecx
2726    UNSPILL(rIBASE)                             # restore rIBASE
2727    SET_VREG_WORD %eax rINST 1
2728    ADVANCE_PC 2
2729    GOTO_NEXT_R %ecx
2730
2731/* ------------------------------ */
2732.L_OP_IGET_OBJECT: /* 0x54 */
2733/* File: x86/OP_IGET_OBJECT.S */
2734/* File: x86/OP_IGET.S */
2735    /*
2736     * General 32-bit instance field get.
2737     *
2738     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2739     */
2740    /* op vA, vB, field@CCCC */
2741    movl    rSELF,%ecx
2742    SPILL(rIBASE)                               # preserve rIBASE
2743    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
2744    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
2745    movzbl  rINSTbl,%ecx                        # ecx<- BA
2746    sarl    $4,%ecx                            # ecx<- B
2747    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2748    andb    $0xf,rINSTbl                       # rINST<- A
2749    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2750    movl    (%eax,rIBASE,4),%eax                # resolved entry
2751    testl   %eax,%eax                           # is resolved entry null?
2752    jne     .LOP_IGET_OBJECT_finish                  # no, already resolved
2753    movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
2754    movl    rSELF,rIBASE
2755    EXPORT_PC
2756    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
2757    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
2758    SPILL_TMP1(%ecx)                            # save obj pointer across call
2759    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
2760    call    dvmResolveInstField                 #  ... to dvmResolveInstField
2761    UNSPILL_TMP1(%ecx)
2762    testl   %eax,%eax                           #  returns InstrField ptr
2763    jne     .LOP_IGET_OBJECT_finish
2764    jmp     common_exceptionThrown
2765
2766.LOP_IGET_OBJECT_finish:
2767    /*
2768     * Currently:
2769     *   eax holds resolved field
2770     *   ecx holds object
2771     *   rINST holds A
2772     */
2773    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
2774    testl   %ecx,%ecx                           # object null?
2775    je      common_errNullObject                # object was null
2776    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
2777    FETCH_INST_OPCODE 2 %eax
2778    UNSPILL(rIBASE)
2779    SET_VREG %ecx rINST
2780    ADVANCE_PC 2
2781    GOTO_NEXT_R %eax
2782
2783
2784/* ------------------------------ */
2785.L_OP_IGET_BOOLEAN: /* 0x55 */
2786/* File: x86/OP_IGET_BOOLEAN.S */
2787/* File: x86/OP_IGET.S */
2788    /*
2789     * General 32-bit instance field get.
2790     *
2791     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2792     */
2793    /* op vA, vB, field@CCCC */
2794    movl    rSELF,%ecx
2795    SPILL(rIBASE)                               # preserve rIBASE
2796    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
2797    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
2798    movzbl  rINSTbl,%ecx                        # ecx<- BA
2799    sarl    $4,%ecx                            # ecx<- B
2800    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2801    andb    $0xf,rINSTbl                       # rINST<- A
2802    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2803    movl    (%eax,rIBASE,4),%eax                # resolved entry
2804    testl   %eax,%eax                           # is resolved entry null?
2805    jne     .LOP_IGET_BOOLEAN_finish                  # no, already resolved
2806    movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
2807    movl    rSELF,rIBASE
2808    EXPORT_PC
2809    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
2810    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
2811    SPILL_TMP1(%ecx)                            # save obj pointer across call
2812    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
2813    call    dvmResolveInstField                 #  ... to dvmResolveInstField
2814    UNSPILL_TMP1(%ecx)
2815    testl   %eax,%eax                           #  returns InstrField ptr
2816    jne     .LOP_IGET_BOOLEAN_finish
2817    jmp     common_exceptionThrown
2818
2819.LOP_IGET_BOOLEAN_finish:
2820    /*
2821     * Currently:
2822     *   eax holds resolved field
2823     *   ecx holds object
2824     *   rINST holds A
2825     */
2826    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
2827    testl   %ecx,%ecx                           # object null?
2828    je      common_errNullObject                # object was null
2829    movzbl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
2830    FETCH_INST_OPCODE 2 %eax
2831    UNSPILL(rIBASE)
2832    SET_VREG %ecx rINST
2833    ADVANCE_PC 2
2834    GOTO_NEXT_R %eax
2835
2836
2837/* ------------------------------ */
2838.L_OP_IGET_BYTE: /* 0x56 */
2839/* File: x86/OP_IGET_BYTE.S */
2840/* File: x86/OP_IGET.S */
2841    /*
2842     * General 32-bit instance field get.
2843     *
2844     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2845     */
2846    /* op vA, vB, field@CCCC */
2847    movl    rSELF,%ecx
2848    SPILL(rIBASE)                               # preserve rIBASE
2849    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
2850    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
2851    movzbl  rINSTbl,%ecx                        # ecx<- BA
2852    sarl    $4,%ecx                            # ecx<- B
2853    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2854    andb    $0xf,rINSTbl                       # rINST<- A
2855    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2856    movl    (%eax,rIBASE,4),%eax                # resolved entry
2857    testl   %eax,%eax                           # is resolved entry null?
2858    jne     .LOP_IGET_BYTE_finish                  # no, already resolved
2859    movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
2860    movl    rSELF,rIBASE
2861    EXPORT_PC
2862    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
2863    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
2864    SPILL_TMP1(%ecx)                            # save obj pointer across call
2865    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
2866    call    dvmResolveInstField                 #  ... to dvmResolveInstField
2867    UNSPILL_TMP1(%ecx)
2868    testl   %eax,%eax                           #  returns InstrField ptr
2869    jne     .LOP_IGET_BYTE_finish
2870    jmp     common_exceptionThrown
2871
2872.LOP_IGET_BYTE_finish:
2873    /*
2874     * Currently:
2875     *   eax holds resolved field
2876     *   ecx holds object
2877     *   rINST holds A
2878     */
2879    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
2880    testl   %ecx,%ecx                           # object null?
2881    je      common_errNullObject                # object was null
2882    movsbl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
2883    FETCH_INST_OPCODE 2 %eax
2884    UNSPILL(rIBASE)
2885    SET_VREG %ecx rINST
2886    ADVANCE_PC 2
2887    GOTO_NEXT_R %eax
2888
2889
2890/* ------------------------------ */
2891.L_OP_IGET_CHAR: /* 0x57 */
2892/* File: x86/OP_IGET_CHAR.S */
2893/* File: x86/OP_IGET.S */
2894    /*
2895     * General 32-bit instance field get.
2896     *
2897     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2898     */
2899    /* op vA, vB, field@CCCC */
2900    movl    rSELF,%ecx
2901    SPILL(rIBASE)                               # preserve rIBASE
2902    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
2903    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
2904    movzbl  rINSTbl,%ecx                        # ecx<- BA
2905    sarl    $4,%ecx                            # ecx<- B
2906    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2907    andb    $0xf,rINSTbl                       # rINST<- A
2908    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2909    movl    (%eax,rIBASE,4),%eax                # resolved entry
2910    testl   %eax,%eax                           # is resolved entry null?
2911    jne     .LOP_IGET_CHAR_finish                  # no, already resolved
2912    movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
2913    movl    rSELF,rIBASE
2914    EXPORT_PC
2915    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
2916    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
2917    SPILL_TMP1(%ecx)                            # save obj pointer across call
2918    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
2919    call    dvmResolveInstField                 #  ... to dvmResolveInstField
2920    UNSPILL_TMP1(%ecx)
2921    testl   %eax,%eax                           #  returns InstrField ptr
2922    jne     .LOP_IGET_CHAR_finish
2923    jmp     common_exceptionThrown
2924
2925.LOP_IGET_CHAR_finish:
2926    /*
2927     * Currently:
2928     *   eax holds resolved field
2929     *   ecx holds object
2930     *   rINST holds A
2931     */
2932    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
2933    testl   %ecx,%ecx                           # object null?
2934    je      common_errNullObject                # object was null
2935    movzwl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
2936    FETCH_INST_OPCODE 2 %eax
2937    UNSPILL(rIBASE)
2938    SET_VREG %ecx rINST
2939    ADVANCE_PC 2
2940    GOTO_NEXT_R %eax
2941
2942
2943/* ------------------------------ */
2944.L_OP_IGET_SHORT: /* 0x58 */
2945/* File: x86/OP_IGET_SHORT.S */
2946/* File: x86/OP_IGET.S */
2947    /*
2948     * General 32-bit instance field get.
2949     *
2950     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2951     */
2952    /* op vA, vB, field@CCCC */
2953    movl    rSELF,%ecx
2954    SPILL(rIBASE)                               # preserve rIBASE
2955    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
2956    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
2957    movzbl  rINSTbl,%ecx                        # ecx<- BA
2958    sarl    $4,%ecx                            # ecx<- B
2959    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
2960    andb    $0xf,rINSTbl                       # rINST<- A
2961    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
2962    movl    (%eax,rIBASE,4),%eax                # resolved entry
2963    testl   %eax,%eax                           # is resolved entry null?
2964    jne     .LOP_IGET_SHORT_finish                  # no, already resolved
2965    movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
2966    movl    rSELF,rIBASE
2967    EXPORT_PC
2968    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
2969    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
2970    SPILL_TMP1(%ecx)                            # save obj pointer across call
2971    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
2972    call    dvmResolveInstField                 #  ... to dvmResolveInstField
2973    UNSPILL_TMP1(%ecx)
2974    testl   %eax,%eax                           #  returns InstrField ptr
2975    jne     .LOP_IGET_SHORT_finish
2976    jmp     common_exceptionThrown
2977
2978.LOP_IGET_SHORT_finish:
2979    /*
2980     * Currently:
2981     *   eax holds resolved field
2982     *   ecx holds object
2983     *   rINST holds A
2984     */
2985    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
2986    testl   %ecx,%ecx                           # object null?
2987    je      common_errNullObject                # object was null
2988    movswl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
2989    FETCH_INST_OPCODE 2 %eax
2990    UNSPILL(rIBASE)
2991    SET_VREG %ecx rINST
2992    ADVANCE_PC 2
2993    GOTO_NEXT_R %eax
2994
2995
2996/* ------------------------------ */
2997.L_OP_IPUT: /* 0x59 */
2998/* File: x86/OP_IPUT.S */
2999
3000    /*
3001     * General 32-bit instance field put.
3002     *
3003     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
3004     */
3005    /* op vA, vB, field@CCCC */
3006    movl    rSELF,%ecx
3007    SPILL   (rIBASE)
3008    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
3009    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
3010    movzbl  rINSTbl,%ecx                        # ecx<- BA
3011    sarl    $4,%ecx                            # ecx<- B
3012    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
3013    andb    $0xf,rINSTbl                       # rINST<- A
3014    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
3015    movl    (%eax,rIBASE,4),%eax                # resolved entry
3016    testl   %eax,%eax                           # is resolved entry null?
3017    jne     .LOP_IPUT_finish                  # no, already resolved
3018    movl    rIBASE,OUT_ARG1(%esp)
3019    movl    rSELF,rIBASE
3020    EXPORT_PC
3021    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
3022    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
3023    SPILL_TMP1(%ecx)                            # save obj pointer across call
3024    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
3025    call    dvmResolveInstField                 #  ... to dvmResolveInstField
3026    UNSPILL_TMP1(%ecx)
3027    testl   %eax,%eax                           # returns InstrField ptr
3028    jne     .LOP_IPUT_finish
3029    jmp     common_exceptionThrown
3030
3031.LOP_IPUT_finish:
3032    /*
3033     * Currently:
3034     *   eax holds resolved field
3035     *   ecx holds object
3036     *   rINST holds A
3037     */
3038    GET_VREG_R rINST rINST                       # rINST<- v[A]
3039    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
3040    testl   %ecx,%ecx                            # object null?
3041    je      common_errNullObject                 # object was null
3042    movl   rINST,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
3043    FETCH_INST_OPCODE 2 %ecx
3044    UNSPILL(rIBASE)
3045    ADVANCE_PC 2
3046    GOTO_NEXT_R %ecx
3047
3048/* ------------------------------ */
3049.L_OP_IPUT_WIDE: /* 0x5a */
3050/* File: x86/OP_IPUT_WIDE.S */
3051    /*
3052     * 64-bit instance field put.
3053     *
3054     */
3055    /* op vA, vB, field@CCCC */
3056    movl    rSELF,%ecx
3057    SPILL(rIBASE)
3058    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
3059    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
3060    movzbl  rINSTbl,%ecx                        # ecx<- BA
3061    sarl    $4,%ecx                            # ecx<- B
3062    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
3063    andb    $0xf,rINSTbl                       # rINST<- A
3064    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
3065    movl    (%eax,rIBASE,4),%eax                # resolved entry
3066    testl   %eax,%eax                           # is resolved entry null?
3067    jne     .LOP_IPUT_WIDE_finish                  # no, already resolved
3068    movl    rIBASE,OUT_ARG1(%esp)
3069    movl    rSELF,rIBASE
3070    EXPORT_PC
3071    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
3072    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
3073    SPILL_TMP1(%ecx)                            # save obj pointer across call
3074    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
3075    call    dvmResolveInstField                 #  ... to dvmResolveInstField
3076    UNSPILL_TMP1(%ecx)
3077    testl   %eax,%eax                           #  ... which returns InstrField ptr
3078    jne     .LOP_IPUT_WIDE_finish
3079    jmp     common_exceptionThrown
3080
3081.LOP_IPUT_WIDE_finish:
3082    /*
3083     * Currently:
3084     *   eax holds resolved field
3085     *   ecx holds object
3086     *   rIBASE is scratch, but needs to be unspilled
3087     *   rINST holds A
3088     */
3089    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
3090    testl   %ecx,%ecx                           # object null?
3091    je      common_errNullObject                # object was null
3092    leal    (%ecx,%eax,1),%eax                  # eax<- address of field
3093    GET_VREG_WORD %ecx rINST 0                  # ecx<- lsw
3094    GET_VREG_WORD rINST rINST 1                 # rINST<- msw
3095    movl    rINST,4(%eax)
3096    movl    %ecx,(%eax)
3097    FETCH_INST_OPCODE 2 %ecx
3098    UNSPILL(rIBASE)
3099    ADVANCE_PC 2
3100    GOTO_NEXT_R %ecx
3101
3102/* ------------------------------ */
3103.L_OP_IPUT_OBJECT: /* 0x5b */
3104/* File: x86/OP_IPUT_OBJECT.S */
3105    /*
3106     * Object field put.
3107     *
3108     * for: iput-object
3109     */
3110    /* op vA, vB, field@CCCC */
3111    movl    rSELF,%ecx
3112    SPILL(rIBASE)
3113    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
3114    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
3115    movzbl  rINSTbl,%ecx                        # ecx<- BA
3116    sarl    $4,%ecx                            # ecx<- B
3117    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
3118    andb    $0xf,rINSTbl                       # rINST<- A
3119    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
3120    movl    (%eax,rIBASE,4),%eax                  # resolved entry
3121    testl   %eax,%eax                           # is resolved entry null?
3122    jne     .LOP_IPUT_OBJECT_finish                  # no, already resolved
3123    movl    rIBASE,OUT_ARG1(%esp)
3124    movl    rSELF,rIBASE
3125    EXPORT_PC
3126    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
3127    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
3128    SPILL_TMP1(%ecx)                            # save obj pointer across call
3129    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
3130    call    dvmResolveInstField                 #  ... to dvmResolveInstField
3131    UNSPILL_TMP1(%ecx)
3132    testl   %eax,%eax                           # returns InstrField ptr
3133    jne     .LOP_IPUT_OBJECT_finish
3134    jmp     common_exceptionThrown
3135
3136.LOP_IPUT_OBJECT_finish:
3137    /*
3138     * Currently:
3139     *   eax holds resolved field
3140     *   ecx holds object
3141     *   rIBASE is scratch, but needs to be unspilled
3142     *   rINST holds A
3143     */
3144    GET_VREG_R rINST rINST                      # rINST<- v[A]
3145    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
3146    testl   %ecx,%ecx                           # object null?
3147    je      common_errNullObject                # object was null
3148    movl    rINST,(%ecx,%eax)      # obj.field <- v[A](8/16/32 bits)
3149    movl    rSELF,%eax
3150    testl   rINST,rINST                         # stored a NULL?
3151    movl    offThread_cardTable(%eax),%eax      # get card table base
3152    je      1f                                  # skip card mark if null store
3153    shrl    $GC_CARD_SHIFT,%ecx                # object head to card number
3154    movb    %al,(%eax,%ecx)                     # mark card using object head
31551:
3156    UNSPILL(rIBASE)
3157    FETCH_INST_OPCODE 2 %ecx
3158    ADVANCE_PC 2
3159    GOTO_NEXT_R %ecx
3160
3161/* ------------------------------ */
3162.L_OP_IPUT_BOOLEAN: /* 0x5c */
3163/* File: x86/OP_IPUT_BOOLEAN.S */
3164/* File: x86/OP_IPUT.S */
3165
3166    /*
3167     * General 32-bit instance field put.
3168     *
3169     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
3170     */
3171    /* op vA, vB, field@CCCC */
3172    movl    rSELF,%ecx
3173    SPILL   (rIBASE)
3174    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
3175    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
3176    movzbl  rINSTbl,%ecx                        # ecx<- BA
3177    sarl    $4,%ecx                            # ecx<- B
3178    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
3179    andb    $0xf,rINSTbl                       # rINST<- A
3180    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
3181    movl    (%eax,rIBASE,4),%eax                # resolved entry
3182    testl   %eax,%eax                           # is resolved entry null?
3183    jne     .LOP_IPUT_BOOLEAN_finish                  # no, already resolved
3184    movl    rIBASE,OUT_ARG1(%esp)
3185    movl    rSELF,rIBASE
3186    EXPORT_PC
3187    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
3188    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
3189    SPILL_TMP1(%ecx)                            # save obj pointer across call
3190    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
3191    call    dvmResolveInstField                 #  ... to dvmResolveInstField
3192    UNSPILL_TMP1(%ecx)
3193    testl   %eax,%eax                           # returns InstrField ptr
3194    jne     .LOP_IPUT_BOOLEAN_finish
3195    jmp     common_exceptionThrown
3196
3197.LOP_IPUT_BOOLEAN_finish:
3198    /*
3199     * Currently:
3200     *   eax holds resolved field
3201     *   ecx holds object
3202     *   rINST holds A
3203     */
3204    GET_VREG_R rINST rINST                       # rINST<- v[A]
3205    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
3206    testl   %ecx,%ecx                            # object null?
3207    je      common_errNullObject                 # object was null
3208    movb   rINSTbl,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
3209    FETCH_INST_OPCODE 2 %ecx
3210    UNSPILL(rIBASE)
3211    ADVANCE_PC 2
3212    GOTO_NEXT_R %ecx
3213
3214
3215/* ------------------------------ */
3216.L_OP_IPUT_BYTE: /* 0x5d */
3217/* File: x86/OP_IPUT_BYTE.S */
3218/* File: x86/OP_IPUT.S */
3219
3220    /*
3221     * General 32-bit instance field put.
3222     *
3223     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
3224     */
3225    /* op vA, vB, field@CCCC */
3226    movl    rSELF,%ecx
3227    SPILL   (rIBASE)
3228    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
3229    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
3230    movzbl  rINSTbl,%ecx                        # ecx<- BA
3231    sarl    $4,%ecx                            # ecx<- B
3232    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
3233    andb    $0xf,rINSTbl                       # rINST<- A
3234    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
3235    movl    (%eax,rIBASE,4),%eax                # resolved entry
3236    testl   %eax,%eax                           # is resolved entry null?
3237    jne     .LOP_IPUT_BYTE_finish                  # no, already resolved
3238    movl    rIBASE,OUT_ARG1(%esp)
3239    movl    rSELF,rIBASE
3240    EXPORT_PC
3241    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
3242    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
3243    SPILL_TMP1(%ecx)                            # save obj pointer across call
3244    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
3245    call    dvmResolveInstField                 #  ... to dvmResolveInstField
3246    UNSPILL_TMP1(%ecx)
3247    testl   %eax,%eax                           # returns InstrField ptr
3248    jne     .LOP_IPUT_BYTE_finish
3249    jmp     common_exceptionThrown
3250
3251.LOP_IPUT_BYTE_finish:
3252    /*
3253     * Currently:
3254     *   eax holds resolved field
3255     *   ecx holds object
3256     *   rINST holds A
3257     */
3258    GET_VREG_R rINST rINST                       # rINST<- v[A]
3259    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
3260    testl   %ecx,%ecx                            # object null?
3261    je      common_errNullObject                 # object was null
3262    movb   rINSTbl,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
3263    FETCH_INST_OPCODE 2 %ecx
3264    UNSPILL(rIBASE)
3265    ADVANCE_PC 2
3266    GOTO_NEXT_R %ecx
3267
3268
3269/* ------------------------------ */
3270.L_OP_IPUT_CHAR: /* 0x5e */
3271/* File: x86/OP_IPUT_CHAR.S */
3272/* File: x86/OP_IPUT.S */
3273
3274    /*
3275     * General 32-bit instance field put.
3276     *
3277     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
3278     */
3279    /* op vA, vB, field@CCCC */
3280    movl    rSELF,%ecx
3281    SPILL   (rIBASE)
3282    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
3283    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
3284    movzbl  rINSTbl,%ecx                        # ecx<- BA
3285    sarl    $4,%ecx                            # ecx<- B
3286    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
3287    andb    $0xf,rINSTbl                       # rINST<- A
3288    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
3289    movl    (%eax,rIBASE,4),%eax                # resolved entry
3290    testl   %eax,%eax                           # is resolved entry null?
3291    jne     .LOP_IPUT_CHAR_finish                  # no, already resolved
3292    movl    rIBASE,OUT_ARG1(%esp)
3293    movl    rSELF,rIBASE
3294    EXPORT_PC
3295    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
3296    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
3297    SPILL_TMP1(%ecx)                            # save obj pointer across call
3298    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
3299    call    dvmResolveInstField                 #  ... to dvmResolveInstField
3300    UNSPILL_TMP1(%ecx)
3301    testl   %eax,%eax                           # returns InstrField ptr
3302    jne     .LOP_IPUT_CHAR_finish
3303    jmp     common_exceptionThrown
3304
3305.LOP_IPUT_CHAR_finish:
3306    /*
3307     * Currently:
3308     *   eax holds resolved field
3309     *   ecx holds object
3310     *   rINST holds A
3311     */
3312    GET_VREG_R rINST rINST                       # rINST<- v[A]
3313    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
3314    testl   %ecx,%ecx                            # object null?
3315    je      common_errNullObject                 # object was null
3316    movw   rINSTw,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
3317    FETCH_INST_OPCODE 2 %ecx
3318    UNSPILL(rIBASE)
3319    ADVANCE_PC 2
3320    GOTO_NEXT_R %ecx
3321
3322
3323/* ------------------------------ */
3324.L_OP_IPUT_SHORT: /* 0x5f */
3325/* File: x86/OP_IPUT_SHORT.S */
3326/* File: x86/OP_IPUT.S */
3327
3328    /*
3329     * General 32-bit instance field put.
3330     *
3331     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
3332     */
3333    /* op vA, vB, field@CCCC */
3334    movl    rSELF,%ecx
3335    SPILL   (rIBASE)
3336    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
3337    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
3338    movzbl  rINSTbl,%ecx                        # ecx<- BA
3339    sarl    $4,%ecx                            # ecx<- B
3340    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
3341    andb    $0xf,rINSTbl                       # rINST<- A
3342    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
3343    movl    (%eax,rIBASE,4),%eax                # resolved entry
3344    testl   %eax,%eax                           # is resolved entry null?
3345    jne     .LOP_IPUT_SHORT_finish                  # no, already resolved
3346    movl    rIBASE,OUT_ARG1(%esp)
3347    movl    rSELF,rIBASE
3348    EXPORT_PC
3349    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
3350    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
3351    SPILL_TMP1(%ecx)                            # save obj pointer across call
3352    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
3353    call    dvmResolveInstField                 #  ... to dvmResolveInstField
3354    UNSPILL_TMP1(%ecx)
3355    testl   %eax,%eax                           # returns InstrField ptr
3356    jne     .LOP_IPUT_SHORT_finish
3357    jmp     common_exceptionThrown
3358
3359.LOP_IPUT_SHORT_finish:
3360    /*
3361     * Currently:
3362     *   eax holds resolved field
3363     *   ecx holds object
3364     *   rINST holds A
3365     */
3366    GET_VREG_R rINST rINST                       # rINST<- v[A]
3367    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
3368    testl   %ecx,%ecx                            # object null?
3369    je      common_errNullObject                 # object was null
3370    movw   rINSTw,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
3371    FETCH_INST_OPCODE 2 %ecx
3372    UNSPILL(rIBASE)
3373    ADVANCE_PC 2
3374    GOTO_NEXT_R %ecx
3375
3376
3377/* ------------------------------ */
3378.L_OP_SGET: /* 0x60 */
3379/* File: x86/OP_SGET.S */
3380    /*
3381     * General 32-bit SGET handler.
3382     *
3383     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
3384     */
3385    /* op vAA, field@BBBB */
3386    movl      rSELF,%ecx
3387    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3388    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3389    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3390#if defined(WITH_JIT)
3391    movl      %ecx, TMP_SPILL1(%ebp)
3392    lea       (%ecx,%eax,4),%ecx
3393    movl      %ecx, TMP_SPILL2(%ebp)
3394    movl      TMP_SPILL1(%ebp), %ecx
3395#endif
3396    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3397    testl     %eax,%eax                          # resolved entry null?
3398    je        .LOP_SGET_resolve                # if not, make it so
3399.LOP_SGET_finish:     # field ptr in eax
3400    movl      offStaticField_value(%eax),%eax
3401    FETCH_INST_OPCODE 2 %ecx
3402    ADVANCE_PC 2
3403    SET_VREG %eax rINST
3404    GOTO_NEXT_R %ecx
3405
3406    /*
3407     * Go resolve the field
3408     */
3409.LOP_SGET_resolve:
3410    movl     rSELF,%ecx
3411    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3412    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3413    EXPORT_PC                                   # could throw, need to export
3414    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3415    movl     %eax,OUT_ARG1(%esp)
3416    movl     %ecx,OUT_ARG0(%esp)
3417    SPILL(rIBASE)
3418    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3419    UNSPILL(rIBASE)
3420    testl    %eax,%eax
3421    je      common_exceptionThrown             # no, handle exception
3422#if defined(WITH_JIT)
3423    movl      TMP_SPILL2(%ebp), %ecx
3424    SPILL(rIBASE)
3425    call     common_verifyField
3426    UNSPILL(rIBASE)
3427#endif
3428    jmp      .LOP_SGET_finish                 # success, continue
3429
3430/* ------------------------------ */
3431.L_OP_SGET_WIDE: /* 0x61 */
3432/* File: x86/OP_SGET_WIDE.S */
3433    /*
3434     * 64-bit SGET handler.
3435     *
3436     */
3437    /* sget-wide vAA, field@BBBB */
3438    movl      rSELF,%ecx
3439    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3440    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3441    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3442#if defined(WITH_JIT)
3443    movl      %ecx, TMP_SPILL1(%ebp)
3444    lea       (%ecx,%eax,4),%ecx
3445    movl      %ecx, TMP_SPILL2(%ebp)
3446    movl      TMP_SPILL1(%ebp), %ecx
3447#endif
3448    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3449    testl     %eax,%eax                          # resolved entry null?
3450    je        .LOP_SGET_WIDE_resolve                # if not, make it so
3451.LOP_SGET_WIDE_finish:     # field ptr in eax
3452    movl      offStaticField_value(%eax),%ecx    # ecx<- lsw
3453    movl      4+offStaticField_value(%eax),%eax  # eax<- msw
3454    SET_VREG_WORD %ecx rINST 0
3455    FETCH_INST_OPCODE 2 %ecx
3456    SET_VREG_WORD %eax rINST 1
3457    ADVANCE_PC 2
3458    GOTO_NEXT_R %ecx
3459
3460    /*
3461     * Go resolve the field
3462     */
3463.LOP_SGET_WIDE_resolve:
3464    movl     rSELF,%ecx
3465    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3466    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3467    EXPORT_PC                                   # could throw, need to export
3468    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3469    movl     %eax,OUT_ARG1(%esp)
3470    movl     %ecx,OUT_ARG0(%esp)
3471    SPILL(rIBASE)
3472    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3473    UNSPILL(rIBASE)
3474    testl    %eax,%eax
3475    je      common_exceptionThrown             # no, handle exception
3476#if defined(WITH_JIT)
3477    movl      TMP_SPILL2(%ebp), %ecx
3478    SPILL(rIBASE)
3479    call     common_verifyField
3480    UNSPILL(rIBASE)
3481#endif
3482    jmp      .LOP_SGET_WIDE_finish                 # success, continue
3483
3484/* ------------------------------ */
3485.L_OP_SGET_OBJECT: /* 0x62 */
3486/* File: x86/OP_SGET_OBJECT.S */
3487/* File: x86/OP_SGET.S */
3488    /*
3489     * General 32-bit SGET handler.
3490     *
3491     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
3492     */
3493    /* op vAA, field@BBBB */
3494    movl      rSELF,%ecx
3495    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3496    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3497    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3498#if defined(WITH_JIT)
3499    movl      %ecx, TMP_SPILL1(%ebp)
3500    lea       (%ecx,%eax,4),%ecx
3501    movl      %ecx, TMP_SPILL2(%ebp)
3502    movl      TMP_SPILL1(%ebp), %ecx
3503#endif
3504    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3505    testl     %eax,%eax                          # resolved entry null?
3506    je        .LOP_SGET_OBJECT_resolve                # if not, make it so
3507.LOP_SGET_OBJECT_finish:     # field ptr in eax
3508    movl      offStaticField_value(%eax),%eax
3509    FETCH_INST_OPCODE 2 %ecx
3510    ADVANCE_PC 2
3511    SET_VREG %eax rINST
3512    GOTO_NEXT_R %ecx
3513
3514    /*
3515     * Go resolve the field
3516     */
3517.LOP_SGET_OBJECT_resolve:
3518    movl     rSELF,%ecx
3519    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3520    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3521    EXPORT_PC                                   # could throw, need to export
3522    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3523    movl     %eax,OUT_ARG1(%esp)
3524    movl     %ecx,OUT_ARG0(%esp)
3525    SPILL(rIBASE)
3526    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3527    UNSPILL(rIBASE)
3528    testl    %eax,%eax
3529    je      common_exceptionThrown             # no, handle exception
3530#if defined(WITH_JIT)
3531    movl      TMP_SPILL2(%ebp), %ecx
3532    SPILL(rIBASE)
3533    call     common_verifyField
3534    UNSPILL(rIBASE)
3535#endif
3536    jmp      .LOP_SGET_OBJECT_finish                 # success, continue
3537
3538
3539/* ------------------------------ */
3540.L_OP_SGET_BOOLEAN: /* 0x63 */
3541/* File: x86/OP_SGET_BOOLEAN.S */
3542/* File: x86/OP_SGET.S */
3543    /*
3544     * General 32-bit SGET handler.
3545     *
3546     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
3547     */
3548    /* op vAA, field@BBBB */
3549    movl      rSELF,%ecx
3550    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3551    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3552    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3553#if defined(WITH_JIT)
3554    movl      %ecx, TMP_SPILL1(%ebp)
3555    lea       (%ecx,%eax,4),%ecx
3556    movl      %ecx, TMP_SPILL2(%ebp)
3557    movl      TMP_SPILL1(%ebp), %ecx
3558#endif
3559    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3560    testl     %eax,%eax                          # resolved entry null?
3561    je        .LOP_SGET_BOOLEAN_resolve                # if not, make it so
3562.LOP_SGET_BOOLEAN_finish:     # field ptr in eax
3563    movl      offStaticField_value(%eax),%eax
3564    FETCH_INST_OPCODE 2 %ecx
3565    ADVANCE_PC 2
3566    SET_VREG %eax rINST
3567    GOTO_NEXT_R %ecx
3568
3569    /*
3570     * Go resolve the field
3571     */
3572.LOP_SGET_BOOLEAN_resolve:
3573    movl     rSELF,%ecx
3574    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3575    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3576    EXPORT_PC                                   # could throw, need to export
3577    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3578    movl     %eax,OUT_ARG1(%esp)
3579    movl     %ecx,OUT_ARG0(%esp)
3580    SPILL(rIBASE)
3581    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3582    UNSPILL(rIBASE)
3583    testl    %eax,%eax
3584    je      common_exceptionThrown             # no, handle exception
3585#if defined(WITH_JIT)
3586    movl      TMP_SPILL2(%ebp), %ecx
3587    SPILL(rIBASE)
3588    call     common_verifyField
3589    UNSPILL(rIBASE)
3590#endif
3591    jmp      .LOP_SGET_BOOLEAN_finish                 # success, continue
3592
3593
3594/* ------------------------------ */
3595.L_OP_SGET_BYTE: /* 0x64 */
3596/* File: x86/OP_SGET_BYTE.S */
3597/* File: x86/OP_SGET.S */
3598    /*
3599     * General 32-bit SGET handler.
3600     *
3601     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
3602     */
3603    /* op vAA, field@BBBB */
3604    movl      rSELF,%ecx
3605    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3606    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3607    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3608#if defined(WITH_JIT)
3609    movl      %ecx, TMP_SPILL1(%ebp)
3610    lea       (%ecx,%eax,4),%ecx
3611    movl      %ecx, TMP_SPILL2(%ebp)
3612    movl      TMP_SPILL1(%ebp), %ecx
3613#endif
3614    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3615    testl     %eax,%eax                          # resolved entry null?
3616    je        .LOP_SGET_BYTE_resolve                # if not, make it so
3617.LOP_SGET_BYTE_finish:     # field ptr in eax
3618    movl      offStaticField_value(%eax),%eax
3619    FETCH_INST_OPCODE 2 %ecx
3620    ADVANCE_PC 2
3621    SET_VREG %eax rINST
3622    GOTO_NEXT_R %ecx
3623
3624    /*
3625     * Go resolve the field
3626     */
3627.LOP_SGET_BYTE_resolve:
3628    movl     rSELF,%ecx
3629    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3630    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3631    EXPORT_PC                                   # could throw, need to export
3632    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3633    movl     %eax,OUT_ARG1(%esp)
3634    movl     %ecx,OUT_ARG0(%esp)
3635    SPILL(rIBASE)
3636    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3637    UNSPILL(rIBASE)
3638    testl    %eax,%eax
3639    je      common_exceptionThrown             # no, handle exception
3640#if defined(WITH_JIT)
3641    movl      TMP_SPILL2(%ebp), %ecx
3642    SPILL(rIBASE)
3643    call     common_verifyField
3644    UNSPILL(rIBASE)
3645#endif
3646    jmp      .LOP_SGET_BYTE_finish                 # success, continue
3647
3648
3649/* ------------------------------ */
3650.L_OP_SGET_CHAR: /* 0x65 */
3651/* File: x86/OP_SGET_CHAR.S */
3652/* File: x86/OP_SGET.S */
3653    /*
3654     * General 32-bit SGET handler.
3655     *
3656     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
3657     */
3658    /* op vAA, field@BBBB */
3659    movl      rSELF,%ecx
3660    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3661    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3662    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3663#if defined(WITH_JIT)
3664    movl      %ecx, TMP_SPILL1(%ebp)
3665    lea       (%ecx,%eax,4),%ecx
3666    movl      %ecx, TMP_SPILL2(%ebp)
3667    movl      TMP_SPILL1(%ebp), %ecx
3668#endif
3669    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3670    testl     %eax,%eax                          # resolved entry null?
3671    je        .LOP_SGET_CHAR_resolve                # if not, make it so
3672.LOP_SGET_CHAR_finish:     # field ptr in eax
3673    movl      offStaticField_value(%eax),%eax
3674    FETCH_INST_OPCODE 2 %ecx
3675    ADVANCE_PC 2
3676    SET_VREG %eax rINST
3677    GOTO_NEXT_R %ecx
3678
3679    /*
3680     * Go resolve the field
3681     */
3682.LOP_SGET_CHAR_resolve:
3683    movl     rSELF,%ecx
3684    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3685    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3686    EXPORT_PC                                   # could throw, need to export
3687    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3688    movl     %eax,OUT_ARG1(%esp)
3689    movl     %ecx,OUT_ARG0(%esp)
3690    SPILL(rIBASE)
3691    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3692    UNSPILL(rIBASE)
3693    testl    %eax,%eax
3694    je      common_exceptionThrown             # no, handle exception
3695#if defined(WITH_JIT)
3696    movl      TMP_SPILL2(%ebp), %ecx
3697    SPILL(rIBASE)
3698    call     common_verifyField
3699    UNSPILL(rIBASE)
3700#endif
3701    jmp      .LOP_SGET_CHAR_finish                 # success, continue
3702
3703
3704/* ------------------------------ */
3705.L_OP_SGET_SHORT: /* 0x66 */
3706/* File: x86/OP_SGET_SHORT.S */
3707/* File: x86/OP_SGET.S */
3708    /*
3709     * General 32-bit SGET handler.
3710     *
3711     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
3712     */
3713    /* op vAA, field@BBBB */
3714    movl      rSELF,%ecx
3715    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3716    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3717    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3718#if defined(WITH_JIT)
3719    movl      %ecx, TMP_SPILL1(%ebp)
3720    lea       (%ecx,%eax,4),%ecx
3721    movl      %ecx, TMP_SPILL2(%ebp)
3722    movl      TMP_SPILL1(%ebp), %ecx
3723#endif
3724    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3725    testl     %eax,%eax                          # resolved entry null?
3726    je        .LOP_SGET_SHORT_resolve                # if not, make it so
3727.LOP_SGET_SHORT_finish:     # field ptr in eax
3728    movl      offStaticField_value(%eax),%eax
3729    FETCH_INST_OPCODE 2 %ecx
3730    ADVANCE_PC 2
3731    SET_VREG %eax rINST
3732    GOTO_NEXT_R %ecx
3733
3734    /*
3735     * Go resolve the field
3736     */
3737.LOP_SGET_SHORT_resolve:
3738    movl     rSELF,%ecx
3739    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3740    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3741    EXPORT_PC                                   # could throw, need to export
3742    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3743    movl     %eax,OUT_ARG1(%esp)
3744    movl     %ecx,OUT_ARG0(%esp)
3745    SPILL(rIBASE)
3746    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3747    UNSPILL(rIBASE)
3748    testl    %eax,%eax
3749    je      common_exceptionThrown             # no, handle exception
3750#if defined(WITH_JIT)
3751    movl      TMP_SPILL2(%ebp), %ecx
3752    SPILL(rIBASE)
3753    call     common_verifyField
3754    UNSPILL(rIBASE)
3755#endif
3756    jmp      .LOP_SGET_SHORT_finish                 # success, continue
3757
3758
3759/* ------------------------------ */
3760.L_OP_SPUT: /* 0x67 */
3761/* File: x86/OP_SPUT.S */
3762    /*
3763     * General 32-bit SPUT handler.
3764     *
3765     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3766     */
3767    /* op vAA, field@BBBB */
3768    movl      rSELF,%ecx
3769    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3770    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3771    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3772#if defined(WITH_JIT)
3773    movl      %ecx, TMP_SPILL1(%ebp)
3774    lea       (%ecx,%eax,4),%ecx
3775    movl      %ecx, TMP_SPILL2(%ebp)
3776    movl      TMP_SPILL1(%ebp), %ecx
3777#endif
3778    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3779    testl     %eax,%eax                          # resolved entry null?
3780    je        .LOP_SPUT_resolve                # if not, make it so
3781.LOP_SPUT_finish:     # field ptr in eax
3782    GET_VREG_R  rINST rINST
3783    FETCH_INST_OPCODE 2 %ecx
3784    ADVANCE_PC 2
3785    movl      rINST,offStaticField_value(%eax)
3786    GOTO_NEXT_R %ecx
3787
3788    /*
3789     * Go resolve the field
3790     */
3791.LOP_SPUT_resolve:
3792    movl     rSELF,%ecx
3793    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3794    movl     offThread_method(%ecx),%ecx        # ecx<- current method
3795    EXPORT_PC                                   # could throw, need to export
3796    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3797    movl     %eax,OUT_ARG1(%esp)
3798    movl     %ecx,OUT_ARG0(%esp)
3799    SPILL(rIBASE)
3800    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3801    UNSPILL(rIBASE)
3802    testl    %eax,%eax
3803    je      common_exceptionThrown             # no, handle exception
3804#if defined(WITH_JIT)
3805    movl      TMP_SPILL2(%ebp), %ecx
3806    SPILL(rIBASE)
3807    call     common_verifyField
3808    UNSPILL(rIBASE)
3809#endif
3810    jmp      .LOP_SPUT_finish                 # success, continue
3811/* ------------------------------ */
3812.L_OP_SPUT_WIDE: /* 0x68 */
3813/* File: x86/OP_SPUT_WIDE.S */
3814    /*
3815     * General 32-bit SPUT handler.
3816     *
3817     * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
3818     */
3819    /* op vAA, field@BBBB */
3820    movl      rSELF,%ecx
3821    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3822    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3823    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3824#if defined(WITH_JIT)
3825    movl      %ecx, TMP_SPILL1(%ebp)
3826    lea       (%ecx,%eax,4),%ecx
3827    movl      %ecx, TMP_SPILL2(%ebp)
3828    movl      TMP_SPILL1(%ebp), %ecx
3829#endif
3830    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3831    testl     %eax,%eax                          # resolved entry null?
3832    je        .LOP_SPUT_WIDE_resolve                # if not, make it so
3833.LOP_SPUT_WIDE_finish:     # field ptr in eax
3834    GET_VREG_WORD %ecx rINST 0                  # rINST<- lsw
3835    GET_VREG_WORD rINST rINST 1                 # ecx<- msw
3836    movl      %ecx,offStaticField_value(%eax)
3837    FETCH_INST_OPCODE 2 %ecx
3838    movl      rINST,4+offStaticField_value(%eax)
3839    ADVANCE_PC 2
3840    GOTO_NEXT_R %ecx
3841
3842    /*
3843     * Go resolve the field
3844     */
3845.LOP_SPUT_WIDE_resolve:
3846    movl     rSELF,%ecx
3847    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3848    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3849    EXPORT_PC                                   # could throw, need to export
3850    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3851    movl     %eax,OUT_ARG1(%esp)
3852    movl     %ecx,OUT_ARG0(%esp)
3853    SPILL(rIBASE)
3854    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3855    UNSPILL(rIBASE)
3856    testl    %eax,%eax
3857    je      common_exceptionThrown             # no, handle exception
3858#if defined(WITH_JIT)
3859    movl      TMP_SPILL2(%ebp), %ecx
3860    SPILL(rIBASE)
3861    call     common_verifyField
3862    UNSPILL(rIBASE)
3863#endif
3864    jmp      .LOP_SPUT_WIDE_finish                 # success, continue
3865
3866/* ------------------------------ */
3867.L_OP_SPUT_OBJECT: /* 0x69 */
3868/* File: x86/OP_SPUT_OBJECT.S */
3869    /*
3870     * SPUT object handler.
3871     */
3872    /* op vAA, field@BBBB */
3873    movl      rSELF,%ecx
3874    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3875    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3876    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3877#if defined(WITH_JIT)
3878    movl      %ecx, TMP_SPILL1(%ebp)
3879    lea       (%ecx,%eax,4),%ecx
3880    movl      %ecx, TMP_SPILL2(%ebp)
3881    movl      TMP_SPILL1(%ebp), %ecx
3882#endif
3883    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField
3884    testl     %eax,%eax                          # resolved entry null?
3885    je        .LOP_SPUT_OBJECT_resolve                # if not, make it so
3886.LOP_SPUT_OBJECT_finish:                              # field ptr in eax
3887    movzbl    rINSTbl,%ecx                       # ecx<- AA
3888    GET_VREG_R  %ecx %ecx
3889    movl      %ecx,offStaticField_value(%eax)    # do the store
3890    testl     %ecx,%ecx                          # stored null object ptr?
3891    je        1f                                 # skip card mark if null
3892    movl      rSELF,%ecx
3893    movl      offField_clazz(%eax),%eax          # eax<- method->clazz
3894    movl      offThread_cardTable(%ecx),%ecx       # get card table base
3895    shrl      $GC_CARD_SHIFT,%eax               # head to card number
3896    movb      %cl,(%ecx,%eax)                    # mark card
38971:
3898    FETCH_INST_OPCODE 2 %ecx
3899    ADVANCE_PC 2
3900    GOTO_NEXT_R %ecx
3901
3902.LOP_SPUT_OBJECT_resolve:
3903    movl     rSELF,%ecx
3904    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3905    movl     offThread_method(%ecx),%ecx          # ecx<- current method
3906    EXPORT_PC                                   # could throw, need to export
3907    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3908    movl     %eax,OUT_ARG1(%esp)
3909    movl     %ecx,OUT_ARG0(%esp)
3910    SPILL(rIBASE)
3911    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3912    UNSPILL(rIBASE)
3913    testl    %eax,%eax
3914    je      common_exceptionThrown             # no, handle exception
3915#if defined(WITH_JIT)
3916    movl      TMP_SPILL2(%ebp), %ecx
3917    SPILL(rIBASE)
3918    call     common_verifyField
3919    UNSPILL(rIBASE)
3920#endif
3921    jmp      .LOP_SPUT_OBJECT_finish                 # success, continue
3922
3923/* ------------------------------ */
3924.L_OP_SPUT_BOOLEAN: /* 0x6a */
3925/* File: x86/OP_SPUT_BOOLEAN.S */
3926/* File: x86/OP_SPUT.S */
3927    /*
3928     * General 32-bit SPUT handler.
3929     *
3930     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3931     */
3932    /* op vAA, field@BBBB */
3933    movl      rSELF,%ecx
3934    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3935    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3936    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3937#if defined(WITH_JIT)
3938    movl      %ecx, TMP_SPILL1(%ebp)
3939    lea       (%ecx,%eax,4),%ecx
3940    movl      %ecx, TMP_SPILL2(%ebp)
3941    movl      TMP_SPILL1(%ebp), %ecx
3942#endif
3943    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3944    testl     %eax,%eax                          # resolved entry null?
3945    je        .LOP_SPUT_BOOLEAN_resolve                # if not, make it so
3946.LOP_SPUT_BOOLEAN_finish:     # field ptr in eax
3947    GET_VREG_R  rINST rINST
3948    FETCH_INST_OPCODE 2 %ecx
3949    ADVANCE_PC 2
3950    movl      rINST,offStaticField_value(%eax)
3951    GOTO_NEXT_R %ecx
3952
3953    /*
3954     * Go resolve the field
3955     */
3956.LOP_SPUT_BOOLEAN_resolve:
3957    movl     rSELF,%ecx
3958    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
3959    movl     offThread_method(%ecx),%ecx        # ecx<- current method
3960    EXPORT_PC                                   # could throw, need to export
3961    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
3962    movl     %eax,OUT_ARG1(%esp)
3963    movl     %ecx,OUT_ARG0(%esp)
3964    SPILL(rIBASE)
3965    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
3966    UNSPILL(rIBASE)
3967    testl    %eax,%eax
3968    je      common_exceptionThrown             # no, handle exception
3969#if defined(WITH_JIT)
3970    movl      TMP_SPILL2(%ebp), %ecx
3971    SPILL(rIBASE)
3972    call     common_verifyField
3973    UNSPILL(rIBASE)
3974#endif
3975    jmp      .LOP_SPUT_BOOLEAN_finish                 # success, continue
3976
3977/* ------------------------------ */
3978.L_OP_SPUT_BYTE: /* 0x6b */
3979/* File: x86/OP_SPUT_BYTE.S */
3980/* File: x86/OP_SPUT.S */
3981    /*
3982     * General 32-bit SPUT handler.
3983     *
3984     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3985     */
3986    /* op vAA, field@BBBB */
3987    movl      rSELF,%ecx
3988    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
3989    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
3990    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
3991#if defined(WITH_JIT)
3992    movl      %ecx, TMP_SPILL1(%ebp)
3993    lea       (%ecx,%eax,4),%ecx
3994    movl      %ecx, TMP_SPILL2(%ebp)
3995    movl      TMP_SPILL1(%ebp), %ecx
3996#endif
3997    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
3998    testl     %eax,%eax                          # resolved entry null?
3999    je        .LOP_SPUT_BYTE_resolve                # if not, make it so
4000.LOP_SPUT_BYTE_finish:     # field ptr in eax
4001    GET_VREG_R  rINST rINST
4002    FETCH_INST_OPCODE 2 %ecx
4003    ADVANCE_PC 2
4004    movl      rINST,offStaticField_value(%eax)
4005    GOTO_NEXT_R %ecx
4006
4007    /*
4008     * Go resolve the field
4009     */
4010.LOP_SPUT_BYTE_resolve:
4011    movl     rSELF,%ecx
4012    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
4013    movl     offThread_method(%ecx),%ecx        # ecx<- current method
4014    EXPORT_PC                                   # could throw, need to export
4015    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
4016    movl     %eax,OUT_ARG1(%esp)
4017    movl     %ecx,OUT_ARG0(%esp)
4018    SPILL(rIBASE)
4019    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
4020    UNSPILL(rIBASE)
4021    testl    %eax,%eax
4022    je      common_exceptionThrown             # no, handle exception
4023#if defined(WITH_JIT)
4024    movl      TMP_SPILL2(%ebp), %ecx
4025    SPILL(rIBASE)
4026    call     common_verifyField
4027    UNSPILL(rIBASE)
4028#endif
4029    jmp      .LOP_SPUT_BYTE_finish                 # success, continue
4030
4031/* ------------------------------ */
4032.L_OP_SPUT_CHAR: /* 0x6c */
4033/* File: x86/OP_SPUT_CHAR.S */
4034/* File: x86/OP_SPUT.S */
4035    /*
4036     * General 32-bit SPUT handler.
4037     *
4038     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
4039     */
4040    /* op vAA, field@BBBB */
4041    movl      rSELF,%ecx
4042    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
4043    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
4044    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
4045#if defined(WITH_JIT)
4046    movl      %ecx, TMP_SPILL1(%ebp)
4047    lea       (%ecx,%eax,4),%ecx
4048    movl      %ecx, TMP_SPILL2(%ebp)
4049    movl      TMP_SPILL1(%ebp), %ecx
4050#endif
4051    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
4052    testl     %eax,%eax                          # resolved entry null?
4053    je        .LOP_SPUT_CHAR_resolve                # if not, make it so
4054.LOP_SPUT_CHAR_finish:     # field ptr in eax
4055    GET_VREG_R  rINST rINST
4056    FETCH_INST_OPCODE 2 %ecx
4057    ADVANCE_PC 2
4058    movl      rINST,offStaticField_value(%eax)
4059    GOTO_NEXT_R %ecx
4060
4061    /*
4062     * Go resolve the field
4063     */
4064.LOP_SPUT_CHAR_resolve:
4065    movl     rSELF,%ecx
4066    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
4067    movl     offThread_method(%ecx),%ecx        # ecx<- current method
4068    EXPORT_PC                                   # could throw, need to export
4069    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
4070    movl     %eax,OUT_ARG1(%esp)
4071    movl     %ecx,OUT_ARG0(%esp)
4072    SPILL(rIBASE)
4073    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
4074    UNSPILL(rIBASE)
4075    testl    %eax,%eax
4076    je      common_exceptionThrown             # no, handle exception
4077#if defined(WITH_JIT)
4078    movl      TMP_SPILL2(%ebp), %ecx
4079    SPILL(rIBASE)
4080    call     common_verifyField
4081    UNSPILL(rIBASE)
4082#endif
4083    jmp      .LOP_SPUT_CHAR_finish                 # success, continue
4084
4085/* ------------------------------ */
4086.L_OP_SPUT_SHORT: /* 0x6d */
4087/* File: x86/OP_SPUT_SHORT.S */
4088/* File: x86/OP_SPUT.S */
4089    /*
4090     * General 32-bit SPUT handler.
4091     *
4092     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
4093     */
4094    /* op vAA, field@BBBB */
4095    movl      rSELF,%ecx
4096    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
4097    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
4098    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
4099#if defined(WITH_JIT)
4100    movl      %ecx, TMP_SPILL1(%ebp)
4101    lea       (%ecx,%eax,4),%ecx
4102    movl      %ecx, TMP_SPILL2(%ebp)
4103    movl      TMP_SPILL1(%ebp), %ecx
4104#endif
4105    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
4106    testl     %eax,%eax                          # resolved entry null?
4107    je        .LOP_SPUT_SHORT_resolve                # if not, make it so
4108.LOP_SPUT_SHORT_finish:     # field ptr in eax
4109    GET_VREG_R  rINST rINST
4110    FETCH_INST_OPCODE 2 %ecx
4111    ADVANCE_PC 2
4112    movl      rINST,offStaticField_value(%eax)
4113    GOTO_NEXT_R %ecx
4114
4115    /*
4116     * Go resolve the field
4117     */
4118.LOP_SPUT_SHORT_resolve:
4119    movl     rSELF,%ecx
4120    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
4121    movl     offThread_method(%ecx),%ecx        # ecx<- current method
4122    EXPORT_PC                                   # could throw, need to export
4123    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
4124    movl     %eax,OUT_ARG1(%esp)
4125    movl     %ecx,OUT_ARG0(%esp)
4126    SPILL(rIBASE)
4127    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
4128    UNSPILL(rIBASE)
4129    testl    %eax,%eax
4130    je      common_exceptionThrown             # no, handle exception
4131#if defined(WITH_JIT)
4132    movl      TMP_SPILL2(%ebp), %ecx
4133    SPILL(rIBASE)
4134    call     common_verifyField
4135    UNSPILL(rIBASE)
4136#endif
4137    jmp      .LOP_SPUT_SHORT_finish                 # success, continue
4138
4139/* ------------------------------ */
4140.L_OP_INVOKE_VIRTUAL: /* 0x6e */
4141/* File: x86/OP_INVOKE_VIRTUAL.S */
4142
4143    /*
4144     * Handle a virtual method call.
4145     *
4146     * for: invoke-virtual, invoke-virtual/range
4147     */
4148    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
4149    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
4150    movl      rSELF,%eax
4151    movzwl    2(rPC),%ecx                 # ecx<- BBBB
4152    movl      offThread_methodClassDex(%eax),%eax  # eax<- pDvmDex
4153    EXPORT_PC
4154    movl      offDvmDex_pResMethods(%eax),%eax   # eax<- pDvmDex->pResMethods
4155    movl      (%eax,%ecx,4),%eax          # eax<- resolved baseMethod
4156    testl     %eax,%eax                   # already resolved?
4157    jne       .LOP_INVOKE_VIRTUAL_continue        # yes, continue
4158    movl      rSELF,%eax
4159    movl      %ecx,OUT_ARG1(%esp)         # arg1<- ref
4160    movl      offThread_method(%eax),%eax   # eax<- self->method
4161    movl      offMethod_clazz(%eax),%eax  # ecx<- method->clazz
4162    movl      %eax,OUT_ARG0(%esp)         # arg0<- clazz
4163    movl      $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags
4164    call      dvmResolveMethod            # eax<- call(clazz, ref, flags)
4165    testl     %eax,%eax                   # got null?
4166    jne       .LOP_INVOKE_VIRTUAL_continue        # no, continue
4167    jmp       common_exceptionThrown      # yes, handle exception
4168
4169    /* At this point:
4170     *   eax = resolved base method
4171     *   ecx = scratch
4172     */
4173.LOP_INVOKE_VIRTUAL_continue:
4174    movzwl    4(rPC),%ecx               # ecx<- GFED or CCCC
4175    .if       (!0)
4176    andl      $0xf,%ecx                # ecx<- D (or stays CCCC)
4177    .endif
4178    GET_VREG_R  %ecx %ecx               # ecx<- "this"
4179    movzwl    offMethod_methodIndex(%eax),%eax  # eax<- baseMethod->methodIndex
4180    testl     %ecx,%ecx                 # null this?
4181    je        common_errNullObject      # go if so
4182    movl      offObject_clazz(%ecx),%edx  # edx<- thisPtr->clazz
4183    movl      offClassObject_vtable(%edx),%edx # edx<- thisPtr->clazz->vtable
4184    movl      (%edx,%eax,4),%eax        # eax<- vtable[methodIndex]
4185    jmp       common_invokeMethodNoRange
4186
4187/* ------------------------------ */
4188.L_OP_INVOKE_SUPER: /* 0x6f */
4189/* File: x86/OP_INVOKE_SUPER.S */
4190    /*
4191     * Handle a "super" method call.
4192     *
4193     * for: invoke-super, invoke-super/range
4194     */
4195    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
4196    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
4197    movl      rSELF,rINST
4198    movzwl    2(rPC),%eax               # eax<- BBBB
4199    movl      offThread_methodClassDex(rINST),%ecx # ecx<- pDvmDex
4200    EXPORT_PC
4201    movl      offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods
4202    movl      (%ecx,%eax,4),%ecx        # ecx<- resolved baseMethod
4203    movl      offThread_method(rINST),%eax # eax<- method
4204    movzwl    4(rPC),rINST              # rINST<- GFED or CCCC
4205    .if       (!0)
4206    andl      $0xf,rINST               # rINST<- D (or stays CCCC)
4207    .endif
4208    GET_VREG_R  %edx rINST             # %edx<- "this" ptr
4209    testl     %edx,%edx                # null "this"?
4210    SPILL_TMP1(%edx)
4211    je        common_errNullObject      # yes, throw
4212    movl      offMethod_clazz(%eax),%eax # eax<- method->clazz
4213    testl     %ecx,%ecx                 # already resolved?
4214    je       .LOP_INVOKE_SUPER_resolve
4215    /*
4216     * At this point:
4217     *  ecx = resolved base method [r0]
4218     *  eax = method->clazz [r9]
4219     */
4220.LOP_INVOKE_SUPER_continue:
4221    movl    offClassObject_super(%eax),%eax   # eax<- method->clazz->super
4222    movzwl  offMethod_methodIndex(%ecx),%edx  # edx<- baseMthod->methodIndex
4223    cmpl    offClassObject_vtableCount(%eax),%edx # compare(methodIndex,vtableCount)
4224    jae     .LOP_INVOKE_SUPER_nsm           # method not present in superclass
4225    movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
4226    movl    (%eax,%edx,4),%eax        # eax<- vtable[methodIndex]
4227    UNSPILL_TMP1(%edx)
4228    movl    %edx, %ecx
4229    jmp     common_invokeMethodNoRange
4230
4231
4232    /* At this point:
4233     * ecx = null (needs to be resolved base method)
4234     * eax = method->clazz
4235    */
4236.LOP_INVOKE_SUPER_resolve:
4237    SPILL_TMP2(%eax)                    # method->clazz
4238    movl    %eax,OUT_ARG0(%esp)         # arg0<- method->clazz
4239    movzwl  2(rPC),%ecx                 # ecx<- BBBB
4240    movl    $METHOD_VIRTUAL,OUT_ARG2(%esp)  # arg2<- resolver method type
4241    movl    %ecx,OUT_ARG1(%esp)         # arg1<- ref
4242    call    dvmResolveMethod            # eax<- call(clazz, ref, flags)
4243    testl   %eax,%eax                   # got null?
4244    movl    %eax,%ecx                   # ecx<- resolved base method
4245    UNSPILL_TMP2(%eax)                  # restore method->clazz
4246    jne     .LOP_INVOKE_SUPER_continue        # good to go - continue
4247    jmp     common_exceptionThrown      # handle exception
4248
4249    /*
4250     * Throw a NoSuchMethodError with the method name as the message.
4251     *  ecx = resolved base method
4252     */
4253.LOP_INVOKE_SUPER_nsm:
4254    movl    offMethod_name(%ecx),%eax
4255    jmp     common_errNoSuchMethod
4256
4257/* ------------------------------ */
4258.L_OP_INVOKE_DIRECT: /* 0x70 */
4259/* File: x86/OP_INVOKE_DIRECT.S */
4260    /*
4261     * Handle a direct method call.
4262     *
4263     * (We could defer the "is 'this' pointer null" test to the common
4264     * method invocation code, and use a flag to indicate that static
4265     * calls don't count.  If we do this as part of copying the arguments
4266     * out we could avoiding loading the first arg twice.)
4267     *
4268     * for: invoke-direct, invoke-direct/range
4269     */
4270    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
4271    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
4272    movl      rSELF,%ecx
4273    movzwl    2(rPC),%eax              # eax<- BBBB
4274    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
4275    EXPORT_PC
4276    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
4277    movzwl    4(rPC),rIBASE            # rIBASE<- GFED or CCCC
4278    movl      (%ecx,%eax,4),%eax       # eax<- resolved methodToCall
4279    .if       (!0)
4280    andl      $0xf,rIBASE             # rIBASE<- D (or stays CCCC)
4281    .endif
4282    testl     %eax,%eax                # already resolved?
4283    GET_VREG_R  %ecx rIBASE            # ecx<- "this" ptr
4284    je        .LOP_INVOKE_DIRECT_resolve      # not resolved, do it now
4285.LOP_INVOKE_DIRECT_finish:
4286    testl     %ecx,%ecx                # null "this"?
4287    jne       common_invokeMethodNoRange  # no, continue on
4288    jmp       common_errNullObject
4289
4290    /*
4291     * On entry:
4292     *   TMP_SPILL  <- "this" register
4293     * Things a bit ugly on this path, but it's the less
4294     * frequent one.  We'll have to do some reloading.
4295     */
4296.LOP_INVOKE_DIRECT_resolve:
4297     SPILL_TMP1(%ecx)
4298     movl     rSELF,%ecx
4299     movl     offThread_method(%ecx),%ecx  # ecx<- self->method
4300     movzwl   2(rPC),%eax      # reference (BBBB or CCCC)
4301     movl     offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
4302     movl     $METHOD_DIRECT,OUT_ARG2(%esp)
4303     movl     %eax,OUT_ARG1(%esp)
4304     movl     %ecx,OUT_ARG0(%esp)
4305     call     dvmResolveMethod # eax<- call(clazz, ref, flags)
4306     UNSPILL_TMP1(%ecx)
4307     testl    %eax,%eax
4308     jne      .LOP_INVOKE_DIRECT_finish
4309     jmp      common_exceptionThrown
4310
4311/* ------------------------------ */
4312.L_OP_INVOKE_STATIC: /* 0x71 */
4313/* File: x86/OP_INVOKE_STATIC.S */
4314    /*
4315     * Handle a static method call.
4316     *
4317     * for: invoke-static, invoke-static/range
4318     */
4319    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
4320    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
4321    movl      rSELF,%ecx
4322    movzwl    2(rPC),%eax               # eax<- BBBB
4323    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
4324    EXPORT_PC
4325    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
4326#if defined(WITH_JIT)
4327    movl     %edx, TMP_SPILL1(%ebp)
4328    lea      (%ecx,%eax,4), %edx
4329    movl     %edx, TMP_SPILL2(%ebp)
4330    movl     TMP_SPILL1(%ebp), %edx
4331#endif
4332    movl      (%ecx,%eax,4),%eax        # eax<- resolved methodToCall
4333    movl      $0, %ecx                 # make "this" null
4334    testl     %eax,%eax
4335    jne       common_invokeMethodNoRange
4336
4337    movl      rSELF,%ecx
4338    movl      offThread_method(%ecx),%ecx # ecx<- self->method
4339    movzwl    2(rPC),%eax
4340    movl      offMethod_clazz(%ecx),%ecx# ecx<- method->clazz
4341    movl      %eax,OUT_ARG1(%esp)       # arg1<- BBBB
4342    movl      %ecx,OUT_ARG0(%esp)       # arg0<- clazz
4343    movl      $METHOD_STATIC,%eax
4344    movl      %eax,OUT_ARG2(%esp)       # arg2<- flags
4345    SPILL(rIBASE)
4346    call      dvmResolveMethod          # call(clazz,ref,flags)
4347    UNSPILL(rIBASE)
4348    testl     %eax,%eax                 # got null?
4349#if defined(WITH_JIT)
4350    movl      TMP_SPILL1(%ebp), %edx
4351    movl      rSELF,%ecx
4352    movzwl    offThread_subMode(%ecx), %ecx
4353    je        common_exceptionThrown    # null, handle exception
4354    andl      $kSubModeJitTraceBuild, %ecx # is trace under construction?
4355    movl      $0, %ecx                 # make "this" null
4356    je        common_invokeMethodNoRange # no (%eax=method, %ecx="this")
4357    movl      TMP_SPILL2(%ebp), %edx
4358    cmpl      $0, (%edx)                  # finished resolving
4359    movl      TMP_SPILL1(%ebp), %edx
4360    jne        common_invokeMethodNoRange # yes (%eax=method, %ecx="this")
4361    movl      rSELF, %edx
4362    movl      %edx, OUT_ARG0(%esp)
4363    movl      rPC, OUT_ARG1(%esp)
4364    movl      %eax, TMP_SPILL2(%ebp)
4365    movl      %ecx, TMP_SPILL3(%ebp)
4366    SPILL(rIBASE)
4367    call      dvmJitEndTraceSelect
4368    UNSPILL(rIBASE)
4369    movl      TMP_SPILL1(%ebp), %edx
4370    movl      TMP_SPILL2(%ebp), %eax
4371    movl      TMP_SPILL3(%ebp), %ecx
4372    jmp       common_invokeMethodNoRange
4373#else
4374    movl      $0, %ecx                 # make "this" null
4375    jne       common_invokeMethodNoRange
4376    jmp       common_exceptionThrown
4377#endif
4378
4379
4380/* ------------------------------ */
4381.L_OP_INVOKE_INTERFACE: /* 0x72 */
4382/* File: x86/OP_INVOKE_INTERFACE.S */
4383    /*
4384     * Handle an interface method call.
4385     *
4386     * for: invoke-interface, invoke-interface/range
4387     */
4388    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
4389    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
4390    movzwl     4(rPC),%eax              # eax<- FEDC or CCCC
4391    movl       rSELF,%ecx
4392    .if        (!0)
4393    andl       $0xf,%eax               # eax<- C (or stays CCCC)
4394    .endif
4395    GET_VREG_R   %eax %eax              # eax<- "this"
4396    EXPORT_PC
4397    testl      %eax,%eax                # null this?
4398    je         common_errNullObject     # yes, fail
4399    movl       %eax, TMP_SPILL1(%ebp)
4400    movl       offObject_clazz(%eax),%eax# eax<- thisPtr->clazz
4401    movl       %eax,OUT_ARG0(%esp)                 # arg0<- class
4402    movl       offThread_methodClassDex(%ecx),%eax   # eax<- methodClassDex
4403    movl       offThread_method(%ecx),%ecx           # ecx<- method
4404    movl       %eax,OUT_ARG3(%esp)                 # arg3<- dex
4405    movzwl     2(rPC),%eax                         # eax<- BBBB
4406    movl       %ecx,OUT_ARG2(%esp)                 # arg2<- method
4407    movl       %eax,OUT_ARG1(%esp)                 # arg1<- BBBB
4408    call       dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex)
4409    testl      %eax,%eax
4410    je         common_exceptionThrown
4411    movl       TMP_SPILL1(%ebp), %ecx
4412    jmp        common_invokeMethodNoRange
4413
4414/* ------------------------------ */
4415.L_OP_UNUSED_73: /* 0x73 */
4416/* File: x86/OP_UNUSED_73.S */
4417/* File: x86/unused.S */
4418    jmp     common_abort
4419
4420
4421/* ------------------------------ */
4422.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
4423/* File: x86/OP_INVOKE_VIRTUAL_RANGE.S */
4424/* File: x86/OP_INVOKE_VIRTUAL.S */
4425
4426    /*
4427     * Handle a virtual method call.
4428     *
4429     * for: invoke-virtual, invoke-virtual/range
4430     */
4431    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
4432    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
4433    movl      rSELF,%eax
4434    movzwl    2(rPC),%ecx                 # ecx<- BBBB
4435    movl      offThread_methodClassDex(%eax),%eax  # eax<- pDvmDex
4436    EXPORT_PC
4437    movl      offDvmDex_pResMethods(%eax),%eax   # eax<- pDvmDex->pResMethods
4438    movl      (%eax,%ecx,4),%eax          # eax<- resolved baseMethod
4439    testl     %eax,%eax                   # already resolved?
4440    jne       .LOP_INVOKE_VIRTUAL_RANGE_continue        # yes, continue
4441    movl      rSELF,%eax
4442    movl      %ecx,OUT_ARG1(%esp)         # arg1<- ref
4443    movl      offThread_method(%eax),%eax   # eax<- self->method
4444    movl      offMethod_clazz(%eax),%eax  # ecx<- method->clazz
4445    movl      %eax,OUT_ARG0(%esp)         # arg0<- clazz
4446    movl      $METHOD_VIRTUAL,OUT_ARG2(%esp) # arg2<- flags
4447    call      dvmResolveMethod            # eax<- call(clazz, ref, flags)
4448    testl     %eax,%eax                   # got null?
4449    jne       .LOP_INVOKE_VIRTUAL_RANGE_continue        # no, continue
4450    jmp       common_exceptionThrown      # yes, handle exception
4451
4452    /* At this point:
4453     *   eax = resolved base method
4454     *   ecx = scratch
4455     */
4456.LOP_INVOKE_VIRTUAL_RANGE_continue:
4457    movzwl    4(rPC),%ecx               # ecx<- GFED or CCCC
4458    .if       (!1)
4459    andl      $0xf,%ecx                # ecx<- D (or stays CCCC)
4460    .endif
4461    GET_VREG_R  %ecx %ecx               # ecx<- "this"
4462    movzwl    offMethod_methodIndex(%eax),%eax  # eax<- baseMethod->methodIndex
4463    testl     %ecx,%ecx                 # null this?
4464    je        common_errNullObject      # go if so
4465    movl      offObject_clazz(%ecx),%edx  # edx<- thisPtr->clazz
4466    movl      offClassObject_vtable(%edx),%edx # edx<- thisPtr->clazz->vtable
4467    movl      (%edx,%eax,4),%eax        # eax<- vtable[methodIndex]
4468    jmp       common_invokeMethodRange
4469
4470
4471/* ------------------------------ */
4472.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */
4473/* File: x86/OP_INVOKE_SUPER_RANGE.S */
4474/* File: x86/OP_INVOKE_SUPER.S */
4475    /*
4476     * Handle a "super" method call.
4477     *
4478     * for: invoke-super, invoke-super/range
4479     */
4480    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
4481    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
4482    movl      rSELF,rINST
4483    movzwl    2(rPC),%eax               # eax<- BBBB
4484    movl      offThread_methodClassDex(rINST),%ecx # ecx<- pDvmDex
4485    EXPORT_PC
4486    movl      offDvmDex_pResMethods(%ecx),%ecx # ecx<- pDvmDex->pResMethods
4487    movl      (%ecx,%eax,4),%ecx        # ecx<- resolved baseMethod
4488    movl      offThread_method(rINST),%eax # eax<- method
4489    movzwl    4(rPC),rINST              # rINST<- GFED or CCCC
4490    .if       (!1)
4491    andl      $0xf,rINST               # rINST<- D (or stays CCCC)
4492    .endif
4493    GET_VREG_R  %edx rINST             # %edx<- "this" ptr
4494    testl     %edx,%edx                # null "this"?
4495    SPILL_TMP1(%edx)
4496    je        common_errNullObject      # yes, throw
4497    movl      offMethod_clazz(%eax),%eax # eax<- method->clazz
4498    testl     %ecx,%ecx                 # already resolved?
4499    je       .LOP_INVOKE_SUPER_RANGE_resolve
4500    /*
4501     * At this point:
4502     *  ecx = resolved base method [r0]
4503     *  eax = method->clazz [r9]
4504     */
4505.LOP_INVOKE_SUPER_RANGE_continue:
4506    movl    offClassObject_super(%eax),%eax   # eax<- method->clazz->super
4507    movzwl  offMethod_methodIndex(%ecx),%edx  # edx<- baseMthod->methodIndex
4508    cmpl    offClassObject_vtableCount(%eax),%edx # compare(methodIndex,vtableCount)
4509    jae     .LOP_INVOKE_SUPER_RANGE_nsm           # method not present in superclass
4510    movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
4511    movl    (%eax,%edx,4),%eax        # eax<- vtable[methodIndex]
4512    UNSPILL_TMP1(%edx)
4513    movl    %edx, %ecx
4514    jmp     common_invokeMethodRange
4515
4516
4517    /* At this point:
4518     * ecx = null (needs to be resolved base method)
4519     * eax = method->clazz
4520    */
4521.LOP_INVOKE_SUPER_RANGE_resolve:
4522    SPILL_TMP2(%eax)                    # method->clazz
4523    movl    %eax,OUT_ARG0(%esp)         # arg0<- method->clazz
4524    movzwl  2(rPC),%ecx                 # ecx<- BBBB
4525    movl    $METHOD_VIRTUAL,OUT_ARG2(%esp)  # arg2<- resolver method type
4526    movl    %ecx,OUT_ARG1(%esp)         # arg1<- ref
4527    call    dvmResolveMethod            # eax<- call(clazz, ref, flags)
4528    testl   %eax,%eax                   # got null?
4529    movl    %eax,%ecx                   # ecx<- resolved base method
4530    UNSPILL_TMP2(%eax)                  # restore method->clazz
4531    jne     .LOP_INVOKE_SUPER_RANGE_continue        # good to go - continue
4532    jmp     common_exceptionThrown      # handle exception
4533
4534    /*
4535     * Throw a NoSuchMethodError with the method name as the message.
4536     *  ecx = resolved base method
4537     */
4538.LOP_INVOKE_SUPER_RANGE_nsm:
4539    movl    offMethod_name(%ecx),%eax
4540    jmp     common_errNoSuchMethod
4541
4542
4543/* ------------------------------ */
4544.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
4545/* File: x86/OP_INVOKE_DIRECT_RANGE.S */
4546/* File: x86/OP_INVOKE_DIRECT.S */
4547    /*
4548     * Handle a direct method call.
4549     *
4550     * (We could defer the "is 'this' pointer null" test to the common
4551     * method invocation code, and use a flag to indicate that static
4552     * calls don't count.  If we do this as part of copying the arguments
4553     * out we could avoiding loading the first arg twice.)
4554     *
4555     * for: invoke-direct, invoke-direct/range
4556     */
4557    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
4558    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
4559    movl      rSELF,%ecx
4560    movzwl    2(rPC),%eax              # eax<- BBBB
4561    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
4562    EXPORT_PC
4563    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
4564    movzwl    4(rPC),rIBASE            # rIBASE<- GFED or CCCC
4565    movl      (%ecx,%eax,4),%eax       # eax<- resolved methodToCall
4566    .if       (!1)
4567    andl      $0xf,rIBASE             # rIBASE<- D (or stays CCCC)
4568    .endif
4569    testl     %eax,%eax                # already resolved?
4570    GET_VREG_R  %ecx rIBASE            # ecx<- "this" ptr
4571    je        .LOP_INVOKE_DIRECT_RANGE_resolve      # not resolved, do it now
4572.LOP_INVOKE_DIRECT_RANGE_finish:
4573    testl     %ecx,%ecx                # null "this"?
4574    jne       common_invokeMethodRange  # no, continue on
4575    jmp       common_errNullObject
4576
4577    /*
4578     * On entry:
4579     *   TMP_SPILL  <- "this" register
4580     * Things a bit ugly on this path, but it's the less
4581     * frequent one.  We'll have to do some reloading.
4582     */
4583.LOP_INVOKE_DIRECT_RANGE_resolve:
4584     SPILL_TMP1(%ecx)
4585     movl     rSELF,%ecx
4586     movl     offThread_method(%ecx),%ecx  # ecx<- self->method
4587     movzwl   2(rPC),%eax      # reference (BBBB or CCCC)
4588     movl     offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
4589     movl     $METHOD_DIRECT,OUT_ARG2(%esp)
4590     movl     %eax,OUT_ARG1(%esp)
4591     movl     %ecx,OUT_ARG0(%esp)
4592     call     dvmResolveMethod # eax<- call(clazz, ref, flags)
4593     UNSPILL_TMP1(%ecx)
4594     testl    %eax,%eax
4595     jne      .LOP_INVOKE_DIRECT_RANGE_finish
4596     jmp      common_exceptionThrown
4597
4598
4599/* ------------------------------ */
4600.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */
4601/* File: x86/OP_INVOKE_STATIC_RANGE.S */
4602/* File: x86/OP_INVOKE_STATIC.S */
4603    /*
4604     * Handle a static method call.
4605     *
4606     * for: invoke-static, invoke-static/range
4607     */
4608    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
4609    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
4610    movl      rSELF,%ecx
4611    movzwl    2(rPC),%eax               # eax<- BBBB
4612    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
4613    EXPORT_PC
4614    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
4615#if defined(WITH_JIT)
4616    movl     %edx, TMP_SPILL1(%ebp)
4617    lea      (%ecx,%eax,4), %edx
4618    movl     %edx, TMP_SPILL2(%ebp)
4619    movl     TMP_SPILL1(%ebp), %edx
4620#endif
4621    movl      (%ecx,%eax,4),%eax        # eax<- resolved methodToCall
4622    movl      $0, %ecx                 # make "this" null
4623    testl     %eax,%eax
4624    jne       common_invokeMethodRange
4625
4626    movl      rSELF,%ecx
4627    movl      offThread_method(%ecx),%ecx # ecx<- self->method
4628    movzwl    2(rPC),%eax
4629    movl      offMethod_clazz(%ecx),%ecx# ecx<- method->clazz
4630    movl      %eax,OUT_ARG1(%esp)       # arg1<- BBBB
4631    movl      %ecx,OUT_ARG0(%esp)       # arg0<- clazz
4632    movl      $METHOD_STATIC,%eax
4633    movl      %eax,OUT_ARG2(%esp)       # arg2<- flags
4634    SPILL(rIBASE)
4635    call      dvmResolveMethod          # call(clazz,ref,flags)
4636    UNSPILL(rIBASE)
4637    testl     %eax,%eax                 # got null?
4638#if defined(WITH_JIT)
4639    movl      TMP_SPILL1(%ebp), %edx
4640    movl      rSELF,%ecx
4641    movzwl    offThread_subMode(%ecx), %ecx
4642    je        common_exceptionThrown    # null, handle exception
4643    andl      $kSubModeJitTraceBuild, %ecx # is trace under construction?
4644    movl      $0, %ecx                 # make "this" null
4645    je        common_invokeMethodRange # no (%eax=method, %ecx="this")
4646    movl      TMP_SPILL2(%ebp), %edx
4647    cmpl      $0, (%edx)                  # finished resolving
4648    movl      TMP_SPILL1(%ebp), %edx
4649    jne        common_invokeMethodRange # yes (%eax=method, %ecx="this")
4650    movl      rSELF, %edx
4651    movl      %edx, OUT_ARG0(%esp)
4652    movl      rPC, OUT_ARG1(%esp)
4653    movl      %eax, TMP_SPILL2(%ebp)
4654    movl      %ecx, TMP_SPILL3(%ebp)
4655    SPILL(rIBASE)
4656    call      dvmJitEndTraceSelect
4657    UNSPILL(rIBASE)
4658    movl      TMP_SPILL1(%ebp), %edx
4659    movl      TMP_SPILL2(%ebp), %eax
4660    movl      TMP_SPILL3(%ebp), %ecx
4661    jmp       common_invokeMethodRange
4662#else
4663    movl      $0, %ecx                 # make "this" null
4664    jne       common_invokeMethodRange
4665    jmp       common_exceptionThrown
4666#endif
4667
4668
4669
4670/* ------------------------------ */
4671.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
4672/* File: x86/OP_INVOKE_INTERFACE_RANGE.S */
4673/* File: x86/OP_INVOKE_INTERFACE.S */
4674    /*
4675     * Handle an interface method call.
4676     *
4677     * for: invoke-interface, invoke-interface/range
4678     */
4679    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
4680    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
4681    movzwl     4(rPC),%eax              # eax<- FEDC or CCCC
4682    movl       rSELF,%ecx
4683    .if        (!1)
4684    andl       $0xf,%eax               # eax<- C (or stays CCCC)
4685    .endif
4686    GET_VREG_R   %eax %eax              # eax<- "this"
4687    EXPORT_PC
4688    testl      %eax,%eax                # null this?
4689    je         common_errNullObject     # yes, fail
4690    movl       %eax, TMP_SPILL1(%ebp)
4691    movl       offObject_clazz(%eax),%eax# eax<- thisPtr->clazz
4692    movl       %eax,OUT_ARG0(%esp)                 # arg0<- class
4693    movl       offThread_methodClassDex(%ecx),%eax   # eax<- methodClassDex
4694    movl       offThread_method(%ecx),%ecx           # ecx<- method
4695    movl       %eax,OUT_ARG3(%esp)                 # arg3<- dex
4696    movzwl     2(rPC),%eax                         # eax<- BBBB
4697    movl       %ecx,OUT_ARG2(%esp)                 # arg2<- method
4698    movl       %eax,OUT_ARG1(%esp)                 # arg1<- BBBB
4699    call       dvmFindInterfaceMethodInCache # eax<- call(class, ref, method, dex)
4700    testl      %eax,%eax
4701    je         common_exceptionThrown
4702    movl       TMP_SPILL1(%ebp), %ecx
4703    jmp        common_invokeMethodRange
4704
4705
4706/* ------------------------------ */
4707.L_OP_UNUSED_79: /* 0x79 */
4708/* File: x86/OP_UNUSED_79.S */
4709/* File: x86/unused.S */
4710    jmp     common_abort
4711
4712
4713/* ------------------------------ */
4714.L_OP_UNUSED_7A: /* 0x7a */
4715/* File: x86/OP_UNUSED_7A.S */
4716/* File: x86/unused.S */
4717    jmp     common_abort
4718
4719
4720/* ------------------------------ */
4721.L_OP_NEG_INT: /* 0x7b */
4722/* File: x86/OP_NEG_INT.S */
4723/* File: x86/unop.S */
4724    /*
4725     * Generic 32-bit unary operation.  Provide an "instr" line that
4726     * specifies an instruction that performs "result = op eax".
4727     */
4728    /* unop vA, vB */
4729    movzbl   rINSTbl,%ecx           # ecx<- A+
4730    sarl     $4,rINST             # rINST<- B
4731    GET_VREG_R %eax rINST           # eax<- vB
4732    andb     $0xf,%cl              # ecx<- A
4733
4734
4735    negl %eax
4736    SET_VREG %eax %ecx
4737    FETCH_INST_OPCODE 1 %ecx
4738    ADVANCE_PC 1
4739    GOTO_NEXT_R %ecx
4740
4741
4742/* ------------------------------ */
4743.L_OP_NOT_INT: /* 0x7c */
4744/* File: x86/OP_NOT_INT.S */
4745/* File: x86/unop.S */
4746    /*
4747     * Generic 32-bit unary operation.  Provide an "instr" line that
4748     * specifies an instruction that performs "result = op eax".
4749     */
4750    /* unop vA, vB */
4751    movzbl   rINSTbl,%ecx           # ecx<- A+
4752    sarl     $4,rINST             # rINST<- B
4753    GET_VREG_R %eax rINST           # eax<- vB
4754    andb     $0xf,%cl              # ecx<- A
4755
4756
4757    notl %eax
4758    SET_VREG %eax %ecx
4759    FETCH_INST_OPCODE 1 %ecx
4760    ADVANCE_PC 1
4761    GOTO_NEXT_R %ecx
4762
4763
4764/* ------------------------------ */
4765.L_OP_NEG_LONG: /* 0x7d */
4766/* File: x86/OP_NEG_LONG.S */
4767    /* unop vA, vB */
4768    movzbl    rINSTbl,%ecx        # ecx<- BA
4769    sarl      $4,%ecx            # ecx<- B
4770    andb      $0xf,rINSTbl       # rINST<- A
4771    GET_VREG_WORD %eax %ecx 0     # eax<- v[B+0]
4772    GET_VREG_WORD %ecx %ecx 1     # ecx<- v[B+1]
4773    negl      %eax
4774    adcl      $0,%ecx
4775    negl      %ecx
4776    SET_VREG_WORD %eax rINST 0    # v[A+0]<- eax
4777    FETCH_INST_OPCODE 1 %eax
4778    SET_VREG_WORD %ecx rINST 1    # v[A+1]<- ecx
4779    ADVANCE_PC 1
4780    GOTO_NEXT_R %eax
4781
4782/* ------------------------------ */
4783.L_OP_NOT_LONG: /* 0x7e */
4784/* File: x86/OP_NOT_LONG.S */
4785    /* unop vA, vB */
4786    movzbl    rINSTbl,%ecx       # ecx<- BA
4787    sarl      $4,%ecx           # ecx<- B
4788    andb      $0xf,rINSTbl      # rINST<- A
4789    GET_VREG_WORD %eax %ecx 0    # eax<- v[B+0]
4790    GET_VREG_WORD %ecx %ecx 1    # ecx<- v[B+1]
4791    notl      %eax
4792    notl      %ecx
4793    SET_VREG_WORD %eax rINST 0   # v[A+0]<- eax
4794    FETCH_INST_OPCODE 1 %eax
4795    SET_VREG_WORD %ecx rINST 1   # v[A+1]<- ecx
4796    ADVANCE_PC 1
4797    GOTO_NEXT_R %eax
4798
4799/* ------------------------------ */
4800.L_OP_NEG_FLOAT: /* 0x7f */
4801/* File: x86/OP_NEG_FLOAT.S */
4802/* File: x86/fpcvt.S */
4803    /*
4804     * Generic 32-bit FP conversion operation.
4805     */
4806    /* unop vA, vB */
4807    movzbl   rINSTbl,%ecx       # ecx<- A+
4808    sarl     $4,rINST         # rINST<- B
4809    flds    (rFP,rINST,4)      # %st0<- vB
4810    andb     $0xf,%cl          # ecx<- A
4811    fchs
4812    fstps  (rFP,%ecx,4)        # vA<- %st0
4813    FETCH_INST_OPCODE 1 %ecx
4814    ADVANCE_PC 1
4815    GOTO_NEXT_R %ecx
4816
4817
4818/* ------------------------------ */
4819.L_OP_NEG_DOUBLE: /* 0x80 */
4820/* File: x86/OP_NEG_DOUBLE.S */
4821/* File: x86/fpcvt.S */
4822    /*
4823     * Generic 32-bit FP conversion operation.
4824     */
4825    /* unop vA, vB */
4826    movzbl   rINSTbl,%ecx       # ecx<- A+
4827    sarl     $4,rINST         # rINST<- B
4828    fldl    (rFP,rINST,4)      # %st0<- vB
4829    andb     $0xf,%cl          # ecx<- A
4830    fchs
4831    fstpl  (rFP,%ecx,4)        # vA<- %st0
4832    FETCH_INST_OPCODE 1 %ecx
4833    ADVANCE_PC 1
4834    GOTO_NEXT_R %ecx
4835
4836
4837/* ------------------------------ */
4838.L_OP_INT_TO_LONG: /* 0x81 */
4839/* File: x86/OP_INT_TO_LONG.S */
4840    /* int to long vA, vB */
4841    movzbl  rINSTbl,%eax                # eax<- +A
4842    sarl    $4,%eax                    # eax<- B
4843    GET_VREG_R %eax %eax                # eax<- vB
4844    andb    $0xf,rINSTbl               # rINST<- A
4845    SPILL(rIBASE)                       # cltd trashes rIBASE/edx
4846    cltd                                # rINST:eax<- sssssssBBBBBBBB
4847    SET_VREG_WORD rIBASE rINST 1        # v[A+1]<- rIBASE/rPC
4848    FETCH_INST_OPCODE 1 %ecx
4849    UNSPILL(rIBASE)
4850    SET_VREG_WORD %eax rINST 0          # v[A+0]<- %eax
4851    ADVANCE_PC 1
4852    GOTO_NEXT_R %ecx
4853
4854/* ------------------------------ */
4855.L_OP_INT_TO_FLOAT: /* 0x82 */
4856/* File: x86/OP_INT_TO_FLOAT.S */
4857/* File: x86/fpcvt.S */
4858    /*
4859     * Generic 32-bit FP conversion operation.
4860     */
4861    /* unop vA, vB */
4862    movzbl   rINSTbl,%ecx       # ecx<- A+
4863    sarl     $4,rINST         # rINST<- B
4864    fildl    (rFP,rINST,4)      # %st0<- vB
4865    andb     $0xf,%cl          # ecx<- A
4866
4867    fstps  (rFP,%ecx,4)        # vA<- %st0
4868    FETCH_INST_OPCODE 1 %ecx
4869    ADVANCE_PC 1
4870    GOTO_NEXT_R %ecx
4871
4872
4873/* ------------------------------ */
4874.L_OP_INT_TO_DOUBLE: /* 0x83 */
4875/* File: x86/OP_INT_TO_DOUBLE.S */
4876/* File: x86/fpcvt.S */
4877    /*
4878     * Generic 32-bit FP conversion operation.
4879     */
4880    /* unop vA, vB */
4881    movzbl   rINSTbl,%ecx       # ecx<- A+
4882    sarl     $4,rINST         # rINST<- B
4883    fildl    (rFP,rINST,4)      # %st0<- vB
4884    andb     $0xf,%cl          # ecx<- A
4885
4886    fstpl  (rFP,%ecx,4)        # vA<- %st0
4887    FETCH_INST_OPCODE 1 %ecx
4888    ADVANCE_PC 1
4889    GOTO_NEXT_R %ecx
4890
4891
4892/* ------------------------------ */
4893.L_OP_LONG_TO_INT: /* 0x84 */
4894/* File: x86/OP_LONG_TO_INT.S */
4895/* we ignore the high word, making this equivalent to a 32-bit reg move */
4896/* File: x86/OP_MOVE.S */
4897    /* for move, move-object, long-to-int */
4898    /* op vA, vB */
4899    movzbl rINSTbl,%eax          # eax<- BA
4900    andb   $0xf,%al             # eax<- A
4901    shrl   $4,rINST            # rINST<- B
4902    GET_VREG_R rINST rINST
4903    FETCH_INST_OPCODE 1 %ecx
4904    ADVANCE_PC 1
4905    SET_VREG rINST %eax           # fp[A]<-fp[B]
4906    GOTO_NEXT_R %ecx
4907
4908
4909/* ------------------------------ */
4910.L_OP_LONG_TO_FLOAT: /* 0x85 */
4911/* File: x86/OP_LONG_TO_FLOAT.S */
4912/* File: x86/fpcvt.S */
4913    /*
4914     * Generic 32-bit FP conversion operation.
4915     */
4916    /* unop vA, vB */
4917    movzbl   rINSTbl,%ecx       # ecx<- A+
4918    sarl     $4,rINST         # rINST<- B
4919    fildll    (rFP,rINST,4)      # %st0<- vB
4920    andb     $0xf,%cl          # ecx<- A
4921
4922    fstps  (rFP,%ecx,4)        # vA<- %st0
4923    FETCH_INST_OPCODE 1 %ecx
4924    ADVANCE_PC 1
4925    GOTO_NEXT_R %ecx
4926
4927
4928/* ------------------------------ */
4929.L_OP_LONG_TO_DOUBLE: /* 0x86 */
4930/* File: x86/OP_LONG_TO_DOUBLE.S */
4931/* File: x86/fpcvt.S */
4932    /*
4933     * Generic 32-bit FP conversion operation.
4934     */
4935    /* unop vA, vB */
4936    movzbl   rINSTbl,%ecx       # ecx<- A+
4937    sarl     $4,rINST         # rINST<- B
4938    fildll    (rFP,rINST,4)      # %st0<- vB
4939    andb     $0xf,%cl          # ecx<- A
4940
4941    fstpl  (rFP,%ecx,4)        # vA<- %st0
4942    FETCH_INST_OPCODE 1 %ecx
4943    ADVANCE_PC 1
4944    GOTO_NEXT_R %ecx
4945
4946
4947/* ------------------------------ */
4948.L_OP_FLOAT_TO_INT: /* 0x87 */
4949/* File: x86/OP_FLOAT_TO_INT.S */
4950/* File: x86/cvtfp_int.S */
4951/* On fp to int conversions, Java requires that
4952 * if the result > maxint, it should be clamped to maxint.  If it is less
4953 * than minint, it should be clamped to minint.  If it is a nan, the result
4954 * should be zero.  Further, the rounding mode is to truncate.  This model
4955 * differs from what is delivered normally via the x86 fpu, so we have
4956 * to play some games.
4957 */
4958    /* float/double to int/long vA, vB */
4959    movzbl    rINSTbl,%ecx       # ecx<- A+
4960    sarl      $4,rINST         # rINST<- B
4961    .if 0
4962    fldl     (rFP,rINST,4)       # %st0<- vB
4963    .else
4964    flds     (rFP,rINST,4)       # %st0<- vB
4965    .endif
4966    ftst
4967    fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
4968    movzwl   LOCAL0_OFFSET(%ebp),%eax
4969    movb     $0xc,%ah
4970    movw     %ax,LOCAL0_OFFSET+2(%ebp)
4971    fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
4972    andb     $0xf,%cl                # ecx<- A
4973    .if 0
4974    fistpll  (rFP,%ecx,4)             # convert and store
4975    .else
4976    fistpl   (rFP,%ecx,4)             # convert and store
4977    .endif
4978    fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
4979    .if 0
4980    movl     $0x80000000,%eax
4981    xorl     4(rFP,%ecx,4),%eax
4982    orl      (rFP,%ecx,4),%eax
4983    .else
4984    cmpl     $0x80000000,(rFP,%ecx,4)
4985    .endif
4986    je       .LOP_FLOAT_TO_INT_special_case # fix up result
4987
4988.LOP_FLOAT_TO_INT_finish:
4989    FETCH_INST_OPCODE 1 %ecx
4990    ADVANCE_PC 1
4991    GOTO_NEXT_R %ecx
4992
4993.LOP_FLOAT_TO_INT_special_case:
4994    fnstsw   %ax
4995    sahf
4996    jp       .LOP_FLOAT_TO_INT_isNaN
4997    adcl     $-1,(rFP,%ecx,4)
4998    .if 0
4999    adcl     $-1,4(rFP,%ecx,4)
5000    .endif
5001   jmp       .LOP_FLOAT_TO_INT_finish
5002.LOP_FLOAT_TO_INT_isNaN:
5003    movl      $0,(rFP,%ecx,4)
5004    .if 0
5005    movl      $0,4(rFP,%ecx,4)
5006    .endif
5007    jmp       .LOP_FLOAT_TO_INT_finish
5008
5009
5010/* ------------------------------ */
5011.L_OP_FLOAT_TO_LONG: /* 0x88 */
5012/* File: x86/OP_FLOAT_TO_LONG.S */
5013/* File: x86/cvtfp_int.S */
5014/* On fp to int conversions, Java requires that
5015 * if the result > maxint, it should be clamped to maxint.  If it is less
5016 * than minint, it should be clamped to minint.  If it is a nan, the result
5017 * should be zero.  Further, the rounding mode is to truncate.  This model
5018 * differs from what is delivered normally via the x86 fpu, so we have
5019 * to play some games.
5020 */
5021    /* float/double to int/long vA, vB */
5022    movzbl    rINSTbl,%ecx       # ecx<- A+
5023    sarl      $4,rINST         # rINST<- B
5024    .if 0
5025    fldl     (rFP,rINST,4)       # %st0<- vB
5026    .else
5027    flds     (rFP,rINST,4)       # %st0<- vB
5028    .endif
5029    ftst
5030    fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
5031    movzwl   LOCAL0_OFFSET(%ebp),%eax
5032    movb     $0xc,%ah
5033    movw     %ax,LOCAL0_OFFSET+2(%ebp)
5034    fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
5035    andb     $0xf,%cl                # ecx<- A
5036    .if 1
5037    fistpll  (rFP,%ecx,4)             # convert and store
5038    .else
5039    fistpl   (rFP,%ecx,4)             # convert and store
5040    .endif
5041    fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
5042    .if 1
5043    movl     $0x80000000,%eax
5044    xorl     4(rFP,%ecx,4),%eax
5045    orl      (rFP,%ecx,4),%eax
5046    .else
5047    cmpl     $0x80000000,(rFP,%ecx,4)
5048    .endif
5049    je       .LOP_FLOAT_TO_LONG_special_case # fix up result
5050
5051.LOP_FLOAT_TO_LONG_finish:
5052    FETCH_INST_OPCODE 1 %ecx
5053    ADVANCE_PC 1
5054    GOTO_NEXT_R %ecx
5055
5056.LOP_FLOAT_TO_LONG_special_case:
5057    fnstsw   %ax
5058    sahf
5059    jp       .LOP_FLOAT_TO_LONG_isNaN
5060    adcl     $-1,(rFP,%ecx,4)
5061    .if 1
5062    adcl     $-1,4(rFP,%ecx,4)
5063    .endif
5064   jmp       .LOP_FLOAT_TO_LONG_finish
5065.LOP_FLOAT_TO_LONG_isNaN:
5066    movl      $0,(rFP,%ecx,4)
5067    .if 1
5068    movl      $0,4(rFP,%ecx,4)
5069    .endif
5070    jmp       .LOP_FLOAT_TO_LONG_finish
5071
5072
5073/* ------------------------------ */
5074.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */
5075/* File: x86/OP_FLOAT_TO_DOUBLE.S */
5076/* File: x86/fpcvt.S */
5077    /*
5078     * Generic 32-bit FP conversion operation.
5079     */
5080    /* unop vA, vB */
5081    movzbl   rINSTbl,%ecx       # ecx<- A+
5082    sarl     $4,rINST         # rINST<- B
5083    flds    (rFP,rINST,4)      # %st0<- vB
5084    andb     $0xf,%cl          # ecx<- A
5085
5086    fstpl  (rFP,%ecx,4)        # vA<- %st0
5087    FETCH_INST_OPCODE 1 %ecx
5088    ADVANCE_PC 1
5089    GOTO_NEXT_R %ecx
5090
5091
5092/* ------------------------------ */
5093.L_OP_DOUBLE_TO_INT: /* 0x8a */
5094/* File: x86/OP_DOUBLE_TO_INT.S */
5095/* File: x86/cvtfp_int.S */
5096/* On fp to int conversions, Java requires that
5097 * if the result > maxint, it should be clamped to maxint.  If it is less
5098 * than minint, it should be clamped to minint.  If it is a nan, the result
5099 * should be zero.  Further, the rounding mode is to truncate.  This model
5100 * differs from what is delivered normally via the x86 fpu, so we have
5101 * to play some games.
5102 */
5103    /* float/double to int/long vA, vB */
5104    movzbl    rINSTbl,%ecx       # ecx<- A+
5105    sarl      $4,rINST         # rINST<- B
5106    .if 1
5107    fldl     (rFP,rINST,4)       # %st0<- vB
5108    .else
5109    flds     (rFP,rINST,4)       # %st0<- vB
5110    .endif
5111    ftst
5112    fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
5113    movzwl   LOCAL0_OFFSET(%ebp),%eax
5114    movb     $0xc,%ah
5115    movw     %ax,LOCAL0_OFFSET+2(%ebp)
5116    fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
5117    andb     $0xf,%cl                # ecx<- A
5118    .if 0
5119    fistpll  (rFP,%ecx,4)             # convert and store
5120    .else
5121    fistpl   (rFP,%ecx,4)             # convert and store
5122    .endif
5123    fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
5124    .if 0
5125    movl     $0x80000000,%eax
5126    xorl     4(rFP,%ecx,4),%eax
5127    orl      (rFP,%ecx,4),%eax
5128    .else
5129    cmpl     $0x80000000,(rFP,%ecx,4)
5130    .endif
5131    je       .LOP_DOUBLE_TO_INT_special_case # fix up result
5132
5133.LOP_DOUBLE_TO_INT_finish:
5134    FETCH_INST_OPCODE 1 %ecx
5135    ADVANCE_PC 1
5136    GOTO_NEXT_R %ecx
5137
5138.LOP_DOUBLE_TO_INT_special_case:
5139    fnstsw   %ax
5140    sahf
5141    jp       .LOP_DOUBLE_TO_INT_isNaN
5142    adcl     $-1,(rFP,%ecx,4)
5143    .if 0
5144    adcl     $-1,4(rFP,%ecx,4)
5145    .endif
5146   jmp       .LOP_DOUBLE_TO_INT_finish
5147.LOP_DOUBLE_TO_INT_isNaN:
5148    movl      $0,(rFP,%ecx,4)
5149    .if 0
5150    movl      $0,4(rFP,%ecx,4)
5151    .endif
5152    jmp       .LOP_DOUBLE_TO_INT_finish
5153
5154
5155/* ------------------------------ */
5156.L_OP_DOUBLE_TO_LONG: /* 0x8b */
5157/* File: x86/OP_DOUBLE_TO_LONG.S */
5158/* File: x86/cvtfp_int.S */
5159/* On fp to int conversions, Java requires that
5160 * if the result > maxint, it should be clamped to maxint.  If it is less
5161 * than minint, it should be clamped to minint.  If it is a nan, the result
5162 * should be zero.  Further, the rounding mode is to truncate.  This model
5163 * differs from what is delivered normally via the x86 fpu, so we have
5164 * to play some games.
5165 */
5166    /* float/double to int/long vA, vB */
5167    movzbl    rINSTbl,%ecx       # ecx<- A+
5168    sarl      $4,rINST         # rINST<- B
5169    .if 1
5170    fldl     (rFP,rINST,4)       # %st0<- vB
5171    .else
5172    flds     (rFP,rINST,4)       # %st0<- vB
5173    .endif
5174    ftst
5175    fnstcw   LOCAL0_OFFSET(%ebp)      # remember original rounding mode
5176    movzwl   LOCAL0_OFFSET(%ebp),%eax
5177    movb     $0xc,%ah
5178    movw     %ax,LOCAL0_OFFSET+2(%ebp)
5179    fldcw    LOCAL0_OFFSET+2(%ebp)    # set "to zero" rounding mode
5180    andb     $0xf,%cl                # ecx<- A
5181    .if 1
5182    fistpll  (rFP,%ecx,4)             # convert and store
5183    .else
5184    fistpl   (rFP,%ecx,4)             # convert and store
5185    .endif
5186    fldcw    LOCAL0_OFFSET(%ebp)      # restore previous rounding mode
5187    .if 1
5188    movl     $0x80000000,%eax
5189    xorl     4(rFP,%ecx,4),%eax
5190    orl      (rFP,%ecx,4),%eax
5191    .else
5192    cmpl     $0x80000000,(rFP,%ecx,4)
5193    .endif
5194    je       .LOP_DOUBLE_TO_LONG_special_case # fix up result
5195
5196.LOP_DOUBLE_TO_LONG_finish:
5197    FETCH_INST_OPCODE 1 %ecx
5198    ADVANCE_PC 1
5199    GOTO_NEXT_R %ecx
5200
5201.LOP_DOUBLE_TO_LONG_special_case:
5202    fnstsw   %ax
5203    sahf
5204    jp       .LOP_DOUBLE_TO_LONG_isNaN
5205    adcl     $-1,(rFP,%ecx,4)
5206    .if 1
5207    adcl     $-1,4(rFP,%ecx,4)
5208    .endif
5209   jmp       .LOP_DOUBLE_TO_LONG_finish
5210.LOP_DOUBLE_TO_LONG_isNaN:
5211    movl      $0,(rFP,%ecx,4)
5212    .if 1
5213    movl      $0,4(rFP,%ecx,4)
5214    .endif
5215    jmp       .LOP_DOUBLE_TO_LONG_finish
5216
5217
5218/* ------------------------------ */
5219.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */
5220/* File: x86/OP_DOUBLE_TO_FLOAT.S */
5221/* File: x86/fpcvt.S */
5222    /*
5223     * Generic 32-bit FP conversion operation.
5224     */
5225    /* unop vA, vB */
5226    movzbl   rINSTbl,%ecx       # ecx<- A+
5227    sarl     $4,rINST         # rINST<- B
5228    fldl    (rFP,rINST,4)      # %st0<- vB
5229    andb     $0xf,%cl          # ecx<- A
5230
5231    fstps  (rFP,%ecx,4)        # vA<- %st0
5232    FETCH_INST_OPCODE 1 %ecx
5233    ADVANCE_PC 1
5234    GOTO_NEXT_R %ecx
5235
5236
5237/* ------------------------------ */
5238.L_OP_INT_TO_BYTE: /* 0x8d */
5239/* File: x86/OP_INT_TO_BYTE.S */
5240/* File: x86/unop.S */
5241    /*
5242     * Generic 32-bit unary operation.  Provide an "instr" line that
5243     * specifies an instruction that performs "result = op eax".
5244     */
5245    /* unop vA, vB */
5246    movzbl   rINSTbl,%ecx           # ecx<- A+
5247    sarl     $4,rINST             # rINST<- B
5248    GET_VREG_R %eax rINST           # eax<- vB
5249    andb     $0xf,%cl              # ecx<- A
5250
5251
5252    movsbl %al,%eax
5253    SET_VREG %eax %ecx
5254    FETCH_INST_OPCODE 1 %ecx
5255    ADVANCE_PC 1
5256    GOTO_NEXT_R %ecx
5257
5258
5259/* ------------------------------ */
5260.L_OP_INT_TO_CHAR: /* 0x8e */
5261/* File: x86/OP_INT_TO_CHAR.S */
5262/* File: x86/unop.S */
5263    /*
5264     * Generic 32-bit unary operation.  Provide an "instr" line that
5265     * specifies an instruction that performs "result = op eax".
5266     */
5267    /* unop vA, vB */
5268    movzbl   rINSTbl,%ecx           # ecx<- A+
5269    sarl     $4,rINST             # rINST<- B
5270    GET_VREG_R %eax rINST           # eax<- vB
5271    andb     $0xf,%cl              # ecx<- A
5272
5273
5274    movzwl %ax,%eax
5275    SET_VREG %eax %ecx
5276    FETCH_INST_OPCODE 1 %ecx
5277    ADVANCE_PC 1
5278    GOTO_NEXT_R %ecx
5279
5280
5281/* ------------------------------ */
5282.L_OP_INT_TO_SHORT: /* 0x8f */
5283/* File: x86/OP_INT_TO_SHORT.S */
5284/* File: x86/unop.S */
5285    /*
5286     * Generic 32-bit unary operation.  Provide an "instr" line that
5287     * specifies an instruction that performs "result = op eax".
5288     */
5289    /* unop vA, vB */
5290    movzbl   rINSTbl,%ecx           # ecx<- A+
5291    sarl     $4,rINST             # rINST<- B
5292    GET_VREG_R %eax rINST           # eax<- vB
5293    andb     $0xf,%cl              # ecx<- A
5294
5295
5296    movswl %ax,%eax
5297    SET_VREG %eax %ecx
5298    FETCH_INST_OPCODE 1 %ecx
5299    ADVANCE_PC 1
5300    GOTO_NEXT_R %ecx
5301
5302
5303/* ------------------------------ */
5304.L_OP_ADD_INT: /* 0x90 */
5305/* File: x86/OP_ADD_INT.S */
5306/* File: x86/binop.S */
5307    /*
5308     * Generic 32-bit binary operation.  Provide an "instr" line that
5309     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
5310     * This could be an x86 instruction or a function call.  (If the result
5311     * comes back in a register other than eax, you can override "result".)
5312     *
5313     * For: add-int, sub-int, and-int, or-int,
5314     *      xor-int, shl-int, shr-int, ushr-int
5315     */
5316    /* binop vAA, vBB, vCC */
5317    movzbl   2(rPC),%eax   # eax<- BB
5318    movzbl   3(rPC),%ecx   # ecx<- CC
5319    GET_VREG_R %eax %eax   # eax<- vBB
5320    addl (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
5321    SET_VREG %eax rINST
5322    FETCH_INST_OPCODE 2 %ecx
5323    ADVANCE_PC 2
5324    GOTO_NEXT_R %ecx
5325
5326
5327/* ------------------------------ */
5328.L_OP_SUB_INT: /* 0x91 */
5329/* File: x86/OP_SUB_INT.S */
5330/* File: x86/binop.S */
5331    /*
5332     * Generic 32-bit binary operation.  Provide an "instr" line that
5333     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
5334     * This could be an x86 instruction or a function call.  (If the result
5335     * comes back in a register other than eax, you can override "result".)
5336     *
5337     * For: add-int, sub-int, and-int, or-int,
5338     *      xor-int, shl-int, shr-int, ushr-int
5339     */
5340    /* binop vAA, vBB, vCC */
5341    movzbl   2(rPC),%eax   # eax<- BB
5342    movzbl   3(rPC),%ecx   # ecx<- CC
5343    GET_VREG_R %eax %eax   # eax<- vBB
5344    subl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
5345    SET_VREG %eax rINST
5346    FETCH_INST_OPCODE 2 %ecx
5347    ADVANCE_PC 2
5348    GOTO_NEXT_R %ecx
5349
5350
5351/* ------------------------------ */
5352.L_OP_MUL_INT: /* 0x92 */
5353/* File: x86/OP_MUL_INT.S */
5354    /*
5355     * 32-bit binary multiplication.
5356     */
5357    /* mul vAA, vBB, vCC */
5358    movzbl   2(rPC),%eax            # eax<- BB
5359    movzbl   3(rPC),%ecx            # ecx<- CC
5360    GET_VREG_R %eax %eax            # eax<- vBB
5361    SPILL(rIBASE)
5362    imull    (rFP,%ecx,4),%eax      # trashes rIBASE/edx
5363    UNSPILL(rIBASE)
5364    FETCH_INST_OPCODE 2 %ecx
5365    ADVANCE_PC 2
5366    SET_VREG %eax rINST
5367    GOTO_NEXT_R %ecx
5368
5369/* ------------------------------ */
5370.L_OP_DIV_INT: /* 0x93 */
5371/* File: x86/OP_DIV_INT.S */
5372/* File: x86/bindiv.S */
5373
5374    /*
5375     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
5376     * op1=-1.
5377     */
5378    /* binop vAA, vBB, vCC */
5379    movzbl   2(rPC),%eax            # eax<- BB
5380    movzbl   3(rPC),%ecx            # ecx<- CC
5381    GET_VREG_R %eax %eax            # eax<- vBB
5382    GET_VREG_R %ecx %ecx            # eax<- vBB
5383    SPILL(rIBASE)
5384    cmpl     $0,%ecx
5385    je       common_errDivideByZero
5386    cmpl     $-1,%ecx
5387    jne      .LOP_DIV_INT_continue_div
5388    cmpl     $0x80000000,%eax
5389    jne      .LOP_DIV_INT_continue_div
5390    movl     $0x80000000,%eax
5391    SET_VREG %eax rINST
5392    UNSPILL(rIBASE)
5393    FETCH_INST_OPCODE 2 %ecx
5394    ADVANCE_PC 2
5395    GOTO_NEXT_R %ecx
5396
5397.LOP_DIV_INT_continue_div:
5398    cltd
5399    idivl   %ecx
5400    SET_VREG %eax rINST
5401    UNSPILL(rIBASE)
5402    FETCH_INST_OPCODE 2 %ecx
5403    ADVANCE_PC 2
5404    GOTO_NEXT_R %ecx
5405
5406
5407/* ------------------------------ */
5408.L_OP_REM_INT: /* 0x94 */
5409/* File: x86/OP_REM_INT.S */
5410/* File: x86/bindiv.S */
5411
5412    /*
5413     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
5414     * op1=-1.
5415     */
5416    /* binop vAA, vBB, vCC */
5417    movzbl   2(rPC),%eax            # eax<- BB
5418    movzbl   3(rPC),%ecx            # ecx<- CC
5419    GET_VREG_R %eax %eax            # eax<- vBB
5420    GET_VREG_R %ecx %ecx            # eax<- vBB
5421    SPILL(rIBASE)
5422    cmpl     $0,%ecx
5423    je       common_errDivideByZero
5424    cmpl     $-1,%ecx
5425    jne      .LOP_REM_INT_continue_div
5426    cmpl     $0x80000000,%eax
5427    jne      .LOP_REM_INT_continue_div
5428    movl     $0,rIBASE
5429    SET_VREG rIBASE rINST
5430    UNSPILL(rIBASE)
5431    FETCH_INST_OPCODE 2 %ecx
5432    ADVANCE_PC 2
5433    GOTO_NEXT_R %ecx
5434
5435.LOP_REM_INT_continue_div:
5436    cltd
5437    idivl   %ecx
5438    SET_VREG rIBASE rINST
5439    UNSPILL(rIBASE)
5440    FETCH_INST_OPCODE 2 %ecx
5441    ADVANCE_PC 2
5442    GOTO_NEXT_R %ecx
5443
5444
5445/* ------------------------------ */
5446.L_OP_AND_INT: /* 0x95 */
5447/* File: x86/OP_AND_INT.S */
5448/* File: x86/binop.S */
5449    /*
5450     * Generic 32-bit binary operation.  Provide an "instr" line that
5451     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
5452     * This could be an x86 instruction or a function call.  (If the result
5453     * comes back in a register other than eax, you can override "result".)
5454     *
5455     * For: add-int, sub-int, and-int, or-int,
5456     *      xor-int, shl-int, shr-int, ushr-int
5457     */
5458    /* binop vAA, vBB, vCC */
5459    movzbl   2(rPC),%eax   # eax<- BB
5460    movzbl   3(rPC),%ecx   # ecx<- CC
5461    GET_VREG_R %eax %eax   # eax<- vBB
5462    andl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
5463    SET_VREG %eax rINST
5464    FETCH_INST_OPCODE 2 %ecx
5465    ADVANCE_PC 2
5466    GOTO_NEXT_R %ecx
5467
5468
5469/* ------------------------------ */
5470.L_OP_OR_INT: /* 0x96 */
5471/* File: x86/OP_OR_INT.S */
5472/* File: x86/binop.S */
5473    /*
5474     * Generic 32-bit binary operation.  Provide an "instr" line that
5475     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
5476     * This could be an x86 instruction or a function call.  (If the result
5477     * comes back in a register other than eax, you can override "result".)
5478     *
5479     * For: add-int, sub-int, and-int, or-int,
5480     *      xor-int, shl-int, shr-int, ushr-int
5481     */
5482    /* binop vAA, vBB, vCC */
5483    movzbl   2(rPC),%eax   # eax<- BB
5484    movzbl   3(rPC),%ecx   # ecx<- CC
5485    GET_VREG_R %eax %eax   # eax<- vBB
5486    orl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
5487    SET_VREG %eax rINST
5488    FETCH_INST_OPCODE 2 %ecx
5489    ADVANCE_PC 2
5490    GOTO_NEXT_R %ecx
5491
5492
5493/* ------------------------------ */
5494.L_OP_XOR_INT: /* 0x97 */
5495/* File: x86/OP_XOR_INT.S */
5496/* File: x86/binop.S */
5497    /*
5498     * Generic 32-bit binary operation.  Provide an "instr" line that
5499     * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
5500     * This could be an x86 instruction or a function call.  (If the result
5501     * comes back in a register other than eax, you can override "result".)
5502     *
5503     * For: add-int, sub-int, and-int, or-int,
5504     *      xor-int, shl-int, shr-int, ushr-int
5505     */
5506    /* binop vAA, vBB, vCC */
5507    movzbl   2(rPC),%eax   # eax<- BB
5508    movzbl   3(rPC),%ecx   # ecx<- CC
5509    GET_VREG_R %eax %eax   # eax<- vBB
5510    xorl   (rFP,%ecx,4),%eax                 # ex: addl    (rFP,%ecx,4),%eax
5511    SET_VREG %eax rINST
5512    FETCH_INST_OPCODE 2 %ecx
5513    ADVANCE_PC 2
5514    GOTO_NEXT_R %ecx
5515
5516
5517/* ------------------------------ */
5518.L_OP_SHL_INT: /* 0x98 */
5519/* File: x86/OP_SHL_INT.S */
5520/* File: x86/binop1.S */
5521    /*
5522     * Generic 32-bit binary operation in which both operands loaded to
5523     * registers (op0 in eax, op1 in ecx).
5524     */
5525    /* binop vAA, vBB, vCC */
5526    movzbl   2(rPC),%eax            # eax<- BB
5527    movzbl   3(rPC),%ecx            # ecx<- CC
5528    GET_VREG_R %eax %eax            # eax<- vBB
5529    GET_VREG_R %ecx %ecx            # eax<- vBB
5530    sall    %cl,%eax                          # ex: addl    %ecx,%eax
5531    SET_VREG %eax rINST
5532    FETCH_INST_OPCODE 2 %ecx
5533    ADVANCE_PC 2
5534    GOTO_NEXT_R %ecx
5535
5536
5537/* ------------------------------ */
5538.L_OP_SHR_INT: /* 0x99 */
5539/* File: x86/OP_SHR_INT.S */
5540/* File: x86/binop1.S */
5541    /*
5542     * Generic 32-bit binary operation in which both operands loaded to
5543     * registers (op0 in eax, op1 in ecx).
5544     */
5545    /* binop vAA, vBB, vCC */
5546    movzbl   2(rPC),%eax            # eax<- BB
5547    movzbl   3(rPC),%ecx            # ecx<- CC
5548    GET_VREG_R %eax %eax            # eax<- vBB
5549    GET_VREG_R %ecx %ecx            # eax<- vBB
5550    sarl    %cl,%eax                          # ex: addl    %ecx,%eax
5551    SET_VREG %eax rINST
5552    FETCH_INST_OPCODE 2 %ecx
5553    ADVANCE_PC 2
5554    GOTO_NEXT_R %ecx
5555
5556
5557/* ------------------------------ */
5558.L_OP_USHR_INT: /* 0x9a */
5559/* File: x86/OP_USHR_INT.S */
5560/* File: x86/binop1.S */
5561    /*
5562     * Generic 32-bit binary operation in which both operands loaded to
5563     * registers (op0 in eax, op1 in ecx).
5564     */
5565    /* binop vAA, vBB, vCC */
5566    movzbl   2(rPC),%eax            # eax<- BB
5567    movzbl   3(rPC),%ecx            # ecx<- CC
5568    GET_VREG_R %eax %eax            # eax<- vBB
5569    GET_VREG_R %ecx %ecx            # eax<- vBB
5570    shrl    %cl,%eax                          # ex: addl    %ecx,%eax
5571    SET_VREG %eax rINST
5572    FETCH_INST_OPCODE 2 %ecx
5573    ADVANCE_PC 2
5574    GOTO_NEXT_R %ecx
5575
5576
5577/* ------------------------------ */
5578.L_OP_ADD_LONG: /* 0x9b */
5579/* File: x86/OP_ADD_LONG.S */
5580/* File: x86/binopWide.S */
5581    /*
5582     * Generic 64-bit binary operation.
5583     */
5584    /* binop vAA, vBB, vCC */
5585
5586    movzbl    2(rPC),%eax               # eax<- BB
5587    movzbl    3(rPC),%ecx               # ecx<- CC
5588    SPILL(rIBASE)                       # save rIBASE
5589    GET_VREG_WORD rIBASE %eax 0         # rIBASE<- v[BB+0]
5590    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
5591    addl (rFP,%ecx,4),rIBASE         # ex: addl   (rFP,%ecx,4),rIBASE
5592    adcl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
5593    SET_VREG_WORD rIBASE rINST 0        # v[AA+0] <- rIBASE
5594    FETCH_INST_OPCODE 2 %ecx
5595    UNSPILL(rIBASE)                     # restore rIBASE
5596    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
5597    ADVANCE_PC 2
5598    GOTO_NEXT_R %ecx
5599
5600
5601/* ------------------------------ */
5602.L_OP_SUB_LONG: /* 0x9c */
5603/* File: x86/OP_SUB_LONG.S */
5604/* File: x86/binopWide.S */
5605    /*
5606     * Generic 64-bit binary operation.
5607     */
5608    /* binop vAA, vBB, vCC */
5609
5610    movzbl    2(rPC),%eax               # eax<- BB
5611    movzbl    3(rPC),%ecx               # ecx<- CC
5612    SPILL(rIBASE)                       # save rIBASE
5613    GET_VREG_WORD rIBASE %eax 0         # rIBASE<- v[BB+0]
5614    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
5615    subl (rFP,%ecx,4),rIBASE         # ex: addl   (rFP,%ecx,4),rIBASE
5616    sbbl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
5617    SET_VREG_WORD rIBASE rINST 0        # v[AA+0] <- rIBASE
5618    FETCH_INST_OPCODE 2 %ecx
5619    UNSPILL(rIBASE)                     # restore rIBASE
5620    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
5621    ADVANCE_PC 2
5622    GOTO_NEXT_R %ecx
5623
5624
5625/* ------------------------------ */
5626.L_OP_MUL_LONG: /* 0x9d */
5627/* File: x86/OP_MUL_LONG.S */
5628    /*
5629     * Signed 64-bit integer multiply.
5630     *
5631     * We could definately use more free registers for
5632     * this code.   We spill rINSTw (ebx),
5633     * giving us eax, ebc, ecx and edx as computational
5634     * temps.  On top of that, we'll spill edi (rFP)
5635     * for use as the vB pointer and esi (rPC) for use
5636     * as the vC pointer.  Yuck.
5637     */
5638    /* mul-long vAA, vBB, vCC */
5639    movzbl    2(rPC),%eax              # eax<- B
5640    movzbl    3(rPC),%ecx              # ecx<- C
5641    SPILL_TMP2(%esi)                   # save Dalvik PC
5642    SPILL(rFP)
5643    SPILL(rINST)
5644    SPILL(rIBASE)
5645    leal      (rFP,%eax,4),%esi        # esi<- &v[B]
5646    leal      (rFP,%ecx,4),rFP         # rFP<- &v[C]
5647    movl      4(%esi),%ecx             # ecx<- Bmsw
5648    imull     (rFP),%ecx               # ecx<- (Bmsw*Clsw)
5649    movl      4(rFP),%eax              # eax<- Cmsw
5650    imull     (%esi),%eax              # eax<- (Cmsw*Blsw)
5651    addl      %eax,%ecx                # ecx<- (Bmsw*Clsw)+(Cmsw*Blsw)
5652    movl      (rFP),%eax               # eax<- Clsw
5653    mull      (%esi)                   # eax<- (Clsw*Alsw)
5654    UNSPILL(rINST)
5655    UNSPILL(rFP)
5656    leal      (%ecx,rIBASE),rIBASE # full result now in rIBASE:%eax
5657    UNSPILL_TMP2(%esi)             # Restore Dalvik PC
5658    FETCH_INST_OPCODE 2 %ecx       # Fetch next instruction
5659    movl      rIBASE,4(rFP,rINST,4)# v[B+1]<- rIBASE
5660    UNSPILL(rIBASE)
5661    movl      %eax,(rFP,rINST,4)   # v[B]<- %eax
5662    ADVANCE_PC 2
5663    GOTO_NEXT_R %ecx
5664
5665/* ------------------------------ */
5666.L_OP_DIV_LONG: /* 0x9e */
5667/* File: x86/OP_DIV_LONG.S */
5668    /* div vAA, vBB, vCC */
5669    movzbl    3(rPC),%eax              # eax<- CC
5670    movzbl    2(rPC),%ecx              # ecx<- BB
5671    SPILL(rIBASE)                      # save rIBASE/%edx
5672    GET_VREG_WORD rIBASE %eax 0
5673    GET_VREG_WORD %eax %eax 1
5674    movl     rIBASE,OUT_ARG2(%esp)
5675    testl    %eax,%eax
5676    je       .LOP_DIV_LONG_check_zero
5677    cmpl     $-1,%eax
5678    je       .LOP_DIV_LONG_check_neg1
5679.LOP_DIV_LONG_notSpecial:
5680    GET_VREG_WORD rIBASE %ecx 0
5681    GET_VREG_WORD %ecx %ecx 1
5682.LOP_DIV_LONG_notSpecial1:
5683    movl     %eax,OUT_ARG3(%esp)
5684    movl     rIBASE,OUT_ARG0(%esp)
5685    movl     %ecx,OUT_ARG1(%esp)
5686    call     __divdi3
5687.LOP_DIV_LONG_finish:
5688    SET_VREG_WORD rIBASE rINST 1
5689    UNSPILL(rIBASE)                 # restore rIBASE/%edx
5690    SET_VREG_WORD %eax rINST 0
5691    FETCH_INST_OPCODE 2 %ecx
5692    ADVANCE_PC 2
5693    GOTO_NEXT_R %ecx
5694
5695.LOP_DIV_LONG_check_zero:
5696    testl   rIBASE,rIBASE
5697    jne     .LOP_DIV_LONG_notSpecial
5698    jmp     common_errDivideByZero
5699.LOP_DIV_LONG_check_neg1:
5700    testl   rIBASE,%eax
5701    jne     .LOP_DIV_LONG_notSpecial
5702    GET_VREG_WORD rIBASE %ecx 0
5703    GET_VREG_WORD %ecx %ecx 1
5704    testl    rIBASE,rIBASE
5705    jne      .LOP_DIV_LONG_notSpecial1
5706    cmpl     $0x80000000,%ecx
5707    jne      .LOP_DIV_LONG_notSpecial1
5708    /* minint / -1, return minint on div, 0 on rem */
5709    xorl     %eax,%eax
5710    movl     $0x80000000,rIBASE
5711    jmp      .LOP_DIV_LONG_finish
5712
5713/* ------------------------------ */
5714.L_OP_REM_LONG: /* 0x9f */
5715/* File: x86/OP_REM_LONG.S */
5716/* File: x86/OP_DIV_LONG.S */
5717    /* div vAA, vBB, vCC */
5718    movzbl    3(rPC),%eax              # eax<- CC
5719    movzbl    2(rPC),%ecx              # ecx<- BB
5720    SPILL(rIBASE)                      # save rIBASE/%edx
5721    GET_VREG_WORD rIBASE %eax 0
5722    GET_VREG_WORD %eax %eax 1
5723    movl     rIBASE,OUT_ARG2(%esp)
5724    testl    %eax,%eax
5725    je       .LOP_REM_LONG_check_zero
5726    cmpl     $-1,%eax
5727    je       .LOP_REM_LONG_check_neg1
5728.LOP_REM_LONG_notSpecial:
5729    GET_VREG_WORD rIBASE %ecx 0
5730    GET_VREG_WORD %ecx %ecx 1
5731.LOP_REM_LONG_notSpecial1:
5732    movl     %eax,OUT_ARG3(%esp)
5733    movl     rIBASE,OUT_ARG0(%esp)
5734    movl     %ecx,OUT_ARG1(%esp)
5735    call     __moddi3
5736.LOP_REM_LONG_finish:
5737    SET_VREG_WORD rIBASE rINST 1
5738    UNSPILL(rIBASE)                 # restore rIBASE/%edx
5739    SET_VREG_WORD %eax rINST 0
5740    FETCH_INST_OPCODE 2 %ecx
5741    ADVANCE_PC 2
5742    GOTO_NEXT_R %ecx
5743
5744.LOP_REM_LONG_check_zero:
5745    testl   rIBASE,rIBASE
5746    jne     .LOP_REM_LONG_notSpecial
5747    jmp     common_errDivideByZero
5748.LOP_REM_LONG_check_neg1:
5749    testl   rIBASE,%eax
5750    jne     .LOP_REM_LONG_notSpecial
5751    GET_VREG_WORD rIBASE %ecx 0
5752    GET_VREG_WORD %ecx %ecx 1
5753    testl    rIBASE,rIBASE
5754    jne      .LOP_REM_LONG_notSpecial1
5755    cmpl     $0x80000000,%ecx
5756    jne      .LOP_REM_LONG_notSpecial1
5757    /* minint / -1, return minint on div, 0 on rem */
5758    xorl     %eax,%eax
5759    movl     $0,rIBASE
5760    jmp      .LOP_REM_LONG_finish
5761
5762
5763/* ------------------------------ */
5764.L_OP_AND_LONG: /* 0xa0 */
5765/* File: x86/OP_AND_LONG.S */
5766/* File: x86/binopWide.S */
5767    /*
5768     * Generic 64-bit binary operation.
5769     */
5770    /* binop vAA, vBB, vCC */
5771
5772    movzbl    2(rPC),%eax               # eax<- BB
5773    movzbl    3(rPC),%ecx               # ecx<- CC
5774    SPILL(rIBASE)                       # save rIBASE
5775    GET_VREG_WORD rIBASE %eax 0         # rIBASE<- v[BB+0]
5776    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
5777    andl (rFP,%ecx,4),rIBASE         # ex: addl   (rFP,%ecx,4),rIBASE
5778    andl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
5779    SET_VREG_WORD rIBASE rINST 0        # v[AA+0] <- rIBASE
5780    FETCH_INST_OPCODE 2 %ecx
5781    UNSPILL(rIBASE)                     # restore rIBASE
5782    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
5783    ADVANCE_PC 2
5784    GOTO_NEXT_R %ecx
5785
5786
5787/* ------------------------------ */
5788.L_OP_OR_LONG: /* 0xa1 */
5789/* File: x86/OP_OR_LONG.S */
5790/* File: x86/binopWide.S */
5791    /*
5792     * Generic 64-bit binary operation.
5793     */
5794    /* binop vAA, vBB, vCC */
5795
5796    movzbl    2(rPC),%eax               # eax<- BB
5797    movzbl    3(rPC),%ecx               # ecx<- CC
5798    SPILL(rIBASE)                       # save rIBASE
5799    GET_VREG_WORD rIBASE %eax 0         # rIBASE<- v[BB+0]
5800    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
5801    orl (rFP,%ecx,4),rIBASE         # ex: addl   (rFP,%ecx,4),rIBASE
5802    orl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
5803    SET_VREG_WORD rIBASE rINST 0        # v[AA+0] <- rIBASE
5804    FETCH_INST_OPCODE 2 %ecx
5805    UNSPILL(rIBASE)                     # restore rIBASE
5806    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
5807    ADVANCE_PC 2
5808    GOTO_NEXT_R %ecx
5809
5810
5811/* ------------------------------ */
5812.L_OP_XOR_LONG: /* 0xa2 */
5813/* File: x86/OP_XOR_LONG.S */
5814/* File: x86/binopWide.S */
5815    /*
5816     * Generic 64-bit binary operation.
5817     */
5818    /* binop vAA, vBB, vCC */
5819
5820    movzbl    2(rPC),%eax               # eax<- BB
5821    movzbl    3(rPC),%ecx               # ecx<- CC
5822    SPILL(rIBASE)                       # save rIBASE
5823    GET_VREG_WORD rIBASE %eax 0         # rIBASE<- v[BB+0]
5824    GET_VREG_WORD %eax %eax 1           # eax<- v[BB+1]
5825    xorl (rFP,%ecx,4),rIBASE         # ex: addl   (rFP,%ecx,4),rIBASE
5826    xorl 4(rFP,%ecx,4),%eax         # ex: adcl   4(rFP,%ecx,4),%eax
5827    SET_VREG_WORD rIBASE rINST 0        # v[AA+0] <- rIBASE
5828    FETCH_INST_OPCODE 2 %ecx
5829    UNSPILL(rIBASE)                     # restore rIBASE
5830    SET_VREG_WORD %eax rINST 1          # v[AA+1] <- eax
5831    ADVANCE_PC 2
5832    GOTO_NEXT_R %ecx
5833
5834
5835/* ------------------------------ */
5836.L_OP_SHL_LONG: /* 0xa3 */
5837/* File: x86/OP_SHL_LONG.S */
5838    /*
5839     * Long integer shift.  This is different from the generic 32/64-bit
5840     * binary operations because vAA/vBB are 64-bit but vCC (the shift
5841     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
5842     * 6 bits of the shift distance.  x86 shifts automatically mask off
5843     * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
5844     * case specially.
5845     */
5846    /* shl-long vAA, vBB, vCC */
5847    /* ecx gets shift count */
5848    /* Need to spill rINST */
5849    /* rINSTw gets AA */
5850    movzbl    2(rPC),%eax               # eax<- BB
5851    movzbl    3(rPC),%ecx               # ecx<- CC
5852    SPILL(rIBASE)
5853    GET_VREG_WORD rIBASE %eax 1         # ecx<- v[BB+1]
5854    GET_VREG_R   %ecx %ecx              # ecx<- vCC
5855    GET_VREG_WORD %eax %eax 0           # eax<- v[BB+0]
5856    shldl     %eax,rIBASE
5857    sall      %cl,%eax
5858    testb     $32,%cl
5859    je        2f
5860    movl      %eax,rIBASE
5861    xorl      %eax,%eax
58622:
5863    SET_VREG_WORD rIBASE rINST 1        # v[AA+1]<- rIBASE
5864    FETCH_INST_OPCODE 2 %ecx
5865    UNSPILL(rIBASE)
5866    SET_VREG_WORD %eax rINST 0          # v[AA+0]<- %eax
5867    ADVANCE_PC 2
5868    GOTO_NEXT_R %ecx
5869
5870/* ------------------------------ */
5871.L_OP_SHR_LONG: /* 0xa4 */
5872/* File: x86/OP_SHR_LONG.S */
5873    /*
5874     * Long integer shift.  This is different from the generic 32/64-bit
5875     * binary operations because vAA/vBB are 64-bit but vCC (the shift
5876     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
5877     * 6 bits of the shift distance.  x86 shifts automatically mask off
5878     * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
5879     * case specially.
5880     */
5881    /* shr-long vAA, vBB, vCC */
5882    /* ecx gets shift count */
5883    /* Need to spill rIBASE */
5884    /* rINSTw gets AA */
5885    movzbl    2(rPC),%eax               # eax<- BB
5886    movzbl    3(rPC),%ecx               # ecx<- CC
5887    SPILL(rIBASE)
5888    GET_VREG_WORD rIBASE %eax 1         # rIBASE<- v[BB+1]
5889    GET_VREG_R   %ecx %ecx              # ecx<- vCC
5890    GET_VREG_WORD %eax %eax 0           # eax<- v[BB+0]
5891    shrdl     rIBASE,%eax
5892    sarl      %cl,rIBASE
5893    testb     $32,%cl
5894    je        2f
5895    movl      rIBASE,%eax
5896    sarl      $31,rIBASE
58972:
5898    SET_VREG_WORD rIBASE rINST 1        # v[AA+1]<- rIBASE
5899    FETCH_INST_OPCODE 2 %ecx
5900    UNSPILL(rIBASE)
5901    SET_VREG_WORD %eax rINST 0          # v[AA+0]<- eax
5902    ADVANCE_PC 2
5903    GOTO_NEXT_R %ecx
5904
5905/* ------------------------------ */
5906.L_OP_USHR_LONG: /* 0xa5 */
5907/* File: x86/OP_USHR_LONG.S */
5908    /*
5909     * Long integer shift.  This is different from the generic 32/64-bit
5910     * binary operations because vAA/vBB are 64-bit but vCC (the shift
5911     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
5912     * 6 bits of the shift distance.  x86 shifts automatically mask off
5913     * the low 5 bits of %cl, so have to handle the 64 > shiftcount > 31
5914     * case specially.
5915     */
5916    /* shr-long vAA, vBB, vCC */
5917    /* ecx gets shift count */
5918    /* Need to spill rIBASE */
5919    /* rINSTw gets AA */
5920    movzbl    2(rPC),%eax               # eax<- BB
5921    movzbl    3(rPC),%ecx               # ecx<- CC
5922    SPILL(rIBASE)
5923    GET_VREG_WORD rIBASE %eax 1         # rIBASE<- v[BB+1]
5924    GET_VREG_R  %ecx %ecx               # ecx<- vCC
5925    GET_VREG_WORD %eax %eax 0           # eax<- v[BB+0]
5926    shrdl     rIBASE,%eax
5927    shrl      %cl,rIBASE
5928    testb     $32,%cl
5929    je        2f
5930    movl      rIBASE,%eax
5931    xorl      rIBASE,rIBASE
59322:
5933    SET_VREG_WORD rIBASE rINST 1          # v[AA+1]<- rIBASE
5934    FETCH_INST_OPCODE 2 %ecx
5935    UNSPILL(rIBASE)
5936    SET_VREG_WORD %eax rINST 0         # v[BB+0]<- eax
5937    ADVANCE_PC 2
5938    GOTO_NEXT_R %ecx
5939
5940/* ------------------------------ */
5941.L_OP_ADD_FLOAT: /* 0xa6 */
5942/* File: x86/OP_ADD_FLOAT.S */
5943/* File: x86/binflop.S */
5944    /*
5945     * Generic 32-bit binary float operation.
5946     *
5947     * For: add-fp, sub-fp, mul-fp, div-fp
5948     */
5949    /* binop vAA, vBB, vCC */
5950    movzbl   2(rPC),%eax          # eax<- CC
5951    movzbl   3(rPC),%ecx          # ecx<- BB
5952    flds    (rFP,%eax,4)         # vCC to fp stack
5953    fadds   (rFP,%ecx,4)         # ex: faddp
5954    FETCH_INST_OPCODE 2 %ecx
5955    ADVANCE_PC 2
5956    fstps   (rFP,rINST,4)         # %st to vAA
5957    GOTO_NEXT_R %ecx
5958
5959
5960/* ------------------------------ */
5961.L_OP_SUB_FLOAT: /* 0xa7 */
5962/* File: x86/OP_SUB_FLOAT.S */
5963/* File: x86/binflop.S */
5964    /*
5965     * Generic 32-bit binary float operation.
5966     *
5967     * For: add-fp, sub-fp, mul-fp, div-fp
5968     */
5969    /* binop vAA, vBB, vCC */
5970    movzbl   2(rPC),%eax          # eax<- CC
5971    movzbl   3(rPC),%ecx          # ecx<- BB
5972    flds    (rFP,%eax,4)         # vCC to fp stack
5973    fsubs   (rFP,%ecx,4)         # ex: faddp
5974    FETCH_INST_OPCODE 2 %ecx
5975    ADVANCE_PC 2
5976    fstps   (rFP,rINST,4)         # %st to vAA
5977    GOTO_NEXT_R %ecx
5978
5979
5980/* ------------------------------ */
5981.L_OP_MUL_FLOAT: /* 0xa8 */
5982/* File: x86/OP_MUL_FLOAT.S */
5983/* File: x86/binflop.S */
5984    /*
5985     * Generic 32-bit binary float operation.
5986     *
5987     * For: add-fp, sub-fp, mul-fp, div-fp
5988     */
5989    /* binop vAA, vBB, vCC */
5990    movzbl   2(rPC),%eax          # eax<- CC
5991    movzbl   3(rPC),%ecx          # ecx<- BB
5992    flds    (rFP,%eax,4)         # vCC to fp stack
5993    fmuls   (rFP,%ecx,4)         # ex: faddp
5994    FETCH_INST_OPCODE 2 %ecx
5995    ADVANCE_PC 2
5996    fstps   (rFP,rINST,4)         # %st to vAA
5997    GOTO_NEXT_R %ecx
5998
5999
6000/* ------------------------------ */
6001.L_OP_DIV_FLOAT: /* 0xa9 */
6002/* File: x86/OP_DIV_FLOAT.S */
6003/* File: x86/binflop.S */
6004    /*
6005     * Generic 32-bit binary float operation.
6006     *
6007     * For: add-fp, sub-fp, mul-fp, div-fp
6008     */
6009    /* binop vAA, vBB, vCC */
6010    movzbl   2(rPC),%eax          # eax<- CC
6011    movzbl   3(rPC),%ecx          # ecx<- BB
6012    flds    (rFP,%eax,4)         # vCC to fp stack
6013    fdivs   (rFP,%ecx,4)         # ex: faddp
6014    FETCH_INST_OPCODE 2 %ecx
6015    ADVANCE_PC 2
6016    fstps   (rFP,rINST,4)         # %st to vAA
6017    GOTO_NEXT_R %ecx
6018
6019
6020/* ------------------------------ */
6021.L_OP_REM_FLOAT: /* 0xaa */
6022/* File: x86/OP_REM_FLOAT.S */
6023    /* rem_float vAA, vBB, vCC */
6024    movzbl   3(rPC),%ecx            # ecx<- BB
6025    movzbl   2(rPC),%eax            # eax<- CC
6026    flds     (rFP,%ecx,4)           # vCC to fp stack
6027    flds     (rFP,%eax,4)           # vCC to fp stack
6028    movzbl   rINSTbl,%ecx           # ecx<- AA
60291:
6030    fprem
6031    fstsw     %ax
6032    sahf
6033    jp        1b
6034    fstp      %st(1)
6035    FETCH_INST_OPCODE 2 %eax
6036    ADVANCE_PC 2
6037    fstps    (rFP,%ecx,4)           # %st to vAA
6038    GOTO_NEXT_R %eax
6039
6040/* ------------------------------ */
6041.L_OP_ADD_DOUBLE: /* 0xab */
6042/* File: x86/OP_ADD_DOUBLE.S */
6043   /*
6044    * File: OP_ADD_DOUBLE.S
6045    */
6046
6047    movzbl   2(rPC),%eax                # eax<- BB
6048    movzbl   3(rPC),%ecx                # ecx<- CC
6049    movq     (rFP, %eax, 4), %xmm0      # %xmm0<- vBB
6050    movq     (rFP, %ecx, 4), %xmm1      # %xmm1<- vCC
6051    FETCH_INST_OPCODE 2 %ecx
6052    addsd    %xmm1, %xmm0
6053    ADVANCE_PC 2
6054    movq     %xmm0, (rFP, rINST, 4)     # vAA<- vBB * vCC
6055    GOTO_NEXT_R %ecx
6056
6057
6058/* ------------------------------ */
6059.L_OP_SUB_DOUBLE: /* 0xac */
6060/* File: x86/OP_SUB_DOUBLE.S */
6061   /*
6062    * File: OP_SUB_DOUBLE.S
6063    */
6064
6065    movzbl   2(rPC),%eax                # eax<- BB
6066    movzbl   3(rPC),%ecx                # ecx<- CC
6067    # TODO: movsd?
6068    movq        (rFP, %eax, 4), %xmm0   # %xmm0<- vBB
6069    movq        (rFP, %ecx, 4), %xmm1   # %xmm1<- vCC
6070    FETCH_INST_OPCODE 2 %ecx
6071    subsd       %xmm1, %xmm0
6072    ADVANCE_PC 2
6073    movq        %xmm0, (rFP, rINST, 4)  # vAA<- vBB - vCC
6074    GOTO_NEXT_R %ecx
6075
6076/* ------------------------------ */
6077.L_OP_MUL_DOUBLE: /* 0xad */
6078/* File: x86/OP_MUL_DOUBLE.S */
6079   /*
6080    * File: OP_MUL_DOUBLE.S
6081    */
6082
6083    movzbl   2(rPC),%eax                # eax<- BB
6084    movzbl   3(rPC),%ecx                # ecx<- CC
6085    # TODO: movsd?
6086    movq        (rFP, %eax, 4), %xmm0   # %xmm0<- vBB
6087    movq        (rFP, %ecx, 4), %xmm1   # %xmm1<- vCC
6088    FETCH_INST_OPCODE 2 %ecx
6089    mulsd       %xmm1, %xmm0
6090    ADVANCE_PC 2
6091    movq        %xmm0, (rFP, rINST, 4)  # vAA<- vBB * vCC
6092    GOTO_NEXT_R %ecx
6093
6094/* ------------------------------ */
6095.L_OP_DIV_DOUBLE: /* 0xae */
6096/* File: x86/OP_DIV_DOUBLE.S */
6097/* File: x86/binflop.S */
6098    /*
6099     * Generic 32-bit binary float operation.
6100     *
6101     * For: add-fp, sub-fp, mul-fp, div-fp
6102     */
6103    /* binop vAA, vBB, vCC */
6104    movzbl   2(rPC),%eax          # eax<- CC
6105    movzbl   3(rPC),%ecx          # ecx<- BB
6106    fldl    (rFP,%eax,4)         # vCC to fp stack
6107    fdivl   (rFP,%ecx,4)         # ex: faddp
6108    FETCH_INST_OPCODE 2 %ecx
6109    ADVANCE_PC 2
6110    fstpl   (rFP,rINST,4)         # %st to vAA
6111    GOTO_NEXT_R %ecx
6112
6113
6114/* ------------------------------ */
6115.L_OP_REM_DOUBLE: /* 0xaf */
6116/* File: x86/OP_REM_DOUBLE.S */
6117    /* rem_float vAA, vBB, vCC */
6118    movzbl   3(rPC),%ecx            # ecx<- BB
6119    movzbl   2(rPC),%eax            # eax<- CC
6120    fldl     (rFP,%ecx,4)           # vCC to fp stack
6121    fldl     (rFP,%eax,4)           # vCC to fp stack
6122    FETCH_INST_OPCODE 2 %ecx
61231:
6124    fprem
6125    fstsw     %ax
6126    sahf
6127    jp        1b
6128    fstp      %st(1)
6129    ADVANCE_PC 2
6130    fstpl    (rFP,rINST,4)           # %st to vAA
6131    GOTO_NEXT_R %ecx
6132
6133/* ------------------------------ */
6134.L_OP_ADD_INT_2ADDR: /* 0xb0 */
6135/* File: x86/OP_ADD_INT_2ADDR.S */
6136/* File: x86/binop2addr.S */
6137    /*
6138     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6139     * that specifies an instruction that performs "result = r0 op r1".
6140     * This could be an instruction or a function call.
6141     *
6142     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6143     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6144     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6145     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6146     */
6147    /* binop/2addr vA, vB */
6148    movzx   rINSTbl,%ecx               # ecx<- A+
6149    sarl    $4,rINST                  # rINST<- B
6150    GET_VREG_R %eax rINST              # eax<- vB
6151    andb    $0xf,%cl                  # ecx<- A
6152    addl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
6153    FETCH_INST_OPCODE 1 %ecx
6154    ADVANCE_PC 1
6155    GOTO_NEXT_R %ecx
6156
6157
6158/* ------------------------------ */
6159.L_OP_SUB_INT_2ADDR: /* 0xb1 */
6160/* File: x86/OP_SUB_INT_2ADDR.S */
6161/* File: x86/binop2addr.S */
6162    /*
6163     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6164     * that specifies an instruction that performs "result = r0 op r1".
6165     * This could be an instruction or a function call.
6166     *
6167     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6168     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6169     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6170     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6171     */
6172    /* binop/2addr vA, vB */
6173    movzx   rINSTbl,%ecx               # ecx<- A+
6174    sarl    $4,rINST                  # rINST<- B
6175    GET_VREG_R %eax rINST              # eax<- vB
6176    andb    $0xf,%cl                  # ecx<- A
6177    subl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
6178    FETCH_INST_OPCODE 1 %ecx
6179    ADVANCE_PC 1
6180    GOTO_NEXT_R %ecx
6181
6182
6183/* ------------------------------ */
6184.L_OP_MUL_INT_2ADDR: /* 0xb2 */
6185/* File: x86/OP_MUL_INT_2ADDR.S */
6186    /* mul vA, vB */
6187    movzx   rINSTbl,%ecx              # ecx<- A+
6188    sarl    $4,rINST                 # rINST<- B
6189    GET_VREG_R %eax rINST             # eax<- vB
6190    andb    $0xf,%cl                 # ecx<- A
6191    SPILL(rIBASE)
6192    imull   (rFP,%ecx,4),%eax         # trashes rIBASE/edx
6193    UNSPILL(rIBASE)
6194    SET_VREG %eax %ecx
6195    FETCH_INST_OPCODE 1 %ecx
6196    ADVANCE_PC 1
6197    GOTO_NEXT_R %ecx
6198
6199/* ------------------------------ */
6200.L_OP_DIV_INT_2ADDR: /* 0xb3 */
6201/* File: x86/OP_DIV_INT_2ADDR.S */
6202/* File: x86/bindiv2addr.S */
6203    /*
6204     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
6205     * op1=-1.
6206     */
6207    /* div/rem/2addr vA, vB */
6208    movzx    rINSTbl,%ecx          # eax<- BA
6209    SPILL(rIBASE)
6210    sarl     $4,%ecx              # ecx<- B
6211    GET_VREG_R %ecx %ecx           # eax<- vBB
6212    andb     $0xf,rINSTbl         # rINST<- A
6213    GET_VREG_R %eax rINST          # eax<- vBB
6214    cmpl     $0,%ecx
6215    je       common_errDivideByZero
6216    cmpl     $-1,%ecx
6217    jne      .LOP_DIV_INT_2ADDR_continue_div2addr
6218    cmpl     $0x80000000,%eax
6219    jne      .LOP_DIV_INT_2ADDR_continue_div2addr
6220    movl     $0x80000000,%eax
6221    SET_VREG %eax rINST
6222    UNSPILL(rIBASE)
6223    FETCH_INST_OPCODE 1 %ecx
6224    ADVANCE_PC 1
6225    GOTO_NEXT_R %ecx
6226
6227.LOP_DIV_INT_2ADDR_continue_div2addr:
6228    cltd
6229    idivl   %ecx
6230    SET_VREG %eax rINST
6231    UNSPILL(rIBASE)
6232    FETCH_INST_OPCODE 1 %ecx
6233    ADVANCE_PC 1
6234    GOTO_NEXT_R %ecx
6235
6236
6237/* ------------------------------ */
6238.L_OP_REM_INT_2ADDR: /* 0xb4 */
6239/* File: x86/OP_REM_INT_2ADDR.S */
6240/* File: x86/bindiv2addr.S */
6241    /*
6242     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
6243     * op1=-1.
6244     */
6245    /* div/rem/2addr vA, vB */
6246    movzx    rINSTbl,%ecx          # eax<- BA
6247    SPILL(rIBASE)
6248    sarl     $4,%ecx              # ecx<- B
6249    GET_VREG_R %ecx %ecx           # eax<- vBB
6250    andb     $0xf,rINSTbl         # rINST<- A
6251    GET_VREG_R %eax rINST          # eax<- vBB
6252    cmpl     $0,%ecx
6253    je       common_errDivideByZero
6254    cmpl     $-1,%ecx
6255    jne      .LOP_REM_INT_2ADDR_continue_div2addr
6256    cmpl     $0x80000000,%eax
6257    jne      .LOP_REM_INT_2ADDR_continue_div2addr
6258    movl     $0,rIBASE
6259    SET_VREG rIBASE rINST
6260    UNSPILL(rIBASE)
6261    FETCH_INST_OPCODE 1 %ecx
6262    ADVANCE_PC 1
6263    GOTO_NEXT_R %ecx
6264
6265.LOP_REM_INT_2ADDR_continue_div2addr:
6266    cltd
6267    idivl   %ecx
6268    SET_VREG rIBASE rINST
6269    UNSPILL(rIBASE)
6270    FETCH_INST_OPCODE 1 %ecx
6271    ADVANCE_PC 1
6272    GOTO_NEXT_R %ecx
6273
6274
6275/* ------------------------------ */
6276.L_OP_AND_INT_2ADDR: /* 0xb5 */
6277/* File: x86/OP_AND_INT_2ADDR.S */
6278/* File: x86/binop2addr.S */
6279    /*
6280     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6281     * that specifies an instruction that performs "result = r0 op r1".
6282     * This could be an instruction or a function call.
6283     *
6284     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6285     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6286     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6287     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6288     */
6289    /* binop/2addr vA, vB */
6290    movzx   rINSTbl,%ecx               # ecx<- A+
6291    sarl    $4,rINST                  # rINST<- B
6292    GET_VREG_R %eax rINST              # eax<- vB
6293    andb    $0xf,%cl                  # ecx<- A
6294    andl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
6295    FETCH_INST_OPCODE 1 %ecx
6296    ADVANCE_PC 1
6297    GOTO_NEXT_R %ecx
6298
6299
6300/* ------------------------------ */
6301.L_OP_OR_INT_2ADDR: /* 0xb6 */
6302/* File: x86/OP_OR_INT_2ADDR.S */
6303/* File: x86/binop2addr.S */
6304    /*
6305     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6306     * that specifies an instruction that performs "result = r0 op r1".
6307     * This could be an instruction or a function call.
6308     *
6309     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6310     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6311     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6312     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6313     */
6314    /* binop/2addr vA, vB */
6315    movzx   rINSTbl,%ecx               # ecx<- A+
6316    sarl    $4,rINST                  # rINST<- B
6317    GET_VREG_R %eax rINST              # eax<- vB
6318    andb    $0xf,%cl                  # ecx<- A
6319    orl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
6320    FETCH_INST_OPCODE 1 %ecx
6321    ADVANCE_PC 1
6322    GOTO_NEXT_R %ecx
6323
6324
6325/* ------------------------------ */
6326.L_OP_XOR_INT_2ADDR: /* 0xb7 */
6327/* File: x86/OP_XOR_INT_2ADDR.S */
6328/* File: x86/binop2addr.S */
6329    /*
6330     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6331     * that specifies an instruction that performs "result = r0 op r1".
6332     * This could be an instruction or a function call.
6333     *
6334     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6335     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6336     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6337     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6338     */
6339    /* binop/2addr vA, vB */
6340    movzx   rINSTbl,%ecx               # ecx<- A+
6341    sarl    $4,rINST                  # rINST<- B
6342    GET_VREG_R %eax rINST              # eax<- vB
6343    andb    $0xf,%cl                  # ecx<- A
6344    xorl     %eax,(rFP,%ecx,4)                             # for ex: addl   %eax,(rFP,%ecx,4)
6345    FETCH_INST_OPCODE 1 %ecx
6346    ADVANCE_PC 1
6347    GOTO_NEXT_R %ecx
6348
6349
6350/* ------------------------------ */
6351.L_OP_SHL_INT_2ADDR: /* 0xb8 */
6352/* File: x86/OP_SHL_INT_2ADDR.S */
6353/* File: x86/shop2addr.S */
6354    /*
6355     * Generic 32-bit "shift/2addr" operation.
6356     */
6357    /* shift/2addr vA, vB */
6358    movzx    rINSTbl,%ecx           # eax<- BA
6359    sarl     $4,%ecx               # ecx<- B
6360    GET_VREG_R %ecx %ecx            # eax<- vBB
6361    andb     $0xf,rINSTbl          # rINST<- A
6362    GET_VREG_R %eax rINST           # eax<- vAA
6363    sall    %cl,%eax                          # ex: sarl %cl,%eax
6364    FETCH_INST_OPCODE 1 %ecx
6365    SET_VREG %eax rINST
6366    ADVANCE_PC 1
6367    GOTO_NEXT_R %ecx
6368
6369
6370/* ------------------------------ */
6371.L_OP_SHR_INT_2ADDR: /* 0xb9 */
6372/* File: x86/OP_SHR_INT_2ADDR.S */
6373/* File: x86/shop2addr.S */
6374    /*
6375     * Generic 32-bit "shift/2addr" operation.
6376     */
6377    /* shift/2addr vA, vB */
6378    movzx    rINSTbl,%ecx           # eax<- BA
6379    sarl     $4,%ecx               # ecx<- B
6380    GET_VREG_R %ecx %ecx            # eax<- vBB
6381    andb     $0xf,rINSTbl          # rINST<- A
6382    GET_VREG_R %eax rINST           # eax<- vAA
6383    sarl    %cl,%eax                          # ex: sarl %cl,%eax
6384    FETCH_INST_OPCODE 1 %ecx
6385    SET_VREG %eax rINST
6386    ADVANCE_PC 1
6387    GOTO_NEXT_R %ecx
6388
6389
6390/* ------------------------------ */
6391.L_OP_USHR_INT_2ADDR: /* 0xba */
6392/* File: x86/OP_USHR_INT_2ADDR.S */
6393/* File: x86/shop2addr.S */
6394    /*
6395     * Generic 32-bit "shift/2addr" operation.
6396     */
6397    /* shift/2addr vA, vB */
6398    movzx    rINSTbl,%ecx           # eax<- BA
6399    sarl     $4,%ecx               # ecx<- B
6400    GET_VREG_R %ecx %ecx            # eax<- vBB
6401    andb     $0xf,rINSTbl          # rINST<- A
6402    GET_VREG_R %eax rINST           # eax<- vAA
6403    shrl    %cl,%eax                          # ex: sarl %cl,%eax
6404    FETCH_INST_OPCODE 1 %ecx
6405    SET_VREG %eax rINST
6406    ADVANCE_PC 1
6407    GOTO_NEXT_R %ecx
6408
6409
6410/* ------------------------------ */
6411.L_OP_ADD_LONG_2ADDR: /* 0xbb */
6412/* File: x86/OP_ADD_LONG_2ADDR.S */
6413/* File: x86/binopWide2addr.S */
6414    /*
6415     * Generic 64-bit binary operation.
6416     */
6417    /* binop/2addr vA, vB */
6418    movzbl    rINSTbl,%ecx              # ecx<- BA
6419    sarl      $4,%ecx                  # ecx<- B
6420    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
6421    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
6422    andb      $0xF,rINSTbl             # rINST<- A
6423    addl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
6424    adcl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
6425    FETCH_INST_OPCODE 1 %ecx
6426    ADVANCE_PC 1
6427    GOTO_NEXT_R %ecx
6428
6429
6430/* ------------------------------ */
6431.L_OP_SUB_LONG_2ADDR: /* 0xbc */
6432/* File: x86/OP_SUB_LONG_2ADDR.S */
6433/* File: x86/binopWide2addr.S */
6434    /*
6435     * Generic 64-bit binary operation.
6436     */
6437    /* binop/2addr vA, vB */
6438    movzbl    rINSTbl,%ecx              # ecx<- BA
6439    sarl      $4,%ecx                  # ecx<- B
6440    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
6441    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
6442    andb      $0xF,rINSTbl             # rINST<- A
6443    subl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
6444    sbbl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
6445    FETCH_INST_OPCODE 1 %ecx
6446    ADVANCE_PC 1
6447    GOTO_NEXT_R %ecx
6448
6449
6450/* ------------------------------ */
6451.L_OP_MUL_LONG_2ADDR: /* 0xbd */
6452/* File: x86/OP_MUL_LONG_2ADDR.S */
6453    /*
6454     * Signed 64-bit integer multiply, 2-addr version
6455     *
6456     * We could definately use more free registers for
6457     * this code.  We must spill %edx (rIBASE) because it
6458     * is used by imul.  We'll also spill rINST (ebx),
6459     * giving us eax, ebc, ecx and rIBASE as computational
6460     * temps.  On top of that, we'll spill %esi (edi)
6461     * for use as the vA pointer and rFP (esi) for use
6462     * as the vB pointer.  Yuck.
6463     */
6464    /* mul-long/2addr vA, vB */
6465    movzbl    rINSTbl,%eax             # eax<- BA
6466    andb      $0xf,%al                # eax<- A
6467    sarl      $4,rINST                # rINST<- B
6468    SPILL_TMP2(%esi)
6469    SPILL(rFP)
6470    SPILL(rIBASE)
6471    leal      (rFP,%eax,4),%esi        # %esi<- &v[A]
6472    leal      (rFP,rINST,4),rFP        # rFP<- &v[B]
6473    movl      4(%esi),%ecx             # ecx<- Amsw
6474    imull     (rFP),%ecx               # ecx<- (Amsw*Blsw)
6475    movl      4(rFP),%eax              # eax<- Bmsw
6476    imull     (%esi),%eax              # eax<- (Bmsw*Alsw)
6477    addl      %eax,%ecx                # ecx<- (Amsw*Blsw)+(Bmsw*Alsw)
6478    movl      (rFP),%eax               # eax<- Blsw
6479    mull      (%esi)                   # eax<- (Blsw*Alsw)
6480    leal      (%ecx,rIBASE),rIBASE     # full result now in %edx:%eax
6481    movl      rIBASE,4(%esi)           # v[A+1]<- rIBASE
6482    movl      %eax,(%esi)              # v[A]<- %eax
6483    UNSPILL_TMP2(%esi)
6484    FETCH_INST_OPCODE 1 %ecx
6485    UNSPILL(rIBASE)
6486    UNSPILL(rFP)
6487    ADVANCE_PC 1
6488    GOTO_NEXT_R %ecx
6489
6490/* ------------------------------ */
6491.L_OP_DIV_LONG_2ADDR: /* 0xbe */
6492/* File: x86/OP_DIV_LONG_2ADDR.S */
6493    /* div/2addr vA, vB */
6494    movzbl    rINSTbl,%eax
6495    shrl      $4,%eax                  # eax<- B
6496    andb      $0xf,rINSTbl             # rINST<- A
6497    SPILL(rIBASE)                       # save rIBASE/%edx
6498    GET_VREG_WORD rIBASE %eax 0
6499    GET_VREG_WORD %eax %eax 1
6500    movl     rIBASE,OUT_ARG2(%esp)
6501    testl    %eax,%eax
6502    je       .LOP_DIV_LONG_2ADDR_check_zero
6503    cmpl     $-1,%eax
6504    je       .LOP_DIV_LONG_2ADDR_check_neg1
6505.LOP_DIV_LONG_2ADDR_notSpecial:
6506    GET_VREG_WORD rIBASE rINST 0
6507    GET_VREG_WORD %ecx rINST 1
6508.LOP_DIV_LONG_2ADDR_notSpecial1:
6509    movl     %eax,OUT_ARG3(%esp)
6510    movl     rIBASE,OUT_ARG0(%esp)
6511    movl     %ecx,OUT_ARG1(%esp)
6512    call     __divdi3
6513.LOP_DIV_LONG_2ADDR_finish:
6514    SET_VREG_WORD rIBASE rINST 1
6515    UNSPILL(rIBASE)                    # restore rIBASE/%edx
6516    SET_VREG_WORD %eax rINST 0
6517    FETCH_INST_OPCODE 1 %ecx
6518    ADVANCE_PC 1
6519    GOTO_NEXT_R %ecx
6520
6521.LOP_DIV_LONG_2ADDR_check_zero:
6522    testl   rIBASE,rIBASE
6523    jne     .LOP_DIV_LONG_2ADDR_notSpecial
6524    jmp     common_errDivideByZero
6525.LOP_DIV_LONG_2ADDR_check_neg1:
6526    testl   rIBASE,%eax
6527    jne     .LOP_DIV_LONG_2ADDR_notSpecial
6528    GET_VREG_WORD rIBASE rINST 0
6529    GET_VREG_WORD %ecx rINST 1
6530    testl    rIBASE,rIBASE
6531    jne      .LOP_DIV_LONG_2ADDR_notSpecial1
6532    cmpl     $0x80000000,%ecx
6533    jne      .LOP_DIV_LONG_2ADDR_notSpecial1
6534    /* minint / -1, return minint on div, 0 on rem */
6535    xorl     %eax,%eax
6536    movl     $0x80000000,rIBASE
6537    jmp      .LOP_DIV_LONG_2ADDR_finish
6538
6539/* ------------------------------ */
6540.L_OP_REM_LONG_2ADDR: /* 0xbf */
6541/* File: x86/OP_REM_LONG_2ADDR.S */
6542/* File: x86/OP_DIV_LONG_2ADDR.S */
6543    /* div/2addr vA, vB */
6544    movzbl    rINSTbl,%eax
6545    shrl      $4,%eax                  # eax<- B
6546    andb      $0xf,rINSTbl             # rINST<- A
6547    SPILL(rIBASE)                       # save rIBASE/%edx
6548    GET_VREG_WORD rIBASE %eax 0
6549    GET_VREG_WORD %eax %eax 1
6550    movl     rIBASE,OUT_ARG2(%esp)
6551    testl    %eax,%eax
6552    je       .LOP_REM_LONG_2ADDR_check_zero
6553    cmpl     $-1,%eax
6554    je       .LOP_REM_LONG_2ADDR_check_neg1
6555.LOP_REM_LONG_2ADDR_notSpecial:
6556    GET_VREG_WORD rIBASE rINST 0
6557    GET_VREG_WORD %ecx rINST 1
6558.LOP_REM_LONG_2ADDR_notSpecial1:
6559    movl     %eax,OUT_ARG3(%esp)
6560    movl     rIBASE,OUT_ARG0(%esp)
6561    movl     %ecx,OUT_ARG1(%esp)
6562    call     __moddi3
6563.LOP_REM_LONG_2ADDR_finish:
6564    SET_VREG_WORD rIBASE rINST 1
6565    UNSPILL(rIBASE)                    # restore rIBASE/%edx
6566    SET_VREG_WORD %eax rINST 0
6567    FETCH_INST_OPCODE 1 %ecx
6568    ADVANCE_PC 1
6569    GOTO_NEXT_R %ecx
6570
6571.LOP_REM_LONG_2ADDR_check_zero:
6572    testl   rIBASE,rIBASE
6573    jne     .LOP_REM_LONG_2ADDR_notSpecial
6574    jmp     common_errDivideByZero
6575.LOP_REM_LONG_2ADDR_check_neg1:
6576    testl   rIBASE,%eax
6577    jne     .LOP_REM_LONG_2ADDR_notSpecial
6578    GET_VREG_WORD rIBASE rINST 0
6579    GET_VREG_WORD %ecx rINST 1
6580    testl    rIBASE,rIBASE
6581    jne      .LOP_REM_LONG_2ADDR_notSpecial1
6582    cmpl     $0x80000000,%ecx
6583    jne      .LOP_REM_LONG_2ADDR_notSpecial1
6584    /* minint / -1, return minint on div, 0 on rem */
6585    xorl     %eax,%eax
6586    movl     $0,rIBASE
6587    jmp      .LOP_REM_LONG_2ADDR_finish
6588
6589
6590/* ------------------------------ */
6591.L_OP_AND_LONG_2ADDR: /* 0xc0 */
6592/* File: x86/OP_AND_LONG_2ADDR.S */
6593/* File: x86/binopWide2addr.S */
6594    /*
6595     * Generic 64-bit binary operation.
6596     */
6597    /* binop/2addr vA, vB */
6598    movzbl    rINSTbl,%ecx              # ecx<- BA
6599    sarl      $4,%ecx                  # ecx<- B
6600    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
6601    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
6602    andb      $0xF,rINSTbl             # rINST<- A
6603    andl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
6604    andl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
6605    FETCH_INST_OPCODE 1 %ecx
6606    ADVANCE_PC 1
6607    GOTO_NEXT_R %ecx
6608
6609
6610/* ------------------------------ */
6611.L_OP_OR_LONG_2ADDR: /* 0xc1 */
6612/* File: x86/OP_OR_LONG_2ADDR.S */
6613/* File: x86/binopWide2addr.S */
6614    /*
6615     * Generic 64-bit binary operation.
6616     */
6617    /* binop/2addr vA, vB */
6618    movzbl    rINSTbl,%ecx              # ecx<- BA
6619    sarl      $4,%ecx                  # ecx<- B
6620    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
6621    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
6622    andb      $0xF,rINSTbl             # rINST<- A
6623    orl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
6624    orl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
6625    FETCH_INST_OPCODE 1 %ecx
6626    ADVANCE_PC 1
6627    GOTO_NEXT_R %ecx
6628
6629
6630/* ------------------------------ */
6631.L_OP_XOR_LONG_2ADDR: /* 0xc2 */
6632/* File: x86/OP_XOR_LONG_2ADDR.S */
6633/* File: x86/binopWide2addr.S */
6634    /*
6635     * Generic 64-bit binary operation.
6636     */
6637    /* binop/2addr vA, vB */
6638    movzbl    rINSTbl,%ecx              # ecx<- BA
6639    sarl      $4,%ecx                  # ecx<- B
6640    GET_VREG_WORD %eax %ecx 0           # eax<- v[B+0]
6641    GET_VREG_WORD %ecx %ecx 1           # eax<- v[B+1]
6642    andb      $0xF,rINSTbl             # rINST<- A
6643    xorl %eax,(rFP,rINST,4)         # example: addl   %eax,(rFP,rINST,4)
6644    xorl %ecx,4(rFP,rINST,4)         # example: adcl   %ecx,4(rFP,rINST,4)
6645    FETCH_INST_OPCODE 1 %ecx
6646    ADVANCE_PC 1
6647    GOTO_NEXT_R %ecx
6648
6649
6650/* ------------------------------ */
6651.L_OP_SHL_LONG_2ADDR: /* 0xc3 */
6652/* File: x86/OP_SHL_LONG_2ADDR.S */
6653    /*
6654     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6655     * 32-bit shift distance.
6656     */
6657    /* shl-long/2addr vA, vB */
6658    /* ecx gets shift count */
6659    /* Need to spill rIBASE */
6660    /* rINSTw gets AA */
6661    movzbl    rINSTbl,%ecx             # ecx<- BA
6662    andb      $0xf,rINSTbl            # rINST<- A
6663    GET_VREG_WORD %eax rINST 0         # eax<- v[AA+0]
6664    sarl      $4,%ecx                 # ecx<- B
6665    SPILL(rIBASE)
6666    GET_VREG_WORD rIBASE rINST 1       # rIBASE<- v[AA+1]
6667    GET_VREG_R  %ecx %ecx              # ecx<- vBB
6668    shldl     %eax,rIBASE
6669    sall      %cl,%eax
6670    testb     $32,%cl
6671    je        2f
6672    movl      %eax,rIBASE
6673    xorl      %eax,%eax
66742:
6675    SET_VREG_WORD rIBASE rINST 1       # v[AA+1]<- rIBASE
6676    UNSPILL(rIBASE)
6677    FETCH_INST_OPCODE 1 %ecx
6678    SET_VREG_WORD %eax rINST 0         # v[AA+0]<- eax
6679    ADVANCE_PC 1
6680    GOTO_NEXT_R %ecx
6681
6682/* ------------------------------ */
6683.L_OP_SHR_LONG_2ADDR: /* 0xc4 */
6684/* File: x86/OP_SHR_LONG_2ADDR.S */
6685    /*
6686     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6687     * 32-bit shift distance.
6688     */
6689    /* shl-long/2addr vA, vB */
6690    /* ecx gets shift count */
6691    /* Need to spill rIBASE */
6692    /* rINSTw gets AA */
6693    movzbl    rINSTbl,%ecx         # ecx<- BA
6694    andb      $0xf,rINSTbl        # rINST<- A
6695    GET_VREG_WORD %eax rINST 0     # eax<- v[AA+0]
6696    sarl      $4,%ecx             # ecx<- B
6697    SPILL(rIBASE)
6698    GET_VREG_WORD rIBASE rINST 1   # rIBASE<- v[AA+1]
6699    GET_VREG_R %ecx %ecx           # ecx<- vBB
6700    shrdl     rIBASE,%eax
6701    sarl      %cl,rIBASE
6702    testb     $32,%cl
6703    je        2f
6704    movl      rIBASE,%eax
6705    sarl      $31,rIBASE
67062:
6707    SET_VREG_WORD rIBASE rINST 1   # v[AA+1]<- rIBASE
6708    UNSPILL(rIBASE)
6709    FETCH_INST_OPCODE 1 %ecx
6710    SET_VREG_WORD %eax rINST 0    # v[AA+0]<- eax
6711    ADVANCE_PC 1
6712    GOTO_NEXT_R %ecx
6713
6714/* ------------------------------ */
6715.L_OP_USHR_LONG_2ADDR: /* 0xc5 */
6716/* File: x86/OP_USHR_LONG_2ADDR.S */
6717    /*
6718     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6719     * 32-bit shift distance.
6720     */
6721    /* shl-long/2addr vA, vB */
6722    /* ecx gets shift count */
6723    /* Need to spill rIBASE */
6724    /* rINSTw gets AA */
6725    movzbl    rINSTbl,%ecx             # ecx<- BA
6726    andb      $0xf,rINSTbl            # rINST<- A
6727    GET_VREG_WORD %eax rINST 0         # eax<- v[AA+0]
6728    sarl      $4,%ecx                 # ecx<- B
6729    SPILL(rIBASE)
6730    GET_VREG_WORD rIBASE rINST 1       # rIBASE<- v[AA+1]
6731    GET_VREG_R %ecx %ecx               # ecx<- vBB
6732    shrdl     rIBASE,%eax
6733    shrl      %cl,rIBASE
6734    testb     $32,%cl
6735    je        2f
6736    movl      rIBASE,%eax
6737    xorl      rIBASE,rIBASE
67382:
6739    SET_VREG_WORD rIBASE rINST 1       # v[AA+1]<- rIBASE
6740    FETCH_INST_OPCODE 1 %ecx
6741    UNSPILL(rIBASE)
6742    SET_VREG_WORD %eax rINST 0         # v[AA+0]<- eax
6743    ADVANCE_PC 1
6744    GOTO_NEXT_R %ecx
6745
6746/* ------------------------------ */
6747.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
6748/* File: x86/OP_ADD_FLOAT_2ADDR.S */
6749/* File: x86/binflop2addr.S */
6750    /*
6751     * Generic 32-bit binary float operation.
6752     *
6753     * For: add-fp, sub-fp, mul-fp, div-fp
6754     */
6755
6756    /* binop/2addr vA, vB */
6757    movzx   rINSTbl,%ecx           # ecx<- A+
6758    andb    $0xf,%cl              # ecx<- A
6759    flds    (rFP,%ecx,4)          # vAA to fp stack
6760    sarl    $4,rINST             # rINST<- B
6761    fadds   (rFP,rINST,4)         # ex: faddp
6762    FETCH_INST_OPCODE 1 %eax
6763    ADVANCE_PC 1
6764    fstps    (rFP,%ecx,4)         # %st to vA
6765    GOTO_NEXT_R %eax
6766
6767
6768/* ------------------------------ */
6769.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
6770/* File: x86/OP_SUB_FLOAT_2ADDR.S */
6771/* File: x86/binflop2addr.S */
6772    /*
6773     * Generic 32-bit binary float operation.
6774     *
6775     * For: add-fp, sub-fp, mul-fp, div-fp
6776     */
6777
6778    /* binop/2addr vA, vB */
6779    movzx   rINSTbl,%ecx           # ecx<- A+
6780    andb    $0xf,%cl              # ecx<- A
6781    flds    (rFP,%ecx,4)          # vAA to fp stack
6782    sarl    $4,rINST             # rINST<- B
6783    fsubs   (rFP,rINST,4)         # ex: faddp
6784    FETCH_INST_OPCODE 1 %eax
6785    ADVANCE_PC 1
6786    fstps    (rFP,%ecx,4)         # %st to vA
6787    GOTO_NEXT_R %eax
6788
6789
6790/* ------------------------------ */
6791.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
6792/* File: x86/OP_MUL_FLOAT_2ADDR.S */
6793/* File: x86/binflop2addr.S */
6794    /*
6795     * Generic 32-bit binary float operation.
6796     *
6797     * For: add-fp, sub-fp, mul-fp, div-fp
6798     */
6799
6800    /* binop/2addr vA, vB */
6801    movzx   rINSTbl,%ecx           # ecx<- A+
6802    andb    $0xf,%cl              # ecx<- A
6803    flds    (rFP,%ecx,4)          # vAA to fp stack
6804    sarl    $4,rINST             # rINST<- B
6805    fmuls   (rFP,rINST,4)         # ex: faddp
6806    FETCH_INST_OPCODE 1 %eax
6807    ADVANCE_PC 1
6808    fstps    (rFP,%ecx,4)         # %st to vA
6809    GOTO_NEXT_R %eax
6810
6811
6812/* ------------------------------ */
6813.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
6814/* File: x86/OP_DIV_FLOAT_2ADDR.S */
6815/* File: x86/binflop2addr.S */
6816    /*
6817     * Generic 32-bit binary float operation.
6818     *
6819     * For: add-fp, sub-fp, mul-fp, div-fp
6820     */
6821
6822    /* binop/2addr vA, vB */
6823    movzx   rINSTbl,%ecx           # ecx<- A+
6824    andb    $0xf,%cl              # ecx<- A
6825    flds    (rFP,%ecx,4)          # vAA to fp stack
6826    sarl    $4,rINST             # rINST<- B
6827    fdivs   (rFP,rINST,4)         # ex: faddp
6828    FETCH_INST_OPCODE 1 %eax
6829    ADVANCE_PC 1
6830    fstps    (rFP,%ecx,4)         # %st to vA
6831    GOTO_NEXT_R %eax
6832
6833
6834/* ------------------------------ */
6835.L_OP_REM_FLOAT_2ADDR: /* 0xca */
6836/* File: x86/OP_REM_FLOAT_2ADDR.S */
6837    /* rem_float/2addr vA, vB */
6838    movzx   rINSTbl,%ecx                # ecx<- A+
6839    sarl    $4,rINST                  # rINST<- B
6840    flds     (rFP,rINST,4)              # vBB to fp stack
6841    andb    $0xf,%cl                   # ecx<- A
6842    flds     (rFP,%ecx,4)               # vAA to fp stack
68431:
6844    fprem
6845    fstsw     %ax
6846    sahf
6847    jp        1b
6848    fstp      %st(1)
6849    FETCH_INST_OPCODE 1 %eax
6850    ADVANCE_PC 1
6851    fstps    (rFP,%ecx,4)               # %st to vA
6852    GOTO_NEXT_R %eax
6853
6854/* ------------------------------ */
6855.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
6856/* File: x86/OP_ADD_DOUBLE_2ADDR.S */
6857   /*
6858    * File: OP_ADD_DOUBLE_2ADDR.S
6859    */
6860
6861    movzx       rINSTbl,%ecx            # ecx<- A+
6862    andb        $0xf,%cl               # ecx<- A
6863    sarl        $4,rINST               # rINST<- B
6864    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
6865    movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vA
6866    FETCH_INST_OPCODE 1 %eax
6867    addsd       %xmm1, %xmm0            # %xmm0<- vA op vB
6868    ADVANCE_PC 1
6869    movq        %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
6870    GOTO_NEXT_R %eax
6871
6872/* ------------------------------ */
6873.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
6874/* File: x86/OP_SUB_DOUBLE_2ADDR.S */
6875   /*
6876    * File: OP_SUB_DOUBLE_2ADDR.S
6877    */
6878
6879    movzx       rINSTbl,%ecx            # ecx<- A+
6880    andb        $0xf,%cl               # ecx<- A
6881    sarl        $4,rINST               # rINST<- B
6882    # TODO: movsd?
6883    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
6884    movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vA
6885    FETCH_INST_OPCODE 1 %eax
6886    subsd       %xmm1, %xmm0            # %xmm0<- vA op vB
6887    ADVANCE_PC 1
6888    movq        %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
6889    GOTO_NEXT_R %eax
6890
6891/* ------------------------------ */
6892.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
6893/* File: x86/OP_MUL_DOUBLE_2ADDR.S */
6894   /*
6895    * File: OP_MUL_DOUBLE_2ADDR.S
6896    */
6897
6898    movzx       rINSTbl,%ecx            # ecx<- A+
6899    andb        $0xf,%cl               # ecx<- A
6900    sarl        $4,rINST               # rINST<- B
6901    # TODO: movsd?
6902    movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
6903    movq        (rFP, %ecx, 4), %xmm0   # %xmm0<- vA
6904    FETCH_INST_OPCODE 1 %eax
6905    mulsd       %xmm1, %xmm0            # %xmm0<- vA op vB
6906    ADVANCE_PC 1
6907    movq        %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
6908    GOTO_NEXT_R %eax
6909
6910/* ------------------------------ */
6911.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */
6912/* File: x86/OP_DIV_DOUBLE_2ADDR.S */
6913/* File: x86/binflop2addr.S */
6914    /*
6915     * Generic 32-bit binary float operation.
6916     *
6917     * For: add-fp, sub-fp, mul-fp, div-fp
6918     */
6919
6920    /* binop/2addr vA, vB */
6921    movzx   rINSTbl,%ecx           # ecx<- A+
6922    andb    $0xf,%cl              # ecx<- A
6923    fldl    (rFP,%ecx,4)          # vAA to fp stack
6924    sarl    $4,rINST             # rINST<- B
6925    fdivl   (rFP,rINST,4)         # ex: faddp
6926    FETCH_INST_OPCODE 1 %eax
6927    ADVANCE_PC 1
6928    fstpl    (rFP,%ecx,4)         # %st to vA
6929    GOTO_NEXT_R %eax
6930
6931
6932/* ------------------------------ */
6933.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */
6934/* File: x86/OP_REM_DOUBLE_2ADDR.S */
6935    /* rem_float/2addr vA, vB */
6936    movzx   rINSTbl,%ecx                # ecx<- A+
6937    sarl    $4,rINST                  # rINST<- B
6938    fldl     (rFP,rINST,4)              # vBB to fp stack
6939    andb    $0xf,%cl                   # ecx<- A
6940    fldl     (rFP,%ecx,4)               # vAA to fp stack
69411:
6942    fprem
6943    fstsw     %ax
6944    sahf
6945    jp        1b
6946    fstp      %st(1)
6947    FETCH_INST_OPCODE 1 %eax
6948    ADVANCE_PC 1
6949    fstpl    (rFP,%ecx,4)               # %st to vA
6950    GOTO_NEXT_R %eax
6951
6952/* ------------------------------ */
6953.L_OP_ADD_INT_LIT16: /* 0xd0 */
6954/* File: x86/OP_ADD_INT_LIT16.S */
6955/* File: x86/binopLit16.S */
6956    /*
6957     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6958     * that specifies an instruction that performs "result = eax op ecx".
6959     * This could be an x86 instruction or a function call.  (If the result
6960     * comes back in a register other than eax, you can override "result".)
6961     *
6962     * For: add-int/lit16, rsub-int,
6963     *      and-int/lit16, or-int/lit16, xor-int/lit16
6964     */
6965    /* binop/lit16 vA, vB, #+CCCC */
6966    movzbl   rINSTbl,%eax               # eax<- 000000BA
6967    sarl     $4,%eax                   # eax<- B
6968    GET_VREG_R %eax %eax                # eax<- vB
6969    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
6970    andb     $0xf,rINSTbl              # rINST<- A
6971    addl %ecx,%eax                              # for example: addl %ecx, %eax
6972    SET_VREG %eax rINST
6973    FETCH_INST_OPCODE 2 %ecx
6974    ADVANCE_PC 2
6975    GOTO_NEXT_R %ecx
6976
6977
6978/* ------------------------------ */
6979.L_OP_RSUB_INT: /* 0xd1 */
6980/* File: x86/OP_RSUB_INT.S */
6981/* File: x86/binopLit16.S */
6982    /*
6983     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6984     * that specifies an instruction that performs "result = eax op ecx".
6985     * This could be an x86 instruction or a function call.  (If the result
6986     * comes back in a register other than eax, you can override "result".)
6987     *
6988     * For: add-int/lit16, rsub-int,
6989     *      and-int/lit16, or-int/lit16, xor-int/lit16
6990     */
6991    /* binop/lit16 vA, vB, #+CCCC */
6992    movzbl   rINSTbl,%eax               # eax<- 000000BA
6993    sarl     $4,%eax                   # eax<- B
6994    GET_VREG_R %eax %eax                # eax<- vB
6995    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
6996    andb     $0xf,rINSTbl              # rINST<- A
6997    subl %eax,%ecx                              # for example: addl %ecx, %eax
6998    SET_VREG %ecx rINST
6999    FETCH_INST_OPCODE 2 %ecx
7000    ADVANCE_PC 2
7001    GOTO_NEXT_R %ecx
7002
7003
7004/* ------------------------------ */
7005.L_OP_MUL_INT_LIT16: /* 0xd2 */
7006/* File: x86/OP_MUL_INT_LIT16.S */
7007    /* mul/lit16 vA, vB, #+CCCC */
7008    /* Need A in rINST, ssssCCCC in ecx, vB in eax */
7009    movzbl   rINSTbl,%eax               # eax<- 000000BA
7010    sarl     $4,%eax                   # eax<- B
7011    GET_VREG_R %eax %eax                # eax<- vB
7012    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
7013    andb     $0xf,rINSTbl              # rINST<- A
7014    SPILL(rIBASE)
7015    imull     %ecx,%eax                 # trashes rIBASE/edx
7016    UNSPILL(rIBASE)
7017    FETCH_INST_OPCODE 2 %ecx
7018    ADVANCE_PC 2
7019    SET_VREG %eax rINST
7020    GOTO_NEXT_R %ecx
7021
7022/* ------------------------------ */
7023.L_OP_DIV_INT_LIT16: /* 0xd3 */
7024/* File: x86/OP_DIV_INT_LIT16.S */
7025/* File: x86/bindivLit16.S */
7026    /*
7027     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
7028     * op1=-1.
7029     */
7030    /* div/rem/lit16 vA, vB, #+CCCC */
7031    /* Need A in rINST, ssssCCCC in ecx, vB in eax */
7032    movzbl   rINSTbl,%eax         # eax<- 000000BA
7033    SPILL(rIBASE)
7034    sarl     $4,%eax             # eax<- B
7035    GET_VREG_R %eax %eax          # eax<- vB
7036    movswl   2(rPC),%ecx          # ecx<- ssssCCCC
7037    andb     $0xf,rINSTbl        # rINST<- A
7038    cmpl     $0,%ecx
7039    je       common_errDivideByZero
7040    cmpl     $-1,%ecx
7041    jne      .LOP_DIV_INT_LIT16_continue_div
7042    cmpl     $0x80000000,%eax
7043    jne      .LOP_DIV_INT_LIT16_continue_div
7044    movl     $0x80000000,%eax
7045    SET_VREG %eax rINST
7046    UNSPILL(rIBASE)
7047    FETCH_INST_OPCODE 2 %ecx
7048    ADVANCE_PC 2
7049    GOTO_NEXT_R %ecx
7050
7051.LOP_DIV_INT_LIT16_continue_div:
7052    cltd
7053    idivl   %ecx
7054    SET_VREG %eax rINST
7055    UNSPILL(rIBASE)
7056    FETCH_INST_OPCODE 2 %ecx
7057    ADVANCE_PC 2
7058    GOTO_NEXT_R %ecx
7059
7060
7061/* ------------------------------ */
7062.L_OP_REM_INT_LIT16: /* 0xd4 */
7063/* File: x86/OP_REM_INT_LIT16.S */
7064/* File: x86/bindivLit16.S */
7065    /*
7066     * 32-bit binary div/rem operation.  Handles special case of op0=minint and
7067     * op1=-1.
7068     */
7069    /* div/rem/lit16 vA, vB, #+CCCC */
7070    /* Need A in rINST, ssssCCCC in ecx, vB in eax */
7071    movzbl   rINSTbl,%eax         # eax<- 000000BA
7072    SPILL(rIBASE)
7073    sarl     $4,%eax             # eax<- B
7074    GET_VREG_R %eax %eax          # eax<- vB
7075    movswl   2(rPC),%ecx          # ecx<- ssssCCCC
7076    andb     $0xf,rINSTbl        # rINST<- A
7077    cmpl     $0,%ecx
7078    je       common_errDivideByZero
7079    cmpl     $-1,%ecx
7080    jne      .LOP_REM_INT_LIT16_continue_div
7081    cmpl     $0x80000000,%eax
7082    jne      .LOP_REM_INT_LIT16_continue_div
7083    movl     $0,rIBASE
7084    SET_VREG rIBASE rINST
7085    UNSPILL(rIBASE)
7086    FETCH_INST_OPCODE 2 %ecx
7087    ADVANCE_PC 2
7088    GOTO_NEXT_R %ecx
7089
7090.LOP_REM_INT_LIT16_continue_div:
7091    cltd
7092    idivl   %ecx
7093    SET_VREG rIBASE rINST
7094    UNSPILL(rIBASE)
7095    FETCH_INST_OPCODE 2 %ecx
7096    ADVANCE_PC 2
7097    GOTO_NEXT_R %ecx
7098
7099
7100/* ------------------------------ */
7101.L_OP_AND_INT_LIT16: /* 0xd5 */
7102/* File: x86/OP_AND_INT_LIT16.S */
7103/* File: x86/binopLit16.S */
7104    /*
7105     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
7106     * that specifies an instruction that performs "result = eax op ecx".
7107     * This could be an x86 instruction or a function call.  (If the result
7108     * comes back in a register other than eax, you can override "result".)
7109     *
7110     * For: add-int/lit16, rsub-int,
7111     *      and-int/lit16, or-int/lit16, xor-int/lit16
7112     */
7113    /* binop/lit16 vA, vB, #+CCCC */
7114    movzbl   rINSTbl,%eax               # eax<- 000000BA
7115    sarl     $4,%eax                   # eax<- B
7116    GET_VREG_R %eax %eax                # eax<- vB
7117    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
7118    andb     $0xf,rINSTbl              # rINST<- A
7119    andl %ecx,%eax                              # for example: addl %ecx, %eax
7120    SET_VREG %eax rINST
7121    FETCH_INST_OPCODE 2 %ecx
7122    ADVANCE_PC 2
7123    GOTO_NEXT_R %ecx
7124
7125
7126/* ------------------------------ */
7127.L_OP_OR_INT_LIT16: /* 0xd6 */
7128/* File: x86/OP_OR_INT_LIT16.S */
7129/* File: x86/binopLit16.S */
7130    /*
7131     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
7132     * that specifies an instruction that performs "result = eax op ecx".
7133     * This could be an x86 instruction or a function call.  (If the result
7134     * comes back in a register other than eax, you can override "result".)
7135     *
7136     * For: add-int/lit16, rsub-int,
7137     *      and-int/lit16, or-int/lit16, xor-int/lit16
7138     */
7139    /* binop/lit16 vA, vB, #+CCCC */
7140    movzbl   rINSTbl,%eax               # eax<- 000000BA
7141    sarl     $4,%eax                   # eax<- B
7142    GET_VREG_R %eax %eax                # eax<- vB
7143    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
7144    andb     $0xf,rINSTbl              # rINST<- A
7145    orl     %ecx,%eax                              # for example: addl %ecx, %eax
7146    SET_VREG %eax rINST
7147    FETCH_INST_OPCODE 2 %ecx
7148    ADVANCE_PC 2
7149    GOTO_NEXT_R %ecx
7150
7151
7152/* ------------------------------ */
7153.L_OP_XOR_INT_LIT16: /* 0xd7 */
7154/* File: x86/OP_XOR_INT_LIT16.S */
7155/* File: x86/binopLit16.S */
7156    /*
7157     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
7158     * that specifies an instruction that performs "result = eax op ecx".
7159     * This could be an x86 instruction or a function call.  (If the result
7160     * comes back in a register other than eax, you can override "result".)
7161     *
7162     * For: add-int/lit16, rsub-int,
7163     *      and-int/lit16, or-int/lit16, xor-int/lit16
7164     */
7165    /* binop/lit16 vA, vB, #+CCCC */
7166    movzbl   rINSTbl,%eax               # eax<- 000000BA
7167    sarl     $4,%eax                   # eax<- B
7168    GET_VREG_R %eax %eax                # eax<- vB
7169    movswl   2(rPC),%ecx                # ecx<- ssssCCCC
7170    andb     $0xf,rINSTbl              # rINST<- A
7171    xor    %ecx,%eax                              # for example: addl %ecx, %eax
7172    SET_VREG %eax rINST
7173    FETCH_INST_OPCODE 2 %ecx
7174    ADVANCE_PC 2
7175    GOTO_NEXT_R %ecx
7176
7177
7178/* ------------------------------ */
7179.L_OP_ADD_INT_LIT8: /* 0xd8 */
7180/* File: x86/OP_ADD_INT_LIT8.S */
7181/* File: x86/binopLit8.S */
7182    /*
7183     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7184     * that specifies an instruction that performs "result = eax op ecx".
7185     * This could be an x86 instruction or a function call.  (If the result
7186     * comes back in a register other than r0, you can override "result".)
7187     *
7188     * For: add-int/lit8, rsub-int/lit8
7189     *      and-int/lit8, or-int/lit8, xor-int/lit8,
7190     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7191     */
7192    /* binop/lit8 vAA, vBB, #+CC */
7193    movzbl    2(rPC),%eax              # eax<- BB
7194    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
7195    GET_VREG_R   %eax %eax             # eax<- rBB
7196    addl %ecx,%eax                             # ex: addl %ecx,%eax
7197    SET_VREG   %eax rINST
7198    FETCH_INST_OPCODE 2 %ecx
7199    ADVANCE_PC 2
7200    GOTO_NEXT_R %ecx
7201
7202
7203/* ------------------------------ */
7204.L_OP_RSUB_INT_LIT8: /* 0xd9 */
7205/* File: x86/OP_RSUB_INT_LIT8.S */
7206/* File: x86/binopLit8.S */
7207    /*
7208     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7209     * that specifies an instruction that performs "result = eax op ecx".
7210     * This could be an x86 instruction or a function call.  (If the result
7211     * comes back in a register other than r0, you can override "result".)
7212     *
7213     * For: add-int/lit8, rsub-int/lit8
7214     *      and-int/lit8, or-int/lit8, xor-int/lit8,
7215     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7216     */
7217    /* binop/lit8 vAA, vBB, #+CC */
7218    movzbl    2(rPC),%eax              # eax<- BB
7219    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
7220    GET_VREG_R   %eax %eax             # eax<- rBB
7221    subl  %eax,%ecx                             # ex: addl %ecx,%eax
7222    SET_VREG   %ecx rINST
7223    FETCH_INST_OPCODE 2 %ecx
7224    ADVANCE_PC 2
7225    GOTO_NEXT_R %ecx
7226
7227
7228/* ------------------------------ */
7229.L_OP_MUL_INT_LIT8: /* 0xda */
7230/* File: x86/OP_MUL_INT_LIT8.S */
7231    /* mul/lit8 vAA, vBB, #+CC */
7232    movzbl    2(rPC),%eax              # eax<- BB
7233    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
7234    GET_VREG_R   %eax %eax             # eax<- rBB
7235    SPILL(rIBASE)
7236    imull     %ecx,%eax                # trashes rIBASE/edx
7237    UNSPILL(rIBASE)
7238    FETCH_INST_OPCODE 2 %ecx
7239    ADVANCE_PC 2
7240    SET_VREG  %eax rINST
7241    GOTO_NEXT_R %ecx
7242
7243/* ------------------------------ */
7244.L_OP_DIV_INT_LIT8: /* 0xdb */
7245/* File: x86/OP_DIV_INT_LIT8.S */
7246/* File: x86/bindivLit8.S */
7247    /*
7248     * 32-bit div/rem "lit8" binary operation.  Handles special case of
7249     * op0=minint & op1=-1
7250     */
7251    /* div/rem/lit8 vAA, vBB, #+CC */
7252    movzbl    2(rPC),%eax        # eax<- BB
7253    movsbl    3(rPC),%ecx        # ecx<- ssssssCC
7254    SPILL(rIBASE)
7255    GET_VREG_R  %eax %eax        # eax<- rBB
7256    cmpl     $0,%ecx
7257    je       common_errDivideByZero
7258    cmpl     $0x80000000,%eax
7259    jne      .LOP_DIV_INT_LIT8_continue_div
7260    cmpl     $-1,%ecx
7261    jne      .LOP_DIV_INT_LIT8_continue_div
7262    movl     $0x80000000,%eax
7263    SET_VREG %eax rINST
7264    UNSPILL(rIBASE)
7265    FETCH_INST_OPCODE 2 %ecx
7266    ADVANCE_PC 2
7267    GOTO_NEXT_R %ecx
7268
7269.LOP_DIV_INT_LIT8_continue_div:
7270    cltd
7271    idivl   %ecx
7272    SET_VREG %eax rINST
7273    UNSPILL(rIBASE)
7274    FETCH_INST_OPCODE 2 %ecx
7275    ADVANCE_PC 2
7276    GOTO_NEXT_R %ecx
7277
7278
7279/* ------------------------------ */
7280.L_OP_REM_INT_LIT8: /* 0xdc */
7281/* File: x86/OP_REM_INT_LIT8.S */
7282/* File: x86/bindivLit8.S */
7283    /*
7284     * 32-bit div/rem "lit8" binary operation.  Handles special case of
7285     * op0=minint & op1=-1
7286     */
7287    /* div/rem/lit8 vAA, vBB, #+CC */
7288    movzbl    2(rPC),%eax        # eax<- BB
7289    movsbl    3(rPC),%ecx        # ecx<- ssssssCC
7290    SPILL(rIBASE)
7291    GET_VREG_R  %eax %eax        # eax<- rBB
7292    cmpl     $0,%ecx
7293    je       common_errDivideByZero
7294    cmpl     $0x80000000,%eax
7295    jne      .LOP_REM_INT_LIT8_continue_div
7296    cmpl     $-1,%ecx
7297    jne      .LOP_REM_INT_LIT8_continue_div
7298    movl     $0,rIBASE
7299    SET_VREG rIBASE rINST
7300    UNSPILL(rIBASE)
7301    FETCH_INST_OPCODE 2 %ecx
7302    ADVANCE_PC 2
7303    GOTO_NEXT_R %ecx
7304
7305.LOP_REM_INT_LIT8_continue_div:
7306    cltd
7307    idivl   %ecx
7308    SET_VREG rIBASE rINST
7309    UNSPILL(rIBASE)
7310    FETCH_INST_OPCODE 2 %ecx
7311    ADVANCE_PC 2
7312    GOTO_NEXT_R %ecx
7313
7314
7315/* ------------------------------ */
7316.L_OP_AND_INT_LIT8: /* 0xdd */
7317/* File: x86/OP_AND_INT_LIT8.S */
7318/* File: x86/binopLit8.S */
7319    /*
7320     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7321     * that specifies an instruction that performs "result = eax op ecx".
7322     * This could be an x86 instruction or a function call.  (If the result
7323     * comes back in a register other than r0, you can override "result".)
7324     *
7325     * For: add-int/lit8, rsub-int/lit8
7326     *      and-int/lit8, or-int/lit8, xor-int/lit8,
7327     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7328     */
7329    /* binop/lit8 vAA, vBB, #+CC */
7330    movzbl    2(rPC),%eax              # eax<- BB
7331    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
7332    GET_VREG_R   %eax %eax             # eax<- rBB
7333    andl %ecx,%eax                             # ex: addl %ecx,%eax
7334    SET_VREG   %eax rINST
7335    FETCH_INST_OPCODE 2 %ecx
7336    ADVANCE_PC 2
7337    GOTO_NEXT_R %ecx
7338
7339
7340/* ------------------------------ */
7341.L_OP_OR_INT_LIT8: /* 0xde */
7342/* File: x86/OP_OR_INT_LIT8.S */
7343/* File: x86/binopLit8.S */
7344    /*
7345     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7346     * that specifies an instruction that performs "result = eax op ecx".
7347     * This could be an x86 instruction or a function call.  (If the result
7348     * comes back in a register other than r0, you can override "result".)
7349     *
7350     * For: add-int/lit8, rsub-int/lit8
7351     *      and-int/lit8, or-int/lit8, xor-int/lit8,
7352     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7353     */
7354    /* binop/lit8 vAA, vBB, #+CC */
7355    movzbl    2(rPC),%eax              # eax<- BB
7356    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
7357    GET_VREG_R   %eax %eax             # eax<- rBB
7358    orl     %ecx,%eax                             # ex: addl %ecx,%eax
7359    SET_VREG   %eax rINST
7360    FETCH_INST_OPCODE 2 %ecx
7361    ADVANCE_PC 2
7362    GOTO_NEXT_R %ecx
7363
7364
7365/* ------------------------------ */
7366.L_OP_XOR_INT_LIT8: /* 0xdf */
7367/* File: x86/OP_XOR_INT_LIT8.S */
7368/* File: x86/binopLit8.S */
7369    /*
7370     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7371     * that specifies an instruction that performs "result = eax op ecx".
7372     * This could be an x86 instruction or a function call.  (If the result
7373     * comes back in a register other than r0, you can override "result".)
7374     *
7375     * For: add-int/lit8, rsub-int/lit8
7376     *      and-int/lit8, or-int/lit8, xor-int/lit8,
7377     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7378     */
7379    /* binop/lit8 vAA, vBB, #+CC */
7380    movzbl    2(rPC),%eax              # eax<- BB
7381    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
7382    GET_VREG_R   %eax %eax             # eax<- rBB
7383    xor    %ecx,%eax                             # ex: addl %ecx,%eax
7384    SET_VREG   %eax rINST
7385    FETCH_INST_OPCODE 2 %ecx
7386    ADVANCE_PC 2
7387    GOTO_NEXT_R %ecx
7388
7389
7390/* ------------------------------ */
7391.L_OP_SHL_INT_LIT8: /* 0xe0 */
7392/* File: x86/OP_SHL_INT_LIT8.S */
7393/* File: x86/binopLit8.S */
7394    /*
7395     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7396     * that specifies an instruction that performs "result = eax op ecx".
7397     * This could be an x86 instruction or a function call.  (If the result
7398     * comes back in a register other than r0, you can override "result".)
7399     *
7400     * For: add-int/lit8, rsub-int/lit8
7401     *      and-int/lit8, or-int/lit8, xor-int/lit8,
7402     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7403     */
7404    /* binop/lit8 vAA, vBB, #+CC */
7405    movzbl    2(rPC),%eax              # eax<- BB
7406    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
7407    GET_VREG_R   %eax %eax             # eax<- rBB
7408    sall  %cl,%eax                             # ex: addl %ecx,%eax
7409    SET_VREG   %eax rINST
7410    FETCH_INST_OPCODE 2 %ecx
7411    ADVANCE_PC 2
7412    GOTO_NEXT_R %ecx
7413
7414
7415/* ------------------------------ */
7416.L_OP_SHR_INT_LIT8: /* 0xe1 */
7417/* File: x86/OP_SHR_INT_LIT8.S */
7418/* File: x86/binopLit8.S */
7419    /*
7420     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7421     * that specifies an instruction that performs "result = eax op ecx".
7422     * This could be an x86 instruction or a function call.  (If the result
7423     * comes back in a register other than r0, you can override "result".)
7424     *
7425     * For: add-int/lit8, rsub-int/lit8
7426     *      and-int/lit8, or-int/lit8, xor-int/lit8,
7427     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7428     */
7429    /* binop/lit8 vAA, vBB, #+CC */
7430    movzbl    2(rPC),%eax              # eax<- BB
7431    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
7432    GET_VREG_R   %eax %eax             # eax<- rBB
7433    sarl    %cl,%eax                             # ex: addl %ecx,%eax
7434    SET_VREG   %eax rINST
7435    FETCH_INST_OPCODE 2 %ecx
7436    ADVANCE_PC 2
7437    GOTO_NEXT_R %ecx
7438
7439
7440/* ------------------------------ */
7441.L_OP_USHR_INT_LIT8: /* 0xe2 */
7442/* File: x86/OP_USHR_INT_LIT8.S */
7443/* File: x86/binopLit8.S */
7444    /*
7445     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7446     * that specifies an instruction that performs "result = eax op ecx".
7447     * This could be an x86 instruction or a function call.  (If the result
7448     * comes back in a register other than r0, you can override "result".)
7449     *
7450     * For: add-int/lit8, rsub-int/lit8
7451     *      and-int/lit8, or-int/lit8, xor-int/lit8,
7452     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7453     */
7454    /* binop/lit8 vAA, vBB, #+CC */
7455    movzbl    2(rPC),%eax              # eax<- BB
7456    movsbl    3(rPC),%ecx              # ecx<- ssssssCC
7457    GET_VREG_R   %eax %eax             # eax<- rBB
7458    shrl     %cl,%eax                             # ex: addl %ecx,%eax
7459    SET_VREG   %eax rINST
7460    FETCH_INST_OPCODE 2 %ecx
7461    ADVANCE_PC 2
7462    GOTO_NEXT_R %ecx
7463
7464
7465/* ------------------------------ */
7466.L_OP_IGET_VOLATILE: /* 0xe3 */
7467/* File: x86/OP_IGET_VOLATILE.S */
7468/* File: x86/OP_IGET.S */
7469    /*
7470     * General 32-bit instance field get.
7471     *
7472     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7473     */
7474    /* op vA, vB, field@CCCC */
7475    movl    rSELF,%ecx
7476    SPILL(rIBASE)                               # preserve rIBASE
7477    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
7478    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
7479    movzbl  rINSTbl,%ecx                        # ecx<- BA
7480    sarl    $4,%ecx                            # ecx<- B
7481    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
7482    andb    $0xf,rINSTbl                       # rINST<- A
7483    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
7484    movl    (%eax,rIBASE,4),%eax                # resolved entry
7485    testl   %eax,%eax                           # is resolved entry null?
7486    jne     .LOP_IGET_VOLATILE_finish                  # no, already resolved
7487    movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
7488    movl    rSELF,rIBASE
7489    EXPORT_PC
7490    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
7491    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
7492    SPILL_TMP1(%ecx)                            # save obj pointer across call
7493    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
7494    call    dvmResolveInstField                 #  ... to dvmResolveInstField
7495    UNSPILL_TMP1(%ecx)
7496    testl   %eax,%eax                           #  returns InstrField ptr
7497    jne     .LOP_IGET_VOLATILE_finish
7498    jmp     common_exceptionThrown
7499
7500.LOP_IGET_VOLATILE_finish:
7501    /*
7502     * Currently:
7503     *   eax holds resolved field
7504     *   ecx holds object
7505     *   rINST holds A
7506     */
7507    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
7508    testl   %ecx,%ecx                           # object null?
7509    je      common_errNullObject                # object was null
7510    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
7511    FETCH_INST_OPCODE 2 %eax
7512    UNSPILL(rIBASE)
7513    SET_VREG %ecx rINST
7514    ADVANCE_PC 2
7515    GOTO_NEXT_R %eax
7516
7517
7518/* ------------------------------ */
7519.L_OP_IPUT_VOLATILE: /* 0xe4 */
7520/* File: x86/OP_IPUT_VOLATILE.S */
7521/* File: x86/OP_IPUT.S */
7522
7523    /*
7524     * General 32-bit instance field put.
7525     *
7526     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
7527     */
7528    /* op vA, vB, field@CCCC */
7529    movl    rSELF,%ecx
7530    SPILL   (rIBASE)
7531    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
7532    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
7533    movzbl  rINSTbl,%ecx                        # ecx<- BA
7534    sarl    $4,%ecx                            # ecx<- B
7535    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
7536    andb    $0xf,rINSTbl                       # rINST<- A
7537    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
7538    movl    (%eax,rIBASE,4),%eax                # resolved entry
7539    testl   %eax,%eax                           # is resolved entry null?
7540    jne     .LOP_IPUT_VOLATILE_finish                  # no, already resolved
7541    movl    rIBASE,OUT_ARG1(%esp)
7542    movl    rSELF,rIBASE
7543    EXPORT_PC
7544    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
7545    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
7546    SPILL_TMP1(%ecx)                            # save obj pointer across call
7547    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
7548    call    dvmResolveInstField                 #  ... to dvmResolveInstField
7549    UNSPILL_TMP1(%ecx)
7550    testl   %eax,%eax                           # returns InstrField ptr
7551    jne     .LOP_IPUT_VOLATILE_finish
7552    jmp     common_exceptionThrown
7553
7554.LOP_IPUT_VOLATILE_finish:
7555    /*
7556     * Currently:
7557     *   eax holds resolved field
7558     *   ecx holds object
7559     *   rINST holds A
7560     */
7561    GET_VREG_R rINST rINST                       # rINST<- v[A]
7562    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
7563    testl   %ecx,%ecx                            # object null?
7564    je      common_errNullObject                 # object was null
7565    movl   rINST,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
7566    FETCH_INST_OPCODE 2 %ecx
7567    UNSPILL(rIBASE)
7568    ADVANCE_PC 2
7569    GOTO_NEXT_R %ecx
7570
7571
7572/* ------------------------------ */
7573.L_OP_SGET_VOLATILE: /* 0xe5 */
7574/* File: x86/OP_SGET_VOLATILE.S */
7575/* File: x86/OP_SGET.S */
7576    /*
7577     * General 32-bit SGET handler.
7578     *
7579     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7580     */
7581    /* op vAA, field@BBBB */
7582    movl      rSELF,%ecx
7583    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
7584    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7585    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7586#if defined(WITH_JIT)
7587    movl      %ecx, TMP_SPILL1(%ebp)
7588    lea       (%ecx,%eax,4),%ecx
7589    movl      %ecx, TMP_SPILL2(%ebp)
7590    movl      TMP_SPILL1(%ebp), %ecx
7591#endif
7592    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7593    testl     %eax,%eax                          # resolved entry null?
7594    je        .LOP_SGET_VOLATILE_resolve                # if not, make it so
7595.LOP_SGET_VOLATILE_finish:     # field ptr in eax
7596    movl      offStaticField_value(%eax),%eax
7597    FETCH_INST_OPCODE 2 %ecx
7598    ADVANCE_PC 2
7599    SET_VREG %eax rINST
7600    GOTO_NEXT_R %ecx
7601
7602    /*
7603     * Go resolve the field
7604     */
7605.LOP_SGET_VOLATILE_resolve:
7606    movl     rSELF,%ecx
7607    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
7608    movl     offThread_method(%ecx),%ecx          # ecx<- current method
7609    EXPORT_PC                                   # could throw, need to export
7610    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
7611    movl     %eax,OUT_ARG1(%esp)
7612    movl     %ecx,OUT_ARG0(%esp)
7613    SPILL(rIBASE)
7614    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
7615    UNSPILL(rIBASE)
7616    testl    %eax,%eax
7617    je      common_exceptionThrown             # no, handle exception
7618#if defined(WITH_JIT)
7619    movl      TMP_SPILL2(%ebp), %ecx
7620    SPILL(rIBASE)
7621    call     common_verifyField
7622    UNSPILL(rIBASE)
7623#endif
7624    jmp      .LOP_SGET_VOLATILE_finish                 # success, continue
7625
7626
7627/* ------------------------------ */
7628.L_OP_SPUT_VOLATILE: /* 0xe6 */
7629/* File: x86/OP_SPUT_VOLATILE.S */
7630/* File: x86/OP_SPUT.S */
7631    /*
7632     * General 32-bit SPUT handler.
7633     *
7634     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
7635     */
7636    /* op vAA, field@BBBB */
7637    movl      rSELF,%ecx
7638    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
7639    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
7640    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
7641#if defined(WITH_JIT)
7642    movl      %ecx, TMP_SPILL1(%ebp)
7643    lea       (%ecx,%eax,4),%ecx
7644    movl      %ecx, TMP_SPILL2(%ebp)
7645    movl      TMP_SPILL1(%ebp), %ecx
7646#endif
7647    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
7648    testl     %eax,%eax                          # resolved entry null?
7649    je        .LOP_SPUT_VOLATILE_resolve                # if not, make it so
7650.LOP_SPUT_VOLATILE_finish:     # field ptr in eax
7651    GET_VREG_R  rINST rINST
7652    FETCH_INST_OPCODE 2 %ecx
7653    ADVANCE_PC 2
7654    movl      rINST,offStaticField_value(%eax)
7655    GOTO_NEXT_R %ecx
7656
7657    /*
7658     * Go resolve the field
7659     */
7660.LOP_SPUT_VOLATILE_resolve:
7661    movl     rSELF,%ecx
7662    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
7663    movl     offThread_method(%ecx),%ecx        # ecx<- current method
7664    EXPORT_PC                                   # could throw, need to export
7665    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
7666    movl     %eax,OUT_ARG1(%esp)
7667    movl     %ecx,OUT_ARG0(%esp)
7668    SPILL(rIBASE)
7669    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
7670    UNSPILL(rIBASE)
7671    testl    %eax,%eax
7672    je      common_exceptionThrown             # no, handle exception
7673#if defined(WITH_JIT)
7674    movl      TMP_SPILL2(%ebp), %ecx
7675    SPILL(rIBASE)
7676    call     common_verifyField
7677    UNSPILL(rIBASE)
7678#endif
7679    jmp      .LOP_SPUT_VOLATILE_finish                 # success, continue
7680
7681/* ------------------------------ */
7682.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
7683/* File: x86/OP_IGET_OBJECT_VOLATILE.S */
7684/* File: x86/OP_IGET.S */
7685    /*
7686     * General 32-bit instance field get.
7687     *
7688     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7689     */
7690    /* op vA, vB, field@CCCC */
7691    movl    rSELF,%ecx
7692    SPILL(rIBASE)                               # preserve rIBASE
7693    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
7694    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
7695    movzbl  rINSTbl,%ecx                        # ecx<- BA
7696    sarl    $4,%ecx                            # ecx<- B
7697    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
7698    andb    $0xf,rINSTbl                       # rINST<- A
7699    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
7700    movl    (%eax,rIBASE,4),%eax                # resolved entry
7701    testl   %eax,%eax                           # is resolved entry null?
7702    jne     .LOP_IGET_OBJECT_VOLATILE_finish                  # no, already resolved
7703    movl    rIBASE,OUT_ARG1(%esp)               # needed by dvmResolveInstField
7704    movl    rSELF,rIBASE
7705    EXPORT_PC
7706    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
7707    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
7708    SPILL_TMP1(%ecx)                            # save obj pointer across call
7709    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
7710    call    dvmResolveInstField                 #  ... to dvmResolveInstField
7711    UNSPILL_TMP1(%ecx)
7712    testl   %eax,%eax                           #  returns InstrField ptr
7713    jne     .LOP_IGET_OBJECT_VOLATILE_finish
7714    jmp     common_exceptionThrown
7715
7716.LOP_IGET_OBJECT_VOLATILE_finish:
7717    /*
7718     * Currently:
7719     *   eax holds resolved field
7720     *   ecx holds object
7721     *   rINST holds A
7722     */
7723    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
7724    testl   %ecx,%ecx                           # object null?
7725    je      common_errNullObject                # object was null
7726    movl   (%ecx,%eax,1),%ecx                  # ecx<- obj.field (8/16/32 bits)
7727    FETCH_INST_OPCODE 2 %eax
7728    UNSPILL(rIBASE)
7729    SET_VREG %ecx rINST
7730    ADVANCE_PC 2
7731    GOTO_NEXT_R %eax
7732
7733
7734/* ------------------------------ */
7735.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
7736    /* (stub) */
7737    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
7738    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
7739    call      dvmMterp_OP_IGET_WIDE_VOLATILE     # do the real work
7740    movl      rSELF,%ecx
7741    LOAD_PC_FP_FROM_SELF             # retrieve updated values
7742    movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
7743    FETCH_INST
7744    GOTO_NEXT
7745/* ------------------------------ */
7746.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
7747    /* (stub) */
7748    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
7749    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
7750    call      dvmMterp_OP_IPUT_WIDE_VOLATILE     # do the real work
7751    movl      rSELF,%ecx
7752    LOAD_PC_FP_FROM_SELF             # retrieve updated values
7753    movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
7754    FETCH_INST
7755    GOTO_NEXT
7756/* ------------------------------ */
7757.L_OP_SGET_WIDE_VOLATILE: /* 0xea */
7758    /* (stub) */
7759    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
7760    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
7761    call      dvmMterp_OP_SGET_WIDE_VOLATILE     # do the real work
7762    movl      rSELF,%ecx
7763    LOAD_PC_FP_FROM_SELF             # retrieve updated values
7764    movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
7765    FETCH_INST
7766    GOTO_NEXT
7767/* ------------------------------ */
7768.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
7769    /* (stub) */
7770    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
7771    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
7772    call      dvmMterp_OP_SPUT_WIDE_VOLATILE     # do the real work
7773    movl      rSELF,%ecx
7774    LOAD_PC_FP_FROM_SELF             # retrieve updated values
7775    movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
7776    FETCH_INST
7777    GOTO_NEXT
7778/* ------------------------------ */
7779.L_OP_BREAKPOINT: /* 0xec */
7780/* File: x86/OP_BREAKPOINT.S */
7781    /*
7782     * Breakpoint handler.
7783     *
7784     * Restart this instruction with the original opcode.  By
7785     * the time we get here, the breakpoint will have already been
7786     * handled.  We also assume that all other special "checkBefore"
7787     * actions have been handled, so we'll transition directly
7788     * to the real handler
7789     */
7790    SPILL(rIBASE)
7791    movl    rPC,OUT_ARG0(%esp)
7792    call    dvmGetOriginalOpcode
7793    UNSPILL(rIBASE)
7794    movl    rSELF,%ecx
7795    movzbl  1(rPC),rINST
7796    movl    offThread_mainHandlerTable(%ecx),%ecx
7797    jmp     *(%ecx,%eax,4)
7798
7799
7800/* ------------------------------ */
7801.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */
7802/* File: x86/OP_THROW_VERIFICATION_ERROR.S */
7803    /*
7804     * Handle a throw-verification-error instruction.  This throws an
7805     * exception for an error discovered during verification.  The
7806     * exception is indicated by AA, with some detail provided by BBBB.
7807     */
7808    /* op AA, ref@BBBB */
7809    movl     rSELF,%ecx
7810    movzwl   2(rPC),%eax                     # eax<- BBBB
7811    movl     offThread_method(%ecx),%ecx       # ecx<- self->method
7812    EXPORT_PC
7813    movl     %eax,OUT_ARG2(%esp)             # arg2<- BBBB
7814    movl     rINST,OUT_ARG1(%esp)            # arg1<- AA
7815    movl     %ecx,OUT_ARG0(%esp)             # arg0<- method
7816    call     dvmThrowVerificationError       # call(method, kind, ref)
7817    jmp      common_exceptionThrown          # handle exception
7818
7819/* ------------------------------ */
7820.L_OP_EXECUTE_INLINE: /* 0xee */
7821/* File: x86/OP_EXECUTE_INLINE.S */
7822    /*
7823     * Execute a "native inline" instruction.
7824     *
7825     * We will be calling through a function table:
7826     *
7827     * (*gDvmInlineOpsTable[opIndex].func)(arg0, arg1, arg2, arg3, pResult)
7828     *
7829     * Ignores argument count - always loads 4.
7830     *
7831     */
7832    /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */
7833    movl      rSELF,%ecx
7834    EXPORT_PC
7835    movzwl    2(rPC),%eax               # eax<- BBBB
7836    SPILL(rIBASE)                       # preserve rIBASE
7837    movl      offThread_subMode(%ecx), %edx # edx<- submode flags
7838    andl      $kSubModeDebugProfile, %edx # debug or profile mode active?
7839    jnz       .LOP_EXECUTE_INLINE_debugprofile   # yes, take slow path
7840.LOP_EXECUTE_INLINE_resume:
7841    leal      offThread_retval(%ecx),%ecx # ecx<- &self->retval
7842    movl      %ecx,OUT_ARG4(%esp)
7843    call      .LOP_EXECUTE_INLINE_continue      # make call; will return after
7844    UNSPILL(rIBASE)                     # restore rIBASE
7845    testl     %eax,%eax                 # successful?
7846    jz        common_exceptionThrown    # no, handle exception
7847    FETCH_INST_OPCODE 3 %ecx
7848    ADVANCE_PC 3
7849    GOTO_NEXT_R %ecx
7850
7851.LOP_EXECUTE_INLINE_continue:
7852    /*
7853     * Extract args, call function.
7854     *  ecx = #of args (0-4)
7855     *  eax = call index
7856     *  @esp = return addr
7857     *  esp is -4 from normal
7858     *
7859     *  Go ahead and load all 4 args, even if not used.
7860     */
7861    movzwl    4(rPC),rIBASE
7862
7863    movl      $0xf,%ecx
7864    andl      rIBASE,%ecx
7865    GET_VREG_R  %ecx %ecx
7866    sarl      $4,rIBASE
7867    movl      %ecx,4+OUT_ARG0(%esp)
7868
7869    movl      $0xf,%ecx
7870    andl      rIBASE,%ecx
7871    GET_VREG_R  %ecx %ecx
7872    sarl      $4,rIBASE
7873    movl      %ecx,4+OUT_ARG1(%esp)
7874
7875    movl      $0xf,%ecx
7876    andl      rIBASE,%ecx
7877    GET_VREG_R  %ecx %ecx
7878    sarl      $4,rIBASE
7879    movl      %ecx,4+OUT_ARG2(%esp)
7880
7881    movl      $0xf,%ecx
7882    andl      rIBASE,%ecx
7883    GET_VREG_R  %ecx %ecx
7884    sarl      $4,rIBASE
7885    movl      %ecx,4+OUT_ARG3(%esp)
7886
7887    sall      $4,%eax      # index *= sizeof(table entry)
7888    jmp       *gDvmInlineOpsTable(%eax)
7889    # will return to caller of .LOP_EXECUTE_INLINE_continue
7890
7891    /*
7892     * We're debugging or profiling.
7893     * eax: opIndex
7894     */
7895.LOP_EXECUTE_INLINE_debugprofile:
7896    movl      %eax,OUT_ARG0(%esp)       # arg0<- BBBB
7897    SPILL_TMP1(%eax)                    # save opIndex
7898    call      dvmResolveInlineNative    # dvmResolveInlineNative(opIndex)
7899    movl      rSELF,%ecx                # restore self
7900    testl     %eax,%eax                 # method resolved?
7901    movl      %eax,%edx                 # save possibly resolved method in edx
7902    UNSPILL_TMP1(%eax)                  # in case not resolved, restore opIndex
7903    jz        .LOP_EXECUTE_INLINE_resume        # not resolved, just move on
7904    SPILL_TMP2(%edx)                    # save method
7905    movl      %edx,OUT_ARG0(%esp)       # arg0<- method
7906    movl      %ecx,OUT_ARG1(%esp)       # arg1<- self
7907    call      dvmFastMethodTraceEnter   # dvmFastMethodTraceEnter(method,self)
7908    movl      rSELF,%ecx                # restore self
7909    UNSPILL_TMP1(%eax)                  # restore opIndex
7910    leal      offThread_retval(%ecx),%ecx # ecx<- &self->retval
7911    movl      %ecx,OUT_ARG4(%esp)       # needed for pResult of inline operation handler
7912    call      .LOP_EXECUTE_INLINE_continue      # make call; will return after
7913    SPILL_TMP1(%eax)                    # save result of inline
7914    UNSPILL_TMP2(%eax)                  # restore method
7915    movl      rSELF,%ecx                # restore self
7916    movl      %eax,OUT_ARG0(%esp)       # arg0<- method
7917    movl      %ecx,OUT_ARG1(%esp)       # arg1<- self
7918    call      dvmFastNativeMethodTraceExit # dvmFastNativeMethodTraceExit(method,self)
7919    UNSPILL(rIBASE)                     # restore rIBASE
7920    UNSPILL_TMP1(%eax)                  # restore result of inline
7921    testl     %eax,%eax                 # successful?
7922    jz        common_exceptionThrown    # no, handle exception
7923    FETCH_INST_OPCODE 3 %ecx
7924    ADVANCE_PC 3
7925    GOTO_NEXT_R %ecx
7926
7927/* ------------------------------ */
7928.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */
7929    /* (stub) */
7930    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
7931    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
7932    call      dvmMterp_OP_EXECUTE_INLINE_RANGE     # do the real work
7933    movl      rSELF,%ecx
7934    LOAD_PC_FP_FROM_SELF             # retrieve updated values
7935    movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
7936    FETCH_INST
7937    GOTO_NEXT
7938/* ------------------------------ */
7939.L_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */
7940    /* (stub) */
7941    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
7942    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
7943    call      dvmMterp_OP_INVOKE_OBJECT_INIT_RANGE     # do the real work
7944    movl      rSELF,%ecx
7945    LOAD_PC_FP_FROM_SELF             # retrieve updated values
7946    movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
7947    FETCH_INST
7948    GOTO_NEXT
7949/* ------------------------------ */
7950.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */
7951    /* (stub) */
7952    SAVE_PC_FP_TO_SELF %ecx          # leaves rSELF in %ecx
7953    movl %ecx,OUT_ARG0(%esp)         # self is first arg to function
7954    call      dvmMterp_OP_RETURN_VOID_BARRIER     # do the real work
7955    movl      rSELF,%ecx
7956    LOAD_PC_FP_FROM_SELF             # retrieve updated values
7957    movl      offThread_curHandlerTable(%ecx),rIBASE  # set up rIBASE
7958    FETCH_INST
7959    GOTO_NEXT
7960/* ------------------------------ */
7961.L_OP_IGET_QUICK: /* 0xf2 */
7962/* File: x86/OP_IGET_QUICK.S */
7963    /* For: iget-quick, iget-object-quick */
7964    /* op vA, vB, offset@CCCC */
7965    movzbl    rINSTbl,%ecx              # ecx<- BA
7966    sarl      $4,%ecx                  # ecx<- B
7967    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
7968    movzwl    2(rPC),%eax               # eax<- field byte offset
7969    cmpl      $0,%ecx                  # is object null?
7970    je        common_errNullObject
7971    movl      (%ecx,%eax,1),%eax
7972    FETCH_INST_OPCODE 2 %ecx
7973    ADVANCE_PC 2
7974    andb      $0xf,rINSTbl             # rINST<- A
7975    SET_VREG  %eax rINST                # fp[A]<- result
7976    GOTO_NEXT_R %ecx
7977
7978/* ------------------------------ */
7979.L_OP_IGET_WIDE_QUICK: /* 0xf3 */
7980/* File: x86/OP_IGET_WIDE_QUICK.S */
7981    /* For: iget-wide-quick */
7982    /* op vA, vB, offset@CCCC */
7983    movzbl    rINSTbl,%ecx              # ecx<- BA
7984    sarl      $4,%ecx                  # ecx<- B
7985    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
7986    movzwl    2(rPC),%eax               # eax<- field byte offset
7987    cmpl      $0,%ecx                  # is object null?
7988    je        common_errNullObject
7989    leal      (%ecx,%eax,1),%eax        # eax<- address of 64-bit source
7990    movl      (%eax),%ecx               # ecx<- lsw
7991    movl      4(%eax),%eax              # eax<- msw
7992    andb      $0xf,rINSTbl             # rINST<- A
7993    SET_VREG_WORD %ecx rINST 0          # v[A+0]<- lsw
7994    FETCH_INST_OPCODE 2 %ecx
7995    SET_VREG_WORD %eax rINST 1          # v[A+1]<- msw
7996    ADVANCE_PC 2
7997    GOTO_NEXT_R %ecx
7998
7999/* ------------------------------ */
8000.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */
8001/* File: x86/OP_IGET_OBJECT_QUICK.S */
8002/* File: x86/OP_IGET_QUICK.S */
8003    /* For: iget-quick, iget-object-quick */
8004    /* op vA, vB, offset@CCCC */
8005    movzbl    rINSTbl,%ecx              # ecx<- BA
8006    sarl      $4,%ecx                  # ecx<- B
8007    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
8008    movzwl    2(rPC),%eax               # eax<- field byte offset
8009    cmpl      $0,%ecx                  # is object null?
8010    je        common_errNullObject
8011    movl      (%ecx,%eax,1),%eax
8012    FETCH_INST_OPCODE 2 %ecx
8013    ADVANCE_PC 2
8014    andb      $0xf,rINSTbl             # rINST<- A
8015    SET_VREG  %eax rINST                # fp[A]<- result
8016    GOTO_NEXT_R %ecx
8017
8018
8019/* ------------------------------ */
8020.L_OP_IPUT_QUICK: /* 0xf5 */
8021/* File: x86/OP_IPUT_QUICK.S */
8022    /* For: iput-quick */
8023    /* op vA, vB, offset@CCCC */
8024    movzbl    rINSTbl,%ecx              # ecx<- BA
8025    sarl      $4,%ecx                  # ecx<- B
8026    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
8027    andb      $0xf,rINSTbl             # rINST<- A
8028    GET_VREG_R  rINST,rINST             # rINST<- v[A]
8029    movzwl    2(rPC),%eax               # eax<- field byte offset
8030    testl     %ecx,%ecx                 # is object null?
8031    je        common_errNullObject
8032    movl      rINST,(%ecx,%eax,1)
8033    FETCH_INST_OPCODE 2 %ecx
8034    ADVANCE_PC 2
8035    GOTO_NEXT_R %ecx
8036
8037/* ------------------------------ */
8038.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */
8039/* File: x86/OP_IPUT_WIDE_QUICK.S */
8040    /* For: iput-wide-quick */
8041    /* op vA, vB, offset@CCCC */
8042    movzbl    rINSTbl,%ecx              # ecx<- BA
8043    sarl      $4,%ecx                  # ecx<- B
8044    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
8045    movzwl    2(rPC),%eax               # eax<- field byte offset
8046    testl      %ecx,%ecx                # is object null?
8047    je        common_errNullObject
8048    leal      (%ecx,%eax,1),%ecx        # ecx<- Address of 64-bit target
8049    andb      $0xf,rINSTbl             # rINST<- A
8050    GET_VREG_WORD %eax rINST 0          # eax<- lsw
8051    GET_VREG_WORD rINST rINST 1         # rINST<- msw
8052    movl      %eax,(%ecx)
8053    movl      rINST,4(%ecx)
8054    FETCH_INST_OPCODE 2 %ecx
8055    ADVANCE_PC 2
8056    GOTO_NEXT_R %ecx
8057
8058/* ------------------------------ */
8059.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
8060/* File: x86/OP_IPUT_OBJECT_QUICK.S */
8061    /* For: iput-object-quick */
8062    /* op vA, vB, offset@CCCC */
8063    movzbl    rINSTbl,%ecx              # ecx<- BA
8064    sarl      $4,%ecx                  # ecx<- B
8065    GET_VREG_R  %ecx %ecx               # vB (object we're operating on)
8066    andb      $0xf,rINSTbl             # rINST<- A
8067    GET_VREG_R  rINST rINST             # rINST<- v[A]
8068    movzwl    2(rPC),%eax               # eax<- field byte offset
8069    testl     %ecx,%ecx                 # is object null?
8070    je        common_errNullObject
8071    movl      rINST,(%ecx,%eax,1)
8072    movl      rSELF,%eax
8073    testl     rINST,rINST               # did we store null?
8074    movl      offThread_cardTable(%eax),%eax  # get card table base
8075    je        1f                            # skip card mark if null store
8076    shrl      $GC_CARD_SHIFT,%ecx          # object head to card number
8077    movb      %al,(%eax,%ecx)               # mark card based on object head
80781:
8079    FETCH_INST_OPCODE 2 %ecx
8080    ADVANCE_PC 2
8081    GOTO_NEXT_R %ecx
8082
8083/* ------------------------------ */
8084.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
8085/* File: x86/OP_INVOKE_VIRTUAL_QUICK.S */
8086    /*
8087     * Handle an optimized virtual method call.
8088     *
8089     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
8090     */
8091    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
8092    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
8093    movzwl    4(rPC),%ecx               # eax<- FEDC or CCCC
8094    movzwl    2(rPC),%edx               # ecx<- BBBB
8095    .if     (!0)
8096    andl      $0xf,%ecx                # eax<- C (or stays CCCC)
8097    .endif
8098    GET_VREG_R  %ecx %ecx               # ecx<- vC ("this" ptr)
8099    testl     %ecx,%ecx                 # null?
8100    je        common_errNullObject      # yep, throw exception
8101    movl      offObject_clazz(%ecx),%eax # eax<- thisPtr->clazz
8102    movl      offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable
8103    EXPORT_PC                           # might throw later - get ready
8104    movl      (%eax,%edx,4),%eax        # eax<- vtable[BBBB]
8105    jmp       common_invokeMethodNoRange
8106
8107/* ------------------------------ */
8108.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
8109/* File: x86/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */
8110/* File: x86/OP_INVOKE_VIRTUAL_QUICK.S */
8111    /*
8112     * Handle an optimized virtual method call.
8113     *
8114     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
8115     */
8116    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
8117    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
8118    movzwl    4(rPC),%ecx               # eax<- FEDC or CCCC
8119    movzwl    2(rPC),%edx               # ecx<- BBBB
8120    .if     (!1)
8121    andl      $0xf,%ecx                # eax<- C (or stays CCCC)
8122    .endif
8123    GET_VREG_R  %ecx %ecx               # ecx<- vC ("this" ptr)
8124    testl     %ecx,%ecx                 # null?
8125    je        common_errNullObject      # yep, throw exception
8126    movl      offObject_clazz(%ecx),%eax # eax<- thisPtr->clazz
8127    movl      offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable
8128    EXPORT_PC                           # might throw later - get ready
8129    movl      (%eax,%edx,4),%eax        # eax<- vtable[BBBB]
8130    jmp       common_invokeMethodRange
8131
8132
8133/* ------------------------------ */
8134.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */
8135/* File: x86/OP_INVOKE_SUPER_QUICK.S */
8136    /*
8137     * Handle an optimized "super" method call.
8138     *
8139     * for: [opt] invoke-super-quick, invoke-super-quick/range
8140     */
8141    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
8142    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
8143    movl      rSELF,%ecx
8144    movzwl    4(rPC),%eax               # eax<- GFED or CCCC
8145    movl      offThread_method(%ecx),%ecx # ecx<- current method
8146    .if       (!0)
8147    andl      $0xf,%eax                # eax<- D (or stays CCCC)
8148    .endif
8149    movl      offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
8150    GET_VREG_R  %eax %eax               # eax<- "this"
8151    movl      offClassObject_super(%ecx),%ecx # ecx<- method->clazz->super
8152    testl     %eax,%eax                 # null "this"?
8153    je        common_errNullObject      # "this" is null, throw exception
8154    movl       %eax, TMP_SPILL1(%ebp)
8155    movzwl    2(rPC),%eax               # eax<- BBBB
8156    movl      offClassObject_vtable(%ecx),%ecx # ecx<- vtable
8157    EXPORT_PC
8158    movl      (%ecx,%eax,4),%eax        # eax<- super->vtable[BBBB]
8159    movl      TMP_SPILL1(%ebp), %ecx
8160    jmp       common_invokeMethodNoRange
8161
8162/* ------------------------------ */
8163.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
8164/* File: x86/OP_INVOKE_SUPER_QUICK_RANGE.S */
8165/* File: x86/OP_INVOKE_SUPER_QUICK.S */
8166    /*
8167     * Handle an optimized "super" method call.
8168     *
8169     * for: [opt] invoke-super-quick, invoke-super-quick/range
8170     */
8171    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
8172    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
8173    movl      rSELF,%ecx
8174    movzwl    4(rPC),%eax               # eax<- GFED or CCCC
8175    movl      offThread_method(%ecx),%ecx # ecx<- current method
8176    .if       (!1)
8177    andl      $0xf,%eax                # eax<- D (or stays CCCC)
8178    .endif
8179    movl      offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
8180    GET_VREG_R  %eax %eax               # eax<- "this"
8181    movl      offClassObject_super(%ecx),%ecx # ecx<- method->clazz->super
8182    testl     %eax,%eax                 # null "this"?
8183    je        common_errNullObject      # "this" is null, throw exception
8184    movl       %eax, TMP_SPILL1(%ebp)
8185    movzwl    2(rPC),%eax               # eax<- BBBB
8186    movl      offClassObject_vtable(%ecx),%ecx # ecx<- vtable
8187    EXPORT_PC
8188    movl      (%ecx,%eax,4),%eax        # eax<- super->vtable[BBBB]
8189    movl      TMP_SPILL1(%ebp), %ecx
8190    jmp       common_invokeMethodRange
8191
8192
8193/* ------------------------------ */
8194.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
8195/* File: x86/OP_IPUT_OBJECT_VOLATILE.S */
8196/* File: x86/OP_IPUT_OBJECT.S */
8197    /*
8198     * Object field put.
8199     *
8200     * for: iput-object
8201     */
8202    /* op vA, vB, field@CCCC */
8203    movl    rSELF,%ecx
8204    SPILL(rIBASE)
8205    movzwl  2(rPC),rIBASE                       # rIBASE<- 0000CCCC
8206    movl    offThread_methodClassDex(%ecx),%eax # eax<- DvmDex
8207    movzbl  rINSTbl,%ecx                        # ecx<- BA
8208    sarl    $4,%ecx                            # ecx<- B
8209    movl    offDvmDex_pResFields(%eax),%eax     # eax<- pDvmDex->pResFields
8210    andb    $0xf,rINSTbl                       # rINST<- A
8211    GET_VREG_R %ecx %ecx                        # ecx<- fp[B], the object ptr
8212    movl    (%eax,rIBASE,4),%eax                  # resolved entry
8213    testl   %eax,%eax                           # is resolved entry null?
8214    jne     .LOP_IPUT_OBJECT_VOLATILE_finish                  # no, already resolved
8215    movl    rIBASE,OUT_ARG1(%esp)
8216    movl    rSELF,rIBASE
8217    EXPORT_PC
8218    movl    offThread_method(rIBASE),rIBASE     # rIBASE<- current method
8219    movl    offMethod_clazz(rIBASE),rIBASE      # rIBASE<- method->clazz
8220    SPILL_TMP1(%ecx)                            # save obj pointer across call
8221    movl    rIBASE,OUT_ARG0(%esp)               # pass in method->clazz
8222    call    dvmResolveInstField                 #  ... to dvmResolveInstField
8223    UNSPILL_TMP1(%ecx)
8224    testl   %eax,%eax                           # returns InstrField ptr
8225    jne     .LOP_IPUT_OBJECT_VOLATILE_finish
8226    jmp     common_exceptionThrown
8227
8228.LOP_IPUT_OBJECT_VOLATILE_finish:
8229    /*
8230     * Currently:
8231     *   eax holds resolved field
8232     *   ecx holds object
8233     *   rIBASE is scratch, but needs to be unspilled
8234     *   rINST holds A
8235     */
8236    GET_VREG_R rINST rINST                      # rINST<- v[A]
8237    movl    offInstField_byteOffset(%eax),%eax  # eax<- byte offset of field
8238    testl   %ecx,%ecx                           # object null?
8239    je      common_errNullObject                # object was null
8240    movl    rINST,(%ecx,%eax)      # obj.field <- v[A](8/16/32 bits)
8241    movl    rSELF,%eax
8242    testl   rINST,rINST                         # stored a NULL?
8243    movl    offThread_cardTable(%eax),%eax      # get card table base
8244    je      1f                                  # skip card mark if null store
8245    shrl    $GC_CARD_SHIFT,%ecx                # object head to card number
8246    movb    %al,(%eax,%ecx)                     # mark card using object head
82471:
8248    UNSPILL(rIBASE)
8249    FETCH_INST_OPCODE 2 %ecx
8250    ADVANCE_PC 2
8251    GOTO_NEXT_R %ecx
8252
8253
8254/* ------------------------------ */
8255.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
8256/* File: x86/OP_SGET_OBJECT_VOLATILE.S */
8257/* File: x86/OP_SGET.S */
8258    /*
8259     * General 32-bit SGET handler.
8260     *
8261     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
8262     */
8263    /* op vAA, field@BBBB */
8264    movl      rSELF,%ecx
8265    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
8266    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
8267    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
8268#if defined(WITH_JIT)
8269    movl      %ecx, TMP_SPILL1(%ebp)
8270    lea       (%ecx,%eax,4),%ecx
8271    movl      %ecx, TMP_SPILL2(%ebp)
8272    movl      TMP_SPILL1(%ebp), %ecx
8273#endif
8274    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
8275    testl     %eax,%eax                          # resolved entry null?
8276    je        .LOP_SGET_OBJECT_VOLATILE_resolve                # if not, make it so
8277.LOP_SGET_OBJECT_VOLATILE_finish:     # field ptr in eax
8278    movl      offStaticField_value(%eax),%eax
8279    FETCH_INST_OPCODE 2 %ecx
8280    ADVANCE_PC 2
8281    SET_VREG %eax rINST
8282    GOTO_NEXT_R %ecx
8283
8284    /*
8285     * Go resolve the field
8286     */
8287.LOP_SGET_OBJECT_VOLATILE_resolve:
8288    movl     rSELF,%ecx
8289    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
8290    movl     offThread_method(%ecx),%ecx          # ecx<- current method
8291    EXPORT_PC                                   # could throw, need to export
8292    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
8293    movl     %eax,OUT_ARG1(%esp)
8294    movl     %ecx,OUT_ARG0(%esp)
8295    SPILL(rIBASE)
8296    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
8297    UNSPILL(rIBASE)
8298    testl    %eax,%eax
8299    je      common_exceptionThrown             # no, handle exception
8300#if defined(WITH_JIT)
8301    movl      TMP_SPILL2(%ebp), %ecx
8302    SPILL(rIBASE)
8303    call     common_verifyField
8304    UNSPILL(rIBASE)
8305#endif
8306    jmp      .LOP_SGET_OBJECT_VOLATILE_finish                 # success, continue
8307
8308
8309/* ------------------------------ */
8310.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
8311/* File: x86/OP_SPUT_OBJECT_VOLATILE.S */
8312/* File: x86/OP_SPUT_OBJECT.S */
8313    /*
8314     * SPUT object handler.
8315     */
8316    /* op vAA, field@BBBB */
8317    movl      rSELF,%ecx
8318    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
8319    movl      offThread_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
8320    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
8321#if defined(WITH_JIT)
8322    movl      %ecx, TMP_SPILL1(%ebp)
8323    lea       (%ecx,%eax,4),%ecx
8324    movl      %ecx, TMP_SPILL2(%ebp)
8325    movl      TMP_SPILL1(%ebp), %ecx
8326#endif
8327    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField
8328    testl     %eax,%eax                          # resolved entry null?
8329    je        .LOP_SPUT_OBJECT_VOLATILE_resolve                # if not, make it so
8330.LOP_SPUT_OBJECT_VOLATILE_finish:                              # field ptr in eax
8331    movzbl    rINSTbl,%ecx                       # ecx<- AA
8332    GET_VREG_R  %ecx %ecx
8333    movl      %ecx,offStaticField_value(%eax)    # do the store
8334    testl     %ecx,%ecx                          # stored null object ptr?
8335    je        1f                                 # skip card mark if null
8336    movl      rSELF,%ecx
8337    movl      offField_clazz(%eax),%eax          # eax<- method->clazz
8338    movl      offThread_cardTable(%ecx),%ecx       # get card table base
8339    shrl      $GC_CARD_SHIFT,%eax               # head to card number
8340    movb      %cl,(%ecx,%eax)                    # mark card
83411:
8342    FETCH_INST_OPCODE 2 %ecx
8343    ADVANCE_PC 2
8344    GOTO_NEXT_R %ecx
8345
8346.LOP_SPUT_OBJECT_VOLATILE_resolve:
8347    movl     rSELF,%ecx
8348    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
8349    movl     offThread_method(%ecx),%ecx          # ecx<- current method
8350    EXPORT_PC                                   # could throw, need to export
8351    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
8352    movl     %eax,OUT_ARG1(%esp)
8353    movl     %ecx,OUT_ARG0(%esp)
8354    SPILL(rIBASE)
8355    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
8356    UNSPILL(rIBASE)
8357    testl    %eax,%eax
8358    je      common_exceptionThrown             # no, handle exception
8359#if defined(WITH_JIT)
8360    movl      TMP_SPILL2(%ebp), %ecx
8361    SPILL(rIBASE)
8362    call     common_verifyField
8363    UNSPILL(rIBASE)
8364#endif
8365    jmp      .LOP_SPUT_OBJECT_VOLATILE_finish                 # success, continue
8366
8367
8368/* ------------------------------ */
8369.L_OP_UNUSED_FF: /* 0xff */
8370/* File: x86/OP_UNUSED_FF.S */
8371/* File: x86/unused.S */
8372    jmp     common_abort
8373
8374
8375    .size   dvmAsmInstructionStartCode, .-dvmAsmInstructionStartCode
8376    .global dvmAsmInstructionEndCode
8377dvmAsmInstructionEndCode:
8378
8379    .global dvmAsmAltInstructionStartCode
8380    .type   dvmAsmAltInstructionStartCode, %function
8381    .text
8382
8383dvmAsmAltInstructionStartCode = .L_ALT_OP_NOP
8384/* ------------------------------ */
8385.L_ALT_OP_NOP: /* 0x00 */
8386/* File: x86/alt_stub.S */
8387/*
8388 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8389 * any interesting requests and then jump to the real instruction
8390 * handler.  Unlike the Arm handler, we can't do this as a tail call
8391 * because rIBASE is caller save and we need to reload it.
8392 *
8393 * Note that unlike in the Arm implementation, we should never arrive
8394 * here with a zero breakFlag because we always refresh rIBASE on
8395 * return.
8396 */
8397    EXPORT_PC
8398    movl   rSELF, %eax
8399    movl   rPC, OUT_ARG0(%esp)
8400    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8401    movl   rFP, OUT_ARG1(%esp)
8402    je     1f                                # reload rIBASE & resume if not
8403    movl   %eax, OUT_ARG2(%esp)
8404    call   dvmCheckBefore                    # (dPC, dFP, self)
8405    movl   rSELF, %eax
84061:
8407    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8408    jmp    *dvmAsmInstructionStart+(0*4)
8409
8410/* ------------------------------ */
8411.L_ALT_OP_MOVE: /* 0x01 */
8412/* File: x86/alt_stub.S */
8413/*
8414 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8415 * any interesting requests and then jump to the real instruction
8416 * handler.  Unlike the Arm handler, we can't do this as a tail call
8417 * because rIBASE is caller save and we need to reload it.
8418 *
8419 * Note that unlike in the Arm implementation, we should never arrive
8420 * here with a zero breakFlag because we always refresh rIBASE on
8421 * return.
8422 */
8423    EXPORT_PC
8424    movl   rSELF, %eax
8425    movl   rPC, OUT_ARG0(%esp)
8426    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8427    movl   rFP, OUT_ARG1(%esp)
8428    je     1f                                # reload rIBASE & resume if not
8429    movl   %eax, OUT_ARG2(%esp)
8430    call   dvmCheckBefore                    # (dPC, dFP, self)
8431    movl   rSELF, %eax
84321:
8433    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8434    jmp    *dvmAsmInstructionStart+(1*4)
8435
8436/* ------------------------------ */
8437.L_ALT_OP_MOVE_FROM16: /* 0x02 */
8438/* File: x86/alt_stub.S */
8439/*
8440 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8441 * any interesting requests and then jump to the real instruction
8442 * handler.  Unlike the Arm handler, we can't do this as a tail call
8443 * because rIBASE is caller save and we need to reload it.
8444 *
8445 * Note that unlike in the Arm implementation, we should never arrive
8446 * here with a zero breakFlag because we always refresh rIBASE on
8447 * return.
8448 */
8449    EXPORT_PC
8450    movl   rSELF, %eax
8451    movl   rPC, OUT_ARG0(%esp)
8452    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8453    movl   rFP, OUT_ARG1(%esp)
8454    je     1f                                # reload rIBASE & resume if not
8455    movl   %eax, OUT_ARG2(%esp)
8456    call   dvmCheckBefore                    # (dPC, dFP, self)
8457    movl   rSELF, %eax
84581:
8459    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8460    jmp    *dvmAsmInstructionStart+(2*4)
8461
8462/* ------------------------------ */
8463.L_ALT_OP_MOVE_16: /* 0x03 */
8464/* File: x86/alt_stub.S */
8465/*
8466 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8467 * any interesting requests and then jump to the real instruction
8468 * handler.  Unlike the Arm handler, we can't do this as a tail call
8469 * because rIBASE is caller save and we need to reload it.
8470 *
8471 * Note that unlike in the Arm implementation, we should never arrive
8472 * here with a zero breakFlag because we always refresh rIBASE on
8473 * return.
8474 */
8475    EXPORT_PC
8476    movl   rSELF, %eax
8477    movl   rPC, OUT_ARG0(%esp)
8478    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8479    movl   rFP, OUT_ARG1(%esp)
8480    je     1f                                # reload rIBASE & resume if not
8481    movl   %eax, OUT_ARG2(%esp)
8482    call   dvmCheckBefore                    # (dPC, dFP, self)
8483    movl   rSELF, %eax
84841:
8485    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8486    jmp    *dvmAsmInstructionStart+(3*4)
8487
8488/* ------------------------------ */
8489.L_ALT_OP_MOVE_WIDE: /* 0x04 */
8490/* File: x86/alt_stub.S */
8491/*
8492 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8493 * any interesting requests and then jump to the real instruction
8494 * handler.  Unlike the Arm handler, we can't do this as a tail call
8495 * because rIBASE is caller save and we need to reload it.
8496 *
8497 * Note that unlike in the Arm implementation, we should never arrive
8498 * here with a zero breakFlag because we always refresh rIBASE on
8499 * return.
8500 */
8501    EXPORT_PC
8502    movl   rSELF, %eax
8503    movl   rPC, OUT_ARG0(%esp)
8504    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8505    movl   rFP, OUT_ARG1(%esp)
8506    je     1f                                # reload rIBASE & resume if not
8507    movl   %eax, OUT_ARG2(%esp)
8508    call   dvmCheckBefore                    # (dPC, dFP, self)
8509    movl   rSELF, %eax
85101:
8511    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8512    jmp    *dvmAsmInstructionStart+(4*4)
8513
8514/* ------------------------------ */
8515.L_ALT_OP_MOVE_WIDE_FROM16: /* 0x05 */
8516/* File: x86/alt_stub.S */
8517/*
8518 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8519 * any interesting requests and then jump to the real instruction
8520 * handler.  Unlike the Arm handler, we can't do this as a tail call
8521 * because rIBASE is caller save and we need to reload it.
8522 *
8523 * Note that unlike in the Arm implementation, we should never arrive
8524 * here with a zero breakFlag because we always refresh rIBASE on
8525 * return.
8526 */
8527    EXPORT_PC
8528    movl   rSELF, %eax
8529    movl   rPC, OUT_ARG0(%esp)
8530    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8531    movl   rFP, OUT_ARG1(%esp)
8532    je     1f                                # reload rIBASE & resume if not
8533    movl   %eax, OUT_ARG2(%esp)
8534    call   dvmCheckBefore                    # (dPC, dFP, self)
8535    movl   rSELF, %eax
85361:
8537    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8538    jmp    *dvmAsmInstructionStart+(5*4)
8539
8540/* ------------------------------ */
8541.L_ALT_OP_MOVE_WIDE_16: /* 0x06 */
8542/* File: x86/alt_stub.S */
8543/*
8544 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8545 * any interesting requests and then jump to the real instruction
8546 * handler.  Unlike the Arm handler, we can't do this as a tail call
8547 * because rIBASE is caller save and we need to reload it.
8548 *
8549 * Note that unlike in the Arm implementation, we should never arrive
8550 * here with a zero breakFlag because we always refresh rIBASE on
8551 * return.
8552 */
8553    EXPORT_PC
8554    movl   rSELF, %eax
8555    movl   rPC, OUT_ARG0(%esp)
8556    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8557    movl   rFP, OUT_ARG1(%esp)
8558    je     1f                                # reload rIBASE & resume if not
8559    movl   %eax, OUT_ARG2(%esp)
8560    call   dvmCheckBefore                    # (dPC, dFP, self)
8561    movl   rSELF, %eax
85621:
8563    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8564    jmp    *dvmAsmInstructionStart+(6*4)
8565
8566/* ------------------------------ */
8567.L_ALT_OP_MOVE_OBJECT: /* 0x07 */
8568/* File: x86/alt_stub.S */
8569/*
8570 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8571 * any interesting requests and then jump to the real instruction
8572 * handler.  Unlike the Arm handler, we can't do this as a tail call
8573 * because rIBASE is caller save and we need to reload it.
8574 *
8575 * Note that unlike in the Arm implementation, we should never arrive
8576 * here with a zero breakFlag because we always refresh rIBASE on
8577 * return.
8578 */
8579    EXPORT_PC
8580    movl   rSELF, %eax
8581    movl   rPC, OUT_ARG0(%esp)
8582    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8583    movl   rFP, OUT_ARG1(%esp)
8584    je     1f                                # reload rIBASE & resume if not
8585    movl   %eax, OUT_ARG2(%esp)
8586    call   dvmCheckBefore                    # (dPC, dFP, self)
8587    movl   rSELF, %eax
85881:
8589    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8590    jmp    *dvmAsmInstructionStart+(7*4)
8591
8592/* ------------------------------ */
8593.L_ALT_OP_MOVE_OBJECT_FROM16: /* 0x08 */
8594/* File: x86/alt_stub.S */
8595/*
8596 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8597 * any interesting requests and then jump to the real instruction
8598 * handler.  Unlike the Arm handler, we can't do this as a tail call
8599 * because rIBASE is caller save and we need to reload it.
8600 *
8601 * Note that unlike in the Arm implementation, we should never arrive
8602 * here with a zero breakFlag because we always refresh rIBASE on
8603 * return.
8604 */
8605    EXPORT_PC
8606    movl   rSELF, %eax
8607    movl   rPC, OUT_ARG0(%esp)
8608    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8609    movl   rFP, OUT_ARG1(%esp)
8610    je     1f                                # reload rIBASE & resume if not
8611    movl   %eax, OUT_ARG2(%esp)
8612    call   dvmCheckBefore                    # (dPC, dFP, self)
8613    movl   rSELF, %eax
86141:
8615    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8616    jmp    *dvmAsmInstructionStart+(8*4)
8617
8618/* ------------------------------ */
8619.L_ALT_OP_MOVE_OBJECT_16: /* 0x09 */
8620/* File: x86/alt_stub.S */
8621/*
8622 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8623 * any interesting requests and then jump to the real instruction
8624 * handler.  Unlike the Arm handler, we can't do this as a tail call
8625 * because rIBASE is caller save and we need to reload it.
8626 *
8627 * Note that unlike in the Arm implementation, we should never arrive
8628 * here with a zero breakFlag because we always refresh rIBASE on
8629 * return.
8630 */
8631    EXPORT_PC
8632    movl   rSELF, %eax
8633    movl   rPC, OUT_ARG0(%esp)
8634    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8635    movl   rFP, OUT_ARG1(%esp)
8636    je     1f                                # reload rIBASE & resume if not
8637    movl   %eax, OUT_ARG2(%esp)
8638    call   dvmCheckBefore                    # (dPC, dFP, self)
8639    movl   rSELF, %eax
86401:
8641    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8642    jmp    *dvmAsmInstructionStart+(9*4)
8643
8644/* ------------------------------ */
8645.L_ALT_OP_MOVE_RESULT: /* 0x0a */
8646/* File: x86/alt_stub.S */
8647/*
8648 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8649 * any interesting requests and then jump to the real instruction
8650 * handler.  Unlike the Arm handler, we can't do this as a tail call
8651 * because rIBASE is caller save and we need to reload it.
8652 *
8653 * Note that unlike in the Arm implementation, we should never arrive
8654 * here with a zero breakFlag because we always refresh rIBASE on
8655 * return.
8656 */
8657    EXPORT_PC
8658    movl   rSELF, %eax
8659    movl   rPC, OUT_ARG0(%esp)
8660    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8661    movl   rFP, OUT_ARG1(%esp)
8662    je     1f                                # reload rIBASE & resume if not
8663    movl   %eax, OUT_ARG2(%esp)
8664    call   dvmCheckBefore                    # (dPC, dFP, self)
8665    movl   rSELF, %eax
86661:
8667    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8668    jmp    *dvmAsmInstructionStart+(10*4)
8669
8670/* ------------------------------ */
8671.L_ALT_OP_MOVE_RESULT_WIDE: /* 0x0b */
8672/* File: x86/alt_stub.S */
8673/*
8674 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8675 * any interesting requests and then jump to the real instruction
8676 * handler.  Unlike the Arm handler, we can't do this as a tail call
8677 * because rIBASE is caller save and we need to reload it.
8678 *
8679 * Note that unlike in the Arm implementation, we should never arrive
8680 * here with a zero breakFlag because we always refresh rIBASE on
8681 * return.
8682 */
8683    EXPORT_PC
8684    movl   rSELF, %eax
8685    movl   rPC, OUT_ARG0(%esp)
8686    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8687    movl   rFP, OUT_ARG1(%esp)
8688    je     1f                                # reload rIBASE & resume if not
8689    movl   %eax, OUT_ARG2(%esp)
8690    call   dvmCheckBefore                    # (dPC, dFP, self)
8691    movl   rSELF, %eax
86921:
8693    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8694    jmp    *dvmAsmInstructionStart+(11*4)
8695
8696/* ------------------------------ */
8697.L_ALT_OP_MOVE_RESULT_OBJECT: /* 0x0c */
8698/* File: x86/alt_stub.S */
8699/*
8700 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8701 * any interesting requests and then jump to the real instruction
8702 * handler.  Unlike the Arm handler, we can't do this as a tail call
8703 * because rIBASE is caller save and we need to reload it.
8704 *
8705 * Note that unlike in the Arm implementation, we should never arrive
8706 * here with a zero breakFlag because we always refresh rIBASE on
8707 * return.
8708 */
8709    EXPORT_PC
8710    movl   rSELF, %eax
8711    movl   rPC, OUT_ARG0(%esp)
8712    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8713    movl   rFP, OUT_ARG1(%esp)
8714    je     1f                                # reload rIBASE & resume if not
8715    movl   %eax, OUT_ARG2(%esp)
8716    call   dvmCheckBefore                    # (dPC, dFP, self)
8717    movl   rSELF, %eax
87181:
8719    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8720    jmp    *dvmAsmInstructionStart+(12*4)
8721
8722/* ------------------------------ */
8723.L_ALT_OP_MOVE_EXCEPTION: /* 0x0d */
8724/* File: x86/alt_stub.S */
8725/*
8726 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8727 * any interesting requests and then jump to the real instruction
8728 * handler.  Unlike the Arm handler, we can't do this as a tail call
8729 * because rIBASE is caller save and we need to reload it.
8730 *
8731 * Note that unlike in the Arm implementation, we should never arrive
8732 * here with a zero breakFlag because we always refresh rIBASE on
8733 * return.
8734 */
8735    EXPORT_PC
8736    movl   rSELF, %eax
8737    movl   rPC, OUT_ARG0(%esp)
8738    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8739    movl   rFP, OUT_ARG1(%esp)
8740    je     1f                                # reload rIBASE & resume if not
8741    movl   %eax, OUT_ARG2(%esp)
8742    call   dvmCheckBefore                    # (dPC, dFP, self)
8743    movl   rSELF, %eax
87441:
8745    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8746    jmp    *dvmAsmInstructionStart+(13*4)
8747
8748/* ------------------------------ */
8749.L_ALT_OP_RETURN_VOID: /* 0x0e */
8750/* File: x86/alt_stub.S */
8751/*
8752 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8753 * any interesting requests and then jump to the real instruction
8754 * handler.  Unlike the Arm handler, we can't do this as a tail call
8755 * because rIBASE is caller save and we need to reload it.
8756 *
8757 * Note that unlike in the Arm implementation, we should never arrive
8758 * here with a zero breakFlag because we always refresh rIBASE on
8759 * return.
8760 */
8761    EXPORT_PC
8762    movl   rSELF, %eax
8763    movl   rPC, OUT_ARG0(%esp)
8764    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8765    movl   rFP, OUT_ARG1(%esp)
8766    je     1f                                # reload rIBASE & resume if not
8767    movl   %eax, OUT_ARG2(%esp)
8768    call   dvmCheckBefore                    # (dPC, dFP, self)
8769    movl   rSELF, %eax
87701:
8771    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8772    jmp    *dvmAsmInstructionStart+(14*4)
8773
8774/* ------------------------------ */
8775.L_ALT_OP_RETURN: /* 0x0f */
8776/* File: x86/alt_stub.S */
8777/*
8778 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8779 * any interesting requests and then jump to the real instruction
8780 * handler.  Unlike the Arm handler, we can't do this as a tail call
8781 * because rIBASE is caller save and we need to reload it.
8782 *
8783 * Note that unlike in the Arm implementation, we should never arrive
8784 * here with a zero breakFlag because we always refresh rIBASE on
8785 * return.
8786 */
8787    EXPORT_PC
8788    movl   rSELF, %eax
8789    movl   rPC, OUT_ARG0(%esp)
8790    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8791    movl   rFP, OUT_ARG1(%esp)
8792    je     1f                                # reload rIBASE & resume if not
8793    movl   %eax, OUT_ARG2(%esp)
8794    call   dvmCheckBefore                    # (dPC, dFP, self)
8795    movl   rSELF, %eax
87961:
8797    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8798    jmp    *dvmAsmInstructionStart+(15*4)
8799
8800/* ------------------------------ */
8801.L_ALT_OP_RETURN_WIDE: /* 0x10 */
8802/* File: x86/alt_stub.S */
8803/*
8804 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8805 * any interesting requests and then jump to the real instruction
8806 * handler.  Unlike the Arm handler, we can't do this as a tail call
8807 * because rIBASE is caller save and we need to reload it.
8808 *
8809 * Note that unlike in the Arm implementation, we should never arrive
8810 * here with a zero breakFlag because we always refresh rIBASE on
8811 * return.
8812 */
8813    EXPORT_PC
8814    movl   rSELF, %eax
8815    movl   rPC, OUT_ARG0(%esp)
8816    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8817    movl   rFP, OUT_ARG1(%esp)
8818    je     1f                                # reload rIBASE & resume if not
8819    movl   %eax, OUT_ARG2(%esp)
8820    call   dvmCheckBefore                    # (dPC, dFP, self)
8821    movl   rSELF, %eax
88221:
8823    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8824    jmp    *dvmAsmInstructionStart+(16*4)
8825
8826/* ------------------------------ */
8827.L_ALT_OP_RETURN_OBJECT: /* 0x11 */
8828/* File: x86/alt_stub.S */
8829/*
8830 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8831 * any interesting requests and then jump to the real instruction
8832 * handler.  Unlike the Arm handler, we can't do this as a tail call
8833 * because rIBASE is caller save and we need to reload it.
8834 *
8835 * Note that unlike in the Arm implementation, we should never arrive
8836 * here with a zero breakFlag because we always refresh rIBASE on
8837 * return.
8838 */
8839    EXPORT_PC
8840    movl   rSELF, %eax
8841    movl   rPC, OUT_ARG0(%esp)
8842    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8843    movl   rFP, OUT_ARG1(%esp)
8844    je     1f                                # reload rIBASE & resume if not
8845    movl   %eax, OUT_ARG2(%esp)
8846    call   dvmCheckBefore                    # (dPC, dFP, self)
8847    movl   rSELF, %eax
88481:
8849    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8850    jmp    *dvmAsmInstructionStart+(17*4)
8851
8852/* ------------------------------ */
8853.L_ALT_OP_CONST_4: /* 0x12 */
8854/* File: x86/alt_stub.S */
8855/*
8856 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8857 * any interesting requests and then jump to the real instruction
8858 * handler.  Unlike the Arm handler, we can't do this as a tail call
8859 * because rIBASE is caller save and we need to reload it.
8860 *
8861 * Note that unlike in the Arm implementation, we should never arrive
8862 * here with a zero breakFlag because we always refresh rIBASE on
8863 * return.
8864 */
8865    EXPORT_PC
8866    movl   rSELF, %eax
8867    movl   rPC, OUT_ARG0(%esp)
8868    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8869    movl   rFP, OUT_ARG1(%esp)
8870    je     1f                                # reload rIBASE & resume if not
8871    movl   %eax, OUT_ARG2(%esp)
8872    call   dvmCheckBefore                    # (dPC, dFP, self)
8873    movl   rSELF, %eax
88741:
8875    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8876    jmp    *dvmAsmInstructionStart+(18*4)
8877
8878/* ------------------------------ */
8879.L_ALT_OP_CONST_16: /* 0x13 */
8880/* File: x86/alt_stub.S */
8881/*
8882 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8883 * any interesting requests and then jump to the real instruction
8884 * handler.  Unlike the Arm handler, we can't do this as a tail call
8885 * because rIBASE is caller save and we need to reload it.
8886 *
8887 * Note that unlike in the Arm implementation, we should never arrive
8888 * here with a zero breakFlag because we always refresh rIBASE on
8889 * return.
8890 */
8891    EXPORT_PC
8892    movl   rSELF, %eax
8893    movl   rPC, OUT_ARG0(%esp)
8894    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8895    movl   rFP, OUT_ARG1(%esp)
8896    je     1f                                # reload rIBASE & resume if not
8897    movl   %eax, OUT_ARG2(%esp)
8898    call   dvmCheckBefore                    # (dPC, dFP, self)
8899    movl   rSELF, %eax
89001:
8901    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8902    jmp    *dvmAsmInstructionStart+(19*4)
8903
8904/* ------------------------------ */
8905.L_ALT_OP_CONST: /* 0x14 */
8906/* File: x86/alt_stub.S */
8907/*
8908 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8909 * any interesting requests and then jump to the real instruction
8910 * handler.  Unlike the Arm handler, we can't do this as a tail call
8911 * because rIBASE is caller save and we need to reload it.
8912 *
8913 * Note that unlike in the Arm implementation, we should never arrive
8914 * here with a zero breakFlag because we always refresh rIBASE on
8915 * return.
8916 */
8917    EXPORT_PC
8918    movl   rSELF, %eax
8919    movl   rPC, OUT_ARG0(%esp)
8920    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8921    movl   rFP, OUT_ARG1(%esp)
8922    je     1f                                # reload rIBASE & resume if not
8923    movl   %eax, OUT_ARG2(%esp)
8924    call   dvmCheckBefore                    # (dPC, dFP, self)
8925    movl   rSELF, %eax
89261:
8927    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8928    jmp    *dvmAsmInstructionStart+(20*4)
8929
8930/* ------------------------------ */
8931.L_ALT_OP_CONST_HIGH16: /* 0x15 */
8932/* File: x86/alt_stub.S */
8933/*
8934 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8935 * any interesting requests and then jump to the real instruction
8936 * handler.  Unlike the Arm handler, we can't do this as a tail call
8937 * because rIBASE is caller save and we need to reload it.
8938 *
8939 * Note that unlike in the Arm implementation, we should never arrive
8940 * here with a zero breakFlag because we always refresh rIBASE on
8941 * return.
8942 */
8943    EXPORT_PC
8944    movl   rSELF, %eax
8945    movl   rPC, OUT_ARG0(%esp)
8946    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8947    movl   rFP, OUT_ARG1(%esp)
8948    je     1f                                # reload rIBASE & resume if not
8949    movl   %eax, OUT_ARG2(%esp)
8950    call   dvmCheckBefore                    # (dPC, dFP, self)
8951    movl   rSELF, %eax
89521:
8953    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8954    jmp    *dvmAsmInstructionStart+(21*4)
8955
8956/* ------------------------------ */
8957.L_ALT_OP_CONST_WIDE_16: /* 0x16 */
8958/* File: x86/alt_stub.S */
8959/*
8960 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8961 * any interesting requests and then jump to the real instruction
8962 * handler.  Unlike the Arm handler, we can't do this as a tail call
8963 * because rIBASE is caller save and we need to reload it.
8964 *
8965 * Note that unlike in the Arm implementation, we should never arrive
8966 * here with a zero breakFlag because we always refresh rIBASE on
8967 * return.
8968 */
8969    EXPORT_PC
8970    movl   rSELF, %eax
8971    movl   rPC, OUT_ARG0(%esp)
8972    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8973    movl   rFP, OUT_ARG1(%esp)
8974    je     1f                                # reload rIBASE & resume if not
8975    movl   %eax, OUT_ARG2(%esp)
8976    call   dvmCheckBefore                    # (dPC, dFP, self)
8977    movl   rSELF, %eax
89781:
8979    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
8980    jmp    *dvmAsmInstructionStart+(22*4)
8981
8982/* ------------------------------ */
8983.L_ALT_OP_CONST_WIDE_32: /* 0x17 */
8984/* File: x86/alt_stub.S */
8985/*
8986 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
8987 * any interesting requests and then jump to the real instruction
8988 * handler.  Unlike the Arm handler, we can't do this as a tail call
8989 * because rIBASE is caller save and we need to reload it.
8990 *
8991 * Note that unlike in the Arm implementation, we should never arrive
8992 * here with a zero breakFlag because we always refresh rIBASE on
8993 * return.
8994 */
8995    EXPORT_PC
8996    movl   rSELF, %eax
8997    movl   rPC, OUT_ARG0(%esp)
8998    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
8999    movl   rFP, OUT_ARG1(%esp)
9000    je     1f                                # reload rIBASE & resume if not
9001    movl   %eax, OUT_ARG2(%esp)
9002    call   dvmCheckBefore                    # (dPC, dFP, self)
9003    movl   rSELF, %eax
90041:
9005    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9006    jmp    *dvmAsmInstructionStart+(23*4)
9007
9008/* ------------------------------ */
9009.L_ALT_OP_CONST_WIDE: /* 0x18 */
9010/* File: x86/alt_stub.S */
9011/*
9012 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9013 * any interesting requests and then jump to the real instruction
9014 * handler.  Unlike the Arm handler, we can't do this as a tail call
9015 * because rIBASE is caller save and we need to reload it.
9016 *
9017 * Note that unlike in the Arm implementation, we should never arrive
9018 * here with a zero breakFlag because we always refresh rIBASE on
9019 * return.
9020 */
9021    EXPORT_PC
9022    movl   rSELF, %eax
9023    movl   rPC, OUT_ARG0(%esp)
9024    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9025    movl   rFP, OUT_ARG1(%esp)
9026    je     1f                                # reload rIBASE & resume if not
9027    movl   %eax, OUT_ARG2(%esp)
9028    call   dvmCheckBefore                    # (dPC, dFP, self)
9029    movl   rSELF, %eax
90301:
9031    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9032    jmp    *dvmAsmInstructionStart+(24*4)
9033
9034/* ------------------------------ */
9035.L_ALT_OP_CONST_WIDE_HIGH16: /* 0x19 */
9036/* File: x86/alt_stub.S */
9037/*
9038 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9039 * any interesting requests and then jump to the real instruction
9040 * handler.  Unlike the Arm handler, we can't do this as a tail call
9041 * because rIBASE is caller save and we need to reload it.
9042 *
9043 * Note that unlike in the Arm implementation, we should never arrive
9044 * here with a zero breakFlag because we always refresh rIBASE on
9045 * return.
9046 */
9047    EXPORT_PC
9048    movl   rSELF, %eax
9049    movl   rPC, OUT_ARG0(%esp)
9050    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9051    movl   rFP, OUT_ARG1(%esp)
9052    je     1f                                # reload rIBASE & resume if not
9053    movl   %eax, OUT_ARG2(%esp)
9054    call   dvmCheckBefore                    # (dPC, dFP, self)
9055    movl   rSELF, %eax
90561:
9057    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9058    jmp    *dvmAsmInstructionStart+(25*4)
9059
9060/* ------------------------------ */
9061.L_ALT_OP_CONST_STRING: /* 0x1a */
9062/* File: x86/alt_stub.S */
9063/*
9064 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9065 * any interesting requests and then jump to the real instruction
9066 * handler.  Unlike the Arm handler, we can't do this as a tail call
9067 * because rIBASE is caller save and we need to reload it.
9068 *
9069 * Note that unlike in the Arm implementation, we should never arrive
9070 * here with a zero breakFlag because we always refresh rIBASE on
9071 * return.
9072 */
9073    EXPORT_PC
9074    movl   rSELF, %eax
9075    movl   rPC, OUT_ARG0(%esp)
9076    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9077    movl   rFP, OUT_ARG1(%esp)
9078    je     1f                                # reload rIBASE & resume if not
9079    movl   %eax, OUT_ARG2(%esp)
9080    call   dvmCheckBefore                    # (dPC, dFP, self)
9081    movl   rSELF, %eax
90821:
9083    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9084    jmp    *dvmAsmInstructionStart+(26*4)
9085
9086/* ------------------------------ */
9087.L_ALT_OP_CONST_STRING_JUMBO: /* 0x1b */
9088/* File: x86/alt_stub.S */
9089/*
9090 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9091 * any interesting requests and then jump to the real instruction
9092 * handler.  Unlike the Arm handler, we can't do this as a tail call
9093 * because rIBASE is caller save and we need to reload it.
9094 *
9095 * Note that unlike in the Arm implementation, we should never arrive
9096 * here with a zero breakFlag because we always refresh rIBASE on
9097 * return.
9098 */
9099    EXPORT_PC
9100    movl   rSELF, %eax
9101    movl   rPC, OUT_ARG0(%esp)
9102    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9103    movl   rFP, OUT_ARG1(%esp)
9104    je     1f                                # reload rIBASE & resume if not
9105    movl   %eax, OUT_ARG2(%esp)
9106    call   dvmCheckBefore                    # (dPC, dFP, self)
9107    movl   rSELF, %eax
91081:
9109    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9110    jmp    *dvmAsmInstructionStart+(27*4)
9111
9112/* ------------------------------ */
9113.L_ALT_OP_CONST_CLASS: /* 0x1c */
9114/* File: x86/alt_stub.S */
9115/*
9116 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9117 * any interesting requests and then jump to the real instruction
9118 * handler.  Unlike the Arm handler, we can't do this as a tail call
9119 * because rIBASE is caller save and we need to reload it.
9120 *
9121 * Note that unlike in the Arm implementation, we should never arrive
9122 * here with a zero breakFlag because we always refresh rIBASE on
9123 * return.
9124 */
9125    EXPORT_PC
9126    movl   rSELF, %eax
9127    movl   rPC, OUT_ARG0(%esp)
9128    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9129    movl   rFP, OUT_ARG1(%esp)
9130    je     1f                                # reload rIBASE & resume if not
9131    movl   %eax, OUT_ARG2(%esp)
9132    call   dvmCheckBefore                    # (dPC, dFP, self)
9133    movl   rSELF, %eax
91341:
9135    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9136    jmp    *dvmAsmInstructionStart+(28*4)
9137
9138/* ------------------------------ */
9139.L_ALT_OP_MONITOR_ENTER: /* 0x1d */
9140/* File: x86/alt_stub.S */
9141/*
9142 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9143 * any interesting requests and then jump to the real instruction
9144 * handler.  Unlike the Arm handler, we can't do this as a tail call
9145 * because rIBASE is caller save and we need to reload it.
9146 *
9147 * Note that unlike in the Arm implementation, we should never arrive
9148 * here with a zero breakFlag because we always refresh rIBASE on
9149 * return.
9150 */
9151    EXPORT_PC
9152    movl   rSELF, %eax
9153    movl   rPC, OUT_ARG0(%esp)
9154    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9155    movl   rFP, OUT_ARG1(%esp)
9156    je     1f                                # reload rIBASE & resume if not
9157    movl   %eax, OUT_ARG2(%esp)
9158    call   dvmCheckBefore                    # (dPC, dFP, self)
9159    movl   rSELF, %eax
91601:
9161    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9162    jmp    *dvmAsmInstructionStart+(29*4)
9163
9164/* ------------------------------ */
9165.L_ALT_OP_MONITOR_EXIT: /* 0x1e */
9166/* File: x86/alt_stub.S */
9167/*
9168 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9169 * any interesting requests and then jump to the real instruction
9170 * handler.  Unlike the Arm handler, we can't do this as a tail call
9171 * because rIBASE is caller save and we need to reload it.
9172 *
9173 * Note that unlike in the Arm implementation, we should never arrive
9174 * here with a zero breakFlag because we always refresh rIBASE on
9175 * return.
9176 */
9177    EXPORT_PC
9178    movl   rSELF, %eax
9179    movl   rPC, OUT_ARG0(%esp)
9180    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9181    movl   rFP, OUT_ARG1(%esp)
9182    je     1f                                # reload rIBASE & resume if not
9183    movl   %eax, OUT_ARG2(%esp)
9184    call   dvmCheckBefore                    # (dPC, dFP, self)
9185    movl   rSELF, %eax
91861:
9187    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9188    jmp    *dvmAsmInstructionStart+(30*4)
9189
9190/* ------------------------------ */
9191.L_ALT_OP_CHECK_CAST: /* 0x1f */
9192/* File: x86/alt_stub.S */
9193/*
9194 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9195 * any interesting requests and then jump to the real instruction
9196 * handler.  Unlike the Arm handler, we can't do this as a tail call
9197 * because rIBASE is caller save and we need to reload it.
9198 *
9199 * Note that unlike in the Arm implementation, we should never arrive
9200 * here with a zero breakFlag because we always refresh rIBASE on
9201 * return.
9202 */
9203    EXPORT_PC
9204    movl   rSELF, %eax
9205    movl   rPC, OUT_ARG0(%esp)
9206    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9207    movl   rFP, OUT_ARG1(%esp)
9208    je     1f                                # reload rIBASE & resume if not
9209    movl   %eax, OUT_ARG2(%esp)
9210    call   dvmCheckBefore                    # (dPC, dFP, self)
9211    movl   rSELF, %eax
92121:
9213    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9214    jmp    *dvmAsmInstructionStart+(31*4)
9215
9216/* ------------------------------ */
9217.L_ALT_OP_INSTANCE_OF: /* 0x20 */
9218/* File: x86/alt_stub.S */
9219/*
9220 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9221 * any interesting requests and then jump to the real instruction
9222 * handler.  Unlike the Arm handler, we can't do this as a tail call
9223 * because rIBASE is caller save and we need to reload it.
9224 *
9225 * Note that unlike in the Arm implementation, we should never arrive
9226 * here with a zero breakFlag because we always refresh rIBASE on
9227 * return.
9228 */
9229    EXPORT_PC
9230    movl   rSELF, %eax
9231    movl   rPC, OUT_ARG0(%esp)
9232    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9233    movl   rFP, OUT_ARG1(%esp)
9234    je     1f                                # reload rIBASE & resume if not
9235    movl   %eax, OUT_ARG2(%esp)
9236    call   dvmCheckBefore                    # (dPC, dFP, self)
9237    movl   rSELF, %eax
92381:
9239    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9240    jmp    *dvmAsmInstructionStart+(32*4)
9241
9242/* ------------------------------ */
9243.L_ALT_OP_ARRAY_LENGTH: /* 0x21 */
9244/* File: x86/alt_stub.S */
9245/*
9246 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9247 * any interesting requests and then jump to the real instruction
9248 * handler.  Unlike the Arm handler, we can't do this as a tail call
9249 * because rIBASE is caller save and we need to reload it.
9250 *
9251 * Note that unlike in the Arm implementation, we should never arrive
9252 * here with a zero breakFlag because we always refresh rIBASE on
9253 * return.
9254 */
9255    EXPORT_PC
9256    movl   rSELF, %eax
9257    movl   rPC, OUT_ARG0(%esp)
9258    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9259    movl   rFP, OUT_ARG1(%esp)
9260    je     1f                                # reload rIBASE & resume if not
9261    movl   %eax, OUT_ARG2(%esp)
9262    call   dvmCheckBefore                    # (dPC, dFP, self)
9263    movl   rSELF, %eax
92641:
9265    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9266    jmp    *dvmAsmInstructionStart+(33*4)
9267
9268/* ------------------------------ */
9269.L_ALT_OP_NEW_INSTANCE: /* 0x22 */
9270/* File: x86/alt_stub.S */
9271/*
9272 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9273 * any interesting requests and then jump to the real instruction
9274 * handler.  Unlike the Arm handler, we can't do this as a tail call
9275 * because rIBASE is caller save and we need to reload it.
9276 *
9277 * Note that unlike in the Arm implementation, we should never arrive
9278 * here with a zero breakFlag because we always refresh rIBASE on
9279 * return.
9280 */
9281    EXPORT_PC
9282    movl   rSELF, %eax
9283    movl   rPC, OUT_ARG0(%esp)
9284    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9285    movl   rFP, OUT_ARG1(%esp)
9286    je     1f                                # reload rIBASE & resume if not
9287    movl   %eax, OUT_ARG2(%esp)
9288    call   dvmCheckBefore                    # (dPC, dFP, self)
9289    movl   rSELF, %eax
92901:
9291    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9292    jmp    *dvmAsmInstructionStart+(34*4)
9293
9294/* ------------------------------ */
9295.L_ALT_OP_NEW_ARRAY: /* 0x23 */
9296/* File: x86/alt_stub.S */
9297/*
9298 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9299 * any interesting requests and then jump to the real instruction
9300 * handler.  Unlike the Arm handler, we can't do this as a tail call
9301 * because rIBASE is caller save and we need to reload it.
9302 *
9303 * Note that unlike in the Arm implementation, we should never arrive
9304 * here with a zero breakFlag because we always refresh rIBASE on
9305 * return.
9306 */
9307    EXPORT_PC
9308    movl   rSELF, %eax
9309    movl   rPC, OUT_ARG0(%esp)
9310    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9311    movl   rFP, OUT_ARG1(%esp)
9312    je     1f                                # reload rIBASE & resume if not
9313    movl   %eax, OUT_ARG2(%esp)
9314    call   dvmCheckBefore                    # (dPC, dFP, self)
9315    movl   rSELF, %eax
93161:
9317    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9318    jmp    *dvmAsmInstructionStart+(35*4)
9319
9320/* ------------------------------ */
9321.L_ALT_OP_FILLED_NEW_ARRAY: /* 0x24 */
9322/* File: x86/alt_stub.S */
9323/*
9324 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9325 * any interesting requests and then jump to the real instruction
9326 * handler.  Unlike the Arm handler, we can't do this as a tail call
9327 * because rIBASE is caller save and we need to reload it.
9328 *
9329 * Note that unlike in the Arm implementation, we should never arrive
9330 * here with a zero breakFlag because we always refresh rIBASE on
9331 * return.
9332 */
9333    EXPORT_PC
9334    movl   rSELF, %eax
9335    movl   rPC, OUT_ARG0(%esp)
9336    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9337    movl   rFP, OUT_ARG1(%esp)
9338    je     1f                                # reload rIBASE & resume if not
9339    movl   %eax, OUT_ARG2(%esp)
9340    call   dvmCheckBefore                    # (dPC, dFP, self)
9341    movl   rSELF, %eax
93421:
9343    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9344    jmp    *dvmAsmInstructionStart+(36*4)
9345
9346/* ------------------------------ */
9347.L_ALT_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
9348/* File: x86/alt_stub.S */
9349/*
9350 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9351 * any interesting requests and then jump to the real instruction
9352 * handler.  Unlike the Arm handler, we can't do this as a tail call
9353 * because rIBASE is caller save and we need to reload it.
9354 *
9355 * Note that unlike in the Arm implementation, we should never arrive
9356 * here with a zero breakFlag because we always refresh rIBASE on
9357 * return.
9358 */
9359    EXPORT_PC
9360    movl   rSELF, %eax
9361    movl   rPC, OUT_ARG0(%esp)
9362    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9363    movl   rFP, OUT_ARG1(%esp)
9364    je     1f                                # reload rIBASE & resume if not
9365    movl   %eax, OUT_ARG2(%esp)
9366    call   dvmCheckBefore                    # (dPC, dFP, self)
9367    movl   rSELF, %eax
93681:
9369    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9370    jmp    *dvmAsmInstructionStart+(37*4)
9371
9372/* ------------------------------ */
9373.L_ALT_OP_FILL_ARRAY_DATA: /* 0x26 */
9374/* File: x86/alt_stub.S */
9375/*
9376 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9377 * any interesting requests and then jump to the real instruction
9378 * handler.  Unlike the Arm handler, we can't do this as a tail call
9379 * because rIBASE is caller save and we need to reload it.
9380 *
9381 * Note that unlike in the Arm implementation, we should never arrive
9382 * here with a zero breakFlag because we always refresh rIBASE on
9383 * return.
9384 */
9385    EXPORT_PC
9386    movl   rSELF, %eax
9387    movl   rPC, OUT_ARG0(%esp)
9388    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9389    movl   rFP, OUT_ARG1(%esp)
9390    je     1f                                # reload rIBASE & resume if not
9391    movl   %eax, OUT_ARG2(%esp)
9392    call   dvmCheckBefore                    # (dPC, dFP, self)
9393    movl   rSELF, %eax
93941:
9395    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9396    jmp    *dvmAsmInstructionStart+(38*4)
9397
9398/* ------------------------------ */
9399.L_ALT_OP_THROW: /* 0x27 */
9400/* File: x86/alt_stub.S */
9401/*
9402 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9403 * any interesting requests and then jump to the real instruction
9404 * handler.  Unlike the Arm handler, we can't do this as a tail call
9405 * because rIBASE is caller save and we need to reload it.
9406 *
9407 * Note that unlike in the Arm implementation, we should never arrive
9408 * here with a zero breakFlag because we always refresh rIBASE on
9409 * return.
9410 */
9411    EXPORT_PC
9412    movl   rSELF, %eax
9413    movl   rPC, OUT_ARG0(%esp)
9414    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9415    movl   rFP, OUT_ARG1(%esp)
9416    je     1f                                # reload rIBASE & resume if not
9417    movl   %eax, OUT_ARG2(%esp)
9418    call   dvmCheckBefore                    # (dPC, dFP, self)
9419    movl   rSELF, %eax
94201:
9421    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9422    jmp    *dvmAsmInstructionStart+(39*4)
9423
9424/* ------------------------------ */
9425.L_ALT_OP_GOTO: /* 0x28 */
9426/* File: x86/alt_stub.S */
9427/*
9428 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9429 * any interesting requests and then jump to the real instruction
9430 * handler.  Unlike the Arm handler, we can't do this as a tail call
9431 * because rIBASE is caller save and we need to reload it.
9432 *
9433 * Note that unlike in the Arm implementation, we should never arrive
9434 * here with a zero breakFlag because we always refresh rIBASE on
9435 * return.
9436 */
9437    EXPORT_PC
9438    movl   rSELF, %eax
9439    movl   rPC, OUT_ARG0(%esp)
9440    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9441    movl   rFP, OUT_ARG1(%esp)
9442    je     1f                                # reload rIBASE & resume if not
9443    movl   %eax, OUT_ARG2(%esp)
9444    call   dvmCheckBefore                    # (dPC, dFP, self)
9445    movl   rSELF, %eax
94461:
9447    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9448    jmp    *dvmAsmInstructionStart+(40*4)
9449
9450/* ------------------------------ */
9451.L_ALT_OP_GOTO_16: /* 0x29 */
9452/* File: x86/alt_stub.S */
9453/*
9454 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9455 * any interesting requests and then jump to the real instruction
9456 * handler.  Unlike the Arm handler, we can't do this as a tail call
9457 * because rIBASE is caller save and we need to reload it.
9458 *
9459 * Note that unlike in the Arm implementation, we should never arrive
9460 * here with a zero breakFlag because we always refresh rIBASE on
9461 * return.
9462 */
9463    EXPORT_PC
9464    movl   rSELF, %eax
9465    movl   rPC, OUT_ARG0(%esp)
9466    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9467    movl   rFP, OUT_ARG1(%esp)
9468    je     1f                                # reload rIBASE & resume if not
9469    movl   %eax, OUT_ARG2(%esp)
9470    call   dvmCheckBefore                    # (dPC, dFP, self)
9471    movl   rSELF, %eax
94721:
9473    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9474    jmp    *dvmAsmInstructionStart+(41*4)
9475
9476/* ------------------------------ */
9477.L_ALT_OP_GOTO_32: /* 0x2a */
9478/* File: x86/alt_stub.S */
9479/*
9480 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9481 * any interesting requests and then jump to the real instruction
9482 * handler.  Unlike the Arm handler, we can't do this as a tail call
9483 * because rIBASE is caller save and we need to reload it.
9484 *
9485 * Note that unlike in the Arm implementation, we should never arrive
9486 * here with a zero breakFlag because we always refresh rIBASE on
9487 * return.
9488 */
9489    EXPORT_PC
9490    movl   rSELF, %eax
9491    movl   rPC, OUT_ARG0(%esp)
9492    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9493    movl   rFP, OUT_ARG1(%esp)
9494    je     1f                                # reload rIBASE & resume if not
9495    movl   %eax, OUT_ARG2(%esp)
9496    call   dvmCheckBefore                    # (dPC, dFP, self)
9497    movl   rSELF, %eax
94981:
9499    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9500    jmp    *dvmAsmInstructionStart+(42*4)
9501
9502/* ------------------------------ */
9503.L_ALT_OP_PACKED_SWITCH: /* 0x2b */
9504/* File: x86/alt_stub.S */
9505/*
9506 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9507 * any interesting requests and then jump to the real instruction
9508 * handler.  Unlike the Arm handler, we can't do this as a tail call
9509 * because rIBASE is caller save and we need to reload it.
9510 *
9511 * Note that unlike in the Arm implementation, we should never arrive
9512 * here with a zero breakFlag because we always refresh rIBASE on
9513 * return.
9514 */
9515    EXPORT_PC
9516    movl   rSELF, %eax
9517    movl   rPC, OUT_ARG0(%esp)
9518    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9519    movl   rFP, OUT_ARG1(%esp)
9520    je     1f                                # reload rIBASE & resume if not
9521    movl   %eax, OUT_ARG2(%esp)
9522    call   dvmCheckBefore                    # (dPC, dFP, self)
9523    movl   rSELF, %eax
95241:
9525    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9526    jmp    *dvmAsmInstructionStart+(43*4)
9527
9528/* ------------------------------ */
9529.L_ALT_OP_SPARSE_SWITCH: /* 0x2c */
9530/* File: x86/alt_stub.S */
9531/*
9532 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9533 * any interesting requests and then jump to the real instruction
9534 * handler.  Unlike the Arm handler, we can't do this as a tail call
9535 * because rIBASE is caller save and we need to reload it.
9536 *
9537 * Note that unlike in the Arm implementation, we should never arrive
9538 * here with a zero breakFlag because we always refresh rIBASE on
9539 * return.
9540 */
9541    EXPORT_PC
9542    movl   rSELF, %eax
9543    movl   rPC, OUT_ARG0(%esp)
9544    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9545    movl   rFP, OUT_ARG1(%esp)
9546    je     1f                                # reload rIBASE & resume if not
9547    movl   %eax, OUT_ARG2(%esp)
9548    call   dvmCheckBefore                    # (dPC, dFP, self)
9549    movl   rSELF, %eax
95501:
9551    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9552    jmp    *dvmAsmInstructionStart+(44*4)
9553
9554/* ------------------------------ */
9555.L_ALT_OP_CMPL_FLOAT: /* 0x2d */
9556/* File: x86/alt_stub.S */
9557/*
9558 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9559 * any interesting requests and then jump to the real instruction
9560 * handler.  Unlike the Arm handler, we can't do this as a tail call
9561 * because rIBASE is caller save and we need to reload it.
9562 *
9563 * Note that unlike in the Arm implementation, we should never arrive
9564 * here with a zero breakFlag because we always refresh rIBASE on
9565 * return.
9566 */
9567    EXPORT_PC
9568    movl   rSELF, %eax
9569    movl   rPC, OUT_ARG0(%esp)
9570    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9571    movl   rFP, OUT_ARG1(%esp)
9572    je     1f                                # reload rIBASE & resume if not
9573    movl   %eax, OUT_ARG2(%esp)
9574    call   dvmCheckBefore                    # (dPC, dFP, self)
9575    movl   rSELF, %eax
95761:
9577    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9578    jmp    *dvmAsmInstructionStart+(45*4)
9579
9580/* ------------------------------ */
9581.L_ALT_OP_CMPG_FLOAT: /* 0x2e */
9582/* File: x86/alt_stub.S */
9583/*
9584 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9585 * any interesting requests and then jump to the real instruction
9586 * handler.  Unlike the Arm handler, we can't do this as a tail call
9587 * because rIBASE is caller save and we need to reload it.
9588 *
9589 * Note that unlike in the Arm implementation, we should never arrive
9590 * here with a zero breakFlag because we always refresh rIBASE on
9591 * return.
9592 */
9593    EXPORT_PC
9594    movl   rSELF, %eax
9595    movl   rPC, OUT_ARG0(%esp)
9596    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9597    movl   rFP, OUT_ARG1(%esp)
9598    je     1f                                # reload rIBASE & resume if not
9599    movl   %eax, OUT_ARG2(%esp)
9600    call   dvmCheckBefore                    # (dPC, dFP, self)
9601    movl   rSELF, %eax
96021:
9603    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9604    jmp    *dvmAsmInstructionStart+(46*4)
9605
9606/* ------------------------------ */
9607.L_ALT_OP_CMPL_DOUBLE: /* 0x2f */
9608/* File: x86/alt_stub.S */
9609/*
9610 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9611 * any interesting requests and then jump to the real instruction
9612 * handler.  Unlike the Arm handler, we can't do this as a tail call
9613 * because rIBASE is caller save and we need to reload it.
9614 *
9615 * Note that unlike in the Arm implementation, we should never arrive
9616 * here with a zero breakFlag because we always refresh rIBASE on
9617 * return.
9618 */
9619    EXPORT_PC
9620    movl   rSELF, %eax
9621    movl   rPC, OUT_ARG0(%esp)
9622    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9623    movl   rFP, OUT_ARG1(%esp)
9624    je     1f                                # reload rIBASE & resume if not
9625    movl   %eax, OUT_ARG2(%esp)
9626    call   dvmCheckBefore                    # (dPC, dFP, self)
9627    movl   rSELF, %eax
96281:
9629    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9630    jmp    *dvmAsmInstructionStart+(47*4)
9631
9632/* ------------------------------ */
9633.L_ALT_OP_CMPG_DOUBLE: /* 0x30 */
9634/* File: x86/alt_stub.S */
9635/*
9636 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9637 * any interesting requests and then jump to the real instruction
9638 * handler.  Unlike the Arm handler, we can't do this as a tail call
9639 * because rIBASE is caller save and we need to reload it.
9640 *
9641 * Note that unlike in the Arm implementation, we should never arrive
9642 * here with a zero breakFlag because we always refresh rIBASE on
9643 * return.
9644 */
9645    EXPORT_PC
9646    movl   rSELF, %eax
9647    movl   rPC, OUT_ARG0(%esp)
9648    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9649    movl   rFP, OUT_ARG1(%esp)
9650    je     1f                                # reload rIBASE & resume if not
9651    movl   %eax, OUT_ARG2(%esp)
9652    call   dvmCheckBefore                    # (dPC, dFP, self)
9653    movl   rSELF, %eax
96541:
9655    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9656    jmp    *dvmAsmInstructionStart+(48*4)
9657
9658/* ------------------------------ */
9659.L_ALT_OP_CMP_LONG: /* 0x31 */
9660/* File: x86/alt_stub.S */
9661/*
9662 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9663 * any interesting requests and then jump to the real instruction
9664 * handler.  Unlike the Arm handler, we can't do this as a tail call
9665 * because rIBASE is caller save and we need to reload it.
9666 *
9667 * Note that unlike in the Arm implementation, we should never arrive
9668 * here with a zero breakFlag because we always refresh rIBASE on
9669 * return.
9670 */
9671    EXPORT_PC
9672    movl   rSELF, %eax
9673    movl   rPC, OUT_ARG0(%esp)
9674    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9675    movl   rFP, OUT_ARG1(%esp)
9676    je     1f                                # reload rIBASE & resume if not
9677    movl   %eax, OUT_ARG2(%esp)
9678    call   dvmCheckBefore                    # (dPC, dFP, self)
9679    movl   rSELF, %eax
96801:
9681    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9682    jmp    *dvmAsmInstructionStart+(49*4)
9683
9684/* ------------------------------ */
9685.L_ALT_OP_IF_EQ: /* 0x32 */
9686/* File: x86/alt_stub.S */
9687/*
9688 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9689 * any interesting requests and then jump to the real instruction
9690 * handler.  Unlike the Arm handler, we can't do this as a tail call
9691 * because rIBASE is caller save and we need to reload it.
9692 *
9693 * Note that unlike in the Arm implementation, we should never arrive
9694 * here with a zero breakFlag because we always refresh rIBASE on
9695 * return.
9696 */
9697    EXPORT_PC
9698    movl   rSELF, %eax
9699    movl   rPC, OUT_ARG0(%esp)
9700    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9701    movl   rFP, OUT_ARG1(%esp)
9702    je     1f                                # reload rIBASE & resume if not
9703    movl   %eax, OUT_ARG2(%esp)
9704    call   dvmCheckBefore                    # (dPC, dFP, self)
9705    movl   rSELF, %eax
97061:
9707    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9708    jmp    *dvmAsmInstructionStart+(50*4)
9709
9710/* ------------------------------ */
9711.L_ALT_OP_IF_NE: /* 0x33 */
9712/* File: x86/alt_stub.S */
9713/*
9714 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9715 * any interesting requests and then jump to the real instruction
9716 * handler.  Unlike the Arm handler, we can't do this as a tail call
9717 * because rIBASE is caller save and we need to reload it.
9718 *
9719 * Note that unlike in the Arm implementation, we should never arrive
9720 * here with a zero breakFlag because we always refresh rIBASE on
9721 * return.
9722 */
9723    EXPORT_PC
9724    movl   rSELF, %eax
9725    movl   rPC, OUT_ARG0(%esp)
9726    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9727    movl   rFP, OUT_ARG1(%esp)
9728    je     1f                                # reload rIBASE & resume if not
9729    movl   %eax, OUT_ARG2(%esp)
9730    call   dvmCheckBefore                    # (dPC, dFP, self)
9731    movl   rSELF, %eax
97321:
9733    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9734    jmp    *dvmAsmInstructionStart+(51*4)
9735
9736/* ------------------------------ */
9737.L_ALT_OP_IF_LT: /* 0x34 */
9738/* File: x86/alt_stub.S */
9739/*
9740 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9741 * any interesting requests and then jump to the real instruction
9742 * handler.  Unlike the Arm handler, we can't do this as a tail call
9743 * because rIBASE is caller save and we need to reload it.
9744 *
9745 * Note that unlike in the Arm implementation, we should never arrive
9746 * here with a zero breakFlag because we always refresh rIBASE on
9747 * return.
9748 */
9749    EXPORT_PC
9750    movl   rSELF, %eax
9751    movl   rPC, OUT_ARG0(%esp)
9752    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9753    movl   rFP, OUT_ARG1(%esp)
9754    je     1f                                # reload rIBASE & resume if not
9755    movl   %eax, OUT_ARG2(%esp)
9756    call   dvmCheckBefore                    # (dPC, dFP, self)
9757    movl   rSELF, %eax
97581:
9759    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9760    jmp    *dvmAsmInstructionStart+(52*4)
9761
9762/* ------------------------------ */
9763.L_ALT_OP_IF_GE: /* 0x35 */
9764/* File: x86/alt_stub.S */
9765/*
9766 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9767 * any interesting requests and then jump to the real instruction
9768 * handler.  Unlike the Arm handler, we can't do this as a tail call
9769 * because rIBASE is caller save and we need to reload it.
9770 *
9771 * Note that unlike in the Arm implementation, we should never arrive
9772 * here with a zero breakFlag because we always refresh rIBASE on
9773 * return.
9774 */
9775    EXPORT_PC
9776    movl   rSELF, %eax
9777    movl   rPC, OUT_ARG0(%esp)
9778    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9779    movl   rFP, OUT_ARG1(%esp)
9780    je     1f                                # reload rIBASE & resume if not
9781    movl   %eax, OUT_ARG2(%esp)
9782    call   dvmCheckBefore                    # (dPC, dFP, self)
9783    movl   rSELF, %eax
97841:
9785    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9786    jmp    *dvmAsmInstructionStart+(53*4)
9787
9788/* ------------------------------ */
9789.L_ALT_OP_IF_GT: /* 0x36 */
9790/* File: x86/alt_stub.S */
9791/*
9792 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9793 * any interesting requests and then jump to the real instruction
9794 * handler.  Unlike the Arm handler, we can't do this as a tail call
9795 * because rIBASE is caller save and we need to reload it.
9796 *
9797 * Note that unlike in the Arm implementation, we should never arrive
9798 * here with a zero breakFlag because we always refresh rIBASE on
9799 * return.
9800 */
9801    EXPORT_PC
9802    movl   rSELF, %eax
9803    movl   rPC, OUT_ARG0(%esp)
9804    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9805    movl   rFP, OUT_ARG1(%esp)
9806    je     1f                                # reload rIBASE & resume if not
9807    movl   %eax, OUT_ARG2(%esp)
9808    call   dvmCheckBefore                    # (dPC, dFP, self)
9809    movl   rSELF, %eax
98101:
9811    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9812    jmp    *dvmAsmInstructionStart+(54*4)
9813
9814/* ------------------------------ */
9815.L_ALT_OP_IF_LE: /* 0x37 */
9816/* File: x86/alt_stub.S */
9817/*
9818 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9819 * any interesting requests and then jump to the real instruction
9820 * handler.  Unlike the Arm handler, we can't do this as a tail call
9821 * because rIBASE is caller save and we need to reload it.
9822 *
9823 * Note that unlike in the Arm implementation, we should never arrive
9824 * here with a zero breakFlag because we always refresh rIBASE on
9825 * return.
9826 */
9827    EXPORT_PC
9828    movl   rSELF, %eax
9829    movl   rPC, OUT_ARG0(%esp)
9830    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9831    movl   rFP, OUT_ARG1(%esp)
9832    je     1f                                # reload rIBASE & resume if not
9833    movl   %eax, OUT_ARG2(%esp)
9834    call   dvmCheckBefore                    # (dPC, dFP, self)
9835    movl   rSELF, %eax
98361:
9837    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9838    jmp    *dvmAsmInstructionStart+(55*4)
9839
9840/* ------------------------------ */
9841.L_ALT_OP_IF_EQZ: /* 0x38 */
9842/* File: x86/alt_stub.S */
9843/*
9844 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9845 * any interesting requests and then jump to the real instruction
9846 * handler.  Unlike the Arm handler, we can't do this as a tail call
9847 * because rIBASE is caller save and we need to reload it.
9848 *
9849 * Note that unlike in the Arm implementation, we should never arrive
9850 * here with a zero breakFlag because we always refresh rIBASE on
9851 * return.
9852 */
9853    EXPORT_PC
9854    movl   rSELF, %eax
9855    movl   rPC, OUT_ARG0(%esp)
9856    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9857    movl   rFP, OUT_ARG1(%esp)
9858    je     1f                                # reload rIBASE & resume if not
9859    movl   %eax, OUT_ARG2(%esp)
9860    call   dvmCheckBefore                    # (dPC, dFP, self)
9861    movl   rSELF, %eax
98621:
9863    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9864    jmp    *dvmAsmInstructionStart+(56*4)
9865
9866/* ------------------------------ */
9867.L_ALT_OP_IF_NEZ: /* 0x39 */
9868/* File: x86/alt_stub.S */
9869/*
9870 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9871 * any interesting requests and then jump to the real instruction
9872 * handler.  Unlike the Arm handler, we can't do this as a tail call
9873 * because rIBASE is caller save and we need to reload it.
9874 *
9875 * Note that unlike in the Arm implementation, we should never arrive
9876 * here with a zero breakFlag because we always refresh rIBASE on
9877 * return.
9878 */
9879    EXPORT_PC
9880    movl   rSELF, %eax
9881    movl   rPC, OUT_ARG0(%esp)
9882    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9883    movl   rFP, OUT_ARG1(%esp)
9884    je     1f                                # reload rIBASE & resume if not
9885    movl   %eax, OUT_ARG2(%esp)
9886    call   dvmCheckBefore                    # (dPC, dFP, self)
9887    movl   rSELF, %eax
98881:
9889    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9890    jmp    *dvmAsmInstructionStart+(57*4)
9891
9892/* ------------------------------ */
9893.L_ALT_OP_IF_LTZ: /* 0x3a */
9894/* File: x86/alt_stub.S */
9895/*
9896 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9897 * any interesting requests and then jump to the real instruction
9898 * handler.  Unlike the Arm handler, we can't do this as a tail call
9899 * because rIBASE is caller save and we need to reload it.
9900 *
9901 * Note that unlike in the Arm implementation, we should never arrive
9902 * here with a zero breakFlag because we always refresh rIBASE on
9903 * return.
9904 */
9905    EXPORT_PC
9906    movl   rSELF, %eax
9907    movl   rPC, OUT_ARG0(%esp)
9908    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9909    movl   rFP, OUT_ARG1(%esp)
9910    je     1f                                # reload rIBASE & resume if not
9911    movl   %eax, OUT_ARG2(%esp)
9912    call   dvmCheckBefore                    # (dPC, dFP, self)
9913    movl   rSELF, %eax
99141:
9915    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9916    jmp    *dvmAsmInstructionStart+(58*4)
9917
9918/* ------------------------------ */
9919.L_ALT_OP_IF_GEZ: /* 0x3b */
9920/* File: x86/alt_stub.S */
9921/*
9922 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9923 * any interesting requests and then jump to the real instruction
9924 * handler.  Unlike the Arm handler, we can't do this as a tail call
9925 * because rIBASE is caller save and we need to reload it.
9926 *
9927 * Note that unlike in the Arm implementation, we should never arrive
9928 * here with a zero breakFlag because we always refresh rIBASE on
9929 * return.
9930 */
9931    EXPORT_PC
9932    movl   rSELF, %eax
9933    movl   rPC, OUT_ARG0(%esp)
9934    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9935    movl   rFP, OUT_ARG1(%esp)
9936    je     1f                                # reload rIBASE & resume if not
9937    movl   %eax, OUT_ARG2(%esp)
9938    call   dvmCheckBefore                    # (dPC, dFP, self)
9939    movl   rSELF, %eax
99401:
9941    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9942    jmp    *dvmAsmInstructionStart+(59*4)
9943
9944/* ------------------------------ */
9945.L_ALT_OP_IF_GTZ: /* 0x3c */
9946/* File: x86/alt_stub.S */
9947/*
9948 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9949 * any interesting requests and then jump to the real instruction
9950 * handler.  Unlike the Arm handler, we can't do this as a tail call
9951 * because rIBASE is caller save and we need to reload it.
9952 *
9953 * Note that unlike in the Arm implementation, we should never arrive
9954 * here with a zero breakFlag because we always refresh rIBASE on
9955 * return.
9956 */
9957    EXPORT_PC
9958    movl   rSELF, %eax
9959    movl   rPC, OUT_ARG0(%esp)
9960    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9961    movl   rFP, OUT_ARG1(%esp)
9962    je     1f                                # reload rIBASE & resume if not
9963    movl   %eax, OUT_ARG2(%esp)
9964    call   dvmCheckBefore                    # (dPC, dFP, self)
9965    movl   rSELF, %eax
99661:
9967    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9968    jmp    *dvmAsmInstructionStart+(60*4)
9969
9970/* ------------------------------ */
9971.L_ALT_OP_IF_LEZ: /* 0x3d */
9972/* File: x86/alt_stub.S */
9973/*
9974 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9975 * any interesting requests and then jump to the real instruction
9976 * handler.  Unlike the Arm handler, we can't do this as a tail call
9977 * because rIBASE is caller save and we need to reload it.
9978 *
9979 * Note that unlike in the Arm implementation, we should never arrive
9980 * here with a zero breakFlag because we always refresh rIBASE on
9981 * return.
9982 */
9983    EXPORT_PC
9984    movl   rSELF, %eax
9985    movl   rPC, OUT_ARG0(%esp)
9986    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
9987    movl   rFP, OUT_ARG1(%esp)
9988    je     1f                                # reload rIBASE & resume if not
9989    movl   %eax, OUT_ARG2(%esp)
9990    call   dvmCheckBefore                    # (dPC, dFP, self)
9991    movl   rSELF, %eax
99921:
9993    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
9994    jmp    *dvmAsmInstructionStart+(61*4)
9995
9996/* ------------------------------ */
9997.L_ALT_OP_UNUSED_3E: /* 0x3e */
9998/* File: x86/alt_stub.S */
9999/*
10000 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10001 * any interesting requests and then jump to the real instruction
10002 * handler.  Unlike the Arm handler, we can't do this as a tail call
10003 * because rIBASE is caller save and we need to reload it.
10004 *
10005 * Note that unlike in the Arm implementation, we should never arrive
10006 * here with a zero breakFlag because we always refresh rIBASE on
10007 * return.
10008 */
10009    EXPORT_PC
10010    movl   rSELF, %eax
10011    movl   rPC, OUT_ARG0(%esp)
10012    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10013    movl   rFP, OUT_ARG1(%esp)
10014    je     1f                                # reload rIBASE & resume if not
10015    movl   %eax, OUT_ARG2(%esp)
10016    call   dvmCheckBefore                    # (dPC, dFP, self)
10017    movl   rSELF, %eax
100181:
10019    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10020    jmp    *dvmAsmInstructionStart+(62*4)
10021
10022/* ------------------------------ */
10023.L_ALT_OP_UNUSED_3F: /* 0x3f */
10024/* File: x86/alt_stub.S */
10025/*
10026 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10027 * any interesting requests and then jump to the real instruction
10028 * handler.  Unlike the Arm handler, we can't do this as a tail call
10029 * because rIBASE is caller save and we need to reload it.
10030 *
10031 * Note that unlike in the Arm implementation, we should never arrive
10032 * here with a zero breakFlag because we always refresh rIBASE on
10033 * return.
10034 */
10035    EXPORT_PC
10036    movl   rSELF, %eax
10037    movl   rPC, OUT_ARG0(%esp)
10038    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10039    movl   rFP, OUT_ARG1(%esp)
10040    je     1f                                # reload rIBASE & resume if not
10041    movl   %eax, OUT_ARG2(%esp)
10042    call   dvmCheckBefore                    # (dPC, dFP, self)
10043    movl   rSELF, %eax
100441:
10045    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10046    jmp    *dvmAsmInstructionStart+(63*4)
10047
10048/* ------------------------------ */
10049.L_ALT_OP_UNUSED_40: /* 0x40 */
10050/* File: x86/alt_stub.S */
10051/*
10052 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10053 * any interesting requests and then jump to the real instruction
10054 * handler.  Unlike the Arm handler, we can't do this as a tail call
10055 * because rIBASE is caller save and we need to reload it.
10056 *
10057 * Note that unlike in the Arm implementation, we should never arrive
10058 * here with a zero breakFlag because we always refresh rIBASE on
10059 * return.
10060 */
10061    EXPORT_PC
10062    movl   rSELF, %eax
10063    movl   rPC, OUT_ARG0(%esp)
10064    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10065    movl   rFP, OUT_ARG1(%esp)
10066    je     1f                                # reload rIBASE & resume if not
10067    movl   %eax, OUT_ARG2(%esp)
10068    call   dvmCheckBefore                    # (dPC, dFP, self)
10069    movl   rSELF, %eax
100701:
10071    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10072    jmp    *dvmAsmInstructionStart+(64*4)
10073
10074/* ------------------------------ */
10075.L_ALT_OP_UNUSED_41: /* 0x41 */
10076/* File: x86/alt_stub.S */
10077/*
10078 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10079 * any interesting requests and then jump to the real instruction
10080 * handler.  Unlike the Arm handler, we can't do this as a tail call
10081 * because rIBASE is caller save and we need to reload it.
10082 *
10083 * Note that unlike in the Arm implementation, we should never arrive
10084 * here with a zero breakFlag because we always refresh rIBASE on
10085 * return.
10086 */
10087    EXPORT_PC
10088    movl   rSELF, %eax
10089    movl   rPC, OUT_ARG0(%esp)
10090    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10091    movl   rFP, OUT_ARG1(%esp)
10092    je     1f                                # reload rIBASE & resume if not
10093    movl   %eax, OUT_ARG2(%esp)
10094    call   dvmCheckBefore                    # (dPC, dFP, self)
10095    movl   rSELF, %eax
100961:
10097    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10098    jmp    *dvmAsmInstructionStart+(65*4)
10099
10100/* ------------------------------ */
10101.L_ALT_OP_UNUSED_42: /* 0x42 */
10102/* File: x86/alt_stub.S */
10103/*
10104 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10105 * any interesting requests and then jump to the real instruction
10106 * handler.  Unlike the Arm handler, we can't do this as a tail call
10107 * because rIBASE is caller save and we need to reload it.
10108 *
10109 * Note that unlike in the Arm implementation, we should never arrive
10110 * here with a zero breakFlag because we always refresh rIBASE on
10111 * return.
10112 */
10113    EXPORT_PC
10114    movl   rSELF, %eax
10115    movl   rPC, OUT_ARG0(%esp)
10116    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10117    movl   rFP, OUT_ARG1(%esp)
10118    je     1f                                # reload rIBASE & resume if not
10119    movl   %eax, OUT_ARG2(%esp)
10120    call   dvmCheckBefore                    # (dPC, dFP, self)
10121    movl   rSELF, %eax
101221:
10123    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10124    jmp    *dvmAsmInstructionStart+(66*4)
10125
10126/* ------------------------------ */
10127.L_ALT_OP_UNUSED_43: /* 0x43 */
10128/* File: x86/alt_stub.S */
10129/*
10130 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10131 * any interesting requests and then jump to the real instruction
10132 * handler.  Unlike the Arm handler, we can't do this as a tail call
10133 * because rIBASE is caller save and we need to reload it.
10134 *
10135 * Note that unlike in the Arm implementation, we should never arrive
10136 * here with a zero breakFlag because we always refresh rIBASE on
10137 * return.
10138 */
10139    EXPORT_PC
10140    movl   rSELF, %eax
10141    movl   rPC, OUT_ARG0(%esp)
10142    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10143    movl   rFP, OUT_ARG1(%esp)
10144    je     1f                                # reload rIBASE & resume if not
10145    movl   %eax, OUT_ARG2(%esp)
10146    call   dvmCheckBefore                    # (dPC, dFP, self)
10147    movl   rSELF, %eax
101481:
10149    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10150    jmp    *dvmAsmInstructionStart+(67*4)
10151
10152/* ------------------------------ */
10153.L_ALT_OP_AGET: /* 0x44 */
10154/* File: x86/alt_stub.S */
10155/*
10156 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10157 * any interesting requests and then jump to the real instruction
10158 * handler.  Unlike the Arm handler, we can't do this as a tail call
10159 * because rIBASE is caller save and we need to reload it.
10160 *
10161 * Note that unlike in the Arm implementation, we should never arrive
10162 * here with a zero breakFlag because we always refresh rIBASE on
10163 * return.
10164 */
10165    EXPORT_PC
10166    movl   rSELF, %eax
10167    movl   rPC, OUT_ARG0(%esp)
10168    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10169    movl   rFP, OUT_ARG1(%esp)
10170    je     1f                                # reload rIBASE & resume if not
10171    movl   %eax, OUT_ARG2(%esp)
10172    call   dvmCheckBefore                    # (dPC, dFP, self)
10173    movl   rSELF, %eax
101741:
10175    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10176    jmp    *dvmAsmInstructionStart+(68*4)
10177
10178/* ------------------------------ */
10179.L_ALT_OP_AGET_WIDE: /* 0x45 */
10180/* File: x86/alt_stub.S */
10181/*
10182 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10183 * any interesting requests and then jump to the real instruction
10184 * handler.  Unlike the Arm handler, we can't do this as a tail call
10185 * because rIBASE is caller save and we need to reload it.
10186 *
10187 * Note that unlike in the Arm implementation, we should never arrive
10188 * here with a zero breakFlag because we always refresh rIBASE on
10189 * return.
10190 */
10191    EXPORT_PC
10192    movl   rSELF, %eax
10193    movl   rPC, OUT_ARG0(%esp)
10194    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10195    movl   rFP, OUT_ARG1(%esp)
10196    je     1f                                # reload rIBASE & resume if not
10197    movl   %eax, OUT_ARG2(%esp)
10198    call   dvmCheckBefore                    # (dPC, dFP, self)
10199    movl   rSELF, %eax
102001:
10201    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10202    jmp    *dvmAsmInstructionStart+(69*4)
10203
10204/* ------------------------------ */
10205.L_ALT_OP_AGET_OBJECT: /* 0x46 */
10206/* File: x86/alt_stub.S */
10207/*
10208 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10209 * any interesting requests and then jump to the real instruction
10210 * handler.  Unlike the Arm handler, we can't do this as a tail call
10211 * because rIBASE is caller save and we need to reload it.
10212 *
10213 * Note that unlike in the Arm implementation, we should never arrive
10214 * here with a zero breakFlag because we always refresh rIBASE on
10215 * return.
10216 */
10217    EXPORT_PC
10218    movl   rSELF, %eax
10219    movl   rPC, OUT_ARG0(%esp)
10220    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10221    movl   rFP, OUT_ARG1(%esp)
10222    je     1f                                # reload rIBASE & resume if not
10223    movl   %eax, OUT_ARG2(%esp)
10224    call   dvmCheckBefore                    # (dPC, dFP, self)
10225    movl   rSELF, %eax
102261:
10227    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10228    jmp    *dvmAsmInstructionStart+(70*4)
10229
10230/* ------------------------------ */
10231.L_ALT_OP_AGET_BOOLEAN: /* 0x47 */
10232/* File: x86/alt_stub.S */
10233/*
10234 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10235 * any interesting requests and then jump to the real instruction
10236 * handler.  Unlike the Arm handler, we can't do this as a tail call
10237 * because rIBASE is caller save and we need to reload it.
10238 *
10239 * Note that unlike in the Arm implementation, we should never arrive
10240 * here with a zero breakFlag because we always refresh rIBASE on
10241 * return.
10242 */
10243    EXPORT_PC
10244    movl   rSELF, %eax
10245    movl   rPC, OUT_ARG0(%esp)
10246    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10247    movl   rFP, OUT_ARG1(%esp)
10248    je     1f                                # reload rIBASE & resume if not
10249    movl   %eax, OUT_ARG2(%esp)
10250    call   dvmCheckBefore                    # (dPC, dFP, self)
10251    movl   rSELF, %eax
102521:
10253    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10254    jmp    *dvmAsmInstructionStart+(71*4)
10255
10256/* ------------------------------ */
10257.L_ALT_OP_AGET_BYTE: /* 0x48 */
10258/* File: x86/alt_stub.S */
10259/*
10260 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10261 * any interesting requests and then jump to the real instruction
10262 * handler.  Unlike the Arm handler, we can't do this as a tail call
10263 * because rIBASE is caller save and we need to reload it.
10264 *
10265 * Note that unlike in the Arm implementation, we should never arrive
10266 * here with a zero breakFlag because we always refresh rIBASE on
10267 * return.
10268 */
10269    EXPORT_PC
10270    movl   rSELF, %eax
10271    movl   rPC, OUT_ARG0(%esp)
10272    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10273    movl   rFP, OUT_ARG1(%esp)
10274    je     1f                                # reload rIBASE & resume if not
10275    movl   %eax, OUT_ARG2(%esp)
10276    call   dvmCheckBefore                    # (dPC, dFP, self)
10277    movl   rSELF, %eax
102781:
10279    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10280    jmp    *dvmAsmInstructionStart+(72*4)
10281
10282/* ------------------------------ */
10283.L_ALT_OP_AGET_CHAR: /* 0x49 */
10284/* File: x86/alt_stub.S */
10285/*
10286 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10287 * any interesting requests and then jump to the real instruction
10288 * handler.  Unlike the Arm handler, we can't do this as a tail call
10289 * because rIBASE is caller save and we need to reload it.
10290 *
10291 * Note that unlike in the Arm implementation, we should never arrive
10292 * here with a zero breakFlag because we always refresh rIBASE on
10293 * return.
10294 */
10295    EXPORT_PC
10296    movl   rSELF, %eax
10297    movl   rPC, OUT_ARG0(%esp)
10298    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10299    movl   rFP, OUT_ARG1(%esp)
10300    je     1f                                # reload rIBASE & resume if not
10301    movl   %eax, OUT_ARG2(%esp)
10302    call   dvmCheckBefore                    # (dPC, dFP, self)
10303    movl   rSELF, %eax
103041:
10305    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10306    jmp    *dvmAsmInstructionStart+(73*4)
10307
10308/* ------------------------------ */
10309.L_ALT_OP_AGET_SHORT: /* 0x4a */
10310/* File: x86/alt_stub.S */
10311/*
10312 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10313 * any interesting requests and then jump to the real instruction
10314 * handler.  Unlike the Arm handler, we can't do this as a tail call
10315 * because rIBASE is caller save and we need to reload it.
10316 *
10317 * Note that unlike in the Arm implementation, we should never arrive
10318 * here with a zero breakFlag because we always refresh rIBASE on
10319 * return.
10320 */
10321    EXPORT_PC
10322    movl   rSELF, %eax
10323    movl   rPC, OUT_ARG0(%esp)
10324    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10325    movl   rFP, OUT_ARG1(%esp)
10326    je     1f                                # reload rIBASE & resume if not
10327    movl   %eax, OUT_ARG2(%esp)
10328    call   dvmCheckBefore                    # (dPC, dFP, self)
10329    movl   rSELF, %eax
103301:
10331    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10332    jmp    *dvmAsmInstructionStart+(74*4)
10333
10334/* ------------------------------ */
10335.L_ALT_OP_APUT: /* 0x4b */
10336/* File: x86/alt_stub.S */
10337/*
10338 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10339 * any interesting requests and then jump to the real instruction
10340 * handler.  Unlike the Arm handler, we can't do this as a tail call
10341 * because rIBASE is caller save and we need to reload it.
10342 *
10343 * Note that unlike in the Arm implementation, we should never arrive
10344 * here with a zero breakFlag because we always refresh rIBASE on
10345 * return.
10346 */
10347    EXPORT_PC
10348    movl   rSELF, %eax
10349    movl   rPC, OUT_ARG0(%esp)
10350    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10351    movl   rFP, OUT_ARG1(%esp)
10352    je     1f                                # reload rIBASE & resume if not
10353    movl   %eax, OUT_ARG2(%esp)
10354    call   dvmCheckBefore                    # (dPC, dFP, self)
10355    movl   rSELF, %eax
103561:
10357    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10358    jmp    *dvmAsmInstructionStart+(75*4)
10359
10360/* ------------------------------ */
10361.L_ALT_OP_APUT_WIDE: /* 0x4c */
10362/* File: x86/alt_stub.S */
10363/*
10364 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10365 * any interesting requests and then jump to the real instruction
10366 * handler.  Unlike the Arm handler, we can't do this as a tail call
10367 * because rIBASE is caller save and we need to reload it.
10368 *
10369 * Note that unlike in the Arm implementation, we should never arrive
10370 * here with a zero breakFlag because we always refresh rIBASE on
10371 * return.
10372 */
10373    EXPORT_PC
10374    movl   rSELF, %eax
10375    movl   rPC, OUT_ARG0(%esp)
10376    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10377    movl   rFP, OUT_ARG1(%esp)
10378    je     1f                                # reload rIBASE & resume if not
10379    movl   %eax, OUT_ARG2(%esp)
10380    call   dvmCheckBefore                    # (dPC, dFP, self)
10381    movl   rSELF, %eax
103821:
10383    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10384    jmp    *dvmAsmInstructionStart+(76*4)
10385
10386/* ------------------------------ */
10387.L_ALT_OP_APUT_OBJECT: /* 0x4d */
10388/* File: x86/alt_stub.S */
10389/*
10390 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10391 * any interesting requests and then jump to the real instruction
10392 * handler.  Unlike the Arm handler, we can't do this as a tail call
10393 * because rIBASE is caller save and we need to reload it.
10394 *
10395 * Note that unlike in the Arm implementation, we should never arrive
10396 * here with a zero breakFlag because we always refresh rIBASE on
10397 * return.
10398 */
10399    EXPORT_PC
10400    movl   rSELF, %eax
10401    movl   rPC, OUT_ARG0(%esp)
10402    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10403    movl   rFP, OUT_ARG1(%esp)
10404    je     1f                                # reload rIBASE & resume if not
10405    movl   %eax, OUT_ARG2(%esp)
10406    call   dvmCheckBefore                    # (dPC, dFP, self)
10407    movl   rSELF, %eax
104081:
10409    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10410    jmp    *dvmAsmInstructionStart+(77*4)
10411
10412/* ------------------------------ */
10413.L_ALT_OP_APUT_BOOLEAN: /* 0x4e */
10414/* File: x86/alt_stub.S */
10415/*
10416 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10417 * any interesting requests and then jump to the real instruction
10418 * handler.  Unlike the Arm handler, we can't do this as a tail call
10419 * because rIBASE is caller save and we need to reload it.
10420 *
10421 * Note that unlike in the Arm implementation, we should never arrive
10422 * here with a zero breakFlag because we always refresh rIBASE on
10423 * return.
10424 */
10425    EXPORT_PC
10426    movl   rSELF, %eax
10427    movl   rPC, OUT_ARG0(%esp)
10428    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10429    movl   rFP, OUT_ARG1(%esp)
10430    je     1f                                # reload rIBASE & resume if not
10431    movl   %eax, OUT_ARG2(%esp)
10432    call   dvmCheckBefore                    # (dPC, dFP, self)
10433    movl   rSELF, %eax
104341:
10435    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10436    jmp    *dvmAsmInstructionStart+(78*4)
10437
10438/* ------------------------------ */
10439.L_ALT_OP_APUT_BYTE: /* 0x4f */
10440/* File: x86/alt_stub.S */
10441/*
10442 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10443 * any interesting requests and then jump to the real instruction
10444 * handler.  Unlike the Arm handler, we can't do this as a tail call
10445 * because rIBASE is caller save and we need to reload it.
10446 *
10447 * Note that unlike in the Arm implementation, we should never arrive
10448 * here with a zero breakFlag because we always refresh rIBASE on
10449 * return.
10450 */
10451    EXPORT_PC
10452    movl   rSELF, %eax
10453    movl   rPC, OUT_ARG0(%esp)
10454    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10455    movl   rFP, OUT_ARG1(%esp)
10456    je     1f                                # reload rIBASE & resume if not
10457    movl   %eax, OUT_ARG2(%esp)
10458    call   dvmCheckBefore                    # (dPC, dFP, self)
10459    movl   rSELF, %eax
104601:
10461    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10462    jmp    *dvmAsmInstructionStart+(79*4)
10463
10464/* ------------------------------ */
10465.L_ALT_OP_APUT_CHAR: /* 0x50 */
10466/* File: x86/alt_stub.S */
10467/*
10468 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10469 * any interesting requests and then jump to the real instruction
10470 * handler.  Unlike the Arm handler, we can't do this as a tail call
10471 * because rIBASE is caller save and we need to reload it.
10472 *
10473 * Note that unlike in the Arm implementation, we should never arrive
10474 * here with a zero breakFlag because we always refresh rIBASE on
10475 * return.
10476 */
10477    EXPORT_PC
10478    movl   rSELF, %eax
10479    movl   rPC, OUT_ARG0(%esp)
10480    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10481    movl   rFP, OUT_ARG1(%esp)
10482    je     1f                                # reload rIBASE & resume if not
10483    movl   %eax, OUT_ARG2(%esp)
10484    call   dvmCheckBefore                    # (dPC, dFP, self)
10485    movl   rSELF, %eax
104861:
10487    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10488    jmp    *dvmAsmInstructionStart+(80*4)
10489
10490/* ------------------------------ */
10491.L_ALT_OP_APUT_SHORT: /* 0x51 */
10492/* File: x86/alt_stub.S */
10493/*
10494 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10495 * any interesting requests and then jump to the real instruction
10496 * handler.  Unlike the Arm handler, we can't do this as a tail call
10497 * because rIBASE is caller save and we need to reload it.
10498 *
10499 * Note that unlike in the Arm implementation, we should never arrive
10500 * here with a zero breakFlag because we always refresh rIBASE on
10501 * return.
10502 */
10503    EXPORT_PC
10504    movl   rSELF, %eax
10505    movl   rPC, OUT_ARG0(%esp)
10506    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10507    movl   rFP, OUT_ARG1(%esp)
10508    je     1f                                # reload rIBASE & resume if not
10509    movl   %eax, OUT_ARG2(%esp)
10510    call   dvmCheckBefore                    # (dPC, dFP, self)
10511    movl   rSELF, %eax
105121:
10513    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10514    jmp    *dvmAsmInstructionStart+(81*4)
10515
10516/* ------------------------------ */
10517.L_ALT_OP_IGET: /* 0x52 */
10518/* File: x86/alt_stub.S */
10519/*
10520 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10521 * any interesting requests and then jump to the real instruction
10522 * handler.  Unlike the Arm handler, we can't do this as a tail call
10523 * because rIBASE is caller save and we need to reload it.
10524 *
10525 * Note that unlike in the Arm implementation, we should never arrive
10526 * here with a zero breakFlag because we always refresh rIBASE on
10527 * return.
10528 */
10529    EXPORT_PC
10530    movl   rSELF, %eax
10531    movl   rPC, OUT_ARG0(%esp)
10532    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10533    movl   rFP, OUT_ARG1(%esp)
10534    je     1f                                # reload rIBASE & resume if not
10535    movl   %eax, OUT_ARG2(%esp)
10536    call   dvmCheckBefore                    # (dPC, dFP, self)
10537    movl   rSELF, %eax
105381:
10539    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10540    jmp    *dvmAsmInstructionStart+(82*4)
10541
10542/* ------------------------------ */
10543.L_ALT_OP_IGET_WIDE: /* 0x53 */
10544/* File: x86/alt_stub.S */
10545/*
10546 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10547 * any interesting requests and then jump to the real instruction
10548 * handler.  Unlike the Arm handler, we can't do this as a tail call
10549 * because rIBASE is caller save and we need to reload it.
10550 *
10551 * Note that unlike in the Arm implementation, we should never arrive
10552 * here with a zero breakFlag because we always refresh rIBASE on
10553 * return.
10554 */
10555    EXPORT_PC
10556    movl   rSELF, %eax
10557    movl   rPC, OUT_ARG0(%esp)
10558    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10559    movl   rFP, OUT_ARG1(%esp)
10560    je     1f                                # reload rIBASE & resume if not
10561    movl   %eax, OUT_ARG2(%esp)
10562    call   dvmCheckBefore                    # (dPC, dFP, self)
10563    movl   rSELF, %eax
105641:
10565    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10566    jmp    *dvmAsmInstructionStart+(83*4)
10567
10568/* ------------------------------ */
10569.L_ALT_OP_IGET_OBJECT: /* 0x54 */
10570/* File: x86/alt_stub.S */
10571/*
10572 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10573 * any interesting requests and then jump to the real instruction
10574 * handler.  Unlike the Arm handler, we can't do this as a tail call
10575 * because rIBASE is caller save and we need to reload it.
10576 *
10577 * Note that unlike in the Arm implementation, we should never arrive
10578 * here with a zero breakFlag because we always refresh rIBASE on
10579 * return.
10580 */
10581    EXPORT_PC
10582    movl   rSELF, %eax
10583    movl   rPC, OUT_ARG0(%esp)
10584    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10585    movl   rFP, OUT_ARG1(%esp)
10586    je     1f                                # reload rIBASE & resume if not
10587    movl   %eax, OUT_ARG2(%esp)
10588    call   dvmCheckBefore                    # (dPC, dFP, self)
10589    movl   rSELF, %eax
105901:
10591    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10592    jmp    *dvmAsmInstructionStart+(84*4)
10593
10594/* ------------------------------ */
10595.L_ALT_OP_IGET_BOOLEAN: /* 0x55 */
10596/* File: x86/alt_stub.S */
10597/*
10598 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10599 * any interesting requests and then jump to the real instruction
10600 * handler.  Unlike the Arm handler, we can't do this as a tail call
10601 * because rIBASE is caller save and we need to reload it.
10602 *
10603 * Note that unlike in the Arm implementation, we should never arrive
10604 * here with a zero breakFlag because we always refresh rIBASE on
10605 * return.
10606 */
10607    EXPORT_PC
10608    movl   rSELF, %eax
10609    movl   rPC, OUT_ARG0(%esp)
10610    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10611    movl   rFP, OUT_ARG1(%esp)
10612    je     1f                                # reload rIBASE & resume if not
10613    movl   %eax, OUT_ARG2(%esp)
10614    call   dvmCheckBefore                    # (dPC, dFP, self)
10615    movl   rSELF, %eax
106161:
10617    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10618    jmp    *dvmAsmInstructionStart+(85*4)
10619
10620/* ------------------------------ */
10621.L_ALT_OP_IGET_BYTE: /* 0x56 */
10622/* File: x86/alt_stub.S */
10623/*
10624 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10625 * any interesting requests and then jump to the real instruction
10626 * handler.  Unlike the Arm handler, we can't do this as a tail call
10627 * because rIBASE is caller save and we need to reload it.
10628 *
10629 * Note that unlike in the Arm implementation, we should never arrive
10630 * here with a zero breakFlag because we always refresh rIBASE on
10631 * return.
10632 */
10633    EXPORT_PC
10634    movl   rSELF, %eax
10635    movl   rPC, OUT_ARG0(%esp)
10636    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10637    movl   rFP, OUT_ARG1(%esp)
10638    je     1f                                # reload rIBASE & resume if not
10639    movl   %eax, OUT_ARG2(%esp)
10640    call   dvmCheckBefore                    # (dPC, dFP, self)
10641    movl   rSELF, %eax
106421:
10643    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10644    jmp    *dvmAsmInstructionStart+(86*4)
10645
10646/* ------------------------------ */
10647.L_ALT_OP_IGET_CHAR: /* 0x57 */
10648/* File: x86/alt_stub.S */
10649/*
10650 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10651 * any interesting requests and then jump to the real instruction
10652 * handler.  Unlike the Arm handler, we can't do this as a tail call
10653 * because rIBASE is caller save and we need to reload it.
10654 *
10655 * Note that unlike in the Arm implementation, we should never arrive
10656 * here with a zero breakFlag because we always refresh rIBASE on
10657 * return.
10658 */
10659    EXPORT_PC
10660    movl   rSELF, %eax
10661    movl   rPC, OUT_ARG0(%esp)
10662    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10663    movl   rFP, OUT_ARG1(%esp)
10664    je     1f                                # reload rIBASE & resume if not
10665    movl   %eax, OUT_ARG2(%esp)
10666    call   dvmCheckBefore                    # (dPC, dFP, self)
10667    movl   rSELF, %eax
106681:
10669    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10670    jmp    *dvmAsmInstructionStart+(87*4)
10671
10672/* ------------------------------ */
10673.L_ALT_OP_IGET_SHORT: /* 0x58 */
10674/* File: x86/alt_stub.S */
10675/*
10676 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10677 * any interesting requests and then jump to the real instruction
10678 * handler.  Unlike the Arm handler, we can't do this as a tail call
10679 * because rIBASE is caller save and we need to reload it.
10680 *
10681 * Note that unlike in the Arm implementation, we should never arrive
10682 * here with a zero breakFlag because we always refresh rIBASE on
10683 * return.
10684 */
10685    EXPORT_PC
10686    movl   rSELF, %eax
10687    movl   rPC, OUT_ARG0(%esp)
10688    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10689    movl   rFP, OUT_ARG1(%esp)
10690    je     1f                                # reload rIBASE & resume if not
10691    movl   %eax, OUT_ARG2(%esp)
10692    call   dvmCheckBefore                    # (dPC, dFP, self)
10693    movl   rSELF, %eax
106941:
10695    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10696    jmp    *dvmAsmInstructionStart+(88*4)
10697
10698/* ------------------------------ */
10699.L_ALT_OP_IPUT: /* 0x59 */
10700/* File: x86/alt_stub.S */
10701/*
10702 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10703 * any interesting requests and then jump to the real instruction
10704 * handler.  Unlike the Arm handler, we can't do this as a tail call
10705 * because rIBASE is caller save and we need to reload it.
10706 *
10707 * Note that unlike in the Arm implementation, we should never arrive
10708 * here with a zero breakFlag because we always refresh rIBASE on
10709 * return.
10710 */
10711    EXPORT_PC
10712    movl   rSELF, %eax
10713    movl   rPC, OUT_ARG0(%esp)
10714    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10715    movl   rFP, OUT_ARG1(%esp)
10716    je     1f                                # reload rIBASE & resume if not
10717    movl   %eax, OUT_ARG2(%esp)
10718    call   dvmCheckBefore                    # (dPC, dFP, self)
10719    movl   rSELF, %eax
107201:
10721    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10722    jmp    *dvmAsmInstructionStart+(89*4)
10723
10724/* ------------------------------ */
10725.L_ALT_OP_IPUT_WIDE: /* 0x5a */
10726/* File: x86/alt_stub.S */
10727/*
10728 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10729 * any interesting requests and then jump to the real instruction
10730 * handler.  Unlike the Arm handler, we can't do this as a tail call
10731 * because rIBASE is caller save and we need to reload it.
10732 *
10733 * Note that unlike in the Arm implementation, we should never arrive
10734 * here with a zero breakFlag because we always refresh rIBASE on
10735 * return.
10736 */
10737    EXPORT_PC
10738    movl   rSELF, %eax
10739    movl   rPC, OUT_ARG0(%esp)
10740    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10741    movl   rFP, OUT_ARG1(%esp)
10742    je     1f                                # reload rIBASE & resume if not
10743    movl   %eax, OUT_ARG2(%esp)
10744    call   dvmCheckBefore                    # (dPC, dFP, self)
10745    movl   rSELF, %eax
107461:
10747    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10748    jmp    *dvmAsmInstructionStart+(90*4)
10749
10750/* ------------------------------ */
10751.L_ALT_OP_IPUT_OBJECT: /* 0x5b */
10752/* File: x86/alt_stub.S */
10753/*
10754 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10755 * any interesting requests and then jump to the real instruction
10756 * handler.  Unlike the Arm handler, we can't do this as a tail call
10757 * because rIBASE is caller save and we need to reload it.
10758 *
10759 * Note that unlike in the Arm implementation, we should never arrive
10760 * here with a zero breakFlag because we always refresh rIBASE on
10761 * return.
10762 */
10763    EXPORT_PC
10764    movl   rSELF, %eax
10765    movl   rPC, OUT_ARG0(%esp)
10766    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10767    movl   rFP, OUT_ARG1(%esp)
10768    je     1f                                # reload rIBASE & resume if not
10769    movl   %eax, OUT_ARG2(%esp)
10770    call   dvmCheckBefore                    # (dPC, dFP, self)
10771    movl   rSELF, %eax
107721:
10773    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10774    jmp    *dvmAsmInstructionStart+(91*4)
10775
10776/* ------------------------------ */
10777.L_ALT_OP_IPUT_BOOLEAN: /* 0x5c */
10778/* File: x86/alt_stub.S */
10779/*
10780 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10781 * any interesting requests and then jump to the real instruction
10782 * handler.  Unlike the Arm handler, we can't do this as a tail call
10783 * because rIBASE is caller save and we need to reload it.
10784 *
10785 * Note that unlike in the Arm implementation, we should never arrive
10786 * here with a zero breakFlag because we always refresh rIBASE on
10787 * return.
10788 */
10789    EXPORT_PC
10790    movl   rSELF, %eax
10791    movl   rPC, OUT_ARG0(%esp)
10792    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10793    movl   rFP, OUT_ARG1(%esp)
10794    je     1f                                # reload rIBASE & resume if not
10795    movl   %eax, OUT_ARG2(%esp)
10796    call   dvmCheckBefore                    # (dPC, dFP, self)
10797    movl   rSELF, %eax
107981:
10799    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10800    jmp    *dvmAsmInstructionStart+(92*4)
10801
10802/* ------------------------------ */
10803.L_ALT_OP_IPUT_BYTE: /* 0x5d */
10804/* File: x86/alt_stub.S */
10805/*
10806 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10807 * any interesting requests and then jump to the real instruction
10808 * handler.  Unlike the Arm handler, we can't do this as a tail call
10809 * because rIBASE is caller save and we need to reload it.
10810 *
10811 * Note that unlike in the Arm implementation, we should never arrive
10812 * here with a zero breakFlag because we always refresh rIBASE on
10813 * return.
10814 */
10815    EXPORT_PC
10816    movl   rSELF, %eax
10817    movl   rPC, OUT_ARG0(%esp)
10818    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10819    movl   rFP, OUT_ARG1(%esp)
10820    je     1f                                # reload rIBASE & resume if not
10821    movl   %eax, OUT_ARG2(%esp)
10822    call   dvmCheckBefore                    # (dPC, dFP, self)
10823    movl   rSELF, %eax
108241:
10825    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10826    jmp    *dvmAsmInstructionStart+(93*4)
10827
10828/* ------------------------------ */
10829.L_ALT_OP_IPUT_CHAR: /* 0x5e */
10830/* File: x86/alt_stub.S */
10831/*
10832 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10833 * any interesting requests and then jump to the real instruction
10834 * handler.  Unlike the Arm handler, we can't do this as a tail call
10835 * because rIBASE is caller save and we need to reload it.
10836 *
10837 * Note that unlike in the Arm implementation, we should never arrive
10838 * here with a zero breakFlag because we always refresh rIBASE on
10839 * return.
10840 */
10841    EXPORT_PC
10842    movl   rSELF, %eax
10843    movl   rPC, OUT_ARG0(%esp)
10844    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10845    movl   rFP, OUT_ARG1(%esp)
10846    je     1f                                # reload rIBASE & resume if not
10847    movl   %eax, OUT_ARG2(%esp)
10848    call   dvmCheckBefore                    # (dPC, dFP, self)
10849    movl   rSELF, %eax
108501:
10851    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10852    jmp    *dvmAsmInstructionStart+(94*4)
10853
10854/* ------------------------------ */
10855.L_ALT_OP_IPUT_SHORT: /* 0x5f */
10856/* File: x86/alt_stub.S */
10857/*
10858 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10859 * any interesting requests and then jump to the real instruction
10860 * handler.  Unlike the Arm handler, we can't do this as a tail call
10861 * because rIBASE is caller save and we need to reload it.
10862 *
10863 * Note that unlike in the Arm implementation, we should never arrive
10864 * here with a zero breakFlag because we always refresh rIBASE on
10865 * return.
10866 */
10867    EXPORT_PC
10868    movl   rSELF, %eax
10869    movl   rPC, OUT_ARG0(%esp)
10870    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10871    movl   rFP, OUT_ARG1(%esp)
10872    je     1f                                # reload rIBASE & resume if not
10873    movl   %eax, OUT_ARG2(%esp)
10874    call   dvmCheckBefore                    # (dPC, dFP, self)
10875    movl   rSELF, %eax
108761:
10877    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10878    jmp    *dvmAsmInstructionStart+(95*4)
10879
10880/* ------------------------------ */
10881.L_ALT_OP_SGET: /* 0x60 */
10882/* File: x86/alt_stub.S */
10883/*
10884 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10885 * any interesting requests and then jump to the real instruction
10886 * handler.  Unlike the Arm handler, we can't do this as a tail call
10887 * because rIBASE is caller save and we need to reload it.
10888 *
10889 * Note that unlike in the Arm implementation, we should never arrive
10890 * here with a zero breakFlag because we always refresh rIBASE on
10891 * return.
10892 */
10893    EXPORT_PC
10894    movl   rSELF, %eax
10895    movl   rPC, OUT_ARG0(%esp)
10896    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10897    movl   rFP, OUT_ARG1(%esp)
10898    je     1f                                # reload rIBASE & resume if not
10899    movl   %eax, OUT_ARG2(%esp)
10900    call   dvmCheckBefore                    # (dPC, dFP, self)
10901    movl   rSELF, %eax
109021:
10903    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10904    jmp    *dvmAsmInstructionStart+(96*4)
10905
10906/* ------------------------------ */
10907.L_ALT_OP_SGET_WIDE: /* 0x61 */
10908/* File: x86/alt_stub.S */
10909/*
10910 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10911 * any interesting requests and then jump to the real instruction
10912 * handler.  Unlike the Arm handler, we can't do this as a tail call
10913 * because rIBASE is caller save and we need to reload it.
10914 *
10915 * Note that unlike in the Arm implementation, we should never arrive
10916 * here with a zero breakFlag because we always refresh rIBASE on
10917 * return.
10918 */
10919    EXPORT_PC
10920    movl   rSELF, %eax
10921    movl   rPC, OUT_ARG0(%esp)
10922    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10923    movl   rFP, OUT_ARG1(%esp)
10924    je     1f                                # reload rIBASE & resume if not
10925    movl   %eax, OUT_ARG2(%esp)
10926    call   dvmCheckBefore                    # (dPC, dFP, self)
10927    movl   rSELF, %eax
109281:
10929    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10930    jmp    *dvmAsmInstructionStart+(97*4)
10931
10932/* ------------------------------ */
10933.L_ALT_OP_SGET_OBJECT: /* 0x62 */
10934/* File: x86/alt_stub.S */
10935/*
10936 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10937 * any interesting requests and then jump to the real instruction
10938 * handler.  Unlike the Arm handler, we can't do this as a tail call
10939 * because rIBASE is caller save and we need to reload it.
10940 *
10941 * Note that unlike in the Arm implementation, we should never arrive
10942 * here with a zero breakFlag because we always refresh rIBASE on
10943 * return.
10944 */
10945    EXPORT_PC
10946    movl   rSELF, %eax
10947    movl   rPC, OUT_ARG0(%esp)
10948    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10949    movl   rFP, OUT_ARG1(%esp)
10950    je     1f                                # reload rIBASE & resume if not
10951    movl   %eax, OUT_ARG2(%esp)
10952    call   dvmCheckBefore                    # (dPC, dFP, self)
10953    movl   rSELF, %eax
109541:
10955    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10956    jmp    *dvmAsmInstructionStart+(98*4)
10957
10958/* ------------------------------ */
10959.L_ALT_OP_SGET_BOOLEAN: /* 0x63 */
10960/* File: x86/alt_stub.S */
10961/*
10962 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10963 * any interesting requests and then jump to the real instruction
10964 * handler.  Unlike the Arm handler, we can't do this as a tail call
10965 * because rIBASE is caller save and we need to reload it.
10966 *
10967 * Note that unlike in the Arm implementation, we should never arrive
10968 * here with a zero breakFlag because we always refresh rIBASE on
10969 * return.
10970 */
10971    EXPORT_PC
10972    movl   rSELF, %eax
10973    movl   rPC, OUT_ARG0(%esp)
10974    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
10975    movl   rFP, OUT_ARG1(%esp)
10976    je     1f                                # reload rIBASE & resume if not
10977    movl   %eax, OUT_ARG2(%esp)
10978    call   dvmCheckBefore                    # (dPC, dFP, self)
10979    movl   rSELF, %eax
109801:
10981    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
10982    jmp    *dvmAsmInstructionStart+(99*4)
10983
10984/* ------------------------------ */
10985.L_ALT_OP_SGET_BYTE: /* 0x64 */
10986/* File: x86/alt_stub.S */
10987/*
10988 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10989 * any interesting requests and then jump to the real instruction
10990 * handler.  Unlike the Arm handler, we can't do this as a tail call
10991 * because rIBASE is caller save and we need to reload it.
10992 *
10993 * Note that unlike in the Arm implementation, we should never arrive
10994 * here with a zero breakFlag because we always refresh rIBASE on
10995 * return.
10996 */
10997    EXPORT_PC
10998    movl   rSELF, %eax
10999    movl   rPC, OUT_ARG0(%esp)
11000    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11001    movl   rFP, OUT_ARG1(%esp)
11002    je     1f                                # reload rIBASE & resume if not
11003    movl   %eax, OUT_ARG2(%esp)
11004    call   dvmCheckBefore                    # (dPC, dFP, self)
11005    movl   rSELF, %eax
110061:
11007    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11008    jmp    *dvmAsmInstructionStart+(100*4)
11009
11010/* ------------------------------ */
11011.L_ALT_OP_SGET_CHAR: /* 0x65 */
11012/* File: x86/alt_stub.S */
11013/*
11014 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11015 * any interesting requests and then jump to the real instruction
11016 * handler.  Unlike the Arm handler, we can't do this as a tail call
11017 * because rIBASE is caller save and we need to reload it.
11018 *
11019 * Note that unlike in the Arm implementation, we should never arrive
11020 * here with a zero breakFlag because we always refresh rIBASE on
11021 * return.
11022 */
11023    EXPORT_PC
11024    movl   rSELF, %eax
11025    movl   rPC, OUT_ARG0(%esp)
11026    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11027    movl   rFP, OUT_ARG1(%esp)
11028    je     1f                                # reload rIBASE & resume if not
11029    movl   %eax, OUT_ARG2(%esp)
11030    call   dvmCheckBefore                    # (dPC, dFP, self)
11031    movl   rSELF, %eax
110321:
11033    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11034    jmp    *dvmAsmInstructionStart+(101*4)
11035
11036/* ------------------------------ */
11037.L_ALT_OP_SGET_SHORT: /* 0x66 */
11038/* File: x86/alt_stub.S */
11039/*
11040 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11041 * any interesting requests and then jump to the real instruction
11042 * handler.  Unlike the Arm handler, we can't do this as a tail call
11043 * because rIBASE is caller save and we need to reload it.
11044 *
11045 * Note that unlike in the Arm implementation, we should never arrive
11046 * here with a zero breakFlag because we always refresh rIBASE on
11047 * return.
11048 */
11049    EXPORT_PC
11050    movl   rSELF, %eax
11051    movl   rPC, OUT_ARG0(%esp)
11052    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11053    movl   rFP, OUT_ARG1(%esp)
11054    je     1f                                # reload rIBASE & resume if not
11055    movl   %eax, OUT_ARG2(%esp)
11056    call   dvmCheckBefore                    # (dPC, dFP, self)
11057    movl   rSELF, %eax
110581:
11059    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11060    jmp    *dvmAsmInstructionStart+(102*4)
11061
11062/* ------------------------------ */
11063.L_ALT_OP_SPUT: /* 0x67 */
11064/* File: x86/alt_stub.S */
11065/*
11066 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11067 * any interesting requests and then jump to the real instruction
11068 * handler.  Unlike the Arm handler, we can't do this as a tail call
11069 * because rIBASE is caller save and we need to reload it.
11070 *
11071 * Note that unlike in the Arm implementation, we should never arrive
11072 * here with a zero breakFlag because we always refresh rIBASE on
11073 * return.
11074 */
11075    EXPORT_PC
11076    movl   rSELF, %eax
11077    movl   rPC, OUT_ARG0(%esp)
11078    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11079    movl   rFP, OUT_ARG1(%esp)
11080    je     1f                                # reload rIBASE & resume if not
11081    movl   %eax, OUT_ARG2(%esp)
11082    call   dvmCheckBefore                    # (dPC, dFP, self)
11083    movl   rSELF, %eax
110841:
11085    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11086    jmp    *dvmAsmInstructionStart+(103*4)
11087
11088/* ------------------------------ */
11089.L_ALT_OP_SPUT_WIDE: /* 0x68 */
11090/* File: x86/alt_stub.S */
11091/*
11092 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11093 * any interesting requests and then jump to the real instruction
11094 * handler.  Unlike the Arm handler, we can't do this as a tail call
11095 * because rIBASE is caller save and we need to reload it.
11096 *
11097 * Note that unlike in the Arm implementation, we should never arrive
11098 * here with a zero breakFlag because we always refresh rIBASE on
11099 * return.
11100 */
11101    EXPORT_PC
11102    movl   rSELF, %eax
11103    movl   rPC, OUT_ARG0(%esp)
11104    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11105    movl   rFP, OUT_ARG1(%esp)
11106    je     1f                                # reload rIBASE & resume if not
11107    movl   %eax, OUT_ARG2(%esp)
11108    call   dvmCheckBefore                    # (dPC, dFP, self)
11109    movl   rSELF, %eax
111101:
11111    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11112    jmp    *dvmAsmInstructionStart+(104*4)
11113
11114/* ------------------------------ */
11115.L_ALT_OP_SPUT_OBJECT: /* 0x69 */
11116/* File: x86/alt_stub.S */
11117/*
11118 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11119 * any interesting requests and then jump to the real instruction
11120 * handler.  Unlike the Arm handler, we can't do this as a tail call
11121 * because rIBASE is caller save and we need to reload it.
11122 *
11123 * Note that unlike in the Arm implementation, we should never arrive
11124 * here with a zero breakFlag because we always refresh rIBASE on
11125 * return.
11126 */
11127    EXPORT_PC
11128    movl   rSELF, %eax
11129    movl   rPC, OUT_ARG0(%esp)
11130    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11131    movl   rFP, OUT_ARG1(%esp)
11132    je     1f                                # reload rIBASE & resume if not
11133    movl   %eax, OUT_ARG2(%esp)
11134    call   dvmCheckBefore                    # (dPC, dFP, self)
11135    movl   rSELF, %eax
111361:
11137    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11138    jmp    *dvmAsmInstructionStart+(105*4)
11139
11140/* ------------------------------ */
11141.L_ALT_OP_SPUT_BOOLEAN: /* 0x6a */
11142/* File: x86/alt_stub.S */
11143/*
11144 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11145 * any interesting requests and then jump to the real instruction
11146 * handler.  Unlike the Arm handler, we can't do this as a tail call
11147 * because rIBASE is caller save and we need to reload it.
11148 *
11149 * Note that unlike in the Arm implementation, we should never arrive
11150 * here with a zero breakFlag because we always refresh rIBASE on
11151 * return.
11152 */
11153    EXPORT_PC
11154    movl   rSELF, %eax
11155    movl   rPC, OUT_ARG0(%esp)
11156    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11157    movl   rFP, OUT_ARG1(%esp)
11158    je     1f                                # reload rIBASE & resume if not
11159    movl   %eax, OUT_ARG2(%esp)
11160    call   dvmCheckBefore                    # (dPC, dFP, self)
11161    movl   rSELF, %eax
111621:
11163    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11164    jmp    *dvmAsmInstructionStart+(106*4)
11165
11166/* ------------------------------ */
11167.L_ALT_OP_SPUT_BYTE: /* 0x6b */
11168/* File: x86/alt_stub.S */
11169/*
11170 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11171 * any interesting requests and then jump to the real instruction
11172 * handler.  Unlike the Arm handler, we can't do this as a tail call
11173 * because rIBASE is caller save and we need to reload it.
11174 *
11175 * Note that unlike in the Arm implementation, we should never arrive
11176 * here with a zero breakFlag because we always refresh rIBASE on
11177 * return.
11178 */
11179    EXPORT_PC
11180    movl   rSELF, %eax
11181    movl   rPC, OUT_ARG0(%esp)
11182    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11183    movl   rFP, OUT_ARG1(%esp)
11184    je     1f                                # reload rIBASE & resume if not
11185    movl   %eax, OUT_ARG2(%esp)
11186    call   dvmCheckBefore                    # (dPC, dFP, self)
11187    movl   rSELF, %eax
111881:
11189    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11190    jmp    *dvmAsmInstructionStart+(107*4)
11191
11192/* ------------------------------ */
11193.L_ALT_OP_SPUT_CHAR: /* 0x6c */
11194/* File: x86/alt_stub.S */
11195/*
11196 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11197 * any interesting requests and then jump to the real instruction
11198 * handler.  Unlike the Arm handler, we can't do this as a tail call
11199 * because rIBASE is caller save and we need to reload it.
11200 *
11201 * Note that unlike in the Arm implementation, we should never arrive
11202 * here with a zero breakFlag because we always refresh rIBASE on
11203 * return.
11204 */
11205    EXPORT_PC
11206    movl   rSELF, %eax
11207    movl   rPC, OUT_ARG0(%esp)
11208    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11209    movl   rFP, OUT_ARG1(%esp)
11210    je     1f                                # reload rIBASE & resume if not
11211    movl   %eax, OUT_ARG2(%esp)
11212    call   dvmCheckBefore                    # (dPC, dFP, self)
11213    movl   rSELF, %eax
112141:
11215    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11216    jmp    *dvmAsmInstructionStart+(108*4)
11217
11218/* ------------------------------ */
11219.L_ALT_OP_SPUT_SHORT: /* 0x6d */
11220/* File: x86/alt_stub.S */
11221/*
11222 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11223 * any interesting requests and then jump to the real instruction
11224 * handler.  Unlike the Arm handler, we can't do this as a tail call
11225 * because rIBASE is caller save and we need to reload it.
11226 *
11227 * Note that unlike in the Arm implementation, we should never arrive
11228 * here with a zero breakFlag because we always refresh rIBASE on
11229 * return.
11230 */
11231    EXPORT_PC
11232    movl   rSELF, %eax
11233    movl   rPC, OUT_ARG0(%esp)
11234    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11235    movl   rFP, OUT_ARG1(%esp)
11236    je     1f                                # reload rIBASE & resume if not
11237    movl   %eax, OUT_ARG2(%esp)
11238    call   dvmCheckBefore                    # (dPC, dFP, self)
11239    movl   rSELF, %eax
112401:
11241    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11242    jmp    *dvmAsmInstructionStart+(109*4)
11243
11244/* ------------------------------ */
11245.L_ALT_OP_INVOKE_VIRTUAL: /* 0x6e */
11246/* File: x86/alt_stub.S */
11247/*
11248 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11249 * any interesting requests and then jump to the real instruction
11250 * handler.  Unlike the Arm handler, we can't do this as a tail call
11251 * because rIBASE is caller save and we need to reload it.
11252 *
11253 * Note that unlike in the Arm implementation, we should never arrive
11254 * here with a zero breakFlag because we always refresh rIBASE on
11255 * return.
11256 */
11257    EXPORT_PC
11258    movl   rSELF, %eax
11259    movl   rPC, OUT_ARG0(%esp)
11260    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11261    movl   rFP, OUT_ARG1(%esp)
11262    je     1f                                # reload rIBASE & resume if not
11263    movl   %eax, OUT_ARG2(%esp)
11264    call   dvmCheckBefore                    # (dPC, dFP, self)
11265    movl   rSELF, %eax
112661:
11267    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11268    jmp    *dvmAsmInstructionStart+(110*4)
11269
11270/* ------------------------------ */
11271.L_ALT_OP_INVOKE_SUPER: /* 0x6f */
11272/* File: x86/alt_stub.S */
11273/*
11274 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11275 * any interesting requests and then jump to the real instruction
11276 * handler.  Unlike the Arm handler, we can't do this as a tail call
11277 * because rIBASE is caller save and we need to reload it.
11278 *
11279 * Note that unlike in the Arm implementation, we should never arrive
11280 * here with a zero breakFlag because we always refresh rIBASE on
11281 * return.
11282 */
11283    EXPORT_PC
11284    movl   rSELF, %eax
11285    movl   rPC, OUT_ARG0(%esp)
11286    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11287    movl   rFP, OUT_ARG1(%esp)
11288    je     1f                                # reload rIBASE & resume if not
11289    movl   %eax, OUT_ARG2(%esp)
11290    call   dvmCheckBefore                    # (dPC, dFP, self)
11291    movl   rSELF, %eax
112921:
11293    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11294    jmp    *dvmAsmInstructionStart+(111*4)
11295
11296/* ------------------------------ */
11297.L_ALT_OP_INVOKE_DIRECT: /* 0x70 */
11298/* File: x86/alt_stub.S */
11299/*
11300 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11301 * any interesting requests and then jump to the real instruction
11302 * handler.  Unlike the Arm handler, we can't do this as a tail call
11303 * because rIBASE is caller save and we need to reload it.
11304 *
11305 * Note that unlike in the Arm implementation, we should never arrive
11306 * here with a zero breakFlag because we always refresh rIBASE on
11307 * return.
11308 */
11309    EXPORT_PC
11310    movl   rSELF, %eax
11311    movl   rPC, OUT_ARG0(%esp)
11312    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11313    movl   rFP, OUT_ARG1(%esp)
11314    je     1f                                # reload rIBASE & resume if not
11315    movl   %eax, OUT_ARG2(%esp)
11316    call   dvmCheckBefore                    # (dPC, dFP, self)
11317    movl   rSELF, %eax
113181:
11319    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11320    jmp    *dvmAsmInstructionStart+(112*4)
11321
11322/* ------------------------------ */
11323.L_ALT_OP_INVOKE_STATIC: /* 0x71 */
11324/* File: x86/alt_stub.S */
11325/*
11326 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11327 * any interesting requests and then jump to the real instruction
11328 * handler.  Unlike the Arm handler, we can't do this as a tail call
11329 * because rIBASE is caller save and we need to reload it.
11330 *
11331 * Note that unlike in the Arm implementation, we should never arrive
11332 * here with a zero breakFlag because we always refresh rIBASE on
11333 * return.
11334 */
11335    EXPORT_PC
11336    movl   rSELF, %eax
11337    movl   rPC, OUT_ARG0(%esp)
11338    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11339    movl   rFP, OUT_ARG1(%esp)
11340    je     1f                                # reload rIBASE & resume if not
11341    movl   %eax, OUT_ARG2(%esp)
11342    call   dvmCheckBefore                    # (dPC, dFP, self)
11343    movl   rSELF, %eax
113441:
11345    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11346    jmp    *dvmAsmInstructionStart+(113*4)
11347
11348/* ------------------------------ */
11349.L_ALT_OP_INVOKE_INTERFACE: /* 0x72 */
11350/* File: x86/alt_stub.S */
11351/*
11352 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11353 * any interesting requests and then jump to the real instruction
11354 * handler.  Unlike the Arm handler, we can't do this as a tail call
11355 * because rIBASE is caller save and we need to reload it.
11356 *
11357 * Note that unlike in the Arm implementation, we should never arrive
11358 * here with a zero breakFlag because we always refresh rIBASE on
11359 * return.
11360 */
11361    EXPORT_PC
11362    movl   rSELF, %eax
11363    movl   rPC, OUT_ARG0(%esp)
11364    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11365    movl   rFP, OUT_ARG1(%esp)
11366    je     1f                                # reload rIBASE & resume if not
11367    movl   %eax, OUT_ARG2(%esp)
11368    call   dvmCheckBefore                    # (dPC, dFP, self)
11369    movl   rSELF, %eax
113701:
11371    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11372    jmp    *dvmAsmInstructionStart+(114*4)
11373
11374/* ------------------------------ */
11375.L_ALT_OP_UNUSED_73: /* 0x73 */
11376/* File: x86/alt_stub.S */
11377/*
11378 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11379 * any interesting requests and then jump to the real instruction
11380 * handler.  Unlike the Arm handler, we can't do this as a tail call
11381 * because rIBASE is caller save and we need to reload it.
11382 *
11383 * Note that unlike in the Arm implementation, we should never arrive
11384 * here with a zero breakFlag because we always refresh rIBASE on
11385 * return.
11386 */
11387    EXPORT_PC
11388    movl   rSELF, %eax
11389    movl   rPC, OUT_ARG0(%esp)
11390    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11391    movl   rFP, OUT_ARG1(%esp)
11392    je     1f                                # reload rIBASE & resume if not
11393    movl   %eax, OUT_ARG2(%esp)
11394    call   dvmCheckBefore                    # (dPC, dFP, self)
11395    movl   rSELF, %eax
113961:
11397    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11398    jmp    *dvmAsmInstructionStart+(115*4)
11399
11400/* ------------------------------ */
11401.L_ALT_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
11402/* File: x86/alt_stub.S */
11403/*
11404 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11405 * any interesting requests and then jump to the real instruction
11406 * handler.  Unlike the Arm handler, we can't do this as a tail call
11407 * because rIBASE is caller save and we need to reload it.
11408 *
11409 * Note that unlike in the Arm implementation, we should never arrive
11410 * here with a zero breakFlag because we always refresh rIBASE on
11411 * return.
11412 */
11413    EXPORT_PC
11414    movl   rSELF, %eax
11415    movl   rPC, OUT_ARG0(%esp)
11416    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11417    movl   rFP, OUT_ARG1(%esp)
11418    je     1f                                # reload rIBASE & resume if not
11419    movl   %eax, OUT_ARG2(%esp)
11420    call   dvmCheckBefore                    # (dPC, dFP, self)
11421    movl   rSELF, %eax
114221:
11423    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11424    jmp    *dvmAsmInstructionStart+(116*4)
11425
11426/* ------------------------------ */
11427.L_ALT_OP_INVOKE_SUPER_RANGE: /* 0x75 */
11428/* File: x86/alt_stub.S */
11429/*
11430 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11431 * any interesting requests and then jump to the real instruction
11432 * handler.  Unlike the Arm handler, we can't do this as a tail call
11433 * because rIBASE is caller save and we need to reload it.
11434 *
11435 * Note that unlike in the Arm implementation, we should never arrive
11436 * here with a zero breakFlag because we always refresh rIBASE on
11437 * return.
11438 */
11439    EXPORT_PC
11440    movl   rSELF, %eax
11441    movl   rPC, OUT_ARG0(%esp)
11442    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11443    movl   rFP, OUT_ARG1(%esp)
11444    je     1f                                # reload rIBASE & resume if not
11445    movl   %eax, OUT_ARG2(%esp)
11446    call   dvmCheckBefore                    # (dPC, dFP, self)
11447    movl   rSELF, %eax
114481:
11449    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11450    jmp    *dvmAsmInstructionStart+(117*4)
11451
11452/* ------------------------------ */
11453.L_ALT_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
11454/* File: x86/alt_stub.S */
11455/*
11456 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11457 * any interesting requests and then jump to the real instruction
11458 * handler.  Unlike the Arm handler, we can't do this as a tail call
11459 * because rIBASE is caller save and we need to reload it.
11460 *
11461 * Note that unlike in the Arm implementation, we should never arrive
11462 * here with a zero breakFlag because we always refresh rIBASE on
11463 * return.
11464 */
11465    EXPORT_PC
11466    movl   rSELF, %eax
11467    movl   rPC, OUT_ARG0(%esp)
11468    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11469    movl   rFP, OUT_ARG1(%esp)
11470    je     1f                                # reload rIBASE & resume if not
11471    movl   %eax, OUT_ARG2(%esp)
11472    call   dvmCheckBefore                    # (dPC, dFP, self)
11473    movl   rSELF, %eax
114741:
11475    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11476    jmp    *dvmAsmInstructionStart+(118*4)
11477
11478/* ------------------------------ */
11479.L_ALT_OP_INVOKE_STATIC_RANGE: /* 0x77 */
11480/* File: x86/alt_stub.S */
11481/*
11482 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11483 * any interesting requests and then jump to the real instruction
11484 * handler.  Unlike the Arm handler, we can't do this as a tail call
11485 * because rIBASE is caller save and we need to reload it.
11486 *
11487 * Note that unlike in the Arm implementation, we should never arrive
11488 * here with a zero breakFlag because we always refresh rIBASE on
11489 * return.
11490 */
11491    EXPORT_PC
11492    movl   rSELF, %eax
11493    movl   rPC, OUT_ARG0(%esp)
11494    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11495    movl   rFP, OUT_ARG1(%esp)
11496    je     1f                                # reload rIBASE & resume if not
11497    movl   %eax, OUT_ARG2(%esp)
11498    call   dvmCheckBefore                    # (dPC, dFP, self)
11499    movl   rSELF, %eax
115001:
11501    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11502    jmp    *dvmAsmInstructionStart+(119*4)
11503
11504/* ------------------------------ */
11505.L_ALT_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
11506/* File: x86/alt_stub.S */
11507/*
11508 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11509 * any interesting requests and then jump to the real instruction
11510 * handler.  Unlike the Arm handler, we can't do this as a tail call
11511 * because rIBASE is caller save and we need to reload it.
11512 *
11513 * Note that unlike in the Arm implementation, we should never arrive
11514 * here with a zero breakFlag because we always refresh rIBASE on
11515 * return.
11516 */
11517    EXPORT_PC
11518    movl   rSELF, %eax
11519    movl   rPC, OUT_ARG0(%esp)
11520    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11521    movl   rFP, OUT_ARG1(%esp)
11522    je     1f                                # reload rIBASE & resume if not
11523    movl   %eax, OUT_ARG2(%esp)
11524    call   dvmCheckBefore                    # (dPC, dFP, self)
11525    movl   rSELF, %eax
115261:
11527    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11528    jmp    *dvmAsmInstructionStart+(120*4)
11529
11530/* ------------------------------ */
11531.L_ALT_OP_UNUSED_79: /* 0x79 */
11532/* File: x86/alt_stub.S */
11533/*
11534 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11535 * any interesting requests and then jump to the real instruction
11536 * handler.  Unlike the Arm handler, we can't do this as a tail call
11537 * because rIBASE is caller save and we need to reload it.
11538 *
11539 * Note that unlike in the Arm implementation, we should never arrive
11540 * here with a zero breakFlag because we always refresh rIBASE on
11541 * return.
11542 */
11543    EXPORT_PC
11544    movl   rSELF, %eax
11545    movl   rPC, OUT_ARG0(%esp)
11546    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11547    movl   rFP, OUT_ARG1(%esp)
11548    je     1f                                # reload rIBASE & resume if not
11549    movl   %eax, OUT_ARG2(%esp)
11550    call   dvmCheckBefore                    # (dPC, dFP, self)
11551    movl   rSELF, %eax
115521:
11553    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11554    jmp    *dvmAsmInstructionStart+(121*4)
11555
11556/* ------------------------------ */
11557.L_ALT_OP_UNUSED_7A: /* 0x7a */
11558/* File: x86/alt_stub.S */
11559/*
11560 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11561 * any interesting requests and then jump to the real instruction
11562 * handler.  Unlike the Arm handler, we can't do this as a tail call
11563 * because rIBASE is caller save and we need to reload it.
11564 *
11565 * Note that unlike in the Arm implementation, we should never arrive
11566 * here with a zero breakFlag because we always refresh rIBASE on
11567 * return.
11568 */
11569    EXPORT_PC
11570    movl   rSELF, %eax
11571    movl   rPC, OUT_ARG0(%esp)
11572    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11573    movl   rFP, OUT_ARG1(%esp)
11574    je     1f                                # reload rIBASE & resume if not
11575    movl   %eax, OUT_ARG2(%esp)
11576    call   dvmCheckBefore                    # (dPC, dFP, self)
11577    movl   rSELF, %eax
115781:
11579    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11580    jmp    *dvmAsmInstructionStart+(122*4)
11581
11582/* ------------------------------ */
11583.L_ALT_OP_NEG_INT: /* 0x7b */
11584/* File: x86/alt_stub.S */
11585/*
11586 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11587 * any interesting requests and then jump to the real instruction
11588 * handler.  Unlike the Arm handler, we can't do this as a tail call
11589 * because rIBASE is caller save and we need to reload it.
11590 *
11591 * Note that unlike in the Arm implementation, we should never arrive
11592 * here with a zero breakFlag because we always refresh rIBASE on
11593 * return.
11594 */
11595    EXPORT_PC
11596    movl   rSELF, %eax
11597    movl   rPC, OUT_ARG0(%esp)
11598    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11599    movl   rFP, OUT_ARG1(%esp)
11600    je     1f                                # reload rIBASE & resume if not
11601    movl   %eax, OUT_ARG2(%esp)
11602    call   dvmCheckBefore                    # (dPC, dFP, self)
11603    movl   rSELF, %eax
116041:
11605    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11606    jmp    *dvmAsmInstructionStart+(123*4)
11607
11608/* ------------------------------ */
11609.L_ALT_OP_NOT_INT: /* 0x7c */
11610/* File: x86/alt_stub.S */
11611/*
11612 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11613 * any interesting requests and then jump to the real instruction
11614 * handler.  Unlike the Arm handler, we can't do this as a tail call
11615 * because rIBASE is caller save and we need to reload it.
11616 *
11617 * Note that unlike in the Arm implementation, we should never arrive
11618 * here with a zero breakFlag because we always refresh rIBASE on
11619 * return.
11620 */
11621    EXPORT_PC
11622    movl   rSELF, %eax
11623    movl   rPC, OUT_ARG0(%esp)
11624    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11625    movl   rFP, OUT_ARG1(%esp)
11626    je     1f                                # reload rIBASE & resume if not
11627    movl   %eax, OUT_ARG2(%esp)
11628    call   dvmCheckBefore                    # (dPC, dFP, self)
11629    movl   rSELF, %eax
116301:
11631    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11632    jmp    *dvmAsmInstructionStart+(124*4)
11633
11634/* ------------------------------ */
11635.L_ALT_OP_NEG_LONG: /* 0x7d */
11636/* File: x86/alt_stub.S */
11637/*
11638 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11639 * any interesting requests and then jump to the real instruction
11640 * handler.  Unlike the Arm handler, we can't do this as a tail call
11641 * because rIBASE is caller save and we need to reload it.
11642 *
11643 * Note that unlike in the Arm implementation, we should never arrive
11644 * here with a zero breakFlag because we always refresh rIBASE on
11645 * return.
11646 */
11647    EXPORT_PC
11648    movl   rSELF, %eax
11649    movl   rPC, OUT_ARG0(%esp)
11650    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11651    movl   rFP, OUT_ARG1(%esp)
11652    je     1f                                # reload rIBASE & resume if not
11653    movl   %eax, OUT_ARG2(%esp)
11654    call   dvmCheckBefore                    # (dPC, dFP, self)
11655    movl   rSELF, %eax
116561:
11657    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11658    jmp    *dvmAsmInstructionStart+(125*4)
11659
11660/* ------------------------------ */
11661.L_ALT_OP_NOT_LONG: /* 0x7e */
11662/* File: x86/alt_stub.S */
11663/*
11664 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11665 * any interesting requests and then jump to the real instruction
11666 * handler.  Unlike the Arm handler, we can't do this as a tail call
11667 * because rIBASE is caller save and we need to reload it.
11668 *
11669 * Note that unlike in the Arm implementation, we should never arrive
11670 * here with a zero breakFlag because we always refresh rIBASE on
11671 * return.
11672 */
11673    EXPORT_PC
11674    movl   rSELF, %eax
11675    movl   rPC, OUT_ARG0(%esp)
11676    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11677    movl   rFP, OUT_ARG1(%esp)
11678    je     1f                                # reload rIBASE & resume if not
11679    movl   %eax, OUT_ARG2(%esp)
11680    call   dvmCheckBefore                    # (dPC, dFP, self)
11681    movl   rSELF, %eax
116821:
11683    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11684    jmp    *dvmAsmInstructionStart+(126*4)
11685
11686/* ------------------------------ */
11687.L_ALT_OP_NEG_FLOAT: /* 0x7f */
11688/* File: x86/alt_stub.S */
11689/*
11690 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11691 * any interesting requests and then jump to the real instruction
11692 * handler.  Unlike the Arm handler, we can't do this as a tail call
11693 * because rIBASE is caller save and we need to reload it.
11694 *
11695 * Note that unlike in the Arm implementation, we should never arrive
11696 * here with a zero breakFlag because we always refresh rIBASE on
11697 * return.
11698 */
11699    EXPORT_PC
11700    movl   rSELF, %eax
11701    movl   rPC, OUT_ARG0(%esp)
11702    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11703    movl   rFP, OUT_ARG1(%esp)
11704    je     1f                                # reload rIBASE & resume if not
11705    movl   %eax, OUT_ARG2(%esp)
11706    call   dvmCheckBefore                    # (dPC, dFP, self)
11707    movl   rSELF, %eax
117081:
11709    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11710    jmp    *dvmAsmInstructionStart+(127*4)
11711
11712/* ------------------------------ */
11713.L_ALT_OP_NEG_DOUBLE: /* 0x80 */
11714/* File: x86/alt_stub.S */
11715/*
11716 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11717 * any interesting requests and then jump to the real instruction
11718 * handler.  Unlike the Arm handler, we can't do this as a tail call
11719 * because rIBASE is caller save and we need to reload it.
11720 *
11721 * Note that unlike in the Arm implementation, we should never arrive
11722 * here with a zero breakFlag because we always refresh rIBASE on
11723 * return.
11724 */
11725    EXPORT_PC
11726    movl   rSELF, %eax
11727    movl   rPC, OUT_ARG0(%esp)
11728    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11729    movl   rFP, OUT_ARG1(%esp)
11730    je     1f                                # reload rIBASE & resume if not
11731    movl   %eax, OUT_ARG2(%esp)
11732    call   dvmCheckBefore                    # (dPC, dFP, self)
11733    movl   rSELF, %eax
117341:
11735    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11736    jmp    *dvmAsmInstructionStart+(128*4)
11737
11738/* ------------------------------ */
11739.L_ALT_OP_INT_TO_LONG: /* 0x81 */
11740/* File: x86/alt_stub.S */
11741/*
11742 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11743 * any interesting requests and then jump to the real instruction
11744 * handler.  Unlike the Arm handler, we can't do this as a tail call
11745 * because rIBASE is caller save and we need to reload it.
11746 *
11747 * Note that unlike in the Arm implementation, we should never arrive
11748 * here with a zero breakFlag because we always refresh rIBASE on
11749 * return.
11750 */
11751    EXPORT_PC
11752    movl   rSELF, %eax
11753    movl   rPC, OUT_ARG0(%esp)
11754    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11755    movl   rFP, OUT_ARG1(%esp)
11756    je     1f                                # reload rIBASE & resume if not
11757    movl   %eax, OUT_ARG2(%esp)
11758    call   dvmCheckBefore                    # (dPC, dFP, self)
11759    movl   rSELF, %eax
117601:
11761    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11762    jmp    *dvmAsmInstructionStart+(129*4)
11763
11764/* ------------------------------ */
11765.L_ALT_OP_INT_TO_FLOAT: /* 0x82 */
11766/* File: x86/alt_stub.S */
11767/*
11768 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11769 * any interesting requests and then jump to the real instruction
11770 * handler.  Unlike the Arm handler, we can't do this as a tail call
11771 * because rIBASE is caller save and we need to reload it.
11772 *
11773 * Note that unlike in the Arm implementation, we should never arrive
11774 * here with a zero breakFlag because we always refresh rIBASE on
11775 * return.
11776 */
11777    EXPORT_PC
11778    movl   rSELF, %eax
11779    movl   rPC, OUT_ARG0(%esp)
11780    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11781    movl   rFP, OUT_ARG1(%esp)
11782    je     1f                                # reload rIBASE & resume if not
11783    movl   %eax, OUT_ARG2(%esp)
11784    call   dvmCheckBefore                    # (dPC, dFP, self)
11785    movl   rSELF, %eax
117861:
11787    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11788    jmp    *dvmAsmInstructionStart+(130*4)
11789
11790/* ------------------------------ */
11791.L_ALT_OP_INT_TO_DOUBLE: /* 0x83 */
11792/* File: x86/alt_stub.S */
11793/*
11794 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11795 * any interesting requests and then jump to the real instruction
11796 * handler.  Unlike the Arm handler, we can't do this as a tail call
11797 * because rIBASE is caller save and we need to reload it.
11798 *
11799 * Note that unlike in the Arm implementation, we should never arrive
11800 * here with a zero breakFlag because we always refresh rIBASE on
11801 * return.
11802 */
11803    EXPORT_PC
11804    movl   rSELF, %eax
11805    movl   rPC, OUT_ARG0(%esp)
11806    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11807    movl   rFP, OUT_ARG1(%esp)
11808    je     1f                                # reload rIBASE & resume if not
11809    movl   %eax, OUT_ARG2(%esp)
11810    call   dvmCheckBefore                    # (dPC, dFP, self)
11811    movl   rSELF, %eax
118121:
11813    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11814    jmp    *dvmAsmInstructionStart+(131*4)
11815
11816/* ------------------------------ */
11817.L_ALT_OP_LONG_TO_INT: /* 0x84 */
11818/* File: x86/alt_stub.S */
11819/*
11820 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11821 * any interesting requests and then jump to the real instruction
11822 * handler.  Unlike the Arm handler, we can't do this as a tail call
11823 * because rIBASE is caller save and we need to reload it.
11824 *
11825 * Note that unlike in the Arm implementation, we should never arrive
11826 * here with a zero breakFlag because we always refresh rIBASE on
11827 * return.
11828 */
11829    EXPORT_PC
11830    movl   rSELF, %eax
11831    movl   rPC, OUT_ARG0(%esp)
11832    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11833    movl   rFP, OUT_ARG1(%esp)
11834    je     1f                                # reload rIBASE & resume if not
11835    movl   %eax, OUT_ARG2(%esp)
11836    call   dvmCheckBefore                    # (dPC, dFP, self)
11837    movl   rSELF, %eax
118381:
11839    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11840    jmp    *dvmAsmInstructionStart+(132*4)
11841
11842/* ------------------------------ */
11843.L_ALT_OP_LONG_TO_FLOAT: /* 0x85 */
11844/* File: x86/alt_stub.S */
11845/*
11846 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11847 * any interesting requests and then jump to the real instruction
11848 * handler.  Unlike the Arm handler, we can't do this as a tail call
11849 * because rIBASE is caller save and we need to reload it.
11850 *
11851 * Note that unlike in the Arm implementation, we should never arrive
11852 * here with a zero breakFlag because we always refresh rIBASE on
11853 * return.
11854 */
11855    EXPORT_PC
11856    movl   rSELF, %eax
11857    movl   rPC, OUT_ARG0(%esp)
11858    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11859    movl   rFP, OUT_ARG1(%esp)
11860    je     1f                                # reload rIBASE & resume if not
11861    movl   %eax, OUT_ARG2(%esp)
11862    call   dvmCheckBefore                    # (dPC, dFP, self)
11863    movl   rSELF, %eax
118641:
11865    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11866    jmp    *dvmAsmInstructionStart+(133*4)
11867
11868/* ------------------------------ */
11869.L_ALT_OP_LONG_TO_DOUBLE: /* 0x86 */
11870/* File: x86/alt_stub.S */
11871/*
11872 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11873 * any interesting requests and then jump to the real instruction
11874 * handler.  Unlike the Arm handler, we can't do this as a tail call
11875 * because rIBASE is caller save and we need to reload it.
11876 *
11877 * Note that unlike in the Arm implementation, we should never arrive
11878 * here with a zero breakFlag because we always refresh rIBASE on
11879 * return.
11880 */
11881    EXPORT_PC
11882    movl   rSELF, %eax
11883    movl   rPC, OUT_ARG0(%esp)
11884    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11885    movl   rFP, OUT_ARG1(%esp)
11886    je     1f                                # reload rIBASE & resume if not
11887    movl   %eax, OUT_ARG2(%esp)
11888    call   dvmCheckBefore                    # (dPC, dFP, self)
11889    movl   rSELF, %eax
118901:
11891    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11892    jmp    *dvmAsmInstructionStart+(134*4)
11893
11894/* ------------------------------ */
11895.L_ALT_OP_FLOAT_TO_INT: /* 0x87 */
11896/* File: x86/alt_stub.S */
11897/*
11898 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11899 * any interesting requests and then jump to the real instruction
11900 * handler.  Unlike the Arm handler, we can't do this as a tail call
11901 * because rIBASE is caller save and we need to reload it.
11902 *
11903 * Note that unlike in the Arm implementation, we should never arrive
11904 * here with a zero breakFlag because we always refresh rIBASE on
11905 * return.
11906 */
11907    EXPORT_PC
11908    movl   rSELF, %eax
11909    movl   rPC, OUT_ARG0(%esp)
11910    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11911    movl   rFP, OUT_ARG1(%esp)
11912    je     1f                                # reload rIBASE & resume if not
11913    movl   %eax, OUT_ARG2(%esp)
11914    call   dvmCheckBefore                    # (dPC, dFP, self)
11915    movl   rSELF, %eax
119161:
11917    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11918    jmp    *dvmAsmInstructionStart+(135*4)
11919
11920/* ------------------------------ */
11921.L_ALT_OP_FLOAT_TO_LONG: /* 0x88 */
11922/* File: x86/alt_stub.S */
11923/*
11924 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11925 * any interesting requests and then jump to the real instruction
11926 * handler.  Unlike the Arm handler, we can't do this as a tail call
11927 * because rIBASE is caller save and we need to reload it.
11928 *
11929 * Note that unlike in the Arm implementation, we should never arrive
11930 * here with a zero breakFlag because we always refresh rIBASE on
11931 * return.
11932 */
11933    EXPORT_PC
11934    movl   rSELF, %eax
11935    movl   rPC, OUT_ARG0(%esp)
11936    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11937    movl   rFP, OUT_ARG1(%esp)
11938    je     1f                                # reload rIBASE & resume if not
11939    movl   %eax, OUT_ARG2(%esp)
11940    call   dvmCheckBefore                    # (dPC, dFP, self)
11941    movl   rSELF, %eax
119421:
11943    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11944    jmp    *dvmAsmInstructionStart+(136*4)
11945
11946/* ------------------------------ */
11947.L_ALT_OP_FLOAT_TO_DOUBLE: /* 0x89 */
11948/* File: x86/alt_stub.S */
11949/*
11950 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11951 * any interesting requests and then jump to the real instruction
11952 * handler.  Unlike the Arm handler, we can't do this as a tail call
11953 * because rIBASE is caller save and we need to reload it.
11954 *
11955 * Note that unlike in the Arm implementation, we should never arrive
11956 * here with a zero breakFlag because we always refresh rIBASE on
11957 * return.
11958 */
11959    EXPORT_PC
11960    movl   rSELF, %eax
11961    movl   rPC, OUT_ARG0(%esp)
11962    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11963    movl   rFP, OUT_ARG1(%esp)
11964    je     1f                                # reload rIBASE & resume if not
11965    movl   %eax, OUT_ARG2(%esp)
11966    call   dvmCheckBefore                    # (dPC, dFP, self)
11967    movl   rSELF, %eax
119681:
11969    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11970    jmp    *dvmAsmInstructionStart+(137*4)
11971
11972/* ------------------------------ */
11973.L_ALT_OP_DOUBLE_TO_INT: /* 0x8a */
11974/* File: x86/alt_stub.S */
11975/*
11976 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11977 * any interesting requests and then jump to the real instruction
11978 * handler.  Unlike the Arm handler, we can't do this as a tail call
11979 * because rIBASE is caller save and we need to reload it.
11980 *
11981 * Note that unlike in the Arm implementation, we should never arrive
11982 * here with a zero breakFlag because we always refresh rIBASE on
11983 * return.
11984 */
11985    EXPORT_PC
11986    movl   rSELF, %eax
11987    movl   rPC, OUT_ARG0(%esp)
11988    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
11989    movl   rFP, OUT_ARG1(%esp)
11990    je     1f                                # reload rIBASE & resume if not
11991    movl   %eax, OUT_ARG2(%esp)
11992    call   dvmCheckBefore                    # (dPC, dFP, self)
11993    movl   rSELF, %eax
119941:
11995    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
11996    jmp    *dvmAsmInstructionStart+(138*4)
11997
11998/* ------------------------------ */
11999.L_ALT_OP_DOUBLE_TO_LONG: /* 0x8b */
12000/* File: x86/alt_stub.S */
12001/*
12002 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12003 * any interesting requests and then jump to the real instruction
12004 * handler.  Unlike the Arm handler, we can't do this as a tail call
12005 * because rIBASE is caller save and we need to reload it.
12006 *
12007 * Note that unlike in the Arm implementation, we should never arrive
12008 * here with a zero breakFlag because we always refresh rIBASE on
12009 * return.
12010 */
12011    EXPORT_PC
12012    movl   rSELF, %eax
12013    movl   rPC, OUT_ARG0(%esp)
12014    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12015    movl   rFP, OUT_ARG1(%esp)
12016    je     1f                                # reload rIBASE & resume if not
12017    movl   %eax, OUT_ARG2(%esp)
12018    call   dvmCheckBefore                    # (dPC, dFP, self)
12019    movl   rSELF, %eax
120201:
12021    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12022    jmp    *dvmAsmInstructionStart+(139*4)
12023
12024/* ------------------------------ */
12025.L_ALT_OP_DOUBLE_TO_FLOAT: /* 0x8c */
12026/* File: x86/alt_stub.S */
12027/*
12028 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12029 * any interesting requests and then jump to the real instruction
12030 * handler.  Unlike the Arm handler, we can't do this as a tail call
12031 * because rIBASE is caller save and we need to reload it.
12032 *
12033 * Note that unlike in the Arm implementation, we should never arrive
12034 * here with a zero breakFlag because we always refresh rIBASE on
12035 * return.
12036 */
12037    EXPORT_PC
12038    movl   rSELF, %eax
12039    movl   rPC, OUT_ARG0(%esp)
12040    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12041    movl   rFP, OUT_ARG1(%esp)
12042    je     1f                                # reload rIBASE & resume if not
12043    movl   %eax, OUT_ARG2(%esp)
12044    call   dvmCheckBefore                    # (dPC, dFP, self)
12045    movl   rSELF, %eax
120461:
12047    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12048    jmp    *dvmAsmInstructionStart+(140*4)
12049
12050/* ------------------------------ */
12051.L_ALT_OP_INT_TO_BYTE: /* 0x8d */
12052/* File: x86/alt_stub.S */
12053/*
12054 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12055 * any interesting requests and then jump to the real instruction
12056 * handler.  Unlike the Arm handler, we can't do this as a tail call
12057 * because rIBASE is caller save and we need to reload it.
12058 *
12059 * Note that unlike in the Arm implementation, we should never arrive
12060 * here with a zero breakFlag because we always refresh rIBASE on
12061 * return.
12062 */
12063    EXPORT_PC
12064    movl   rSELF, %eax
12065    movl   rPC, OUT_ARG0(%esp)
12066    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12067    movl   rFP, OUT_ARG1(%esp)
12068    je     1f                                # reload rIBASE & resume if not
12069    movl   %eax, OUT_ARG2(%esp)
12070    call   dvmCheckBefore                    # (dPC, dFP, self)
12071    movl   rSELF, %eax
120721:
12073    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12074    jmp    *dvmAsmInstructionStart+(141*4)
12075
12076/* ------------------------------ */
12077.L_ALT_OP_INT_TO_CHAR: /* 0x8e */
12078/* File: x86/alt_stub.S */
12079/*
12080 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12081 * any interesting requests and then jump to the real instruction
12082 * handler.  Unlike the Arm handler, we can't do this as a tail call
12083 * because rIBASE is caller save and we need to reload it.
12084 *
12085 * Note that unlike in the Arm implementation, we should never arrive
12086 * here with a zero breakFlag because we always refresh rIBASE on
12087 * return.
12088 */
12089    EXPORT_PC
12090    movl   rSELF, %eax
12091    movl   rPC, OUT_ARG0(%esp)
12092    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12093    movl   rFP, OUT_ARG1(%esp)
12094    je     1f                                # reload rIBASE & resume if not
12095    movl   %eax, OUT_ARG2(%esp)
12096    call   dvmCheckBefore                    # (dPC, dFP, self)
12097    movl   rSELF, %eax
120981:
12099    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12100    jmp    *dvmAsmInstructionStart+(142*4)
12101
12102/* ------------------------------ */
12103.L_ALT_OP_INT_TO_SHORT: /* 0x8f */
12104/* File: x86/alt_stub.S */
12105/*
12106 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12107 * any interesting requests and then jump to the real instruction
12108 * handler.  Unlike the Arm handler, we can't do this as a tail call
12109 * because rIBASE is caller save and we need to reload it.
12110 *
12111 * Note that unlike in the Arm implementation, we should never arrive
12112 * here with a zero breakFlag because we always refresh rIBASE on
12113 * return.
12114 */
12115    EXPORT_PC
12116    movl   rSELF, %eax
12117    movl   rPC, OUT_ARG0(%esp)
12118    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12119    movl   rFP, OUT_ARG1(%esp)
12120    je     1f                                # reload rIBASE & resume if not
12121    movl   %eax, OUT_ARG2(%esp)
12122    call   dvmCheckBefore                    # (dPC, dFP, self)
12123    movl   rSELF, %eax
121241:
12125    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12126    jmp    *dvmAsmInstructionStart+(143*4)
12127
12128/* ------------------------------ */
12129.L_ALT_OP_ADD_INT: /* 0x90 */
12130/* File: x86/alt_stub.S */
12131/*
12132 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12133 * any interesting requests and then jump to the real instruction
12134 * handler.  Unlike the Arm handler, we can't do this as a tail call
12135 * because rIBASE is caller save and we need to reload it.
12136 *
12137 * Note that unlike in the Arm implementation, we should never arrive
12138 * here with a zero breakFlag because we always refresh rIBASE on
12139 * return.
12140 */
12141    EXPORT_PC
12142    movl   rSELF, %eax
12143    movl   rPC, OUT_ARG0(%esp)
12144    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12145    movl   rFP, OUT_ARG1(%esp)
12146    je     1f                                # reload rIBASE & resume if not
12147    movl   %eax, OUT_ARG2(%esp)
12148    call   dvmCheckBefore                    # (dPC, dFP, self)
12149    movl   rSELF, %eax
121501:
12151    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12152    jmp    *dvmAsmInstructionStart+(144*4)
12153
12154/* ------------------------------ */
12155.L_ALT_OP_SUB_INT: /* 0x91 */
12156/* File: x86/alt_stub.S */
12157/*
12158 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12159 * any interesting requests and then jump to the real instruction
12160 * handler.  Unlike the Arm handler, we can't do this as a tail call
12161 * because rIBASE is caller save and we need to reload it.
12162 *
12163 * Note that unlike in the Arm implementation, we should never arrive
12164 * here with a zero breakFlag because we always refresh rIBASE on
12165 * return.
12166 */
12167    EXPORT_PC
12168    movl   rSELF, %eax
12169    movl   rPC, OUT_ARG0(%esp)
12170    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12171    movl   rFP, OUT_ARG1(%esp)
12172    je     1f                                # reload rIBASE & resume if not
12173    movl   %eax, OUT_ARG2(%esp)
12174    call   dvmCheckBefore                    # (dPC, dFP, self)
12175    movl   rSELF, %eax
121761:
12177    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12178    jmp    *dvmAsmInstructionStart+(145*4)
12179
12180/* ------------------------------ */
12181.L_ALT_OP_MUL_INT: /* 0x92 */
12182/* File: x86/alt_stub.S */
12183/*
12184 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12185 * any interesting requests and then jump to the real instruction
12186 * handler.  Unlike the Arm handler, we can't do this as a tail call
12187 * because rIBASE is caller save and we need to reload it.
12188 *
12189 * Note that unlike in the Arm implementation, we should never arrive
12190 * here with a zero breakFlag because we always refresh rIBASE on
12191 * return.
12192 */
12193    EXPORT_PC
12194    movl   rSELF, %eax
12195    movl   rPC, OUT_ARG0(%esp)
12196    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12197    movl   rFP, OUT_ARG1(%esp)
12198    je     1f                                # reload rIBASE & resume if not
12199    movl   %eax, OUT_ARG2(%esp)
12200    call   dvmCheckBefore                    # (dPC, dFP, self)
12201    movl   rSELF, %eax
122021:
12203    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12204    jmp    *dvmAsmInstructionStart+(146*4)
12205
12206/* ------------------------------ */
12207.L_ALT_OP_DIV_INT: /* 0x93 */
12208/* File: x86/alt_stub.S */
12209/*
12210 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12211 * any interesting requests and then jump to the real instruction
12212 * handler.  Unlike the Arm handler, we can't do this as a tail call
12213 * because rIBASE is caller save and we need to reload it.
12214 *
12215 * Note that unlike in the Arm implementation, we should never arrive
12216 * here with a zero breakFlag because we always refresh rIBASE on
12217 * return.
12218 */
12219    EXPORT_PC
12220    movl   rSELF, %eax
12221    movl   rPC, OUT_ARG0(%esp)
12222    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12223    movl   rFP, OUT_ARG1(%esp)
12224    je     1f                                # reload rIBASE & resume if not
12225    movl   %eax, OUT_ARG2(%esp)
12226    call   dvmCheckBefore                    # (dPC, dFP, self)
12227    movl   rSELF, %eax
122281:
12229    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12230    jmp    *dvmAsmInstructionStart+(147*4)
12231
12232/* ------------------------------ */
12233.L_ALT_OP_REM_INT: /* 0x94 */
12234/* File: x86/alt_stub.S */
12235/*
12236 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12237 * any interesting requests and then jump to the real instruction
12238 * handler.  Unlike the Arm handler, we can't do this as a tail call
12239 * because rIBASE is caller save and we need to reload it.
12240 *
12241 * Note that unlike in the Arm implementation, we should never arrive
12242 * here with a zero breakFlag because we always refresh rIBASE on
12243 * return.
12244 */
12245    EXPORT_PC
12246    movl   rSELF, %eax
12247    movl   rPC, OUT_ARG0(%esp)
12248    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12249    movl   rFP, OUT_ARG1(%esp)
12250    je     1f                                # reload rIBASE & resume if not
12251    movl   %eax, OUT_ARG2(%esp)
12252    call   dvmCheckBefore                    # (dPC, dFP, self)
12253    movl   rSELF, %eax
122541:
12255    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12256    jmp    *dvmAsmInstructionStart+(148*4)
12257
12258/* ------------------------------ */
12259.L_ALT_OP_AND_INT: /* 0x95 */
12260/* File: x86/alt_stub.S */
12261/*
12262 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12263 * any interesting requests and then jump to the real instruction
12264 * handler.  Unlike the Arm handler, we can't do this as a tail call
12265 * because rIBASE is caller save and we need to reload it.
12266 *
12267 * Note that unlike in the Arm implementation, we should never arrive
12268 * here with a zero breakFlag because we always refresh rIBASE on
12269 * return.
12270 */
12271    EXPORT_PC
12272    movl   rSELF, %eax
12273    movl   rPC, OUT_ARG0(%esp)
12274    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12275    movl   rFP, OUT_ARG1(%esp)
12276    je     1f                                # reload rIBASE & resume if not
12277    movl   %eax, OUT_ARG2(%esp)
12278    call   dvmCheckBefore                    # (dPC, dFP, self)
12279    movl   rSELF, %eax
122801:
12281    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12282    jmp    *dvmAsmInstructionStart+(149*4)
12283
12284/* ------------------------------ */
12285.L_ALT_OP_OR_INT: /* 0x96 */
12286/* File: x86/alt_stub.S */
12287/*
12288 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12289 * any interesting requests and then jump to the real instruction
12290 * handler.  Unlike the Arm handler, we can't do this as a tail call
12291 * because rIBASE is caller save and we need to reload it.
12292 *
12293 * Note that unlike in the Arm implementation, we should never arrive
12294 * here with a zero breakFlag because we always refresh rIBASE on
12295 * return.
12296 */
12297    EXPORT_PC
12298    movl   rSELF, %eax
12299    movl   rPC, OUT_ARG0(%esp)
12300    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12301    movl   rFP, OUT_ARG1(%esp)
12302    je     1f                                # reload rIBASE & resume if not
12303    movl   %eax, OUT_ARG2(%esp)
12304    call   dvmCheckBefore                    # (dPC, dFP, self)
12305    movl   rSELF, %eax
123061:
12307    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12308    jmp    *dvmAsmInstructionStart+(150*4)
12309
12310/* ------------------------------ */
12311.L_ALT_OP_XOR_INT: /* 0x97 */
12312/* File: x86/alt_stub.S */
12313/*
12314 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12315 * any interesting requests and then jump to the real instruction
12316 * handler.  Unlike the Arm handler, we can't do this as a tail call
12317 * because rIBASE is caller save and we need to reload it.
12318 *
12319 * Note that unlike in the Arm implementation, we should never arrive
12320 * here with a zero breakFlag because we always refresh rIBASE on
12321 * return.
12322 */
12323    EXPORT_PC
12324    movl   rSELF, %eax
12325    movl   rPC, OUT_ARG0(%esp)
12326    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12327    movl   rFP, OUT_ARG1(%esp)
12328    je     1f                                # reload rIBASE & resume if not
12329    movl   %eax, OUT_ARG2(%esp)
12330    call   dvmCheckBefore                    # (dPC, dFP, self)
12331    movl   rSELF, %eax
123321:
12333    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12334    jmp    *dvmAsmInstructionStart+(151*4)
12335
12336/* ------------------------------ */
12337.L_ALT_OP_SHL_INT: /* 0x98 */
12338/* File: x86/alt_stub.S */
12339/*
12340 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12341 * any interesting requests and then jump to the real instruction
12342 * handler.  Unlike the Arm handler, we can't do this as a tail call
12343 * because rIBASE is caller save and we need to reload it.
12344 *
12345 * Note that unlike in the Arm implementation, we should never arrive
12346 * here with a zero breakFlag because we always refresh rIBASE on
12347 * return.
12348 */
12349    EXPORT_PC
12350    movl   rSELF, %eax
12351    movl   rPC, OUT_ARG0(%esp)
12352    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12353    movl   rFP, OUT_ARG1(%esp)
12354    je     1f                                # reload rIBASE & resume if not
12355    movl   %eax, OUT_ARG2(%esp)
12356    call   dvmCheckBefore                    # (dPC, dFP, self)
12357    movl   rSELF, %eax
123581:
12359    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12360    jmp    *dvmAsmInstructionStart+(152*4)
12361
12362/* ------------------------------ */
12363.L_ALT_OP_SHR_INT: /* 0x99 */
12364/* File: x86/alt_stub.S */
12365/*
12366 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12367 * any interesting requests and then jump to the real instruction
12368 * handler.  Unlike the Arm handler, we can't do this as a tail call
12369 * because rIBASE is caller save and we need to reload it.
12370 *
12371 * Note that unlike in the Arm implementation, we should never arrive
12372 * here with a zero breakFlag because we always refresh rIBASE on
12373 * return.
12374 */
12375    EXPORT_PC
12376    movl   rSELF, %eax
12377    movl   rPC, OUT_ARG0(%esp)
12378    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12379    movl   rFP, OUT_ARG1(%esp)
12380    je     1f                                # reload rIBASE & resume if not
12381    movl   %eax, OUT_ARG2(%esp)
12382    call   dvmCheckBefore                    # (dPC, dFP, self)
12383    movl   rSELF, %eax
123841:
12385    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12386    jmp    *dvmAsmInstructionStart+(153*4)
12387
12388/* ------------------------------ */
12389.L_ALT_OP_USHR_INT: /* 0x9a */
12390/* File: x86/alt_stub.S */
12391/*
12392 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12393 * any interesting requests and then jump to the real instruction
12394 * handler.  Unlike the Arm handler, we can't do this as a tail call
12395 * because rIBASE is caller save and we need to reload it.
12396 *
12397 * Note that unlike in the Arm implementation, we should never arrive
12398 * here with a zero breakFlag because we always refresh rIBASE on
12399 * return.
12400 */
12401    EXPORT_PC
12402    movl   rSELF, %eax
12403    movl   rPC, OUT_ARG0(%esp)
12404    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12405    movl   rFP, OUT_ARG1(%esp)
12406    je     1f                                # reload rIBASE & resume if not
12407    movl   %eax, OUT_ARG2(%esp)
12408    call   dvmCheckBefore                    # (dPC, dFP, self)
12409    movl   rSELF, %eax
124101:
12411    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12412    jmp    *dvmAsmInstructionStart+(154*4)
12413
12414/* ------------------------------ */
12415.L_ALT_OP_ADD_LONG: /* 0x9b */
12416/* File: x86/alt_stub.S */
12417/*
12418 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12419 * any interesting requests and then jump to the real instruction
12420 * handler.  Unlike the Arm handler, we can't do this as a tail call
12421 * because rIBASE is caller save and we need to reload it.
12422 *
12423 * Note that unlike in the Arm implementation, we should never arrive
12424 * here with a zero breakFlag because we always refresh rIBASE on
12425 * return.
12426 */
12427    EXPORT_PC
12428    movl   rSELF, %eax
12429    movl   rPC, OUT_ARG0(%esp)
12430    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12431    movl   rFP, OUT_ARG1(%esp)
12432    je     1f                                # reload rIBASE & resume if not
12433    movl   %eax, OUT_ARG2(%esp)
12434    call   dvmCheckBefore                    # (dPC, dFP, self)
12435    movl   rSELF, %eax
124361:
12437    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12438    jmp    *dvmAsmInstructionStart+(155*4)
12439
12440/* ------------------------------ */
12441.L_ALT_OP_SUB_LONG: /* 0x9c */
12442/* File: x86/alt_stub.S */
12443/*
12444 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12445 * any interesting requests and then jump to the real instruction
12446 * handler.  Unlike the Arm handler, we can't do this as a tail call
12447 * because rIBASE is caller save and we need to reload it.
12448 *
12449 * Note that unlike in the Arm implementation, we should never arrive
12450 * here with a zero breakFlag because we always refresh rIBASE on
12451 * return.
12452 */
12453    EXPORT_PC
12454    movl   rSELF, %eax
12455    movl   rPC, OUT_ARG0(%esp)
12456    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12457    movl   rFP, OUT_ARG1(%esp)
12458    je     1f                                # reload rIBASE & resume if not
12459    movl   %eax, OUT_ARG2(%esp)
12460    call   dvmCheckBefore                    # (dPC, dFP, self)
12461    movl   rSELF, %eax
124621:
12463    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12464    jmp    *dvmAsmInstructionStart+(156*4)
12465
12466/* ------------------------------ */
12467.L_ALT_OP_MUL_LONG: /* 0x9d */
12468/* File: x86/alt_stub.S */
12469/*
12470 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12471 * any interesting requests and then jump to the real instruction
12472 * handler.  Unlike the Arm handler, we can't do this as a tail call
12473 * because rIBASE is caller save and we need to reload it.
12474 *
12475 * Note that unlike in the Arm implementation, we should never arrive
12476 * here with a zero breakFlag because we always refresh rIBASE on
12477 * return.
12478 */
12479    EXPORT_PC
12480    movl   rSELF, %eax
12481    movl   rPC, OUT_ARG0(%esp)
12482    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12483    movl   rFP, OUT_ARG1(%esp)
12484    je     1f                                # reload rIBASE & resume if not
12485    movl   %eax, OUT_ARG2(%esp)
12486    call   dvmCheckBefore                    # (dPC, dFP, self)
12487    movl   rSELF, %eax
124881:
12489    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12490    jmp    *dvmAsmInstructionStart+(157*4)
12491
12492/* ------------------------------ */
12493.L_ALT_OP_DIV_LONG: /* 0x9e */
12494/* File: x86/alt_stub.S */
12495/*
12496 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12497 * any interesting requests and then jump to the real instruction
12498 * handler.  Unlike the Arm handler, we can't do this as a tail call
12499 * because rIBASE is caller save and we need to reload it.
12500 *
12501 * Note that unlike in the Arm implementation, we should never arrive
12502 * here with a zero breakFlag because we always refresh rIBASE on
12503 * return.
12504 */
12505    EXPORT_PC
12506    movl   rSELF, %eax
12507    movl   rPC, OUT_ARG0(%esp)
12508    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12509    movl   rFP, OUT_ARG1(%esp)
12510    je     1f                                # reload rIBASE & resume if not
12511    movl   %eax, OUT_ARG2(%esp)
12512    call   dvmCheckBefore                    # (dPC, dFP, self)
12513    movl   rSELF, %eax
125141:
12515    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12516    jmp    *dvmAsmInstructionStart+(158*4)
12517
12518/* ------------------------------ */
12519.L_ALT_OP_REM_LONG: /* 0x9f */
12520/* File: x86/alt_stub.S */
12521/*
12522 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12523 * any interesting requests and then jump to the real instruction
12524 * handler.  Unlike the Arm handler, we can't do this as a tail call
12525 * because rIBASE is caller save and we need to reload it.
12526 *
12527 * Note that unlike in the Arm implementation, we should never arrive
12528 * here with a zero breakFlag because we always refresh rIBASE on
12529 * return.
12530 */
12531    EXPORT_PC
12532    movl   rSELF, %eax
12533    movl   rPC, OUT_ARG0(%esp)
12534    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12535    movl   rFP, OUT_ARG1(%esp)
12536    je     1f                                # reload rIBASE & resume if not
12537    movl   %eax, OUT_ARG2(%esp)
12538    call   dvmCheckBefore                    # (dPC, dFP, self)
12539    movl   rSELF, %eax
125401:
12541    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12542    jmp    *dvmAsmInstructionStart+(159*4)
12543
12544/* ------------------------------ */
12545.L_ALT_OP_AND_LONG: /* 0xa0 */
12546/* File: x86/alt_stub.S */
12547/*
12548 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12549 * any interesting requests and then jump to the real instruction
12550 * handler.  Unlike the Arm handler, we can't do this as a tail call
12551 * because rIBASE is caller save and we need to reload it.
12552 *
12553 * Note that unlike in the Arm implementation, we should never arrive
12554 * here with a zero breakFlag because we always refresh rIBASE on
12555 * return.
12556 */
12557    EXPORT_PC
12558    movl   rSELF, %eax
12559    movl   rPC, OUT_ARG0(%esp)
12560    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12561    movl   rFP, OUT_ARG1(%esp)
12562    je     1f                                # reload rIBASE & resume if not
12563    movl   %eax, OUT_ARG2(%esp)
12564    call   dvmCheckBefore                    # (dPC, dFP, self)
12565    movl   rSELF, %eax
125661:
12567    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12568    jmp    *dvmAsmInstructionStart+(160*4)
12569
12570/* ------------------------------ */
12571.L_ALT_OP_OR_LONG: /* 0xa1 */
12572/* File: x86/alt_stub.S */
12573/*
12574 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12575 * any interesting requests and then jump to the real instruction
12576 * handler.  Unlike the Arm handler, we can't do this as a tail call
12577 * because rIBASE is caller save and we need to reload it.
12578 *
12579 * Note that unlike in the Arm implementation, we should never arrive
12580 * here with a zero breakFlag because we always refresh rIBASE on
12581 * return.
12582 */
12583    EXPORT_PC
12584    movl   rSELF, %eax
12585    movl   rPC, OUT_ARG0(%esp)
12586    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12587    movl   rFP, OUT_ARG1(%esp)
12588    je     1f                                # reload rIBASE & resume if not
12589    movl   %eax, OUT_ARG2(%esp)
12590    call   dvmCheckBefore                    # (dPC, dFP, self)
12591    movl   rSELF, %eax
125921:
12593    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12594    jmp    *dvmAsmInstructionStart+(161*4)
12595
12596/* ------------------------------ */
12597.L_ALT_OP_XOR_LONG: /* 0xa2 */
12598/* File: x86/alt_stub.S */
12599/*
12600 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12601 * any interesting requests and then jump to the real instruction
12602 * handler.  Unlike the Arm handler, we can't do this as a tail call
12603 * because rIBASE is caller save and we need to reload it.
12604 *
12605 * Note that unlike in the Arm implementation, we should never arrive
12606 * here with a zero breakFlag because we always refresh rIBASE on
12607 * return.
12608 */
12609    EXPORT_PC
12610    movl   rSELF, %eax
12611    movl   rPC, OUT_ARG0(%esp)
12612    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12613    movl   rFP, OUT_ARG1(%esp)
12614    je     1f                                # reload rIBASE & resume if not
12615    movl   %eax, OUT_ARG2(%esp)
12616    call   dvmCheckBefore                    # (dPC, dFP, self)
12617    movl   rSELF, %eax
126181:
12619    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12620    jmp    *dvmAsmInstructionStart+(162*4)
12621
12622/* ------------------------------ */
12623.L_ALT_OP_SHL_LONG: /* 0xa3 */
12624/* File: x86/alt_stub.S */
12625/*
12626 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12627 * any interesting requests and then jump to the real instruction
12628 * handler.  Unlike the Arm handler, we can't do this as a tail call
12629 * because rIBASE is caller save and we need to reload it.
12630 *
12631 * Note that unlike in the Arm implementation, we should never arrive
12632 * here with a zero breakFlag because we always refresh rIBASE on
12633 * return.
12634 */
12635    EXPORT_PC
12636    movl   rSELF, %eax
12637    movl   rPC, OUT_ARG0(%esp)
12638    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12639    movl   rFP, OUT_ARG1(%esp)
12640    je     1f                                # reload rIBASE & resume if not
12641    movl   %eax, OUT_ARG2(%esp)
12642    call   dvmCheckBefore                    # (dPC, dFP, self)
12643    movl   rSELF, %eax
126441:
12645    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12646    jmp    *dvmAsmInstructionStart+(163*4)
12647
12648/* ------------------------------ */
12649.L_ALT_OP_SHR_LONG: /* 0xa4 */
12650/* File: x86/alt_stub.S */
12651/*
12652 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12653 * any interesting requests and then jump to the real instruction
12654 * handler.  Unlike the Arm handler, we can't do this as a tail call
12655 * because rIBASE is caller save and we need to reload it.
12656 *
12657 * Note that unlike in the Arm implementation, we should never arrive
12658 * here with a zero breakFlag because we always refresh rIBASE on
12659 * return.
12660 */
12661    EXPORT_PC
12662    movl   rSELF, %eax
12663    movl   rPC, OUT_ARG0(%esp)
12664    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12665    movl   rFP, OUT_ARG1(%esp)
12666    je     1f                                # reload rIBASE & resume if not
12667    movl   %eax, OUT_ARG2(%esp)
12668    call   dvmCheckBefore                    # (dPC, dFP, self)
12669    movl   rSELF, %eax
126701:
12671    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12672    jmp    *dvmAsmInstructionStart+(164*4)
12673
12674/* ------------------------------ */
12675.L_ALT_OP_USHR_LONG: /* 0xa5 */
12676/* File: x86/alt_stub.S */
12677/*
12678 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12679 * any interesting requests and then jump to the real instruction
12680 * handler.  Unlike the Arm handler, we can't do this as a tail call
12681 * because rIBASE is caller save and we need to reload it.
12682 *
12683 * Note that unlike in the Arm implementation, we should never arrive
12684 * here with a zero breakFlag because we always refresh rIBASE on
12685 * return.
12686 */
12687    EXPORT_PC
12688    movl   rSELF, %eax
12689    movl   rPC, OUT_ARG0(%esp)
12690    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12691    movl   rFP, OUT_ARG1(%esp)
12692    je     1f                                # reload rIBASE & resume if not
12693    movl   %eax, OUT_ARG2(%esp)
12694    call   dvmCheckBefore                    # (dPC, dFP, self)
12695    movl   rSELF, %eax
126961:
12697    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12698    jmp    *dvmAsmInstructionStart+(165*4)
12699
12700/* ------------------------------ */
12701.L_ALT_OP_ADD_FLOAT: /* 0xa6 */
12702/* File: x86/alt_stub.S */
12703/*
12704 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12705 * any interesting requests and then jump to the real instruction
12706 * handler.  Unlike the Arm handler, we can't do this as a tail call
12707 * because rIBASE is caller save and we need to reload it.
12708 *
12709 * Note that unlike in the Arm implementation, we should never arrive
12710 * here with a zero breakFlag because we always refresh rIBASE on
12711 * return.
12712 */
12713    EXPORT_PC
12714    movl   rSELF, %eax
12715    movl   rPC, OUT_ARG0(%esp)
12716    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12717    movl   rFP, OUT_ARG1(%esp)
12718    je     1f                                # reload rIBASE & resume if not
12719    movl   %eax, OUT_ARG2(%esp)
12720    call   dvmCheckBefore                    # (dPC, dFP, self)
12721    movl   rSELF, %eax
127221:
12723    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12724    jmp    *dvmAsmInstructionStart+(166*4)
12725
12726/* ------------------------------ */
12727.L_ALT_OP_SUB_FLOAT: /* 0xa7 */
12728/* File: x86/alt_stub.S */
12729/*
12730 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12731 * any interesting requests and then jump to the real instruction
12732 * handler.  Unlike the Arm handler, we can't do this as a tail call
12733 * because rIBASE is caller save and we need to reload it.
12734 *
12735 * Note that unlike in the Arm implementation, we should never arrive
12736 * here with a zero breakFlag because we always refresh rIBASE on
12737 * return.
12738 */
12739    EXPORT_PC
12740    movl   rSELF, %eax
12741    movl   rPC, OUT_ARG0(%esp)
12742    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12743    movl   rFP, OUT_ARG1(%esp)
12744    je     1f                                # reload rIBASE & resume if not
12745    movl   %eax, OUT_ARG2(%esp)
12746    call   dvmCheckBefore                    # (dPC, dFP, self)
12747    movl   rSELF, %eax
127481:
12749    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12750    jmp    *dvmAsmInstructionStart+(167*4)
12751
12752/* ------------------------------ */
12753.L_ALT_OP_MUL_FLOAT: /* 0xa8 */
12754/* File: x86/alt_stub.S */
12755/*
12756 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12757 * any interesting requests and then jump to the real instruction
12758 * handler.  Unlike the Arm handler, we can't do this as a tail call
12759 * because rIBASE is caller save and we need to reload it.
12760 *
12761 * Note that unlike in the Arm implementation, we should never arrive
12762 * here with a zero breakFlag because we always refresh rIBASE on
12763 * return.
12764 */
12765    EXPORT_PC
12766    movl   rSELF, %eax
12767    movl   rPC, OUT_ARG0(%esp)
12768    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12769    movl   rFP, OUT_ARG1(%esp)
12770    je     1f                                # reload rIBASE & resume if not
12771    movl   %eax, OUT_ARG2(%esp)
12772    call   dvmCheckBefore                    # (dPC, dFP, self)
12773    movl   rSELF, %eax
127741:
12775    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12776    jmp    *dvmAsmInstructionStart+(168*4)
12777
12778/* ------------------------------ */
12779.L_ALT_OP_DIV_FLOAT: /* 0xa9 */
12780/* File: x86/alt_stub.S */
12781/*
12782 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12783 * any interesting requests and then jump to the real instruction
12784 * handler.  Unlike the Arm handler, we can't do this as a tail call
12785 * because rIBASE is caller save and we need to reload it.
12786 *
12787 * Note that unlike in the Arm implementation, we should never arrive
12788 * here with a zero breakFlag because we always refresh rIBASE on
12789 * return.
12790 */
12791    EXPORT_PC
12792    movl   rSELF, %eax
12793    movl   rPC, OUT_ARG0(%esp)
12794    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12795    movl   rFP, OUT_ARG1(%esp)
12796    je     1f                                # reload rIBASE & resume if not
12797    movl   %eax, OUT_ARG2(%esp)
12798    call   dvmCheckBefore                    # (dPC, dFP, self)
12799    movl   rSELF, %eax
128001:
12801    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12802    jmp    *dvmAsmInstructionStart+(169*4)
12803
12804/* ------------------------------ */
12805.L_ALT_OP_REM_FLOAT: /* 0xaa */
12806/* File: x86/alt_stub.S */
12807/*
12808 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12809 * any interesting requests and then jump to the real instruction
12810 * handler.  Unlike the Arm handler, we can't do this as a tail call
12811 * because rIBASE is caller save and we need to reload it.
12812 *
12813 * Note that unlike in the Arm implementation, we should never arrive
12814 * here with a zero breakFlag because we always refresh rIBASE on
12815 * return.
12816 */
12817    EXPORT_PC
12818    movl   rSELF, %eax
12819    movl   rPC, OUT_ARG0(%esp)
12820    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12821    movl   rFP, OUT_ARG1(%esp)
12822    je     1f                                # reload rIBASE & resume if not
12823    movl   %eax, OUT_ARG2(%esp)
12824    call   dvmCheckBefore                    # (dPC, dFP, self)
12825    movl   rSELF, %eax
128261:
12827    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12828    jmp    *dvmAsmInstructionStart+(170*4)
12829
12830/* ------------------------------ */
12831.L_ALT_OP_ADD_DOUBLE: /* 0xab */
12832/* File: x86/alt_stub.S */
12833/*
12834 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12835 * any interesting requests and then jump to the real instruction
12836 * handler.  Unlike the Arm handler, we can't do this as a tail call
12837 * because rIBASE is caller save and we need to reload it.
12838 *
12839 * Note that unlike in the Arm implementation, we should never arrive
12840 * here with a zero breakFlag because we always refresh rIBASE on
12841 * return.
12842 */
12843    EXPORT_PC
12844    movl   rSELF, %eax
12845    movl   rPC, OUT_ARG0(%esp)
12846    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12847    movl   rFP, OUT_ARG1(%esp)
12848    je     1f                                # reload rIBASE & resume if not
12849    movl   %eax, OUT_ARG2(%esp)
12850    call   dvmCheckBefore                    # (dPC, dFP, self)
12851    movl   rSELF, %eax
128521:
12853    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12854    jmp    *dvmAsmInstructionStart+(171*4)
12855
12856/* ------------------------------ */
12857.L_ALT_OP_SUB_DOUBLE: /* 0xac */
12858/* File: x86/alt_stub.S */
12859/*
12860 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12861 * any interesting requests and then jump to the real instruction
12862 * handler.  Unlike the Arm handler, we can't do this as a tail call
12863 * because rIBASE is caller save and we need to reload it.
12864 *
12865 * Note that unlike in the Arm implementation, we should never arrive
12866 * here with a zero breakFlag because we always refresh rIBASE on
12867 * return.
12868 */
12869    EXPORT_PC
12870    movl   rSELF, %eax
12871    movl   rPC, OUT_ARG0(%esp)
12872    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12873    movl   rFP, OUT_ARG1(%esp)
12874    je     1f                                # reload rIBASE & resume if not
12875    movl   %eax, OUT_ARG2(%esp)
12876    call   dvmCheckBefore                    # (dPC, dFP, self)
12877    movl   rSELF, %eax
128781:
12879    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12880    jmp    *dvmAsmInstructionStart+(172*4)
12881
12882/* ------------------------------ */
12883.L_ALT_OP_MUL_DOUBLE: /* 0xad */
12884/* File: x86/alt_stub.S */
12885/*
12886 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12887 * any interesting requests and then jump to the real instruction
12888 * handler.  Unlike the Arm handler, we can't do this as a tail call
12889 * because rIBASE is caller save and we need to reload it.
12890 *
12891 * Note that unlike in the Arm implementation, we should never arrive
12892 * here with a zero breakFlag because we always refresh rIBASE on
12893 * return.
12894 */
12895    EXPORT_PC
12896    movl   rSELF, %eax
12897    movl   rPC, OUT_ARG0(%esp)
12898    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12899    movl   rFP, OUT_ARG1(%esp)
12900    je     1f                                # reload rIBASE & resume if not
12901    movl   %eax, OUT_ARG2(%esp)
12902    call   dvmCheckBefore                    # (dPC, dFP, self)
12903    movl   rSELF, %eax
129041:
12905    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12906    jmp    *dvmAsmInstructionStart+(173*4)
12907
12908/* ------------------------------ */
12909.L_ALT_OP_DIV_DOUBLE: /* 0xae */
12910/* File: x86/alt_stub.S */
12911/*
12912 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12913 * any interesting requests and then jump to the real instruction
12914 * handler.  Unlike the Arm handler, we can't do this as a tail call
12915 * because rIBASE is caller save and we need to reload it.
12916 *
12917 * Note that unlike in the Arm implementation, we should never arrive
12918 * here with a zero breakFlag because we always refresh rIBASE on
12919 * return.
12920 */
12921    EXPORT_PC
12922    movl   rSELF, %eax
12923    movl   rPC, OUT_ARG0(%esp)
12924    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12925    movl   rFP, OUT_ARG1(%esp)
12926    je     1f                                # reload rIBASE & resume if not
12927    movl   %eax, OUT_ARG2(%esp)
12928    call   dvmCheckBefore                    # (dPC, dFP, self)
12929    movl   rSELF, %eax
129301:
12931    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12932    jmp    *dvmAsmInstructionStart+(174*4)
12933
12934/* ------------------------------ */
12935.L_ALT_OP_REM_DOUBLE: /* 0xaf */
12936/* File: x86/alt_stub.S */
12937/*
12938 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12939 * any interesting requests and then jump to the real instruction
12940 * handler.  Unlike the Arm handler, we can't do this as a tail call
12941 * because rIBASE is caller save and we need to reload it.
12942 *
12943 * Note that unlike in the Arm implementation, we should never arrive
12944 * here with a zero breakFlag because we always refresh rIBASE on
12945 * return.
12946 */
12947    EXPORT_PC
12948    movl   rSELF, %eax
12949    movl   rPC, OUT_ARG0(%esp)
12950    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12951    movl   rFP, OUT_ARG1(%esp)
12952    je     1f                                # reload rIBASE & resume if not
12953    movl   %eax, OUT_ARG2(%esp)
12954    call   dvmCheckBefore                    # (dPC, dFP, self)
12955    movl   rSELF, %eax
129561:
12957    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12958    jmp    *dvmAsmInstructionStart+(175*4)
12959
12960/* ------------------------------ */
12961.L_ALT_OP_ADD_INT_2ADDR: /* 0xb0 */
12962/* File: x86/alt_stub.S */
12963/*
12964 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12965 * any interesting requests and then jump to the real instruction
12966 * handler.  Unlike the Arm handler, we can't do this as a tail call
12967 * because rIBASE is caller save and we need to reload it.
12968 *
12969 * Note that unlike in the Arm implementation, we should never arrive
12970 * here with a zero breakFlag because we always refresh rIBASE on
12971 * return.
12972 */
12973    EXPORT_PC
12974    movl   rSELF, %eax
12975    movl   rPC, OUT_ARG0(%esp)
12976    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
12977    movl   rFP, OUT_ARG1(%esp)
12978    je     1f                                # reload rIBASE & resume if not
12979    movl   %eax, OUT_ARG2(%esp)
12980    call   dvmCheckBefore                    # (dPC, dFP, self)
12981    movl   rSELF, %eax
129821:
12983    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
12984    jmp    *dvmAsmInstructionStart+(176*4)
12985
12986/* ------------------------------ */
12987.L_ALT_OP_SUB_INT_2ADDR: /* 0xb1 */
12988/* File: x86/alt_stub.S */
12989/*
12990 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12991 * any interesting requests and then jump to the real instruction
12992 * handler.  Unlike the Arm handler, we can't do this as a tail call
12993 * because rIBASE is caller save and we need to reload it.
12994 *
12995 * Note that unlike in the Arm implementation, we should never arrive
12996 * here with a zero breakFlag because we always refresh rIBASE on
12997 * return.
12998 */
12999    EXPORT_PC
13000    movl   rSELF, %eax
13001    movl   rPC, OUT_ARG0(%esp)
13002    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13003    movl   rFP, OUT_ARG1(%esp)
13004    je     1f                                # reload rIBASE & resume if not
13005    movl   %eax, OUT_ARG2(%esp)
13006    call   dvmCheckBefore                    # (dPC, dFP, self)
13007    movl   rSELF, %eax
130081:
13009    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13010    jmp    *dvmAsmInstructionStart+(177*4)
13011
13012/* ------------------------------ */
13013.L_ALT_OP_MUL_INT_2ADDR: /* 0xb2 */
13014/* File: x86/alt_stub.S */
13015/*
13016 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13017 * any interesting requests and then jump to the real instruction
13018 * handler.  Unlike the Arm handler, we can't do this as a tail call
13019 * because rIBASE is caller save and we need to reload it.
13020 *
13021 * Note that unlike in the Arm implementation, we should never arrive
13022 * here with a zero breakFlag because we always refresh rIBASE on
13023 * return.
13024 */
13025    EXPORT_PC
13026    movl   rSELF, %eax
13027    movl   rPC, OUT_ARG0(%esp)
13028    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13029    movl   rFP, OUT_ARG1(%esp)
13030    je     1f                                # reload rIBASE & resume if not
13031    movl   %eax, OUT_ARG2(%esp)
13032    call   dvmCheckBefore                    # (dPC, dFP, self)
13033    movl   rSELF, %eax
130341:
13035    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13036    jmp    *dvmAsmInstructionStart+(178*4)
13037
13038/* ------------------------------ */
13039.L_ALT_OP_DIV_INT_2ADDR: /* 0xb3 */
13040/* File: x86/alt_stub.S */
13041/*
13042 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13043 * any interesting requests and then jump to the real instruction
13044 * handler.  Unlike the Arm handler, we can't do this as a tail call
13045 * because rIBASE is caller save and we need to reload it.
13046 *
13047 * Note that unlike in the Arm implementation, we should never arrive
13048 * here with a zero breakFlag because we always refresh rIBASE on
13049 * return.
13050 */
13051    EXPORT_PC
13052    movl   rSELF, %eax
13053    movl   rPC, OUT_ARG0(%esp)
13054    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13055    movl   rFP, OUT_ARG1(%esp)
13056    je     1f                                # reload rIBASE & resume if not
13057    movl   %eax, OUT_ARG2(%esp)
13058    call   dvmCheckBefore                    # (dPC, dFP, self)
13059    movl   rSELF, %eax
130601:
13061    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13062    jmp    *dvmAsmInstructionStart+(179*4)
13063
13064/* ------------------------------ */
13065.L_ALT_OP_REM_INT_2ADDR: /* 0xb4 */
13066/* File: x86/alt_stub.S */
13067/*
13068 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13069 * any interesting requests and then jump to the real instruction
13070 * handler.  Unlike the Arm handler, we can't do this as a tail call
13071 * because rIBASE is caller save and we need to reload it.
13072 *
13073 * Note that unlike in the Arm implementation, we should never arrive
13074 * here with a zero breakFlag because we always refresh rIBASE on
13075 * return.
13076 */
13077    EXPORT_PC
13078    movl   rSELF, %eax
13079    movl   rPC, OUT_ARG0(%esp)
13080    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13081    movl   rFP, OUT_ARG1(%esp)
13082    je     1f                                # reload rIBASE & resume if not
13083    movl   %eax, OUT_ARG2(%esp)
13084    call   dvmCheckBefore                    # (dPC, dFP, self)
13085    movl   rSELF, %eax
130861:
13087    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13088    jmp    *dvmAsmInstructionStart+(180*4)
13089
13090/* ------------------------------ */
13091.L_ALT_OP_AND_INT_2ADDR: /* 0xb5 */
13092/* File: x86/alt_stub.S */
13093/*
13094 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13095 * any interesting requests and then jump to the real instruction
13096 * handler.  Unlike the Arm handler, we can't do this as a tail call
13097 * because rIBASE is caller save and we need to reload it.
13098 *
13099 * Note that unlike in the Arm implementation, we should never arrive
13100 * here with a zero breakFlag because we always refresh rIBASE on
13101 * return.
13102 */
13103    EXPORT_PC
13104    movl   rSELF, %eax
13105    movl   rPC, OUT_ARG0(%esp)
13106    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13107    movl   rFP, OUT_ARG1(%esp)
13108    je     1f                                # reload rIBASE & resume if not
13109    movl   %eax, OUT_ARG2(%esp)
13110    call   dvmCheckBefore                    # (dPC, dFP, self)
13111    movl   rSELF, %eax
131121:
13113    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13114    jmp    *dvmAsmInstructionStart+(181*4)
13115
13116/* ------------------------------ */
13117.L_ALT_OP_OR_INT_2ADDR: /* 0xb6 */
13118/* File: x86/alt_stub.S */
13119/*
13120 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13121 * any interesting requests and then jump to the real instruction
13122 * handler.  Unlike the Arm handler, we can't do this as a tail call
13123 * because rIBASE is caller save and we need to reload it.
13124 *
13125 * Note that unlike in the Arm implementation, we should never arrive
13126 * here with a zero breakFlag because we always refresh rIBASE on
13127 * return.
13128 */
13129    EXPORT_PC
13130    movl   rSELF, %eax
13131    movl   rPC, OUT_ARG0(%esp)
13132    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13133    movl   rFP, OUT_ARG1(%esp)
13134    je     1f                                # reload rIBASE & resume if not
13135    movl   %eax, OUT_ARG2(%esp)
13136    call   dvmCheckBefore                    # (dPC, dFP, self)
13137    movl   rSELF, %eax
131381:
13139    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13140    jmp    *dvmAsmInstructionStart+(182*4)
13141
13142/* ------------------------------ */
13143.L_ALT_OP_XOR_INT_2ADDR: /* 0xb7 */
13144/* File: x86/alt_stub.S */
13145/*
13146 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13147 * any interesting requests and then jump to the real instruction
13148 * handler.  Unlike the Arm handler, we can't do this as a tail call
13149 * because rIBASE is caller save and we need to reload it.
13150 *
13151 * Note that unlike in the Arm implementation, we should never arrive
13152 * here with a zero breakFlag because we always refresh rIBASE on
13153 * return.
13154 */
13155    EXPORT_PC
13156    movl   rSELF, %eax
13157    movl   rPC, OUT_ARG0(%esp)
13158    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13159    movl   rFP, OUT_ARG1(%esp)
13160    je     1f                                # reload rIBASE & resume if not
13161    movl   %eax, OUT_ARG2(%esp)
13162    call   dvmCheckBefore                    # (dPC, dFP, self)
13163    movl   rSELF, %eax
131641:
13165    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13166    jmp    *dvmAsmInstructionStart+(183*4)
13167
13168/* ------------------------------ */
13169.L_ALT_OP_SHL_INT_2ADDR: /* 0xb8 */
13170/* File: x86/alt_stub.S */
13171/*
13172 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13173 * any interesting requests and then jump to the real instruction
13174 * handler.  Unlike the Arm handler, we can't do this as a tail call
13175 * because rIBASE is caller save and we need to reload it.
13176 *
13177 * Note that unlike in the Arm implementation, we should never arrive
13178 * here with a zero breakFlag because we always refresh rIBASE on
13179 * return.
13180 */
13181    EXPORT_PC
13182    movl   rSELF, %eax
13183    movl   rPC, OUT_ARG0(%esp)
13184    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13185    movl   rFP, OUT_ARG1(%esp)
13186    je     1f                                # reload rIBASE & resume if not
13187    movl   %eax, OUT_ARG2(%esp)
13188    call   dvmCheckBefore                    # (dPC, dFP, self)
13189    movl   rSELF, %eax
131901:
13191    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13192    jmp    *dvmAsmInstructionStart+(184*4)
13193
13194/* ------------------------------ */
13195.L_ALT_OP_SHR_INT_2ADDR: /* 0xb9 */
13196/* File: x86/alt_stub.S */
13197/*
13198 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13199 * any interesting requests and then jump to the real instruction
13200 * handler.  Unlike the Arm handler, we can't do this as a tail call
13201 * because rIBASE is caller save and we need to reload it.
13202 *
13203 * Note that unlike in the Arm implementation, we should never arrive
13204 * here with a zero breakFlag because we always refresh rIBASE on
13205 * return.
13206 */
13207    EXPORT_PC
13208    movl   rSELF, %eax
13209    movl   rPC, OUT_ARG0(%esp)
13210    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13211    movl   rFP, OUT_ARG1(%esp)
13212    je     1f                                # reload rIBASE & resume if not
13213    movl   %eax, OUT_ARG2(%esp)
13214    call   dvmCheckBefore                    # (dPC, dFP, self)
13215    movl   rSELF, %eax
132161:
13217    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13218    jmp    *dvmAsmInstructionStart+(185*4)
13219
13220/* ------------------------------ */
13221.L_ALT_OP_USHR_INT_2ADDR: /* 0xba */
13222/* File: x86/alt_stub.S */
13223/*
13224 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13225 * any interesting requests and then jump to the real instruction
13226 * handler.  Unlike the Arm handler, we can't do this as a tail call
13227 * because rIBASE is caller save and we need to reload it.
13228 *
13229 * Note that unlike in the Arm implementation, we should never arrive
13230 * here with a zero breakFlag because we always refresh rIBASE on
13231 * return.
13232 */
13233    EXPORT_PC
13234    movl   rSELF, %eax
13235    movl   rPC, OUT_ARG0(%esp)
13236    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13237    movl   rFP, OUT_ARG1(%esp)
13238    je     1f                                # reload rIBASE & resume if not
13239    movl   %eax, OUT_ARG2(%esp)
13240    call   dvmCheckBefore                    # (dPC, dFP, self)
13241    movl   rSELF, %eax
132421:
13243    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13244    jmp    *dvmAsmInstructionStart+(186*4)
13245
13246/* ------------------------------ */
13247.L_ALT_OP_ADD_LONG_2ADDR: /* 0xbb */
13248/* File: x86/alt_stub.S */
13249/*
13250 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13251 * any interesting requests and then jump to the real instruction
13252 * handler.  Unlike the Arm handler, we can't do this as a tail call
13253 * because rIBASE is caller save and we need to reload it.
13254 *
13255 * Note that unlike in the Arm implementation, we should never arrive
13256 * here with a zero breakFlag because we always refresh rIBASE on
13257 * return.
13258 */
13259    EXPORT_PC
13260    movl   rSELF, %eax
13261    movl   rPC, OUT_ARG0(%esp)
13262    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13263    movl   rFP, OUT_ARG1(%esp)
13264    je     1f                                # reload rIBASE & resume if not
13265    movl   %eax, OUT_ARG2(%esp)
13266    call   dvmCheckBefore                    # (dPC, dFP, self)
13267    movl   rSELF, %eax
132681:
13269    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13270    jmp    *dvmAsmInstructionStart+(187*4)
13271
13272/* ------------------------------ */
13273.L_ALT_OP_SUB_LONG_2ADDR: /* 0xbc */
13274/* File: x86/alt_stub.S */
13275/*
13276 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13277 * any interesting requests and then jump to the real instruction
13278 * handler.  Unlike the Arm handler, we can't do this as a tail call
13279 * because rIBASE is caller save and we need to reload it.
13280 *
13281 * Note that unlike in the Arm implementation, we should never arrive
13282 * here with a zero breakFlag because we always refresh rIBASE on
13283 * return.
13284 */
13285    EXPORT_PC
13286    movl   rSELF, %eax
13287    movl   rPC, OUT_ARG0(%esp)
13288    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13289    movl   rFP, OUT_ARG1(%esp)
13290    je     1f                                # reload rIBASE & resume if not
13291    movl   %eax, OUT_ARG2(%esp)
13292    call   dvmCheckBefore                    # (dPC, dFP, self)
13293    movl   rSELF, %eax
132941:
13295    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13296    jmp    *dvmAsmInstructionStart+(188*4)
13297
13298/* ------------------------------ */
13299.L_ALT_OP_MUL_LONG_2ADDR: /* 0xbd */
13300/* File: x86/alt_stub.S */
13301/*
13302 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13303 * any interesting requests and then jump to the real instruction
13304 * handler.  Unlike the Arm handler, we can't do this as a tail call
13305 * because rIBASE is caller save and we need to reload it.
13306 *
13307 * Note that unlike in the Arm implementation, we should never arrive
13308 * here with a zero breakFlag because we always refresh rIBASE on
13309 * return.
13310 */
13311    EXPORT_PC
13312    movl   rSELF, %eax
13313    movl   rPC, OUT_ARG0(%esp)
13314    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13315    movl   rFP, OUT_ARG1(%esp)
13316    je     1f                                # reload rIBASE & resume if not
13317    movl   %eax, OUT_ARG2(%esp)
13318    call   dvmCheckBefore                    # (dPC, dFP, self)
13319    movl   rSELF, %eax
133201:
13321    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13322    jmp    *dvmAsmInstructionStart+(189*4)
13323
13324/* ------------------------------ */
13325.L_ALT_OP_DIV_LONG_2ADDR: /* 0xbe */
13326/* File: x86/alt_stub.S */
13327/*
13328 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13329 * any interesting requests and then jump to the real instruction
13330 * handler.  Unlike the Arm handler, we can't do this as a tail call
13331 * because rIBASE is caller save and we need to reload it.
13332 *
13333 * Note that unlike in the Arm implementation, we should never arrive
13334 * here with a zero breakFlag because we always refresh rIBASE on
13335 * return.
13336 */
13337    EXPORT_PC
13338    movl   rSELF, %eax
13339    movl   rPC, OUT_ARG0(%esp)
13340    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13341    movl   rFP, OUT_ARG1(%esp)
13342    je     1f                                # reload rIBASE & resume if not
13343    movl   %eax, OUT_ARG2(%esp)
13344    call   dvmCheckBefore                    # (dPC, dFP, self)
13345    movl   rSELF, %eax
133461:
13347    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13348    jmp    *dvmAsmInstructionStart+(190*4)
13349
13350/* ------------------------------ */
13351.L_ALT_OP_REM_LONG_2ADDR: /* 0xbf */
13352/* File: x86/alt_stub.S */
13353/*
13354 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13355 * any interesting requests and then jump to the real instruction
13356 * handler.  Unlike the Arm handler, we can't do this as a tail call
13357 * because rIBASE is caller save and we need to reload it.
13358 *
13359 * Note that unlike in the Arm implementation, we should never arrive
13360 * here with a zero breakFlag because we always refresh rIBASE on
13361 * return.
13362 */
13363    EXPORT_PC
13364    movl   rSELF, %eax
13365    movl   rPC, OUT_ARG0(%esp)
13366    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13367    movl   rFP, OUT_ARG1(%esp)
13368    je     1f                                # reload rIBASE & resume if not
13369    movl   %eax, OUT_ARG2(%esp)
13370    call   dvmCheckBefore                    # (dPC, dFP, self)
13371    movl   rSELF, %eax
133721:
13373    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13374    jmp    *dvmAsmInstructionStart+(191*4)
13375
13376/* ------------------------------ */
13377.L_ALT_OP_AND_LONG_2ADDR: /* 0xc0 */
13378/* File: x86/alt_stub.S */
13379/*
13380 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13381 * any interesting requests and then jump to the real instruction
13382 * handler.  Unlike the Arm handler, we can't do this as a tail call
13383 * because rIBASE is caller save and we need to reload it.
13384 *
13385 * Note that unlike in the Arm implementation, we should never arrive
13386 * here with a zero breakFlag because we always refresh rIBASE on
13387 * return.
13388 */
13389    EXPORT_PC
13390    movl   rSELF, %eax
13391    movl   rPC, OUT_ARG0(%esp)
13392    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13393    movl   rFP, OUT_ARG1(%esp)
13394    je     1f                                # reload rIBASE & resume if not
13395    movl   %eax, OUT_ARG2(%esp)
13396    call   dvmCheckBefore                    # (dPC, dFP, self)
13397    movl   rSELF, %eax
133981:
13399    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13400    jmp    *dvmAsmInstructionStart+(192*4)
13401
13402/* ------------------------------ */
13403.L_ALT_OP_OR_LONG_2ADDR: /* 0xc1 */
13404/* File: x86/alt_stub.S */
13405/*
13406 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13407 * any interesting requests and then jump to the real instruction
13408 * handler.  Unlike the Arm handler, we can't do this as a tail call
13409 * because rIBASE is caller save and we need to reload it.
13410 *
13411 * Note that unlike in the Arm implementation, we should never arrive
13412 * here with a zero breakFlag because we always refresh rIBASE on
13413 * return.
13414 */
13415    EXPORT_PC
13416    movl   rSELF, %eax
13417    movl   rPC, OUT_ARG0(%esp)
13418    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13419    movl   rFP, OUT_ARG1(%esp)
13420    je     1f                                # reload rIBASE & resume if not
13421    movl   %eax, OUT_ARG2(%esp)
13422    call   dvmCheckBefore                    # (dPC, dFP, self)
13423    movl   rSELF, %eax
134241:
13425    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13426    jmp    *dvmAsmInstructionStart+(193*4)
13427
13428/* ------------------------------ */
13429.L_ALT_OP_XOR_LONG_2ADDR: /* 0xc2 */
13430/* File: x86/alt_stub.S */
13431/*
13432 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13433 * any interesting requests and then jump to the real instruction
13434 * handler.  Unlike the Arm handler, we can't do this as a tail call
13435 * because rIBASE is caller save and we need to reload it.
13436 *
13437 * Note that unlike in the Arm implementation, we should never arrive
13438 * here with a zero breakFlag because we always refresh rIBASE on
13439 * return.
13440 */
13441    EXPORT_PC
13442    movl   rSELF, %eax
13443    movl   rPC, OUT_ARG0(%esp)
13444    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13445    movl   rFP, OUT_ARG1(%esp)
13446    je     1f                                # reload rIBASE & resume if not
13447    movl   %eax, OUT_ARG2(%esp)
13448    call   dvmCheckBefore                    # (dPC, dFP, self)
13449    movl   rSELF, %eax
134501:
13451    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13452    jmp    *dvmAsmInstructionStart+(194*4)
13453
13454/* ------------------------------ */
13455.L_ALT_OP_SHL_LONG_2ADDR: /* 0xc3 */
13456/* File: x86/alt_stub.S */
13457/*
13458 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13459 * any interesting requests and then jump to the real instruction
13460 * handler.  Unlike the Arm handler, we can't do this as a tail call
13461 * because rIBASE is caller save and we need to reload it.
13462 *
13463 * Note that unlike in the Arm implementation, we should never arrive
13464 * here with a zero breakFlag because we always refresh rIBASE on
13465 * return.
13466 */
13467    EXPORT_PC
13468    movl   rSELF, %eax
13469    movl   rPC, OUT_ARG0(%esp)
13470    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13471    movl   rFP, OUT_ARG1(%esp)
13472    je     1f                                # reload rIBASE & resume if not
13473    movl   %eax, OUT_ARG2(%esp)
13474    call   dvmCheckBefore                    # (dPC, dFP, self)
13475    movl   rSELF, %eax
134761:
13477    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13478    jmp    *dvmAsmInstructionStart+(195*4)
13479
13480/* ------------------------------ */
13481.L_ALT_OP_SHR_LONG_2ADDR: /* 0xc4 */
13482/* File: x86/alt_stub.S */
13483/*
13484 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13485 * any interesting requests and then jump to the real instruction
13486 * handler.  Unlike the Arm handler, we can't do this as a tail call
13487 * because rIBASE is caller save and we need to reload it.
13488 *
13489 * Note that unlike in the Arm implementation, we should never arrive
13490 * here with a zero breakFlag because we always refresh rIBASE on
13491 * return.
13492 */
13493    EXPORT_PC
13494    movl   rSELF, %eax
13495    movl   rPC, OUT_ARG0(%esp)
13496    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13497    movl   rFP, OUT_ARG1(%esp)
13498    je     1f                                # reload rIBASE & resume if not
13499    movl   %eax, OUT_ARG2(%esp)
13500    call   dvmCheckBefore                    # (dPC, dFP, self)
13501    movl   rSELF, %eax
135021:
13503    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13504    jmp    *dvmAsmInstructionStart+(196*4)
13505
13506/* ------------------------------ */
13507.L_ALT_OP_USHR_LONG_2ADDR: /* 0xc5 */
13508/* File: x86/alt_stub.S */
13509/*
13510 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13511 * any interesting requests and then jump to the real instruction
13512 * handler.  Unlike the Arm handler, we can't do this as a tail call
13513 * because rIBASE is caller save and we need to reload it.
13514 *
13515 * Note that unlike in the Arm implementation, we should never arrive
13516 * here with a zero breakFlag because we always refresh rIBASE on
13517 * return.
13518 */
13519    EXPORT_PC
13520    movl   rSELF, %eax
13521    movl   rPC, OUT_ARG0(%esp)
13522    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13523    movl   rFP, OUT_ARG1(%esp)
13524    je     1f                                # reload rIBASE & resume if not
13525    movl   %eax, OUT_ARG2(%esp)
13526    call   dvmCheckBefore                    # (dPC, dFP, self)
13527    movl   rSELF, %eax
135281:
13529    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13530    jmp    *dvmAsmInstructionStart+(197*4)
13531
13532/* ------------------------------ */
13533.L_ALT_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
13534/* File: x86/alt_stub.S */
13535/*
13536 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13537 * any interesting requests and then jump to the real instruction
13538 * handler.  Unlike the Arm handler, we can't do this as a tail call
13539 * because rIBASE is caller save and we need to reload it.
13540 *
13541 * Note that unlike in the Arm implementation, we should never arrive
13542 * here with a zero breakFlag because we always refresh rIBASE on
13543 * return.
13544 */
13545    EXPORT_PC
13546    movl   rSELF, %eax
13547    movl   rPC, OUT_ARG0(%esp)
13548    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13549    movl   rFP, OUT_ARG1(%esp)
13550    je     1f                                # reload rIBASE & resume if not
13551    movl   %eax, OUT_ARG2(%esp)
13552    call   dvmCheckBefore                    # (dPC, dFP, self)
13553    movl   rSELF, %eax
135541:
13555    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13556    jmp    *dvmAsmInstructionStart+(198*4)
13557
13558/* ------------------------------ */
13559.L_ALT_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
13560/* File: x86/alt_stub.S */
13561/*
13562 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13563 * any interesting requests and then jump to the real instruction
13564 * handler.  Unlike the Arm handler, we can't do this as a tail call
13565 * because rIBASE is caller save and we need to reload it.
13566 *
13567 * Note that unlike in the Arm implementation, we should never arrive
13568 * here with a zero breakFlag because we always refresh rIBASE on
13569 * return.
13570 */
13571    EXPORT_PC
13572    movl   rSELF, %eax
13573    movl   rPC, OUT_ARG0(%esp)
13574    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13575    movl   rFP, OUT_ARG1(%esp)
13576    je     1f                                # reload rIBASE & resume if not
13577    movl   %eax, OUT_ARG2(%esp)
13578    call   dvmCheckBefore                    # (dPC, dFP, self)
13579    movl   rSELF, %eax
135801:
13581    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13582    jmp    *dvmAsmInstructionStart+(199*4)
13583
13584/* ------------------------------ */
13585.L_ALT_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
13586/* File: x86/alt_stub.S */
13587/*
13588 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13589 * any interesting requests and then jump to the real instruction
13590 * handler.  Unlike the Arm handler, we can't do this as a tail call
13591 * because rIBASE is caller save and we need to reload it.
13592 *
13593 * Note that unlike in the Arm implementation, we should never arrive
13594 * here with a zero breakFlag because we always refresh rIBASE on
13595 * return.
13596 */
13597    EXPORT_PC
13598    movl   rSELF, %eax
13599    movl   rPC, OUT_ARG0(%esp)
13600    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13601    movl   rFP, OUT_ARG1(%esp)
13602    je     1f                                # reload rIBASE & resume if not
13603    movl   %eax, OUT_ARG2(%esp)
13604    call   dvmCheckBefore                    # (dPC, dFP, self)
13605    movl   rSELF, %eax
136061:
13607    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13608    jmp    *dvmAsmInstructionStart+(200*4)
13609
13610/* ------------------------------ */
13611.L_ALT_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
13612/* File: x86/alt_stub.S */
13613/*
13614 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13615 * any interesting requests and then jump to the real instruction
13616 * handler.  Unlike the Arm handler, we can't do this as a tail call
13617 * because rIBASE is caller save and we need to reload it.
13618 *
13619 * Note that unlike in the Arm implementation, we should never arrive
13620 * here with a zero breakFlag because we always refresh rIBASE on
13621 * return.
13622 */
13623    EXPORT_PC
13624    movl   rSELF, %eax
13625    movl   rPC, OUT_ARG0(%esp)
13626    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13627    movl   rFP, OUT_ARG1(%esp)
13628    je     1f                                # reload rIBASE & resume if not
13629    movl   %eax, OUT_ARG2(%esp)
13630    call   dvmCheckBefore                    # (dPC, dFP, self)
13631    movl   rSELF, %eax
136321:
13633    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13634    jmp    *dvmAsmInstructionStart+(201*4)
13635
13636/* ------------------------------ */
13637.L_ALT_OP_REM_FLOAT_2ADDR: /* 0xca */
13638/* File: x86/alt_stub.S */
13639/*
13640 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13641 * any interesting requests and then jump to the real instruction
13642 * handler.  Unlike the Arm handler, we can't do this as a tail call
13643 * because rIBASE is caller save and we need to reload it.
13644 *
13645 * Note that unlike in the Arm implementation, we should never arrive
13646 * here with a zero breakFlag because we always refresh rIBASE on
13647 * return.
13648 */
13649    EXPORT_PC
13650    movl   rSELF, %eax
13651    movl   rPC, OUT_ARG0(%esp)
13652    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13653    movl   rFP, OUT_ARG1(%esp)
13654    je     1f                                # reload rIBASE & resume if not
13655    movl   %eax, OUT_ARG2(%esp)
13656    call   dvmCheckBefore                    # (dPC, dFP, self)
13657    movl   rSELF, %eax
136581:
13659    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13660    jmp    *dvmAsmInstructionStart+(202*4)
13661
13662/* ------------------------------ */
13663.L_ALT_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
13664/* File: x86/alt_stub.S */
13665/*
13666 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13667 * any interesting requests and then jump to the real instruction
13668 * handler.  Unlike the Arm handler, we can't do this as a tail call
13669 * because rIBASE is caller save and we need to reload it.
13670 *
13671 * Note that unlike in the Arm implementation, we should never arrive
13672 * here with a zero breakFlag because we always refresh rIBASE on
13673 * return.
13674 */
13675    EXPORT_PC
13676    movl   rSELF, %eax
13677    movl   rPC, OUT_ARG0(%esp)
13678    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13679    movl   rFP, OUT_ARG1(%esp)
13680    je     1f                                # reload rIBASE & resume if not
13681    movl   %eax, OUT_ARG2(%esp)
13682    call   dvmCheckBefore                    # (dPC, dFP, self)
13683    movl   rSELF, %eax
136841:
13685    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13686    jmp    *dvmAsmInstructionStart+(203*4)
13687
13688/* ------------------------------ */
13689.L_ALT_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
13690/* File: x86/alt_stub.S */
13691/*
13692 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13693 * any interesting requests and then jump to the real instruction
13694 * handler.  Unlike the Arm handler, we can't do this as a tail call
13695 * because rIBASE is caller save and we need to reload it.
13696 *
13697 * Note that unlike in the Arm implementation, we should never arrive
13698 * here with a zero breakFlag because we always refresh rIBASE on
13699 * return.
13700 */
13701    EXPORT_PC
13702    movl   rSELF, %eax
13703    movl   rPC, OUT_ARG0(%esp)
13704    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13705    movl   rFP, OUT_ARG1(%esp)
13706    je     1f                                # reload rIBASE & resume if not
13707    movl   %eax, OUT_ARG2(%esp)
13708    call   dvmCheckBefore                    # (dPC, dFP, self)
13709    movl   rSELF, %eax
137101:
13711    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13712    jmp    *dvmAsmInstructionStart+(204*4)
13713
13714/* ------------------------------ */
13715.L_ALT_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
13716/* File: x86/alt_stub.S */
13717/*
13718 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13719 * any interesting requests and then jump to the real instruction
13720 * handler.  Unlike the Arm handler, we can't do this as a tail call
13721 * because rIBASE is caller save and we need to reload it.
13722 *
13723 * Note that unlike in the Arm implementation, we should never arrive
13724 * here with a zero breakFlag because we always refresh rIBASE on
13725 * return.
13726 */
13727    EXPORT_PC
13728    movl   rSELF, %eax
13729    movl   rPC, OUT_ARG0(%esp)
13730    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13731    movl   rFP, OUT_ARG1(%esp)
13732    je     1f                                # reload rIBASE & resume if not
13733    movl   %eax, OUT_ARG2(%esp)
13734    call   dvmCheckBefore                    # (dPC, dFP, self)
13735    movl   rSELF, %eax
137361:
13737    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13738    jmp    *dvmAsmInstructionStart+(205*4)
13739
13740/* ------------------------------ */
13741.L_ALT_OP_DIV_DOUBLE_2ADDR: /* 0xce */
13742/* File: x86/alt_stub.S */
13743/*
13744 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13745 * any interesting requests and then jump to the real instruction
13746 * handler.  Unlike the Arm handler, we can't do this as a tail call
13747 * because rIBASE is caller save and we need to reload it.
13748 *
13749 * Note that unlike in the Arm implementation, we should never arrive
13750 * here with a zero breakFlag because we always refresh rIBASE on
13751 * return.
13752 */
13753    EXPORT_PC
13754    movl   rSELF, %eax
13755    movl   rPC, OUT_ARG0(%esp)
13756    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13757    movl   rFP, OUT_ARG1(%esp)
13758    je     1f                                # reload rIBASE & resume if not
13759    movl   %eax, OUT_ARG2(%esp)
13760    call   dvmCheckBefore                    # (dPC, dFP, self)
13761    movl   rSELF, %eax
137621:
13763    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13764    jmp    *dvmAsmInstructionStart+(206*4)
13765
13766/* ------------------------------ */
13767.L_ALT_OP_REM_DOUBLE_2ADDR: /* 0xcf */
13768/* File: x86/alt_stub.S */
13769/*
13770 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13771 * any interesting requests and then jump to the real instruction
13772 * handler.  Unlike the Arm handler, we can't do this as a tail call
13773 * because rIBASE is caller save and we need to reload it.
13774 *
13775 * Note that unlike in the Arm implementation, we should never arrive
13776 * here with a zero breakFlag because we always refresh rIBASE on
13777 * return.
13778 */
13779    EXPORT_PC
13780    movl   rSELF, %eax
13781    movl   rPC, OUT_ARG0(%esp)
13782    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13783    movl   rFP, OUT_ARG1(%esp)
13784    je     1f                                # reload rIBASE & resume if not
13785    movl   %eax, OUT_ARG2(%esp)
13786    call   dvmCheckBefore                    # (dPC, dFP, self)
13787    movl   rSELF, %eax
137881:
13789    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13790    jmp    *dvmAsmInstructionStart+(207*4)
13791
13792/* ------------------------------ */
13793.L_ALT_OP_ADD_INT_LIT16: /* 0xd0 */
13794/* File: x86/alt_stub.S */
13795/*
13796 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13797 * any interesting requests and then jump to the real instruction
13798 * handler.  Unlike the Arm handler, we can't do this as a tail call
13799 * because rIBASE is caller save and we need to reload it.
13800 *
13801 * Note that unlike in the Arm implementation, we should never arrive
13802 * here with a zero breakFlag because we always refresh rIBASE on
13803 * return.
13804 */
13805    EXPORT_PC
13806    movl   rSELF, %eax
13807    movl   rPC, OUT_ARG0(%esp)
13808    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13809    movl   rFP, OUT_ARG1(%esp)
13810    je     1f                                # reload rIBASE & resume if not
13811    movl   %eax, OUT_ARG2(%esp)
13812    call   dvmCheckBefore                    # (dPC, dFP, self)
13813    movl   rSELF, %eax
138141:
13815    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13816    jmp    *dvmAsmInstructionStart+(208*4)
13817
13818/* ------------------------------ */
13819.L_ALT_OP_RSUB_INT: /* 0xd1 */
13820/* File: x86/alt_stub.S */
13821/*
13822 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13823 * any interesting requests and then jump to the real instruction
13824 * handler.  Unlike the Arm handler, we can't do this as a tail call
13825 * because rIBASE is caller save and we need to reload it.
13826 *
13827 * Note that unlike in the Arm implementation, we should never arrive
13828 * here with a zero breakFlag because we always refresh rIBASE on
13829 * return.
13830 */
13831    EXPORT_PC
13832    movl   rSELF, %eax
13833    movl   rPC, OUT_ARG0(%esp)
13834    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13835    movl   rFP, OUT_ARG1(%esp)
13836    je     1f                                # reload rIBASE & resume if not
13837    movl   %eax, OUT_ARG2(%esp)
13838    call   dvmCheckBefore                    # (dPC, dFP, self)
13839    movl   rSELF, %eax
138401:
13841    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13842    jmp    *dvmAsmInstructionStart+(209*4)
13843
13844/* ------------------------------ */
13845.L_ALT_OP_MUL_INT_LIT16: /* 0xd2 */
13846/* File: x86/alt_stub.S */
13847/*
13848 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13849 * any interesting requests and then jump to the real instruction
13850 * handler.  Unlike the Arm handler, we can't do this as a tail call
13851 * because rIBASE is caller save and we need to reload it.
13852 *
13853 * Note that unlike in the Arm implementation, we should never arrive
13854 * here with a zero breakFlag because we always refresh rIBASE on
13855 * return.
13856 */
13857    EXPORT_PC
13858    movl   rSELF, %eax
13859    movl   rPC, OUT_ARG0(%esp)
13860    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13861    movl   rFP, OUT_ARG1(%esp)
13862    je     1f                                # reload rIBASE & resume if not
13863    movl   %eax, OUT_ARG2(%esp)
13864    call   dvmCheckBefore                    # (dPC, dFP, self)
13865    movl   rSELF, %eax
138661:
13867    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13868    jmp    *dvmAsmInstructionStart+(210*4)
13869
13870/* ------------------------------ */
13871.L_ALT_OP_DIV_INT_LIT16: /* 0xd3 */
13872/* File: x86/alt_stub.S */
13873/*
13874 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13875 * any interesting requests and then jump to the real instruction
13876 * handler.  Unlike the Arm handler, we can't do this as a tail call
13877 * because rIBASE is caller save and we need to reload it.
13878 *
13879 * Note that unlike in the Arm implementation, we should never arrive
13880 * here with a zero breakFlag because we always refresh rIBASE on
13881 * return.
13882 */
13883    EXPORT_PC
13884    movl   rSELF, %eax
13885    movl   rPC, OUT_ARG0(%esp)
13886    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13887    movl   rFP, OUT_ARG1(%esp)
13888    je     1f                                # reload rIBASE & resume if not
13889    movl   %eax, OUT_ARG2(%esp)
13890    call   dvmCheckBefore                    # (dPC, dFP, self)
13891    movl   rSELF, %eax
138921:
13893    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13894    jmp    *dvmAsmInstructionStart+(211*4)
13895
13896/* ------------------------------ */
13897.L_ALT_OP_REM_INT_LIT16: /* 0xd4 */
13898/* File: x86/alt_stub.S */
13899/*
13900 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13901 * any interesting requests and then jump to the real instruction
13902 * handler.  Unlike the Arm handler, we can't do this as a tail call
13903 * because rIBASE is caller save and we need to reload it.
13904 *
13905 * Note that unlike in the Arm implementation, we should never arrive
13906 * here with a zero breakFlag because we always refresh rIBASE on
13907 * return.
13908 */
13909    EXPORT_PC
13910    movl   rSELF, %eax
13911    movl   rPC, OUT_ARG0(%esp)
13912    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13913    movl   rFP, OUT_ARG1(%esp)
13914    je     1f                                # reload rIBASE & resume if not
13915    movl   %eax, OUT_ARG2(%esp)
13916    call   dvmCheckBefore                    # (dPC, dFP, self)
13917    movl   rSELF, %eax
139181:
13919    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13920    jmp    *dvmAsmInstructionStart+(212*4)
13921
13922/* ------------------------------ */
13923.L_ALT_OP_AND_INT_LIT16: /* 0xd5 */
13924/* File: x86/alt_stub.S */
13925/*
13926 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13927 * any interesting requests and then jump to the real instruction
13928 * handler.  Unlike the Arm handler, we can't do this as a tail call
13929 * because rIBASE is caller save and we need to reload it.
13930 *
13931 * Note that unlike in the Arm implementation, we should never arrive
13932 * here with a zero breakFlag because we always refresh rIBASE on
13933 * return.
13934 */
13935    EXPORT_PC
13936    movl   rSELF, %eax
13937    movl   rPC, OUT_ARG0(%esp)
13938    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13939    movl   rFP, OUT_ARG1(%esp)
13940    je     1f                                # reload rIBASE & resume if not
13941    movl   %eax, OUT_ARG2(%esp)
13942    call   dvmCheckBefore                    # (dPC, dFP, self)
13943    movl   rSELF, %eax
139441:
13945    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13946    jmp    *dvmAsmInstructionStart+(213*4)
13947
13948/* ------------------------------ */
13949.L_ALT_OP_OR_INT_LIT16: /* 0xd6 */
13950/* File: x86/alt_stub.S */
13951/*
13952 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13953 * any interesting requests and then jump to the real instruction
13954 * handler.  Unlike the Arm handler, we can't do this as a tail call
13955 * because rIBASE is caller save and we need to reload it.
13956 *
13957 * Note that unlike in the Arm implementation, we should never arrive
13958 * here with a zero breakFlag because we always refresh rIBASE on
13959 * return.
13960 */
13961    EXPORT_PC
13962    movl   rSELF, %eax
13963    movl   rPC, OUT_ARG0(%esp)
13964    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13965    movl   rFP, OUT_ARG1(%esp)
13966    je     1f                                # reload rIBASE & resume if not
13967    movl   %eax, OUT_ARG2(%esp)
13968    call   dvmCheckBefore                    # (dPC, dFP, self)
13969    movl   rSELF, %eax
139701:
13971    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13972    jmp    *dvmAsmInstructionStart+(214*4)
13973
13974/* ------------------------------ */
13975.L_ALT_OP_XOR_INT_LIT16: /* 0xd7 */
13976/* File: x86/alt_stub.S */
13977/*
13978 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13979 * any interesting requests and then jump to the real instruction
13980 * handler.  Unlike the Arm handler, we can't do this as a tail call
13981 * because rIBASE is caller save and we need to reload it.
13982 *
13983 * Note that unlike in the Arm implementation, we should never arrive
13984 * here with a zero breakFlag because we always refresh rIBASE on
13985 * return.
13986 */
13987    EXPORT_PC
13988    movl   rSELF, %eax
13989    movl   rPC, OUT_ARG0(%esp)
13990    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
13991    movl   rFP, OUT_ARG1(%esp)
13992    je     1f                                # reload rIBASE & resume if not
13993    movl   %eax, OUT_ARG2(%esp)
13994    call   dvmCheckBefore                    # (dPC, dFP, self)
13995    movl   rSELF, %eax
139961:
13997    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
13998    jmp    *dvmAsmInstructionStart+(215*4)
13999
14000/* ------------------------------ */
14001.L_ALT_OP_ADD_INT_LIT8: /* 0xd8 */
14002/* File: x86/alt_stub.S */
14003/*
14004 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14005 * any interesting requests and then jump to the real instruction
14006 * handler.  Unlike the Arm handler, we can't do this as a tail call
14007 * because rIBASE is caller save and we need to reload it.
14008 *
14009 * Note that unlike in the Arm implementation, we should never arrive
14010 * here with a zero breakFlag because we always refresh rIBASE on
14011 * return.
14012 */
14013    EXPORT_PC
14014    movl   rSELF, %eax
14015    movl   rPC, OUT_ARG0(%esp)
14016    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14017    movl   rFP, OUT_ARG1(%esp)
14018    je     1f                                # reload rIBASE & resume if not
14019    movl   %eax, OUT_ARG2(%esp)
14020    call   dvmCheckBefore                    # (dPC, dFP, self)
14021    movl   rSELF, %eax
140221:
14023    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14024    jmp    *dvmAsmInstructionStart+(216*4)
14025
14026/* ------------------------------ */
14027.L_ALT_OP_RSUB_INT_LIT8: /* 0xd9 */
14028/* File: x86/alt_stub.S */
14029/*
14030 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14031 * any interesting requests and then jump to the real instruction
14032 * handler.  Unlike the Arm handler, we can't do this as a tail call
14033 * because rIBASE is caller save and we need to reload it.
14034 *
14035 * Note that unlike in the Arm implementation, we should never arrive
14036 * here with a zero breakFlag because we always refresh rIBASE on
14037 * return.
14038 */
14039    EXPORT_PC
14040    movl   rSELF, %eax
14041    movl   rPC, OUT_ARG0(%esp)
14042    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14043    movl   rFP, OUT_ARG1(%esp)
14044    je     1f                                # reload rIBASE & resume if not
14045    movl   %eax, OUT_ARG2(%esp)
14046    call   dvmCheckBefore                    # (dPC, dFP, self)
14047    movl   rSELF, %eax
140481:
14049    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14050    jmp    *dvmAsmInstructionStart+(217*4)
14051
14052/* ------------------------------ */
14053.L_ALT_OP_MUL_INT_LIT8: /* 0xda */
14054/* File: x86/alt_stub.S */
14055/*
14056 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14057 * any interesting requests and then jump to the real instruction
14058 * handler.  Unlike the Arm handler, we can't do this as a tail call
14059 * because rIBASE is caller save and we need to reload it.
14060 *
14061 * Note that unlike in the Arm implementation, we should never arrive
14062 * here with a zero breakFlag because we always refresh rIBASE on
14063 * return.
14064 */
14065    EXPORT_PC
14066    movl   rSELF, %eax
14067    movl   rPC, OUT_ARG0(%esp)
14068    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14069    movl   rFP, OUT_ARG1(%esp)
14070    je     1f                                # reload rIBASE & resume if not
14071    movl   %eax, OUT_ARG2(%esp)
14072    call   dvmCheckBefore                    # (dPC, dFP, self)
14073    movl   rSELF, %eax
140741:
14075    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14076    jmp    *dvmAsmInstructionStart+(218*4)
14077
14078/* ------------------------------ */
14079.L_ALT_OP_DIV_INT_LIT8: /* 0xdb */
14080/* File: x86/alt_stub.S */
14081/*
14082 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14083 * any interesting requests and then jump to the real instruction
14084 * handler.  Unlike the Arm handler, we can't do this as a tail call
14085 * because rIBASE is caller save and we need to reload it.
14086 *
14087 * Note that unlike in the Arm implementation, we should never arrive
14088 * here with a zero breakFlag because we always refresh rIBASE on
14089 * return.
14090 */
14091    EXPORT_PC
14092    movl   rSELF, %eax
14093    movl   rPC, OUT_ARG0(%esp)
14094    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14095    movl   rFP, OUT_ARG1(%esp)
14096    je     1f                                # reload rIBASE & resume if not
14097    movl   %eax, OUT_ARG2(%esp)
14098    call   dvmCheckBefore                    # (dPC, dFP, self)
14099    movl   rSELF, %eax
141001:
14101    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14102    jmp    *dvmAsmInstructionStart+(219*4)
14103
14104/* ------------------------------ */
14105.L_ALT_OP_REM_INT_LIT8: /* 0xdc */
14106/* File: x86/alt_stub.S */
14107/*
14108 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14109 * any interesting requests and then jump to the real instruction
14110 * handler.  Unlike the Arm handler, we can't do this as a tail call
14111 * because rIBASE is caller save and we need to reload it.
14112 *
14113 * Note that unlike in the Arm implementation, we should never arrive
14114 * here with a zero breakFlag because we always refresh rIBASE on
14115 * return.
14116 */
14117    EXPORT_PC
14118    movl   rSELF, %eax
14119    movl   rPC, OUT_ARG0(%esp)
14120    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14121    movl   rFP, OUT_ARG1(%esp)
14122    je     1f                                # reload rIBASE & resume if not
14123    movl   %eax, OUT_ARG2(%esp)
14124    call   dvmCheckBefore                    # (dPC, dFP, self)
14125    movl   rSELF, %eax
141261:
14127    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14128    jmp    *dvmAsmInstructionStart+(220*4)
14129
14130/* ------------------------------ */
14131.L_ALT_OP_AND_INT_LIT8: /* 0xdd */
14132/* File: x86/alt_stub.S */
14133/*
14134 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14135 * any interesting requests and then jump to the real instruction
14136 * handler.  Unlike the Arm handler, we can't do this as a tail call
14137 * because rIBASE is caller save and we need to reload it.
14138 *
14139 * Note that unlike in the Arm implementation, we should never arrive
14140 * here with a zero breakFlag because we always refresh rIBASE on
14141 * return.
14142 */
14143    EXPORT_PC
14144    movl   rSELF, %eax
14145    movl   rPC, OUT_ARG0(%esp)
14146    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14147    movl   rFP, OUT_ARG1(%esp)
14148    je     1f                                # reload rIBASE & resume if not
14149    movl   %eax, OUT_ARG2(%esp)
14150    call   dvmCheckBefore                    # (dPC, dFP, self)
14151    movl   rSELF, %eax
141521:
14153    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14154    jmp    *dvmAsmInstructionStart+(221*4)
14155
14156/* ------------------------------ */
14157.L_ALT_OP_OR_INT_LIT8: /* 0xde */
14158/* File: x86/alt_stub.S */
14159/*
14160 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14161 * any interesting requests and then jump to the real instruction
14162 * handler.  Unlike the Arm handler, we can't do this as a tail call
14163 * because rIBASE is caller save and we need to reload it.
14164 *
14165 * Note that unlike in the Arm implementation, we should never arrive
14166 * here with a zero breakFlag because we always refresh rIBASE on
14167 * return.
14168 */
14169    EXPORT_PC
14170    movl   rSELF, %eax
14171    movl   rPC, OUT_ARG0(%esp)
14172    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14173    movl   rFP, OUT_ARG1(%esp)
14174    je     1f                                # reload rIBASE & resume if not
14175    movl   %eax, OUT_ARG2(%esp)
14176    call   dvmCheckBefore                    # (dPC, dFP, self)
14177    movl   rSELF, %eax
141781:
14179    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14180    jmp    *dvmAsmInstructionStart+(222*4)
14181
14182/* ------------------------------ */
14183.L_ALT_OP_XOR_INT_LIT8: /* 0xdf */
14184/* File: x86/alt_stub.S */
14185/*
14186 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14187 * any interesting requests and then jump to the real instruction
14188 * handler.  Unlike the Arm handler, we can't do this as a tail call
14189 * because rIBASE is caller save and we need to reload it.
14190 *
14191 * Note that unlike in the Arm implementation, we should never arrive
14192 * here with a zero breakFlag because we always refresh rIBASE on
14193 * return.
14194 */
14195    EXPORT_PC
14196    movl   rSELF, %eax
14197    movl   rPC, OUT_ARG0(%esp)
14198    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14199    movl   rFP, OUT_ARG1(%esp)
14200    je     1f                                # reload rIBASE & resume if not
14201    movl   %eax, OUT_ARG2(%esp)
14202    call   dvmCheckBefore                    # (dPC, dFP, self)
14203    movl   rSELF, %eax
142041:
14205    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14206    jmp    *dvmAsmInstructionStart+(223*4)
14207
14208/* ------------------------------ */
14209.L_ALT_OP_SHL_INT_LIT8: /* 0xe0 */
14210/* File: x86/alt_stub.S */
14211/*
14212 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14213 * any interesting requests and then jump to the real instruction
14214 * handler.  Unlike the Arm handler, we can't do this as a tail call
14215 * because rIBASE is caller save and we need to reload it.
14216 *
14217 * Note that unlike in the Arm implementation, we should never arrive
14218 * here with a zero breakFlag because we always refresh rIBASE on
14219 * return.
14220 */
14221    EXPORT_PC
14222    movl   rSELF, %eax
14223    movl   rPC, OUT_ARG0(%esp)
14224    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14225    movl   rFP, OUT_ARG1(%esp)
14226    je     1f                                # reload rIBASE & resume if not
14227    movl   %eax, OUT_ARG2(%esp)
14228    call   dvmCheckBefore                    # (dPC, dFP, self)
14229    movl   rSELF, %eax
142301:
14231    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14232    jmp    *dvmAsmInstructionStart+(224*4)
14233
14234/* ------------------------------ */
14235.L_ALT_OP_SHR_INT_LIT8: /* 0xe1 */
14236/* File: x86/alt_stub.S */
14237/*
14238 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14239 * any interesting requests and then jump to the real instruction
14240 * handler.  Unlike the Arm handler, we can't do this as a tail call
14241 * because rIBASE is caller save and we need to reload it.
14242 *
14243 * Note that unlike in the Arm implementation, we should never arrive
14244 * here with a zero breakFlag because we always refresh rIBASE on
14245 * return.
14246 */
14247    EXPORT_PC
14248    movl   rSELF, %eax
14249    movl   rPC, OUT_ARG0(%esp)
14250    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14251    movl   rFP, OUT_ARG1(%esp)
14252    je     1f                                # reload rIBASE & resume if not
14253    movl   %eax, OUT_ARG2(%esp)
14254    call   dvmCheckBefore                    # (dPC, dFP, self)
14255    movl   rSELF, %eax
142561:
14257    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14258    jmp    *dvmAsmInstructionStart+(225*4)
14259
14260/* ------------------------------ */
14261.L_ALT_OP_USHR_INT_LIT8: /* 0xe2 */
14262/* File: x86/alt_stub.S */
14263/*
14264 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14265 * any interesting requests and then jump to the real instruction
14266 * handler.  Unlike the Arm handler, we can't do this as a tail call
14267 * because rIBASE is caller save and we need to reload it.
14268 *
14269 * Note that unlike in the Arm implementation, we should never arrive
14270 * here with a zero breakFlag because we always refresh rIBASE on
14271 * return.
14272 */
14273    EXPORT_PC
14274    movl   rSELF, %eax
14275    movl   rPC, OUT_ARG0(%esp)
14276    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14277    movl   rFP, OUT_ARG1(%esp)
14278    je     1f                                # reload rIBASE & resume if not
14279    movl   %eax, OUT_ARG2(%esp)
14280    call   dvmCheckBefore                    # (dPC, dFP, self)
14281    movl   rSELF, %eax
142821:
14283    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14284    jmp    *dvmAsmInstructionStart+(226*4)
14285
14286/* ------------------------------ */
14287.L_ALT_OP_IGET_VOLATILE: /* 0xe3 */
14288/* File: x86/alt_stub.S */
14289/*
14290 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14291 * any interesting requests and then jump to the real instruction
14292 * handler.  Unlike the Arm handler, we can't do this as a tail call
14293 * because rIBASE is caller save and we need to reload it.
14294 *
14295 * Note that unlike in the Arm implementation, we should never arrive
14296 * here with a zero breakFlag because we always refresh rIBASE on
14297 * return.
14298 */
14299    EXPORT_PC
14300    movl   rSELF, %eax
14301    movl   rPC, OUT_ARG0(%esp)
14302    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14303    movl   rFP, OUT_ARG1(%esp)
14304    je     1f                                # reload rIBASE & resume if not
14305    movl   %eax, OUT_ARG2(%esp)
14306    call   dvmCheckBefore                    # (dPC, dFP, self)
14307    movl   rSELF, %eax
143081:
14309    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14310    jmp    *dvmAsmInstructionStart+(227*4)
14311
14312/* ------------------------------ */
14313.L_ALT_OP_IPUT_VOLATILE: /* 0xe4 */
14314/* File: x86/alt_stub.S */
14315/*
14316 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14317 * any interesting requests and then jump to the real instruction
14318 * handler.  Unlike the Arm handler, we can't do this as a tail call
14319 * because rIBASE is caller save and we need to reload it.
14320 *
14321 * Note that unlike in the Arm implementation, we should never arrive
14322 * here with a zero breakFlag because we always refresh rIBASE on
14323 * return.
14324 */
14325    EXPORT_PC
14326    movl   rSELF, %eax
14327    movl   rPC, OUT_ARG0(%esp)
14328    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14329    movl   rFP, OUT_ARG1(%esp)
14330    je     1f                                # reload rIBASE & resume if not
14331    movl   %eax, OUT_ARG2(%esp)
14332    call   dvmCheckBefore                    # (dPC, dFP, self)
14333    movl   rSELF, %eax
143341:
14335    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14336    jmp    *dvmAsmInstructionStart+(228*4)
14337
14338/* ------------------------------ */
14339.L_ALT_OP_SGET_VOLATILE: /* 0xe5 */
14340/* File: x86/alt_stub.S */
14341/*
14342 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14343 * any interesting requests and then jump to the real instruction
14344 * handler.  Unlike the Arm handler, we can't do this as a tail call
14345 * because rIBASE is caller save and we need to reload it.
14346 *
14347 * Note that unlike in the Arm implementation, we should never arrive
14348 * here with a zero breakFlag because we always refresh rIBASE on
14349 * return.
14350 */
14351    EXPORT_PC
14352    movl   rSELF, %eax
14353    movl   rPC, OUT_ARG0(%esp)
14354    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14355    movl   rFP, OUT_ARG1(%esp)
14356    je     1f                                # reload rIBASE & resume if not
14357    movl   %eax, OUT_ARG2(%esp)
14358    call   dvmCheckBefore                    # (dPC, dFP, self)
14359    movl   rSELF, %eax
143601:
14361    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14362    jmp    *dvmAsmInstructionStart+(229*4)
14363
14364/* ------------------------------ */
14365.L_ALT_OP_SPUT_VOLATILE: /* 0xe6 */
14366/* File: x86/alt_stub.S */
14367/*
14368 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14369 * any interesting requests and then jump to the real instruction
14370 * handler.  Unlike the Arm handler, we can't do this as a tail call
14371 * because rIBASE is caller save and we need to reload it.
14372 *
14373 * Note that unlike in the Arm implementation, we should never arrive
14374 * here with a zero breakFlag because we always refresh rIBASE on
14375 * return.
14376 */
14377    EXPORT_PC
14378    movl   rSELF, %eax
14379    movl   rPC, OUT_ARG0(%esp)
14380    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14381    movl   rFP, OUT_ARG1(%esp)
14382    je     1f                                # reload rIBASE & resume if not
14383    movl   %eax, OUT_ARG2(%esp)
14384    call   dvmCheckBefore                    # (dPC, dFP, self)
14385    movl   rSELF, %eax
143861:
14387    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14388    jmp    *dvmAsmInstructionStart+(230*4)
14389
14390/* ------------------------------ */
14391.L_ALT_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
14392/* File: x86/alt_stub.S */
14393/*
14394 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14395 * any interesting requests and then jump to the real instruction
14396 * handler.  Unlike the Arm handler, we can't do this as a tail call
14397 * because rIBASE is caller save and we need to reload it.
14398 *
14399 * Note that unlike in the Arm implementation, we should never arrive
14400 * here with a zero breakFlag because we always refresh rIBASE on
14401 * return.
14402 */
14403    EXPORT_PC
14404    movl   rSELF, %eax
14405    movl   rPC, OUT_ARG0(%esp)
14406    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14407    movl   rFP, OUT_ARG1(%esp)
14408    je     1f                                # reload rIBASE & resume if not
14409    movl   %eax, OUT_ARG2(%esp)
14410    call   dvmCheckBefore                    # (dPC, dFP, self)
14411    movl   rSELF, %eax
144121:
14413    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14414    jmp    *dvmAsmInstructionStart+(231*4)
14415
14416/* ------------------------------ */
14417.L_ALT_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
14418/* File: x86/alt_stub.S */
14419/*
14420 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14421 * any interesting requests and then jump to the real instruction
14422 * handler.  Unlike the Arm handler, we can't do this as a tail call
14423 * because rIBASE is caller save and we need to reload it.
14424 *
14425 * Note that unlike in the Arm implementation, we should never arrive
14426 * here with a zero breakFlag because we always refresh rIBASE on
14427 * return.
14428 */
14429    EXPORT_PC
14430    movl   rSELF, %eax
14431    movl   rPC, OUT_ARG0(%esp)
14432    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14433    movl   rFP, OUT_ARG1(%esp)
14434    je     1f                                # reload rIBASE & resume if not
14435    movl   %eax, OUT_ARG2(%esp)
14436    call   dvmCheckBefore                    # (dPC, dFP, self)
14437    movl   rSELF, %eax
144381:
14439    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14440    jmp    *dvmAsmInstructionStart+(232*4)
14441
14442/* ------------------------------ */
14443.L_ALT_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
14444/* File: x86/alt_stub.S */
14445/*
14446 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14447 * any interesting requests and then jump to the real instruction
14448 * handler.  Unlike the Arm handler, we can't do this as a tail call
14449 * because rIBASE is caller save and we need to reload it.
14450 *
14451 * Note that unlike in the Arm implementation, we should never arrive
14452 * here with a zero breakFlag because we always refresh rIBASE on
14453 * return.
14454 */
14455    EXPORT_PC
14456    movl   rSELF, %eax
14457    movl   rPC, OUT_ARG0(%esp)
14458    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14459    movl   rFP, OUT_ARG1(%esp)
14460    je     1f                                # reload rIBASE & resume if not
14461    movl   %eax, OUT_ARG2(%esp)
14462    call   dvmCheckBefore                    # (dPC, dFP, self)
14463    movl   rSELF, %eax
144641:
14465    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14466    jmp    *dvmAsmInstructionStart+(233*4)
14467
14468/* ------------------------------ */
14469.L_ALT_OP_SGET_WIDE_VOLATILE: /* 0xea */
14470/* File: x86/alt_stub.S */
14471/*
14472 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14473 * any interesting requests and then jump to the real instruction
14474 * handler.  Unlike the Arm handler, we can't do this as a tail call
14475 * because rIBASE is caller save and we need to reload it.
14476 *
14477 * Note that unlike in the Arm implementation, we should never arrive
14478 * here with a zero breakFlag because we always refresh rIBASE on
14479 * return.
14480 */
14481    EXPORT_PC
14482    movl   rSELF, %eax
14483    movl   rPC, OUT_ARG0(%esp)
14484    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14485    movl   rFP, OUT_ARG1(%esp)
14486    je     1f                                # reload rIBASE & resume if not
14487    movl   %eax, OUT_ARG2(%esp)
14488    call   dvmCheckBefore                    # (dPC, dFP, self)
14489    movl   rSELF, %eax
144901:
14491    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14492    jmp    *dvmAsmInstructionStart+(234*4)
14493
14494/* ------------------------------ */
14495.L_ALT_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
14496/* File: x86/alt_stub.S */
14497/*
14498 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14499 * any interesting requests and then jump to the real instruction
14500 * handler.  Unlike the Arm handler, we can't do this as a tail call
14501 * because rIBASE is caller save and we need to reload it.
14502 *
14503 * Note that unlike in the Arm implementation, we should never arrive
14504 * here with a zero breakFlag because we always refresh rIBASE on
14505 * return.
14506 */
14507    EXPORT_PC
14508    movl   rSELF, %eax
14509    movl   rPC, OUT_ARG0(%esp)
14510    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14511    movl   rFP, OUT_ARG1(%esp)
14512    je     1f                                # reload rIBASE & resume if not
14513    movl   %eax, OUT_ARG2(%esp)
14514    call   dvmCheckBefore                    # (dPC, dFP, self)
14515    movl   rSELF, %eax
145161:
14517    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14518    jmp    *dvmAsmInstructionStart+(235*4)
14519
14520/* ------------------------------ */
14521.L_ALT_OP_BREAKPOINT: /* 0xec */
14522/* File: x86/alt_stub.S */
14523/*
14524 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14525 * any interesting requests and then jump to the real instruction
14526 * handler.  Unlike the Arm handler, we can't do this as a tail call
14527 * because rIBASE is caller save and we need to reload it.
14528 *
14529 * Note that unlike in the Arm implementation, we should never arrive
14530 * here with a zero breakFlag because we always refresh rIBASE on
14531 * return.
14532 */
14533    EXPORT_PC
14534    movl   rSELF, %eax
14535    movl   rPC, OUT_ARG0(%esp)
14536    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14537    movl   rFP, OUT_ARG1(%esp)
14538    je     1f                                # reload rIBASE & resume if not
14539    movl   %eax, OUT_ARG2(%esp)
14540    call   dvmCheckBefore                    # (dPC, dFP, self)
14541    movl   rSELF, %eax
145421:
14543    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14544    jmp    *dvmAsmInstructionStart+(236*4)
14545
14546/* ------------------------------ */
14547.L_ALT_OP_THROW_VERIFICATION_ERROR: /* 0xed */
14548/* File: x86/alt_stub.S */
14549/*
14550 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14551 * any interesting requests and then jump to the real instruction
14552 * handler.  Unlike the Arm handler, we can't do this as a tail call
14553 * because rIBASE is caller save and we need to reload it.
14554 *
14555 * Note that unlike in the Arm implementation, we should never arrive
14556 * here with a zero breakFlag because we always refresh rIBASE on
14557 * return.
14558 */
14559    EXPORT_PC
14560    movl   rSELF, %eax
14561    movl   rPC, OUT_ARG0(%esp)
14562    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14563    movl   rFP, OUT_ARG1(%esp)
14564    je     1f                                # reload rIBASE & resume if not
14565    movl   %eax, OUT_ARG2(%esp)
14566    call   dvmCheckBefore                    # (dPC, dFP, self)
14567    movl   rSELF, %eax
145681:
14569    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14570    jmp    *dvmAsmInstructionStart+(237*4)
14571
14572/* ------------------------------ */
14573.L_ALT_OP_EXECUTE_INLINE: /* 0xee */
14574/* File: x86/alt_stub.S */
14575/*
14576 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14577 * any interesting requests and then jump to the real instruction
14578 * handler.  Unlike the Arm handler, we can't do this as a tail call
14579 * because rIBASE is caller save and we need to reload it.
14580 *
14581 * Note that unlike in the Arm implementation, we should never arrive
14582 * here with a zero breakFlag because we always refresh rIBASE on
14583 * return.
14584 */
14585    EXPORT_PC
14586    movl   rSELF, %eax
14587    movl   rPC, OUT_ARG0(%esp)
14588    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14589    movl   rFP, OUT_ARG1(%esp)
14590    je     1f                                # reload rIBASE & resume if not
14591    movl   %eax, OUT_ARG2(%esp)
14592    call   dvmCheckBefore                    # (dPC, dFP, self)
14593    movl   rSELF, %eax
145941:
14595    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14596    jmp    *dvmAsmInstructionStart+(238*4)
14597
14598/* ------------------------------ */
14599.L_ALT_OP_EXECUTE_INLINE_RANGE: /* 0xef */
14600/* File: x86/alt_stub.S */
14601/*
14602 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14603 * any interesting requests and then jump to the real instruction
14604 * handler.  Unlike the Arm handler, we can't do this as a tail call
14605 * because rIBASE is caller save and we need to reload it.
14606 *
14607 * Note that unlike in the Arm implementation, we should never arrive
14608 * here with a zero breakFlag because we always refresh rIBASE on
14609 * return.
14610 */
14611    EXPORT_PC
14612    movl   rSELF, %eax
14613    movl   rPC, OUT_ARG0(%esp)
14614    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14615    movl   rFP, OUT_ARG1(%esp)
14616    je     1f                                # reload rIBASE & resume if not
14617    movl   %eax, OUT_ARG2(%esp)
14618    call   dvmCheckBefore                    # (dPC, dFP, self)
14619    movl   rSELF, %eax
146201:
14621    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14622    jmp    *dvmAsmInstructionStart+(239*4)
14623
14624/* ------------------------------ */
14625.L_ALT_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */
14626/* File: x86/alt_stub.S */
14627/*
14628 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14629 * any interesting requests and then jump to the real instruction
14630 * handler.  Unlike the Arm handler, we can't do this as a tail call
14631 * because rIBASE is caller save and we need to reload it.
14632 *
14633 * Note that unlike in the Arm implementation, we should never arrive
14634 * here with a zero breakFlag because we always refresh rIBASE on
14635 * return.
14636 */
14637    EXPORT_PC
14638    movl   rSELF, %eax
14639    movl   rPC, OUT_ARG0(%esp)
14640    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14641    movl   rFP, OUT_ARG1(%esp)
14642    je     1f                                # reload rIBASE & resume if not
14643    movl   %eax, OUT_ARG2(%esp)
14644    call   dvmCheckBefore                    # (dPC, dFP, self)
14645    movl   rSELF, %eax
146461:
14647    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14648    jmp    *dvmAsmInstructionStart+(240*4)
14649
14650/* ------------------------------ */
14651.L_ALT_OP_RETURN_VOID_BARRIER: /* 0xf1 */
14652/* File: x86/alt_stub.S */
14653/*
14654 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14655 * any interesting requests and then jump to the real instruction
14656 * handler.  Unlike the Arm handler, we can't do this as a tail call
14657 * because rIBASE is caller save and we need to reload it.
14658 *
14659 * Note that unlike in the Arm implementation, we should never arrive
14660 * here with a zero breakFlag because we always refresh rIBASE on
14661 * return.
14662 */
14663    EXPORT_PC
14664    movl   rSELF, %eax
14665    movl   rPC, OUT_ARG0(%esp)
14666    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14667    movl   rFP, OUT_ARG1(%esp)
14668    je     1f                                # reload rIBASE & resume if not
14669    movl   %eax, OUT_ARG2(%esp)
14670    call   dvmCheckBefore                    # (dPC, dFP, self)
14671    movl   rSELF, %eax
146721:
14673    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14674    jmp    *dvmAsmInstructionStart+(241*4)
14675
14676/* ------------------------------ */
14677.L_ALT_OP_IGET_QUICK: /* 0xf2 */
14678/* File: x86/alt_stub.S */
14679/*
14680 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14681 * any interesting requests and then jump to the real instruction
14682 * handler.  Unlike the Arm handler, we can't do this as a tail call
14683 * because rIBASE is caller save and we need to reload it.
14684 *
14685 * Note that unlike in the Arm implementation, we should never arrive
14686 * here with a zero breakFlag because we always refresh rIBASE on
14687 * return.
14688 */
14689    EXPORT_PC
14690    movl   rSELF, %eax
14691    movl   rPC, OUT_ARG0(%esp)
14692    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14693    movl   rFP, OUT_ARG1(%esp)
14694    je     1f                                # reload rIBASE & resume if not
14695    movl   %eax, OUT_ARG2(%esp)
14696    call   dvmCheckBefore                    # (dPC, dFP, self)
14697    movl   rSELF, %eax
146981:
14699    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14700    jmp    *dvmAsmInstructionStart+(242*4)
14701
14702/* ------------------------------ */
14703.L_ALT_OP_IGET_WIDE_QUICK: /* 0xf3 */
14704/* File: x86/alt_stub.S */
14705/*
14706 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14707 * any interesting requests and then jump to the real instruction
14708 * handler.  Unlike the Arm handler, we can't do this as a tail call
14709 * because rIBASE is caller save and we need to reload it.
14710 *
14711 * Note that unlike in the Arm implementation, we should never arrive
14712 * here with a zero breakFlag because we always refresh rIBASE on
14713 * return.
14714 */
14715    EXPORT_PC
14716    movl   rSELF, %eax
14717    movl   rPC, OUT_ARG0(%esp)
14718    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14719    movl   rFP, OUT_ARG1(%esp)
14720    je     1f                                # reload rIBASE & resume if not
14721    movl   %eax, OUT_ARG2(%esp)
14722    call   dvmCheckBefore                    # (dPC, dFP, self)
14723    movl   rSELF, %eax
147241:
14725    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14726    jmp    *dvmAsmInstructionStart+(243*4)
14727
14728/* ------------------------------ */
14729.L_ALT_OP_IGET_OBJECT_QUICK: /* 0xf4 */
14730/* File: x86/alt_stub.S */
14731/*
14732 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14733 * any interesting requests and then jump to the real instruction
14734 * handler.  Unlike the Arm handler, we can't do this as a tail call
14735 * because rIBASE is caller save and we need to reload it.
14736 *
14737 * Note that unlike in the Arm implementation, we should never arrive
14738 * here with a zero breakFlag because we always refresh rIBASE on
14739 * return.
14740 */
14741    EXPORT_PC
14742    movl   rSELF, %eax
14743    movl   rPC, OUT_ARG0(%esp)
14744    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14745    movl   rFP, OUT_ARG1(%esp)
14746    je     1f                                # reload rIBASE & resume if not
14747    movl   %eax, OUT_ARG2(%esp)
14748    call   dvmCheckBefore                    # (dPC, dFP, self)
14749    movl   rSELF, %eax
147501:
14751    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14752    jmp    *dvmAsmInstructionStart+(244*4)
14753
14754/* ------------------------------ */
14755.L_ALT_OP_IPUT_QUICK: /* 0xf5 */
14756/* File: x86/alt_stub.S */
14757/*
14758 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14759 * any interesting requests and then jump to the real instruction
14760 * handler.  Unlike the Arm handler, we can't do this as a tail call
14761 * because rIBASE is caller save and we need to reload it.
14762 *
14763 * Note that unlike in the Arm implementation, we should never arrive
14764 * here with a zero breakFlag because we always refresh rIBASE on
14765 * return.
14766 */
14767    EXPORT_PC
14768    movl   rSELF, %eax
14769    movl   rPC, OUT_ARG0(%esp)
14770    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14771    movl   rFP, OUT_ARG1(%esp)
14772    je     1f                                # reload rIBASE & resume if not
14773    movl   %eax, OUT_ARG2(%esp)
14774    call   dvmCheckBefore                    # (dPC, dFP, self)
14775    movl   rSELF, %eax
147761:
14777    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14778    jmp    *dvmAsmInstructionStart+(245*4)
14779
14780/* ------------------------------ */
14781.L_ALT_OP_IPUT_WIDE_QUICK: /* 0xf6 */
14782/* File: x86/alt_stub.S */
14783/*
14784 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14785 * any interesting requests and then jump to the real instruction
14786 * handler.  Unlike the Arm handler, we can't do this as a tail call
14787 * because rIBASE is caller save and we need to reload it.
14788 *
14789 * Note that unlike in the Arm implementation, we should never arrive
14790 * here with a zero breakFlag because we always refresh rIBASE on
14791 * return.
14792 */
14793    EXPORT_PC
14794    movl   rSELF, %eax
14795    movl   rPC, OUT_ARG0(%esp)
14796    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14797    movl   rFP, OUT_ARG1(%esp)
14798    je     1f                                # reload rIBASE & resume if not
14799    movl   %eax, OUT_ARG2(%esp)
14800    call   dvmCheckBefore                    # (dPC, dFP, self)
14801    movl   rSELF, %eax
148021:
14803    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14804    jmp    *dvmAsmInstructionStart+(246*4)
14805
14806/* ------------------------------ */
14807.L_ALT_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
14808/* File: x86/alt_stub.S */
14809/*
14810 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14811 * any interesting requests and then jump to the real instruction
14812 * handler.  Unlike the Arm handler, we can't do this as a tail call
14813 * because rIBASE is caller save and we need to reload it.
14814 *
14815 * Note that unlike in the Arm implementation, we should never arrive
14816 * here with a zero breakFlag because we always refresh rIBASE on
14817 * return.
14818 */
14819    EXPORT_PC
14820    movl   rSELF, %eax
14821    movl   rPC, OUT_ARG0(%esp)
14822    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14823    movl   rFP, OUT_ARG1(%esp)
14824    je     1f                                # reload rIBASE & resume if not
14825    movl   %eax, OUT_ARG2(%esp)
14826    call   dvmCheckBefore                    # (dPC, dFP, self)
14827    movl   rSELF, %eax
148281:
14829    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14830    jmp    *dvmAsmInstructionStart+(247*4)
14831
14832/* ------------------------------ */
14833.L_ALT_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
14834/* File: x86/alt_stub.S */
14835/*
14836 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14837 * any interesting requests and then jump to the real instruction
14838 * handler.  Unlike the Arm handler, we can't do this as a tail call
14839 * because rIBASE is caller save and we need to reload it.
14840 *
14841 * Note that unlike in the Arm implementation, we should never arrive
14842 * here with a zero breakFlag because we always refresh rIBASE on
14843 * return.
14844 */
14845    EXPORT_PC
14846    movl   rSELF, %eax
14847    movl   rPC, OUT_ARG0(%esp)
14848    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14849    movl   rFP, OUT_ARG1(%esp)
14850    je     1f                                # reload rIBASE & resume if not
14851    movl   %eax, OUT_ARG2(%esp)
14852    call   dvmCheckBefore                    # (dPC, dFP, self)
14853    movl   rSELF, %eax
148541:
14855    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14856    jmp    *dvmAsmInstructionStart+(248*4)
14857
14858/* ------------------------------ */
14859.L_ALT_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
14860/* File: x86/alt_stub.S */
14861/*
14862 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14863 * any interesting requests and then jump to the real instruction
14864 * handler.  Unlike the Arm handler, we can't do this as a tail call
14865 * because rIBASE is caller save and we need to reload it.
14866 *
14867 * Note that unlike in the Arm implementation, we should never arrive
14868 * here with a zero breakFlag because we always refresh rIBASE on
14869 * return.
14870 */
14871    EXPORT_PC
14872    movl   rSELF, %eax
14873    movl   rPC, OUT_ARG0(%esp)
14874    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14875    movl   rFP, OUT_ARG1(%esp)
14876    je     1f                                # reload rIBASE & resume if not
14877    movl   %eax, OUT_ARG2(%esp)
14878    call   dvmCheckBefore                    # (dPC, dFP, self)
14879    movl   rSELF, %eax
148801:
14881    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14882    jmp    *dvmAsmInstructionStart+(249*4)
14883
14884/* ------------------------------ */
14885.L_ALT_OP_INVOKE_SUPER_QUICK: /* 0xfa */
14886/* File: x86/alt_stub.S */
14887/*
14888 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14889 * any interesting requests and then jump to the real instruction
14890 * handler.  Unlike the Arm handler, we can't do this as a tail call
14891 * because rIBASE is caller save and we need to reload it.
14892 *
14893 * Note that unlike in the Arm implementation, we should never arrive
14894 * here with a zero breakFlag because we always refresh rIBASE on
14895 * return.
14896 */
14897    EXPORT_PC
14898    movl   rSELF, %eax
14899    movl   rPC, OUT_ARG0(%esp)
14900    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14901    movl   rFP, OUT_ARG1(%esp)
14902    je     1f                                # reload rIBASE & resume if not
14903    movl   %eax, OUT_ARG2(%esp)
14904    call   dvmCheckBefore                    # (dPC, dFP, self)
14905    movl   rSELF, %eax
149061:
14907    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14908    jmp    *dvmAsmInstructionStart+(250*4)
14909
14910/* ------------------------------ */
14911.L_ALT_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
14912/* File: x86/alt_stub.S */
14913/*
14914 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14915 * any interesting requests and then jump to the real instruction
14916 * handler.  Unlike the Arm handler, we can't do this as a tail call
14917 * because rIBASE is caller save and we need to reload it.
14918 *
14919 * Note that unlike in the Arm implementation, we should never arrive
14920 * here with a zero breakFlag because we always refresh rIBASE on
14921 * return.
14922 */
14923    EXPORT_PC
14924    movl   rSELF, %eax
14925    movl   rPC, OUT_ARG0(%esp)
14926    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14927    movl   rFP, OUT_ARG1(%esp)
14928    je     1f                                # reload rIBASE & resume if not
14929    movl   %eax, OUT_ARG2(%esp)
14930    call   dvmCheckBefore                    # (dPC, dFP, self)
14931    movl   rSELF, %eax
149321:
14933    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14934    jmp    *dvmAsmInstructionStart+(251*4)
14935
14936/* ------------------------------ */
14937.L_ALT_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
14938/* File: x86/alt_stub.S */
14939/*
14940 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14941 * any interesting requests and then jump to the real instruction
14942 * handler.  Unlike the Arm handler, we can't do this as a tail call
14943 * because rIBASE is caller save and we need to reload it.
14944 *
14945 * Note that unlike in the Arm implementation, we should never arrive
14946 * here with a zero breakFlag because we always refresh rIBASE on
14947 * return.
14948 */
14949    EXPORT_PC
14950    movl   rSELF, %eax
14951    movl   rPC, OUT_ARG0(%esp)
14952    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14953    movl   rFP, OUT_ARG1(%esp)
14954    je     1f                                # reload rIBASE & resume if not
14955    movl   %eax, OUT_ARG2(%esp)
14956    call   dvmCheckBefore                    # (dPC, dFP, self)
14957    movl   rSELF, %eax
149581:
14959    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14960    jmp    *dvmAsmInstructionStart+(252*4)
14961
14962/* ------------------------------ */
14963.L_ALT_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
14964/* File: x86/alt_stub.S */
14965/*
14966 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14967 * any interesting requests and then jump to the real instruction
14968 * handler.  Unlike the Arm handler, we can't do this as a tail call
14969 * because rIBASE is caller save and we need to reload it.
14970 *
14971 * Note that unlike in the Arm implementation, we should never arrive
14972 * here with a zero breakFlag because we always refresh rIBASE on
14973 * return.
14974 */
14975    EXPORT_PC
14976    movl   rSELF, %eax
14977    movl   rPC, OUT_ARG0(%esp)
14978    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
14979    movl   rFP, OUT_ARG1(%esp)
14980    je     1f                                # reload rIBASE & resume if not
14981    movl   %eax, OUT_ARG2(%esp)
14982    call   dvmCheckBefore                    # (dPC, dFP, self)
14983    movl   rSELF, %eax
149841:
14985    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
14986    jmp    *dvmAsmInstructionStart+(253*4)
14987
14988/* ------------------------------ */
14989.L_ALT_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
14990/* File: x86/alt_stub.S */
14991/*
14992 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14993 * any interesting requests and then jump to the real instruction
14994 * handler.  Unlike the Arm handler, we can't do this as a tail call
14995 * because rIBASE is caller save and we need to reload it.
14996 *
14997 * Note that unlike in the Arm implementation, we should never arrive
14998 * here with a zero breakFlag because we always refresh rIBASE on
14999 * return.
15000 */
15001    EXPORT_PC
15002    movl   rSELF, %eax
15003    movl   rPC, OUT_ARG0(%esp)
15004    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
15005    movl   rFP, OUT_ARG1(%esp)
15006    je     1f                                # reload rIBASE & resume if not
15007    movl   %eax, OUT_ARG2(%esp)
15008    call   dvmCheckBefore                    # (dPC, dFP, self)
15009    movl   rSELF, %eax
150101:
15011    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
15012    jmp    *dvmAsmInstructionStart+(254*4)
15013
15014/* ------------------------------ */
15015.L_ALT_OP_UNUSED_FF: /* 0xff */
15016/* File: x86/alt_stub.S */
15017/*
15018 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15019 * any interesting requests and then jump to the real instruction
15020 * handler.  Unlike the Arm handler, we can't do this as a tail call
15021 * because rIBASE is caller save and we need to reload it.
15022 *
15023 * Note that unlike in the Arm implementation, we should never arrive
15024 * here with a zero breakFlag because we always refresh rIBASE on
15025 * return.
15026 */
15027    EXPORT_PC
15028    movl   rSELF, %eax
15029    movl   rPC, OUT_ARG0(%esp)
15030    cmpb   $0,offThread_breakFlags(%eax)    # anything to do?
15031    movl   rFP, OUT_ARG1(%esp)
15032    je     1f                                # reload rIBASE & resume if not
15033    movl   %eax, OUT_ARG2(%esp)
15034    call   dvmCheckBefore                    # (dPC, dFP, self)
15035    movl   rSELF, %eax
150361:
15037    movl   offThread_curHandlerTable(%eax), rIBASE # reload rIBASE
15038    jmp    *dvmAsmInstructionStart+(255*4)
15039
15040    .size   dvmAsmAltInstructionStartCode, .-dvmAsmAltInstructionStartCode
15041    .global dvmAsmAltInstructionEndCode
15042dvmAsmAltInstructionEndCode:
15043
15044    .global dvmAsmInstructionStart
15045    .text
15046dvmAsmInstructionStart:
15047    .long .L_OP_NOP /* 0x00 */
15048    .long .L_OP_MOVE /* 0x01 */
15049    .long .L_OP_MOVE_FROM16 /* 0x02 */
15050    .long .L_OP_MOVE_16 /* 0x03 */
15051    .long .L_OP_MOVE_WIDE /* 0x04 */
15052    .long .L_OP_MOVE_WIDE_FROM16 /* 0x05 */
15053    .long .L_OP_MOVE_WIDE_16 /* 0x06 */
15054    .long .L_OP_MOVE_OBJECT /* 0x07 */
15055    .long .L_OP_MOVE_OBJECT_FROM16 /* 0x08 */
15056    .long .L_OP_MOVE_OBJECT_16 /* 0x09 */
15057    .long .L_OP_MOVE_RESULT /* 0x0a */
15058    .long .L_OP_MOVE_RESULT_WIDE /* 0x0b */
15059    .long .L_OP_MOVE_RESULT_OBJECT /* 0x0c */
15060    .long .L_OP_MOVE_EXCEPTION /* 0x0d */
15061    .long .L_OP_RETURN_VOID /* 0x0e */
15062    .long .L_OP_RETURN /* 0x0f */
15063    .long .L_OP_RETURN_WIDE /* 0x10 */
15064    .long .L_OP_RETURN_OBJECT /* 0x11 */
15065    .long .L_OP_CONST_4 /* 0x12 */
15066    .long .L_OP_CONST_16 /* 0x13 */
15067    .long .L_OP_CONST /* 0x14 */
15068    .long .L_OP_CONST_HIGH16 /* 0x15 */
15069    .long .L_OP_CONST_WIDE_16 /* 0x16 */
15070    .long .L_OP_CONST_WIDE_32 /* 0x17 */
15071    .long .L_OP_CONST_WIDE /* 0x18 */
15072    .long .L_OP_CONST_WIDE_HIGH16 /* 0x19 */
15073    .long .L_OP_CONST_STRING /* 0x1a */
15074    .long .L_OP_CONST_STRING_JUMBO /* 0x1b */
15075    .long .L_OP_CONST_CLASS /* 0x1c */
15076    .long .L_OP_MONITOR_ENTER /* 0x1d */
15077    .long .L_OP_MONITOR_EXIT /* 0x1e */
15078    .long .L_OP_CHECK_CAST /* 0x1f */
15079    .long .L_OP_INSTANCE_OF /* 0x20 */
15080    .long .L_OP_ARRAY_LENGTH /* 0x21 */
15081    .long .L_OP_NEW_INSTANCE /* 0x22 */
15082    .long .L_OP_NEW_ARRAY /* 0x23 */
15083    .long .L_OP_FILLED_NEW_ARRAY /* 0x24 */
15084    .long .L_OP_FILLED_NEW_ARRAY_RANGE /* 0x25 */
15085    .long .L_OP_FILL_ARRAY_DATA /* 0x26 */
15086    .long .L_OP_THROW /* 0x27 */
15087    .long .L_OP_GOTO /* 0x28 */
15088    .long .L_OP_GOTO_16 /* 0x29 */
15089    .long .L_OP_GOTO_32 /* 0x2a */
15090    .long .L_OP_PACKED_SWITCH /* 0x2b */
15091    .long .L_OP_SPARSE_SWITCH /* 0x2c */
15092    .long .L_OP_CMPL_FLOAT /* 0x2d */
15093    .long .L_OP_CMPG_FLOAT /* 0x2e */
15094    .long .L_OP_CMPL_DOUBLE /* 0x2f */
15095    .long .L_OP_CMPG_DOUBLE /* 0x30 */
15096    .long .L_OP_CMP_LONG /* 0x31 */
15097    .long .L_OP_IF_EQ /* 0x32 */
15098    .long .L_OP_IF_NE /* 0x33 */
15099    .long .L_OP_IF_LT /* 0x34 */
15100    .long .L_OP_IF_GE /* 0x35 */
15101    .long .L_OP_IF_GT /* 0x36 */
15102    .long .L_OP_IF_LE /* 0x37 */
15103    .long .L_OP_IF_EQZ /* 0x38 */
15104    .long .L_OP_IF_NEZ /* 0x39 */
15105    .long .L_OP_IF_LTZ /* 0x3a */
15106    .long .L_OP_IF_GEZ /* 0x3b */
15107    .long .L_OP_IF_GTZ /* 0x3c */
15108    .long .L_OP_IF_LEZ /* 0x3d */
15109    .long .L_OP_UNUSED_3E /* 0x3e */
15110    .long .L_OP_UNUSED_3F /* 0x3f */
15111    .long .L_OP_UNUSED_40 /* 0x40 */
15112    .long .L_OP_UNUSED_41 /* 0x41 */
15113    .long .L_OP_UNUSED_42 /* 0x42 */
15114    .long .L_OP_UNUSED_43 /* 0x43 */
15115    .long .L_OP_AGET /* 0x44 */
15116    .long .L_OP_AGET_WIDE /* 0x45 */
15117    .long .L_OP_AGET_OBJECT /* 0x46 */
15118    .long .L_OP_AGET_BOOLEAN /* 0x47 */
15119    .long .L_OP_AGET_BYTE /* 0x48 */
15120    .long .L_OP_AGET_CHAR /* 0x49 */
15121    .long .L_OP_AGET_SHORT /* 0x4a */
15122    .long .L_OP_APUT /* 0x4b */
15123    .long .L_OP_APUT_WIDE /* 0x4c */
15124    .long .L_OP_APUT_OBJECT /* 0x4d */
15125    .long .L_OP_APUT_BOOLEAN /* 0x4e */
15126    .long .L_OP_APUT_BYTE /* 0x4f */
15127    .long .L_OP_APUT_CHAR /* 0x50 */
15128    .long .L_OP_APUT_SHORT /* 0x51 */
15129    .long .L_OP_IGET /* 0x52 */
15130    .long .L_OP_IGET_WIDE /* 0x53 */
15131    .long .L_OP_IGET_OBJECT /* 0x54 */
15132    .long .L_OP_IGET_BOOLEAN /* 0x55 */
15133    .long .L_OP_IGET_BYTE /* 0x56 */
15134    .long .L_OP_IGET_CHAR /* 0x57 */
15135    .long .L_OP_IGET_SHORT /* 0x58 */
15136    .long .L_OP_IPUT /* 0x59 */
15137    .long .L_OP_IPUT_WIDE /* 0x5a */
15138    .long .L_OP_IPUT_OBJECT /* 0x5b */
15139    .long .L_OP_IPUT_BOOLEAN /* 0x5c */
15140    .long .L_OP_IPUT_BYTE /* 0x5d */
15141    .long .L_OP_IPUT_CHAR /* 0x5e */
15142    .long .L_OP_IPUT_SHORT /* 0x5f */
15143    .long .L_OP_SGET /* 0x60 */
15144    .long .L_OP_SGET_WIDE /* 0x61 */
15145    .long .L_OP_SGET_OBJECT /* 0x62 */
15146    .long .L_OP_SGET_BOOLEAN /* 0x63 */
15147    .long .L_OP_SGET_BYTE /* 0x64 */
15148    .long .L_OP_SGET_CHAR /* 0x65 */
15149    .long .L_OP_SGET_SHORT /* 0x66 */
15150    .long .L_OP_SPUT /* 0x67 */
15151    .long .L_OP_SPUT_WIDE /* 0x68 */
15152    .long .L_OP_SPUT_OBJECT /* 0x69 */
15153    .long .L_OP_SPUT_BOOLEAN /* 0x6a */
15154    .long .L_OP_SPUT_BYTE /* 0x6b */
15155    .long .L_OP_SPUT_CHAR /* 0x6c */
15156    .long .L_OP_SPUT_SHORT /* 0x6d */
15157    .long .L_OP_INVOKE_VIRTUAL /* 0x6e */
15158    .long .L_OP_INVOKE_SUPER /* 0x6f */
15159    .long .L_OP_INVOKE_DIRECT /* 0x70 */
15160    .long .L_OP_INVOKE_STATIC /* 0x71 */
15161    .long .L_OP_INVOKE_INTERFACE /* 0x72 */
15162    .long .L_OP_UNUSED_73 /* 0x73 */
15163    .long .L_OP_INVOKE_VIRTUAL_RANGE /* 0x74 */
15164    .long .L_OP_INVOKE_SUPER_RANGE /* 0x75 */
15165    .long .L_OP_INVOKE_DIRECT_RANGE /* 0x76 */
15166    .long .L_OP_INVOKE_STATIC_RANGE /* 0x77 */
15167    .long .L_OP_INVOKE_INTERFACE_RANGE /* 0x78 */
15168    .long .L_OP_UNUSED_79 /* 0x79 */
15169    .long .L_OP_UNUSED_7A /* 0x7a */
15170    .long .L_OP_NEG_INT /* 0x7b */
15171    .long .L_OP_NOT_INT /* 0x7c */
15172    .long .L_OP_NEG_LONG /* 0x7d */
15173    .long .L_OP_NOT_LONG /* 0x7e */
15174    .long .L_OP_NEG_FLOAT /* 0x7f */
15175    .long .L_OP_NEG_DOUBLE /* 0x80 */
15176    .long .L_OP_INT_TO_LONG /* 0x81 */
15177    .long .L_OP_INT_TO_FLOAT /* 0x82 */
15178    .long .L_OP_INT_TO_DOUBLE /* 0x83 */
15179    .long .L_OP_LONG_TO_INT /* 0x84 */
15180    .long .L_OP_LONG_TO_FLOAT /* 0x85 */
15181    .long .L_OP_LONG_TO_DOUBLE /* 0x86 */
15182    .long .L_OP_FLOAT_TO_INT /* 0x87 */
15183    .long .L_OP_FLOAT_TO_LONG /* 0x88 */
15184    .long .L_OP_FLOAT_TO_DOUBLE /* 0x89 */
15185    .long .L_OP_DOUBLE_TO_INT /* 0x8a */
15186    .long .L_OP_DOUBLE_TO_LONG /* 0x8b */
15187    .long .L_OP_DOUBLE_TO_FLOAT /* 0x8c */
15188    .long .L_OP_INT_TO_BYTE /* 0x8d */
15189    .long .L_OP_INT_TO_CHAR /* 0x8e */
15190    .long .L_OP_INT_TO_SHORT /* 0x8f */
15191    .long .L_OP_ADD_INT /* 0x90 */
15192    .long .L_OP_SUB_INT /* 0x91 */
15193    .long .L_OP_MUL_INT /* 0x92 */
15194    .long .L_OP_DIV_INT /* 0x93 */
15195    .long .L_OP_REM_INT /* 0x94 */
15196    .long .L_OP_AND_INT /* 0x95 */
15197    .long .L_OP_OR_INT /* 0x96 */
15198    .long .L_OP_XOR_INT /* 0x97 */
15199    .long .L_OP_SHL_INT /* 0x98 */
15200    .long .L_OP_SHR_INT /* 0x99 */
15201    .long .L_OP_USHR_INT /* 0x9a */
15202    .long .L_OP_ADD_LONG /* 0x9b */
15203    .long .L_OP_SUB_LONG /* 0x9c */
15204    .long .L_OP_MUL_LONG /* 0x9d */
15205    .long .L_OP_DIV_LONG /* 0x9e */
15206    .long .L_OP_REM_LONG /* 0x9f */
15207    .long .L_OP_AND_LONG /* 0xa0 */
15208    .long .L_OP_OR_LONG /* 0xa1 */
15209    .long .L_OP_XOR_LONG /* 0xa2 */
15210    .long .L_OP_SHL_LONG /* 0xa3 */
15211    .long .L_OP_SHR_LONG /* 0xa4 */
15212    .long .L_OP_USHR_LONG /* 0xa5 */
15213    .long .L_OP_ADD_FLOAT /* 0xa6 */
15214    .long .L_OP_SUB_FLOAT /* 0xa7 */
15215    .long .L_OP_MUL_FLOAT /* 0xa8 */
15216    .long .L_OP_DIV_FLOAT /* 0xa9 */
15217    .long .L_OP_REM_FLOAT /* 0xaa */
15218    .long .L_OP_ADD_DOUBLE /* 0xab */
15219    .long .L_OP_SUB_DOUBLE /* 0xac */
15220    .long .L_OP_MUL_DOUBLE /* 0xad */
15221    .long .L_OP_DIV_DOUBLE /* 0xae */
15222    .long .L_OP_REM_DOUBLE /* 0xaf */
15223    .long .L_OP_ADD_INT_2ADDR /* 0xb0 */
15224    .long .L_OP_SUB_INT_2ADDR /* 0xb1 */
15225    .long .L_OP_MUL_INT_2ADDR /* 0xb2 */
15226    .long .L_OP_DIV_INT_2ADDR /* 0xb3 */
15227    .long .L_OP_REM_INT_2ADDR /* 0xb4 */
15228    .long .L_OP_AND_INT_2ADDR /* 0xb5 */
15229    .long .L_OP_OR_INT_2ADDR /* 0xb6 */
15230    .long .L_OP_XOR_INT_2ADDR /* 0xb7 */
15231    .long .L_OP_SHL_INT_2ADDR /* 0xb8 */
15232    .long .L_OP_SHR_INT_2ADDR /* 0xb9 */
15233    .long .L_OP_USHR_INT_2ADDR /* 0xba */
15234    .long .L_OP_ADD_LONG_2ADDR /* 0xbb */
15235    .long .L_OP_SUB_LONG_2ADDR /* 0xbc */
15236    .long .L_OP_MUL_LONG_2ADDR /* 0xbd */
15237    .long .L_OP_DIV_LONG_2ADDR /* 0xbe */
15238    .long .L_OP_REM_LONG_2ADDR /* 0xbf */
15239    .long .L_OP_AND_LONG_2ADDR /* 0xc0 */
15240    .long .L_OP_OR_LONG_2ADDR /* 0xc1 */
15241    .long .L_OP_XOR_LONG_2ADDR /* 0xc2 */
15242    .long .L_OP_SHL_LONG_2ADDR /* 0xc3 */
15243    .long .L_OP_SHR_LONG_2ADDR /* 0xc4 */
15244    .long .L_OP_USHR_LONG_2ADDR /* 0xc5 */
15245    .long .L_OP_ADD_FLOAT_2ADDR /* 0xc6 */
15246    .long .L_OP_SUB_FLOAT_2ADDR /* 0xc7 */
15247    .long .L_OP_MUL_FLOAT_2ADDR /* 0xc8 */
15248    .long .L_OP_DIV_FLOAT_2ADDR /* 0xc9 */
15249    .long .L_OP_REM_FLOAT_2ADDR /* 0xca */
15250    .long .L_OP_ADD_DOUBLE_2ADDR /* 0xcb */
15251    .long .L_OP_SUB_DOUBLE_2ADDR /* 0xcc */
15252    .long .L_OP_MUL_DOUBLE_2ADDR /* 0xcd */
15253    .long .L_OP_DIV_DOUBLE_2ADDR /* 0xce */
15254    .long .L_OP_REM_DOUBLE_2ADDR /* 0xcf */
15255    .long .L_OP_ADD_INT_LIT16 /* 0xd0 */
15256    .long .L_OP_RSUB_INT /* 0xd1 */
15257    .long .L_OP_MUL_INT_LIT16 /* 0xd2 */
15258    .long .L_OP_DIV_INT_LIT16 /* 0xd3 */
15259    .long .L_OP_REM_INT_LIT16 /* 0xd4 */
15260    .long .L_OP_AND_INT_LIT16 /* 0xd5 */
15261    .long .L_OP_OR_INT_LIT16 /* 0xd6 */
15262    .long .L_OP_XOR_INT_LIT16 /* 0xd7 */
15263    .long .L_OP_ADD_INT_LIT8 /* 0xd8 */
15264    .long .L_OP_RSUB_INT_LIT8 /* 0xd9 */
15265    .long .L_OP_MUL_INT_LIT8 /* 0xda */
15266    .long .L_OP_DIV_INT_LIT8 /* 0xdb */
15267    .long .L_OP_REM_INT_LIT8 /* 0xdc */
15268    .long .L_OP_AND_INT_LIT8 /* 0xdd */
15269    .long .L_OP_OR_INT_LIT8 /* 0xde */
15270    .long .L_OP_XOR_INT_LIT8 /* 0xdf */
15271    .long .L_OP_SHL_INT_LIT8 /* 0xe0 */
15272    .long .L_OP_SHR_INT_LIT8 /* 0xe1 */
15273    .long .L_OP_USHR_INT_LIT8 /* 0xe2 */
15274    .long .L_OP_IGET_VOLATILE /* 0xe3 */
15275    .long .L_OP_IPUT_VOLATILE /* 0xe4 */
15276    .long .L_OP_SGET_VOLATILE /* 0xe5 */
15277    .long .L_OP_SPUT_VOLATILE /* 0xe6 */
15278    .long .L_OP_IGET_OBJECT_VOLATILE /* 0xe7 */
15279    .long .L_OP_IGET_WIDE_VOLATILE /* 0xe8 */
15280    .long .L_OP_IPUT_WIDE_VOLATILE /* 0xe9 */
15281    .long .L_OP_SGET_WIDE_VOLATILE /* 0xea */
15282    .long .L_OP_SPUT_WIDE_VOLATILE /* 0xeb */
15283    .long .L_OP_BREAKPOINT /* 0xec */
15284    .long .L_OP_THROW_VERIFICATION_ERROR /* 0xed */
15285    .long .L_OP_EXECUTE_INLINE /* 0xee */
15286    .long .L_OP_EXECUTE_INLINE_RANGE /* 0xef */
15287    .long .L_OP_INVOKE_OBJECT_INIT_RANGE /* 0xf0 */
15288    .long .L_OP_RETURN_VOID_BARRIER /* 0xf1 */
15289    .long .L_OP_IGET_QUICK /* 0xf2 */
15290    .long .L_OP_IGET_WIDE_QUICK /* 0xf3 */
15291    .long .L_OP_IGET_OBJECT_QUICK /* 0xf4 */
15292    .long .L_OP_IPUT_QUICK /* 0xf5 */
15293    .long .L_OP_IPUT_WIDE_QUICK /* 0xf6 */
15294    .long .L_OP_IPUT_OBJECT_QUICK /* 0xf7 */
15295    .long .L_OP_INVOKE_VIRTUAL_QUICK /* 0xf8 */
15296    .long .L_OP_INVOKE_VIRTUAL_QUICK_RANGE /* 0xf9 */
15297    .long .L_OP_INVOKE_SUPER_QUICK /* 0xfa */
15298    .long .L_OP_INVOKE_SUPER_QUICK_RANGE /* 0xfb */
15299    .long .L_OP_IPUT_OBJECT_VOLATILE /* 0xfc */
15300    .long .L_OP_SGET_OBJECT_VOLATILE /* 0xfd */
15301    .long .L_OP_SPUT_OBJECT_VOLATILE /* 0xfe */
15302    .long .L_OP_UNUSED_FF /* 0xff */
15303
15304    .global dvmAsmAltInstructionStart
15305    .text
15306dvmAsmAltInstructionStart:
15307    .long .L_ALT_OP_NOP /* 0x00 */
15308    .long .L_ALT_OP_MOVE /* 0x01 */
15309    .long .L_ALT_OP_MOVE_FROM16 /* 0x02 */
15310    .long .L_ALT_OP_MOVE_16 /* 0x03 */
15311    .long .L_ALT_OP_MOVE_WIDE /* 0x04 */
15312    .long .L_ALT_OP_MOVE_WIDE_FROM16 /* 0x05 */
15313    .long .L_ALT_OP_MOVE_WIDE_16 /* 0x06 */
15314    .long .L_ALT_OP_MOVE_OBJECT /* 0x07 */
15315    .long .L_ALT_OP_MOVE_OBJECT_FROM16 /* 0x08 */
15316    .long .L_ALT_OP_MOVE_OBJECT_16 /* 0x09 */
15317    .long .L_ALT_OP_MOVE_RESULT /* 0x0a */
15318    .long .L_ALT_OP_MOVE_RESULT_WIDE /* 0x0b */
15319    .long .L_ALT_OP_MOVE_RESULT_OBJECT /* 0x0c */
15320    .long .L_ALT_OP_MOVE_EXCEPTION /* 0x0d */
15321    .long .L_ALT_OP_RETURN_VOID /* 0x0e */
15322    .long .L_ALT_OP_RETURN /* 0x0f */
15323    .long .L_ALT_OP_RETURN_WIDE /* 0x10 */
15324    .long .L_ALT_OP_RETURN_OBJECT /* 0x11 */
15325    .long .L_ALT_OP_CONST_4 /* 0x12 */
15326    .long .L_ALT_OP_CONST_16 /* 0x13 */
15327    .long .L_ALT_OP_CONST /* 0x14 */
15328    .long .L_ALT_OP_CONST_HIGH16 /* 0x15 */
15329    .long .L_ALT_OP_CONST_WIDE_16 /* 0x16 */
15330    .long .L_ALT_OP_CONST_WIDE_32 /* 0x17 */
15331    .long .L_ALT_OP_CONST_WIDE /* 0x18 */
15332    .long .L_ALT_OP_CONST_WIDE_HIGH16 /* 0x19 */
15333    .long .L_ALT_OP_CONST_STRING /* 0x1a */
15334    .long .L_ALT_OP_CONST_STRING_JUMBO /* 0x1b */
15335    .long .L_ALT_OP_CONST_CLASS /* 0x1c */
15336    .long .L_ALT_OP_MONITOR_ENTER /* 0x1d */
15337    .long .L_ALT_OP_MONITOR_EXIT /* 0x1e */
15338    .long .L_ALT_OP_CHECK_CAST /* 0x1f */
15339    .long .L_ALT_OP_INSTANCE_OF /* 0x20 */
15340    .long .L_ALT_OP_ARRAY_LENGTH /* 0x21 */
15341    .long .L_ALT_OP_NEW_INSTANCE /* 0x22 */
15342    .long .L_ALT_OP_NEW_ARRAY /* 0x23 */
15343    .long .L_ALT_OP_FILLED_NEW_ARRAY /* 0x24 */
15344    .long .L_ALT_OP_FILLED_NEW_ARRAY_RANGE /* 0x25 */
15345    .long .L_ALT_OP_FILL_ARRAY_DATA /* 0x26 */
15346    .long .L_ALT_OP_THROW /* 0x27 */
15347    .long .L_ALT_OP_GOTO /* 0x28 */
15348    .long .L_ALT_OP_GOTO_16 /* 0x29 */
15349    .long .L_ALT_OP_GOTO_32 /* 0x2a */
15350    .long .L_ALT_OP_PACKED_SWITCH /* 0x2b */
15351    .long .L_ALT_OP_SPARSE_SWITCH /* 0x2c */
15352    .long .L_ALT_OP_CMPL_FLOAT /* 0x2d */
15353    .long .L_ALT_OP_CMPG_FLOAT /* 0x2e */
15354    .long .L_ALT_OP_CMPL_DOUBLE /* 0x2f */
15355    .long .L_ALT_OP_CMPG_DOUBLE /* 0x30 */
15356    .long .L_ALT_OP_CMP_LONG /* 0x31 */
15357    .long .L_ALT_OP_IF_EQ /* 0x32 */
15358    .long .L_ALT_OP_IF_NE /* 0x33 */
15359    .long .L_ALT_OP_IF_LT /* 0x34 */
15360    .long .L_ALT_OP_IF_GE /* 0x35 */
15361    .long .L_ALT_OP_IF_GT /* 0x36 */
15362    .long .L_ALT_OP_IF_LE /* 0x37 */
15363    .long .L_ALT_OP_IF_EQZ /* 0x38 */
15364    .long .L_ALT_OP_IF_NEZ /* 0x39 */
15365    .long .L_ALT_OP_IF_LTZ /* 0x3a */
15366    .long .L_ALT_OP_IF_GEZ /* 0x3b */
15367    .long .L_ALT_OP_IF_GTZ /* 0x3c */
15368    .long .L_ALT_OP_IF_LEZ /* 0x3d */
15369    .long .L_ALT_OP_UNUSED_3E /* 0x3e */
15370    .long .L_ALT_OP_UNUSED_3F /* 0x3f */
15371    .long .L_ALT_OP_UNUSED_40 /* 0x40 */
15372    .long .L_ALT_OP_UNUSED_41 /* 0x41 */
15373    .long .L_ALT_OP_UNUSED_42 /* 0x42 */
15374    .long .L_ALT_OP_UNUSED_43 /* 0x43 */
15375    .long .L_ALT_OP_AGET /* 0x44 */
15376    .long .L_ALT_OP_AGET_WIDE /* 0x45 */
15377    .long .L_ALT_OP_AGET_OBJECT /* 0x46 */
15378    .long .L_ALT_OP_AGET_BOOLEAN /* 0x47 */
15379    .long .L_ALT_OP_AGET_BYTE /* 0x48 */
15380    .long .L_ALT_OP_AGET_CHAR /* 0x49 */
15381    .long .L_ALT_OP_AGET_SHORT /* 0x4a */
15382    .long .L_ALT_OP_APUT /* 0x4b */
15383    .long .L_ALT_OP_APUT_WIDE /* 0x4c */
15384    .long .L_ALT_OP_APUT_OBJECT /* 0x4d */
15385    .long .L_ALT_OP_APUT_BOOLEAN /* 0x4e */
15386    .long .L_ALT_OP_APUT_BYTE /* 0x4f */
15387    .long .L_ALT_OP_APUT_CHAR /* 0x50 */
15388    .long .L_ALT_OP_APUT_SHORT /* 0x51 */
15389    .long .L_ALT_OP_IGET /* 0x52 */
15390    .long .L_ALT_OP_IGET_WIDE /* 0x53 */
15391    .long .L_ALT_OP_IGET_OBJECT /* 0x54 */
15392    .long .L_ALT_OP_IGET_BOOLEAN /* 0x55 */
15393    .long .L_ALT_OP_IGET_BYTE /* 0x56 */
15394    .long .L_ALT_OP_IGET_CHAR /* 0x57 */
15395    .long .L_ALT_OP_IGET_SHORT /* 0x58 */
15396    .long .L_ALT_OP_IPUT /* 0x59 */
15397    .long .L_ALT_OP_IPUT_WIDE /* 0x5a */
15398    .long .L_ALT_OP_IPUT_OBJECT /* 0x5b */
15399    .long .L_ALT_OP_IPUT_BOOLEAN /* 0x5c */
15400    .long .L_ALT_OP_IPUT_BYTE /* 0x5d */
15401    .long .L_ALT_OP_IPUT_CHAR /* 0x5e */
15402    .long .L_ALT_OP_IPUT_SHORT /* 0x5f */
15403    .long .L_ALT_OP_SGET /* 0x60 */
15404    .long .L_ALT_OP_SGET_WIDE /* 0x61 */
15405    .long .L_ALT_OP_SGET_OBJECT /* 0x62 */
15406    .long .L_ALT_OP_SGET_BOOLEAN /* 0x63 */
15407    .long .L_ALT_OP_SGET_BYTE /* 0x64 */
15408    .long .L_ALT_OP_SGET_CHAR /* 0x65 */
15409    .long .L_ALT_OP_SGET_SHORT /* 0x66 */
15410    .long .L_ALT_OP_SPUT /* 0x67 */
15411    .long .L_ALT_OP_SPUT_WIDE /* 0x68 */
15412    .long .L_ALT_OP_SPUT_OBJECT /* 0x69 */
15413    .long .L_ALT_OP_SPUT_BOOLEAN /* 0x6a */
15414    .long .L_ALT_OP_SPUT_BYTE /* 0x6b */
15415    .long .L_ALT_OP_SPUT_CHAR /* 0x6c */
15416    .long .L_ALT_OP_SPUT_SHORT /* 0x6d */
15417    .long .L_ALT_OP_INVOKE_VIRTUAL /* 0x6e */
15418    .long .L_ALT_OP_INVOKE_SUPER /* 0x6f */
15419    .long .L_ALT_OP_INVOKE_DIRECT /* 0x70 */
15420    .long .L_ALT_OP_INVOKE_STATIC /* 0x71 */
15421    .long .L_ALT_OP_INVOKE_INTERFACE /* 0x72 */
15422    .long .L_ALT_OP_UNUSED_73 /* 0x73 */
15423    .long .L_ALT_OP_INVOKE_VIRTUAL_RANGE /* 0x74 */
15424    .long .L_ALT_OP_INVOKE_SUPER_RANGE /* 0x75 */
15425    .long .L_ALT_OP_INVOKE_DIRECT_RANGE /* 0x76 */
15426    .long .L_ALT_OP_INVOKE_STATIC_RANGE /* 0x77 */
15427    .long .L_ALT_OP_INVOKE_INTERFACE_RANGE /* 0x78 */
15428    .long .L_ALT_OP_UNUSED_79 /* 0x79 */
15429    .long .L_ALT_OP_UNUSED_7A /* 0x7a */
15430    .long .L_ALT_OP_NEG_INT /* 0x7b */
15431    .long .L_ALT_OP_NOT_INT /* 0x7c */
15432    .long .L_ALT_OP_NEG_LONG /* 0x7d */
15433    .long .L_ALT_OP_NOT_LONG /* 0x7e */
15434    .long .L_ALT_OP_NEG_FLOAT /* 0x7f */
15435    .long .L_ALT_OP_NEG_DOUBLE /* 0x80 */
15436    .long .L_ALT_OP_INT_TO_LONG /* 0x81 */
15437    .long .L_ALT_OP_INT_TO_FLOAT /* 0x82 */
15438    .long .L_ALT_OP_INT_TO_DOUBLE /* 0x83 */
15439    .long .L_ALT_OP_LONG_TO_INT /* 0x84 */
15440    .long .L_ALT_OP_LONG_TO_FLOAT /* 0x85 */
15441    .long .L_ALT_OP_LONG_TO_DOUBLE /* 0x86 */
15442    .long .L_ALT_OP_FLOAT_TO_INT /* 0x87 */
15443    .long .L_ALT_OP_FLOAT_TO_LONG /* 0x88 */
15444    .long .L_ALT_OP_FLOAT_TO_DOUBLE /* 0x89 */
15445    .long .L_ALT_OP_DOUBLE_TO_INT /* 0x8a */
15446    .long .L_ALT_OP_DOUBLE_TO_LONG /* 0x8b */
15447    .long .L_ALT_OP_DOUBLE_TO_FLOAT /* 0x8c */
15448    .long .L_ALT_OP_INT_TO_BYTE /* 0x8d */
15449    .long .L_ALT_OP_INT_TO_CHAR /* 0x8e */
15450    .long .L_ALT_OP_INT_TO_SHORT /* 0x8f */
15451    .long .L_ALT_OP_ADD_INT /* 0x90 */
15452    .long .L_ALT_OP_SUB_INT /* 0x91 */
15453    .long .L_ALT_OP_MUL_INT /* 0x92 */
15454    .long .L_ALT_OP_DIV_INT /* 0x93 */
15455    .long .L_ALT_OP_REM_INT /* 0x94 */
15456    .long .L_ALT_OP_AND_INT /* 0x95 */
15457    .long .L_ALT_OP_OR_INT /* 0x96 */
15458    .long .L_ALT_OP_XOR_INT /* 0x97 */
15459    .long .L_ALT_OP_SHL_INT /* 0x98 */
15460    .long .L_ALT_OP_SHR_INT /* 0x99 */
15461    .long .L_ALT_OP_USHR_INT /* 0x9a */
15462    .long .L_ALT_OP_ADD_LONG /* 0x9b */
15463    .long .L_ALT_OP_SUB_LONG /* 0x9c */
15464    .long .L_ALT_OP_MUL_LONG /* 0x9d */
15465    .long .L_ALT_OP_DIV_LONG /* 0x9e */
15466    .long .L_ALT_OP_REM_LONG /* 0x9f */
15467    .long .L_ALT_OP_AND_LONG /* 0xa0 */
15468    .long .L_ALT_OP_OR_LONG /* 0xa1 */
15469    .long .L_ALT_OP_XOR_LONG /* 0xa2 */
15470    .long .L_ALT_OP_SHL_LONG /* 0xa3 */
15471    .long .L_ALT_OP_SHR_LONG /* 0xa4 */
15472    .long .L_ALT_OP_USHR_LONG /* 0xa5 */
15473    .long .L_ALT_OP_ADD_FLOAT /* 0xa6 */
15474    .long .L_ALT_OP_SUB_FLOAT /* 0xa7 */
15475    .long .L_ALT_OP_MUL_FLOAT /* 0xa8 */
15476    .long .L_ALT_OP_DIV_FLOAT /* 0xa9 */
15477    .long .L_ALT_OP_REM_FLOAT /* 0xaa */
15478    .long .L_ALT_OP_ADD_DOUBLE /* 0xab */
15479    .long .L_ALT_OP_SUB_DOUBLE /* 0xac */
15480    .long .L_ALT_OP_MUL_DOUBLE /* 0xad */
15481    .long .L_ALT_OP_DIV_DOUBLE /* 0xae */
15482    .long .L_ALT_OP_REM_DOUBLE /* 0xaf */
15483    .long .L_ALT_OP_ADD_INT_2ADDR /* 0xb0 */
15484    .long .L_ALT_OP_SUB_INT_2ADDR /* 0xb1 */
15485    .long .L_ALT_OP_MUL_INT_2ADDR /* 0xb2 */
15486    .long .L_ALT_OP_DIV_INT_2ADDR /* 0xb3 */
15487    .long .L_ALT_OP_REM_INT_2ADDR /* 0xb4 */
15488    .long .L_ALT_OP_AND_INT_2ADDR /* 0xb5 */
15489    .long .L_ALT_OP_OR_INT_2ADDR /* 0xb6 */
15490    .long .L_ALT_OP_XOR_INT_2ADDR /* 0xb7 */
15491    .long .L_ALT_OP_SHL_INT_2ADDR /* 0xb8 */
15492    .long .L_ALT_OP_SHR_INT_2ADDR /* 0xb9 */
15493    .long .L_ALT_OP_USHR_INT_2ADDR /* 0xba */
15494    .long .L_ALT_OP_ADD_LONG_2ADDR /* 0xbb */
15495    .long .L_ALT_OP_SUB_LONG_2ADDR /* 0xbc */
15496    .long .L_ALT_OP_MUL_LONG_2ADDR /* 0xbd */
15497    .long .L_ALT_OP_DIV_LONG_2ADDR /* 0xbe */
15498    .long .L_ALT_OP_REM_LONG_2ADDR /* 0xbf */
15499    .long .L_ALT_OP_AND_LONG_2ADDR /* 0xc0 */
15500    .long .L_ALT_OP_OR_LONG_2ADDR /* 0xc1 */
15501    .long .L_ALT_OP_XOR_LONG_2ADDR /* 0xc2 */
15502    .long .L_ALT_OP_SHL_LONG_2ADDR /* 0xc3 */
15503    .long .L_ALT_OP_SHR_LONG_2ADDR /* 0xc4 */
15504    .long .L_ALT_OP_USHR_LONG_2ADDR /* 0xc5 */
15505    .long .L_ALT_OP_ADD_FLOAT_2ADDR /* 0xc6 */
15506    .long .L_ALT_OP_SUB_FLOAT_2ADDR /* 0xc7 */
15507    .long .L_ALT_OP_MUL_FLOAT_2ADDR /* 0xc8 */
15508    .long .L_ALT_OP_DIV_FLOAT_2ADDR /* 0xc9 */
15509    .long .L_ALT_OP_REM_FLOAT_2ADDR /* 0xca */
15510    .long .L_ALT_OP_ADD_DOUBLE_2ADDR /* 0xcb */
15511    .long .L_ALT_OP_SUB_DOUBLE_2ADDR /* 0xcc */
15512    .long .L_ALT_OP_MUL_DOUBLE_2ADDR /* 0xcd */
15513    .long .L_ALT_OP_DIV_DOUBLE_2ADDR /* 0xce */
15514    .long .L_ALT_OP_REM_DOUBLE_2ADDR /* 0xcf */
15515    .long .L_ALT_OP_ADD_INT_LIT16 /* 0xd0 */
15516    .long .L_ALT_OP_RSUB_INT /* 0xd1 */
15517    .long .L_ALT_OP_MUL_INT_LIT16 /* 0xd2 */
15518    .long .L_ALT_OP_DIV_INT_LIT16 /* 0xd3 */
15519    .long .L_ALT_OP_REM_INT_LIT16 /* 0xd4 */
15520    .long .L_ALT_OP_AND_INT_LIT16 /* 0xd5 */
15521    .long .L_ALT_OP_OR_INT_LIT16 /* 0xd6 */
15522    .long .L_ALT_OP_XOR_INT_LIT16 /* 0xd7 */
15523    .long .L_ALT_OP_ADD_INT_LIT8 /* 0xd8 */
15524    .long .L_ALT_OP_RSUB_INT_LIT8 /* 0xd9 */
15525    .long .L_ALT_OP_MUL_INT_LIT8 /* 0xda */
15526    .long .L_ALT_OP_DIV_INT_LIT8 /* 0xdb */
15527    .long .L_ALT_OP_REM_INT_LIT8 /* 0xdc */
15528    .long .L_ALT_OP_AND_INT_LIT8 /* 0xdd */
15529    .long .L_ALT_OP_OR_INT_LIT8 /* 0xde */
15530    .long .L_ALT_OP_XOR_INT_LIT8 /* 0xdf */
15531    .long .L_ALT_OP_SHL_INT_LIT8 /* 0xe0 */
15532    .long .L_ALT_OP_SHR_INT_LIT8 /* 0xe1 */
15533    .long .L_ALT_OP_USHR_INT_LIT8 /* 0xe2 */
15534    .long .L_ALT_OP_IGET_VOLATILE /* 0xe3 */
15535    .long .L_ALT_OP_IPUT_VOLATILE /* 0xe4 */
15536    .long .L_ALT_OP_SGET_VOLATILE /* 0xe5 */
15537    .long .L_ALT_OP_SPUT_VOLATILE /* 0xe6 */
15538    .long .L_ALT_OP_IGET_OBJECT_VOLATILE /* 0xe7 */
15539    .long .L_ALT_OP_IGET_WIDE_VOLATILE /* 0xe8 */
15540    .long .L_ALT_OP_IPUT_WIDE_VOLATILE /* 0xe9 */
15541    .long .L_ALT_OP_SGET_WIDE_VOLATILE /* 0xea */
15542    .long .L_ALT_OP_SPUT_WIDE_VOLATILE /* 0xeb */
15543    .long .L_ALT_OP_BREAKPOINT /* 0xec */
15544    .long .L_ALT_OP_THROW_VERIFICATION_ERROR /* 0xed */
15545    .long .L_ALT_OP_EXECUTE_INLINE /* 0xee */
15546    .long .L_ALT_OP_EXECUTE_INLINE_RANGE /* 0xef */
15547    .long .L_ALT_OP_INVOKE_OBJECT_INIT_RANGE /* 0xf0 */
15548    .long .L_ALT_OP_RETURN_VOID_BARRIER /* 0xf1 */
15549    .long .L_ALT_OP_IGET_QUICK /* 0xf2 */
15550    .long .L_ALT_OP_IGET_WIDE_QUICK /* 0xf3 */
15551    .long .L_ALT_OP_IGET_OBJECT_QUICK /* 0xf4 */
15552    .long .L_ALT_OP_IPUT_QUICK /* 0xf5 */
15553    .long .L_ALT_OP_IPUT_WIDE_QUICK /* 0xf6 */
15554    .long .L_ALT_OP_IPUT_OBJECT_QUICK /* 0xf7 */
15555    .long .L_ALT_OP_INVOKE_VIRTUAL_QUICK /* 0xf8 */
15556    .long .L_ALT_OP_INVOKE_VIRTUAL_QUICK_RANGE /* 0xf9 */
15557    .long .L_ALT_OP_INVOKE_SUPER_QUICK /* 0xfa */
15558    .long .L_ALT_OP_INVOKE_SUPER_QUICK_RANGE /* 0xfb */
15559    .long .L_ALT_OP_IPUT_OBJECT_VOLATILE /* 0xfc */
15560    .long .L_ALT_OP_SGET_OBJECT_VOLATILE /* 0xfd */
15561    .long .L_ALT_OP_SPUT_OBJECT_VOLATILE /* 0xfe */
15562    .long .L_ALT_OP_UNUSED_FF /* 0xff */
15563/* File: x86/entry.S */
15564/*
15565 * Copyright (C) 2008 The Android Open Source Project
15566 *
15567 * Licensed under the Apache License, Version 2.0 (the "License");
15568 * you may not use this file except in compliance with the License.
15569 * You may obtain a copy of the License at
15570 *
15571 *      http://www.apache.org/licenses/LICENSE-2.0
15572 *
15573 * Unless required by applicable law or agreed to in writing, software
15574 * distributed under the License is distributed on an "AS IS" BASIS,
15575 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15576 * See the License for the specific language governing permissions and
15577 * limitations under the License.
15578 */
15579
15580
15581    .text
15582    .global dvmMterpStdRun
15583    .type   dvmMterpStdRun, %function
15584/*
15585 * bool dvmMterpStdRun(Thread* self)
15586 *
15587 * Interpreter entry point.  Returns changeInterp.
15588 *
15589 */
15590dvmMterpStdRun:
15591    push    %ebp                 # save caller base pointer
15592    movl    %esp, %ebp           # set our %ebp
15593    movl    rSELF, %ecx          # get incoming rSELF
15594/*
15595 * At this point we've allocated one slot on the stack
15596 * via push and stack is 8-byte aligned.  Allocate space
15597 * for 9 spill slots, 4 local slots, 5 arg slots to bring
15598 * us to 16-byte alignment
15599 */
15600    subl    $(FRAME_SIZE-4), %esp
15601
15602/* Spill callee save regs */
15603    movl    %edi,EDI_SPILL(%ebp)
15604    movl    %esi,ESI_SPILL(%ebp)
15605    movl    %ebx,EBX_SPILL(%ebp)
15606
15607/* Set up "named" registers */
15608    movl    offThread_pc(%ecx),rPC
15609    movl    offThread_curFrame(%ecx),rFP
15610    movl    offThread_curHandlerTable(%ecx),rIBASE
15611
15612    /* Remember %esp for future "longjmp" */
15613    movl    %esp,offThread_bailPtr(%ecx)
15614
15615    /* Fetch next instruction before potential jump */
15616    FETCH_INST
15617#if defined(WITH_JIT)
15618    GET_JIT_PROF_TABLE %ecx %eax
15619    movl        $0, offThread_inJitCodeCache(%ecx)
15620    cmpl        $0, %eax
15621    jne         common_updateProfile # set up %ebx & %edx & rPC
15622#endif
15623
15624   /* Normal case: start executing the instruction at rPC */
15625    GOTO_NEXT
15626
15627    .global dvmMterpStdBail
15628    .type   dvmMterpStdBail, %function
15629/*
15630 * void dvmMterpStdBail(Thread* self, bool changeInterp)
15631 *
15632 * Restore the stack pointer and PC from the save point established on entry.
15633 * This is essentially the same as a longjmp, but should be cheaper.  The
15634 * last instruction causes us to return to whoever called dvmMterpStdRun.
15635 *
15636 * We're not going to build a standard frame here, so the arg accesses will
15637 * look a little strange.
15638 *
15639 * On entry:
15640 *  esp+4 (arg0)  Thread* self
15641 *  esp+8 (arg1)  bool changeInterp
15642 */
15643dvmMterpStdBail:
15644    movl    4(%esp),%ecx                 # grab self
15645    movl    8(%esp),%eax                 # changeInterp to return reg
15646    movl    offThread_bailPtr(%ecx),%esp # Restore "setjmp" esp
15647    movl    %esp,%ebp
15648    addl    $(FRAME_SIZE-4), %ebp       # Restore %ebp at point of setjmp
15649    movl    EDI_SPILL(%ebp),%edi
15650    movl    ESI_SPILL(%ebp),%esi
15651    movl    EBX_SPILL(%ebp),%ebx
15652    movl    %ebp, %esp                   # strip frame
15653    pop     %ebp                         # restore caller's ebp
15654    ret                                  # return to dvmMterpStdRun's caller
15655
15656
15657#ifdef WITH_JIT
15658    .global     dvmNcgInvokeInterpreter
15659    .type       dvmNcgInvokeInterpreter, %function
15660/* input: start of method in %eax */
15661dvmNcgInvokeInterpreter:
15662    movl        %eax, rPC
15663    movl   rSELF, %ecx
15664    movl   offThread_curHandlerTable(%ecx),rIBASE
15665    FETCH_INST_R %ecx                    # %edx<- opcode
15666    GOTO_NEXT_R %ecx                    # start executing the instruction at rPC
15667#endif
15668
15669/*
15670 * Strings
15671 */
15672    .section    .rodata
15673.LstrBadEntryPoint:
15674    .asciz  "Bad entry point %d\n"
15675
15676
15677/* File: x86/footer.S */
15678/*
15679 * Copyright (C) 2008 The Android Open Source Project
15680 *
15681 * Licensed under the Apache License, Version 2.0 (the "License");
15682 * you may not use this file except in compliance with the License.
15683 * You may obtain a copy of the License at
15684 *
15685 *      http://www.apache.org/licenses/LICENSE-2.0
15686 *
15687 * Unless required by applicable law or agreed to in writing, software
15688 * distributed under the License is distributed on an "AS IS" BASIS,
15689 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15690 * See the License for the specific language governing permissions and
15691 * limitations under the License.
15692 */
15693/*
15694 * Common subroutines and data.
15695 */
15696
15697#if defined(WITH_JIT)
15698/*
15699 * JIT-related re-entries into the interpreter.  In general, if the
15700 * exit from a translation can at some point be chained, the entry
15701 * here requires that control arrived via a call, and that the "rp"
15702 * on TOS is actually a pointer to a 32-bit cell containing the Dalvik PC
15703 * of the next insn to handle.  If no chaining will happen, the entry
15704 * should be reached via a direct jump and rPC set beforehand.
15705 */
15706
15707    .global dvmJitToInterpPunt
15708/*
15709 * The compiler will generate a jump to this entry point when it is
15710 * having difficulty translating a Dalvik instruction.  We must skip
15711 * the code cache lookup & prevent chaining to avoid bouncing between
15712 * the interpreter and code cache. rPC must be set on entry.
15713 */
15714dvmJitToInterpPunt:
15715    GET_PC
15716#if defined(WITH_JIT_TUNING)
15717    movl   rPC, OUT_ARG0(%esp)
15718    call   dvmBumpPunt
15719#endif
15720    movl   rSELF, %ecx
15721    movl   offThread_curHandlerTable(%ecx),rIBASE
15722    movl        $0, offThread_inJitCodeCache(%ecx)
15723    FETCH_INST_R %ecx
15724    GOTO_NEXT_R %ecx
15725
15726    .global dvmJitToInterpSingleStep
15727/*
15728 * Return to the interpreter to handle a single instruction.
15729 * Should be reached via a call.
15730 * On entry:
15731 *   0(%esp)          <= native return address within trace
15732 *   rPC              <= Dalvik PC of this instruction
15733 *   OUT_ARG0+4(%esp) <= Dalvik PC of next instruction
15734 */
15735dvmJitToInterpSingleStep:
15736/* TODO */
15737    call     dvmAbort
15738#if 0
15739    pop    %eax
15740    movl   rSELF, %ecx
15741    movl   OUT_ARG0(%esp), %edx
15742    movl   %eax,offThread_jitResumeNPC(%ecx)
15743    movl   %edx,offThread_jitResumeDPC(%ecx)
15744    movl   $kInterpEntryInstr,offThread_entryPoint(%ecx)
15745    movl   $1,rINST     # changeInterp <= true
15746    jmp    common_gotoBail
15747#endif
15748
15749    .global dvmJitToInterpNoChainNoProfile
15750/*
15751 * Return from the translation cache to the interpreter to do method
15752 * invocation.  Check if the translation exists for the callee, but don't
15753 * chain to it. rPC must be set on entry.
15754 */
15755dvmJitToInterpNoChainNoProfile:
15756#if defined(WITH_JIT_TUNING)
15757    SPILL_TMP1(%eax)
15758    call   dvmBumpNoChain
15759    UNSPILL_TMP1(%eax)
15760#endif
15761    movl   %eax, rPC
15762    movl   rSELF, %eax
15763    movl   rPC,OUT_ARG0(%esp)
15764    movl   %eax,OUT_ARG1(%esp)
15765    call   dvmJitGetTraceAddrThread  # (pc, self)
15766    movl   rSELF,%ecx                # ecx <- self
15767    movl   %eax,offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
15768    cmpl   $0, %eax
15769    jz     1f
15770    jmp    *%eax                     # exec translation if we've got one
15771    # won't return
157721:
15773    EXPORT_PC
15774    movl   rSELF, %ecx
15775    movl   offThread_curHandlerTable(%ecx),rIBASE
15776    FETCH_INST_R %ecx
15777    GOTO_NEXT_R %ecx
15778
15779/*
15780 * Return from the translation cache and immediately request a
15781 * translation from the exit target, but don't attempt to chain.
15782 * rPC set on entry.
15783 */
15784    .global dvmJitToInterpTraceSelectNoChain
15785dvmJitToInterpTraceSelectNoChain:
15786#if defined(WITH_JIT_TUNING)
15787    movl   %edx, OUT_ARG0(%esp)
15788    call   dvmBumpNoChain
15789#endif
15790    movl   %ebx, rPC
15791    lea    4(%esp), %esp #to recover the esp update due to function call
15792    movl   rSELF, %eax
15793    movl   rPC,OUT_ARG0(%esp)
15794    movl   %eax,OUT_ARG1(%esp)
15795    call   dvmJitGetTraceAddrThread  # (pc, self)
15796    movl   rSELF,%ecx
15797    cmpl   $0,%eax
15798    movl   %eax,offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
15799    jz     1f
15800    jmp    *%eax              # jump to tranlation
15801    # won't return
15802
15803/* No Translation - request one */
158041:
15805    GET_JIT_PROF_TABLE %ecx %eax
15806    cmpl   $0, %eax          # JIT enabled?
15807    jnz    2f                 # Request one if so
15808    movl   rSELF, %ecx
15809    movl   offThread_curHandlerTable(%ecx),rIBASE
15810    FETCH_INST_R %ecx         # Continue interpreting if not
15811    GOTO_NEXT_R %ecx
158122:
15813    ## Looks like an EXPORT_PC is needed here. Now jmp to common_selectTrace2
15814    movl   $kJitTSelectRequestHot,%eax # ask for trace select
15815    jmp    common_selectTrace
15816
15817/*
15818 * Return from the translation cache and immediately request a
15819 * translation for the exit target.  Reached via a call, and
15820 * (TOS)->rPC.
15821 */
15822    .global dvmJitToInterpTraceSelect
15823dvmJitToInterpTraceSelect:
15824    movl   0(%esp), %eax          # get return address
15825    movl   %ebx, rPC              # get first argument (target rPC)
15826
15827    ## TODO, need to clean up stack manipulation ... this isn't signal safe and
15828    ## doesn't use the calling conventions of header.S
15829    lea    4(%esp), %esp #to recover the esp update due to function call
15830
15831    ## An additional 5B instruction "jump 0" was added for a thread-safe
15832    ## chaining cell update in JIT code cache. So the offset is now -17=-12-5.
15833    lea    -17(%eax), %ebx #$JIT_OFFSET_CHAIN_START(%eax), %ebx
15834    lea    -4(%esp), %esp
15835    movl   rSELF, %eax
15836    movl   rPC,OUT_ARG0(%esp)
15837    movl   %eax,OUT_ARG1(%esp)
15838    call   dvmJitGetTraceAddrThread # (pc, self)
15839    lea    4(%esp), %esp
15840    cmpl   $0,%eax
15841    movl   rSELF, %ecx
15842    movl   %eax,offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
15843    jz     1b                 # no - ask for one
15844    movl   %eax,OUT_ARG0(%esp)
15845    movl   rINST,OUT_ARG1(%esp)
15846    call   dvmJitChain        # Attempt dvmJitChain(codeAddr,chainAddr)
15847    cmpl   $0,%eax           # Success?
15848    jz     toInterpreter      # didn't chain - interpret
15849    jmp    *%eax
15850    # won't return
15851
15852/*
15853 * Placeholder entries for x86 JIT
15854 */
15855    .global dvmJitToInterpBackwardBranch
15856dvmJitToInterpBackwardBranch:
15857
15858    .global     dvmJitToExceptionThrown
15859dvmJitToExceptionThrown: //rPC in
15860    movl   rSELF, %edx
15861    GET_PC
15862    movl   $0, offThread_inJitCodeCache(%edx)
15863    jmp common_exceptionThrown
15864
15865    .global dvmJitToInterpNormal
15866dvmJitToInterpNormal:
15867/* one input: the target rPC value */
15868    movl        0(%esp), %eax          # get return address
15869    movl        %ebx, rPC              # get first argument (target rPC)
15870
15871    ## TODO, need to clean up stack manipulation ... this isn't signal safe and
15872    ## doesn't use the calling conventions of header.S
15873
15874    ## An additional 5B instruction "jump 0" was added for a thread-safe
15875    ## chaining cell update in JIT code cache. So the offset is now -17=-12-5.
15876    lea         -17(%eax), %ebx #$JIT_OFFSET_CHAIN_START(%eax), %ebx
15877    lea         4(%esp), %esp
15878    movl        rPC, OUT_ARG0(%esp)
15879    movl        rSELF, %ecx
15880    movl        %ecx, OUT_ARG1(%esp)
15881    call        dvmJitGetTraceAddrThread
15882    ## Here is the change from using rGLUE to rSELF for accessing the
15883    ## JIT code cache flag
15884    movl        rSELF, %ecx
15885    movl        %eax, offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
15886    #lea         4(%esp), %esp
15887    cmp         $0, %eax
15888    je          toInterpreter
15889    #lea         -8(%esp), %esp
15890    movl        %ebx, OUT_ARG1(%esp)    # %ebx live thorugh dvmJitGetTraceAddrThread
15891    movl        %eax, OUT_ARG0(%esp)    # first argument
15892    call        dvmJitChain
15893    #lea         8(%esp), %esp
15894    cmp         $0, %eax
15895    je          toInterpreter
15896    jmp         *%eax                   #to native address
15897
15898    .global dvmJitToInterpNoChain
15899dvmJitToInterpNoChain:
15900dvmJitToInterpNoChain: #rPC in eax
15901#if defined(WITH_JIT_TUNING)
15902    SPILL_TMP1(%eax)
15903    call   dvmBumpNoChain
15904    UNSPILL_TMP1(%eax)
15905#endif
15906    ## TODO, need to clean up stack manipulation ... this isn't signal safe and
15907    ## doesn't use the calling conventions of header.S
15908    movl        %eax, rPC
15909    movl        rPC, OUT_ARG0(%esp)
15910    movl        rSELF, %ecx
15911    movl        %ecx, OUT_ARG1(%esp)
15912    call        dvmJitGetTraceAddrThread
15913    ## Here is the change from using rGLUE to rSELF for accessing the
15914    ## JIT code cache flag
15915    movl        rSELF, %ecx
15916    movl        %eax, offThread_inJitCodeCache(%ecx)  # set inJitCodeCache flag
15917    cmp         $0, %eax
15918    je          toInterpreter
15919    jmp         *%eax                   #to native address
15920
15921toInterpreter:
15922    EXPORT_PC
15923    movl        rSELF, %ecx
15924    movl        offThread_curHandlerTable(%ecx), rIBASE
15925    FETCH_INST
15926    movl        offThread_pJitProfTable(%ecx), %eax
15927    #Fallthrough
15928
15929/* ebx holds the pointer to the jit profile table
15930   edx has the opCode */
15931common_testUpdateProfile:
15932    cmp         $0, %eax
15933    je          4f
15934/* eax holds the pointer to the jit profile table
15935   edx has the opCode
15936   rPC points to the next bytecode */
15937
15938common_updateProfile:
15939    # quick & dirty hash
15940    movl   rPC, %ecx
15941    shrl   $12, %ecx
15942    xorl   rPC, %ecx
15943    andl   $((1<<JIT_PROF_SIZE_LOG_2)-1), %ecx
15944    decb   (%ecx,%eax)
15945    #jmp    1f # remove
15946    jz     2f
159471:
15948    GOTO_NEXT
159492:
15950common_Profile:
15951/*
15952 * Here, we switch to the debug interpreter to request
15953 * trace selection.  First, though, check to see if there
15954 * is already a native translation in place (and, if so,
15955 * jump to it now.
15956 */
15957    SPILL(rIBASE)
15958    SPILL_TMP1(rINST)
15959    movl        rSELF, rIBASE
15960    GET_JIT_THRESHOLD rIBASE rINST  # leaves rSELF in %ecx
15961    EXPORT_PC
15962    movb   rINSTbl,(%ecx,%eax)   # reset counter
15963    movl   rIBASE,rINST            # preserve rSELF
15964    movl   rSELF, %eax
15965    movl   rPC,OUT_ARG0(%esp)
15966    movl   rIBASE,OUT_ARG1(%esp)
15967    call   dvmJitGetTraceAddrThread  # (pc, self)
15968    UNSPILL(rIBASE)
15969    movl   %eax,offThread_inJitCodeCache(rINST)   # set the inJitCodeCache flag
15970    UNSPILL_TMP1(rINST)
15971    cmpl   $0,%eax
15972    #jmp    1f # remove
15973    jz     1f
15974    jmp   *%eax        # TODO: decide call vs/ jmp!.  No return either way
159751:
15976    movl   $kJitTSelectRequest,%eax
15977    # On entry, eax<- jitState, rPC valid
15978common_selectTrace:
15979    mov         %ebx, EBX_SPILL(%ebp)
15980    movl        rSELF, %ebx
15981    movzwl      offThread_subMode(%ebx), %ecx
15982    and         $(kSubModeJitTraceBuild | kSubModeJitSV), %ecx
15983    jne         3f                     # already doing JIT work, continue
15984    movl        %eax, offThread_jitState(%ebx)
15985    movl        rSELF, %eax
15986    movl       %eax, OUT_ARG0(%esp)
15987
15988/*
15989 * Call out to validate trace-building request. If successful, rIBASE will be swapped
15990 * to send us into single-steppign trace building mode, so we need to refresh before
15991 * we continue.
15992 */
15993
15994   EXPORT_PC
15995   SAVE_PC_FP_TO_SELF %ecx
15996   call dvmJitCheckTraceRequest
159973:
15998   mov          EBX_SPILL(%ebp), %ebx
15999   FETCH_INST
16000   movl rSELF, %ecx
16001   movl offThread_curHandlerTable(%ecx), rIBASE
160024:
16003   GOTO_NEXT
16004
16005common_selectTrace2:
16006    mov         %ebx, EBX_SPILL(%ebp)
16007    movl        rSELF, %ebx
16008    movl        %ebx, OUT_ARG0(%esp)
16009    movl        %eax, offThread_jitState(%ebx)
16010    movzwl      offThread_subMode(%ebx), %ecx
16011    mov         EBX_SPILL(%ebp), %ebx
16012    and         (kSubModeJitTraceBuild | kSubModeJitSV), %ecx
16013    jne         3f                     # already doing JIT work, continue
16014
16015
16016
16017/*
16018 * Call out to validate trace-building request. If successful, rIBASE will be swapped
16019 * to send us into single-steppign trace building mode, so we need to refresh before
16020 * we continue.
16021 */
16022
16023   EXPORT_PC
16024   SAVE_PC_FP_TO_SELF %ecx
16025   call dvmJitCheckTraceRequest
160263:
16027   FETCH_INST
16028   movl rSELF, %ecx
16029   movl offThread_curHandlerTable(%ecx), rIBASE
160304:
16031   GOTO_NEXT
16032
16033#endif
16034
16035/*
16036 * For the invoke codes we need to know what register holds the "this" pointer. However
16037 * it seems the this pointer is assigned consistently most times it is in %ecx but other
16038 * times it is in OP_INVOKE_INTERFACE, OP_INVOKE_SUPER_QUICK, or OP_INVOKE_VIRTUAL_QUICK.
16039*/
16040
16041/*
16042 * Common code for method invocation with range.
16043 *
16044 * On entry:
16045 *   eax = Method* methodToCall
16046 *   ecx = "this"
16047 *   rINSTw trashed, must reload
16048 *   rIBASE trashed, must reload before resuming interpreter
16049 */
16050
16051common_invokeMethodRange:
16052.LinvokeNewRange:
16053#if defined(WITH_JIT)
16054    SPILL_TMP1(%edx)
16055    SPILL_TMP2(%ebx)
16056    movl        rSELF, %edx
16057    movzwl      offThread_subMode(%edx), %ebx
16058    and         $kSubModeJitTraceBuild, %ebx
16059    jz          6f
16060    call        save_callsiteinfo
160616:
16062    UNSPILL_TMP2(%ebx)
16063    UNSPILL_TMP1(%edx)
16064#endif
16065   /*
16066    * prepare to copy args to "outs" area of current frame
16067    */
16068
16069    movzbl      1(rPC),rINST       # rINST<- AA
16070    movzwl      4(rPC), %ecx            # %ecx<- CCCC
16071    SAVEAREA_FROM_FP %edx               # %edx<- &StackSaveArea
16072    test        rINST, rINST
16073    movl        rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- AA
16074    jz          .LinvokeArgsDone        # no args; jump to args done
16075
16076
16077   /*
16078    * %eax=methodToCall, %ecx=CCCC, LOCAL0_OFFSET(%ebp)=count,
16079    * %edx=&outs (&stackSaveArea).  (very few methods have > 10 args;
16080    * could unroll for common cases)
16081    */
16082
16083.LinvokeRangeArgs:
16084    movl        %ebx, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- save %ebx
16085    lea         (rFP, %ecx, 4), %ecx    # %ecx<- &vCCCC
16086    shll        $2, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- offset
16087    subl        LOCAL0_OFFSET(%ebp), %edx       # %edx<- update &outs
16088    shrl        $2, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- offset
160891:
16090    movl        (%ecx), %ebx            # %ebx<- vCCCC
16091    lea         4(%ecx), %ecx           # %ecx<- &vCCCC++
16092    subl        $1, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET<- LOCAL0_OFFSET--
16093    movl        %ebx, (%edx)            # *outs<- vCCCC
16094    lea         4(%edx), %edx           # outs++
16095    jne         1b                      # loop if count (LOCAL0_OFFSET(%ebp)) not zero
16096    movl        LOCAL1_OFFSET(%ebp), %ebx       # %ebx<- restore %ebx
16097    jmp         .LinvokeArgsDone        # continue
16098
16099   /*
16100    * %eax is "Method* methodToCall", the method we're trying to call
16101    * prepare to copy args to "outs" area of current frame
16102    * rIBASE trashed, must reload before resuming interpreter
16103    */
16104
16105common_invokeMethodNoRange:
16106#if defined(WITH_JIT)
16107    SPILL_TMP1(%edx)
16108    SPILL_TMP2(%ebx)
16109    movl        rSELF, %edx
16110    movzwl      offThread_subMode(%edx), %ebx
16111    and         $kSubModeJitTraceBuild, %ebx
16112    jz          6f
16113    call        save_callsiteinfo
161146:
16115    UNSPILL_TMP2(%ebx)
16116    UNSPILL_TMP1(%edx)
16117#endif
16118.LinvokeNewNoRange:
16119    movzbl      1(rPC),rINST       # rINST<- BA
16120    movl        rINST, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- BA
16121    shrl        $4, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- B
16122    je          .LinvokeArgsDone        # no args; jump to args done
16123    movzwl      4(rPC), %ecx            # %ecx<- GFED
16124    SAVEAREA_FROM_FP %edx               # %edx<- &StackSaveArea
16125
16126   /*
16127    * %eax=methodToCall, %ecx=GFED, LOCAL0_OFFSET(%ebp)=count, %edx=outs
16128    */
16129
16130.LinvokeNonRange:
16131    cmp         $2, LOCAL0_OFFSET(%ebp)        # compare LOCAL0_OFFSET(%ebp) to 2
16132    movl        %ecx, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- GFED
16133    jl          1f                      # handle 1 arg
16134    je          2f                      # handle 2 args
16135    cmp         $4, LOCAL0_OFFSET(%ebp)        # compare LOCAL0_OFFSET(%ebp) to 4
16136    jl          3f                      # handle 3 args
16137    je          4f                      # handle 4 args
161385:
16139    andl        $15, rINST             # rINSTw<- A
16140    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
16141    movl        (rFP, rINST, 4), %ecx   # %ecx<- vA
16142    movl        %ecx, (%edx)            # *outs<- vA
16143    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
161444:
16145    shr         $12, %ecx              # %ecx<- G
16146    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
16147    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vG
16148    movl        %ecx, (%edx)            # *outs<- vG
16149    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
161503:
16151    and         $0x0f00, %ecx          # %ecx<- 0F00
16152    shr         $8, %ecx               # %ecx<- F
16153    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
16154    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vF
16155    movl        %ecx, (%edx)            # *outs<- vF
16156    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
161572:
16158    and         $0x00f0, %ecx          # %ecx<- 00E0
16159    shr         $4, %ecx               # %ecx<- E
16160    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
16161    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vE
16162    movl        %ecx, (%edx)            # *outs<- vE
16163    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
161641:
16165    and         $0x000f, %ecx          # %ecx<- 000D
16166    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vD
16167    movl        %ecx, -4(%edx)          # *--outs<- vD
161680:
16169
16170   /*
16171    * %eax is "Method* methodToCall", the method we're trying to call
16172    * find space for the new stack frame, check for overflow
16173    */
16174
16175.LinvokeArgsDone:
16176    movzwl      offMethod_registersSize(%eax), %edx # %edx<- methodToCall->regsSize
16177    movzwl      offMethod_outsSize(%eax), %ecx # %ecx<- methodToCall->outsSize
16178    movl        %eax, LOCAL0_OFFSET(%ebp)       # LOCAL0_OFFSET<- methodToCall
16179    shl         $2, %edx               # %edx<- update offset
16180    SAVEAREA_FROM_FP %eax               # %eax<- &StackSaveArea
16181    subl        %edx, %eax              # %eax<- newFP; (old savearea - regsSize)
16182    movl        rSELF,%edx              # %edx<- pthread
16183    movl        %eax, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- &outs
16184    subl        $sizeofStackSaveArea, %eax # %eax<- newSaveArea (stack save area using newFP)
16185    movl        offThread_interpStackEnd(%edx), %edx # %edx<- self->interpStackEnd
16186    movl        %edx, TMP_SPILL1(%ebp)  # spill self->interpStackEnd
16187    shl         $2, %ecx               # %ecx<- update offset for outsSize
16188    movl        %eax, %edx              # %edx<- newSaveArea
16189    sub         %ecx, %eax              # %eax<- bottom; (newSaveArea - outsSize)
16190    cmp         TMP_SPILL1(%ebp), %eax  # compare interpStackEnd and bottom
16191    movl        LOCAL0_OFFSET(%ebp), %eax       # %eax<- restore methodToCall
16192    jl          .LstackOverflow         # handle frame overflow
16193
16194   /*
16195    * set up newSaveArea
16196    */
16197
16198#ifdef EASY_GDB
16199    SAVEAREA_FROM_FP %ecx               # %ecx<- &StackSaveArea
16200    movl        %ecx, offStackSaveArea_prevSave(%edx) # newSaveArea->prevSave<- &outs
16201#endif
16202    movl        rSELF,%ecx              # %ecx<- pthread
16203    movl        rFP, offStackSaveArea_prevFrame(%edx) # newSaveArea->prevFrame<- rFP
16204    movl        rPC, offStackSaveArea_savedPc(%edx) # newSaveArea->savedPc<- rPC
16205#if defined(WITH_JIT)
16206    movl        $0, offStackSaveArea_returnAddr(%edx)
16207#endif
16208
16209    /* Any special actions to take? */
16210    cmpw        $0, offThread_subMode(%ecx)
16211    jne         2f                     # Yes - handle them
162121:
16213    testl       $ACC_NATIVE, offMethod_accessFlags(%eax) # check for native call
16214    movl        %eax, offStackSaveArea_method(%edx) # newSaveArea->method<- method to call
16215    jne         .LinvokeNative          # handle native call
16216
16217   /*
16218    * Update "self" values for the new method
16219    * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFp
16220    */
16221    movl        offMethod_clazz(%eax), %edx # %edx<- method->clazz
16222    movl        offClassObject_pDvmDex(%edx), %edx # %edx<- method->clazz->pDvmDex
16223    movl        %eax, offThread_method(%ecx) # self->method<- methodToCall
16224    movl        %edx, offThread_methodClassDex(%ecx) # self->methodClassDex<- method->clazz->pDvmDex
16225    movl        offMethod_insns(%eax), rPC # rPC<- methodToCall->insns
16226    movl        $1, offThread_debugIsMethodEntry(%ecx)
16227    movl        LOCAL1_OFFSET(%ebp), rFP # rFP<- newFP
16228    movl        rFP, offThread_curFrame(%ecx) # curFrame<-newFP
16229    movl        offThread_curHandlerTable(%ecx),rIBASE
16230    FETCH_INST
16231#if defined(WITH_JIT)
16232    /* rPC is already updated */
16233    GET_JIT_PROF_TABLE %ecx %eax
16234    cmp         $0, %eax
16235    jne         common_updateProfile # set up %ebx & %edx & rPC
16236#endif
16237    GOTO_NEXT                           # jump to methodToCall->insns
16238
162392:
16240    /*
16241     * On entry, preserve all:
16242     *  %eax: method
16243     *  %ecx: self
16244     *  %edx: new save area
16245     */
16246    SPILL_TMP1(%eax)                   # preserve methodToCall
16247    SPILL_TMP2(%edx)                   # preserve newSaveArea
16248    movl        rPC, offThread_pc(%ecx) # update interpSave.pc
16249    movl        %ecx, OUT_ARG0(%esp)
16250    movl        %eax, OUT_ARG1(%esp)
16251    call        dvmReportInvoke        # (self, method)
16252    UNSPILL_TMP1(%eax)
16253    UNSPILL_TMP2(%edx)
16254    movl        rSELF,%ecx             # restore rSELF
16255    jmp         1b
16256
16257   /*
16258    * Prep for the native call
16259    * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFP, %edx=newSaveArea, %ecx=self
16260    */
16261
16262.LinvokeNative:
16263    movl        offThread_jniLocal_topCookie(%ecx), rINST # rINST<- self->localRef->...
16264    movl        rINST, offStackSaveArea_localRefCookie(%edx) # newSaveArea->localRefCookie<- top
16265    movl        %edx, LOCAL2_OFFSET(%ebp)  # save newSaveArea
16266    movl        LOCAL1_OFFSET(%ebp), rINST # rINST<- newFP
16267    movl        rINST, offThread_curFrame(%ecx)  # curFrame<- newFP
16268    cmpw        $0, offThread_subMode(%ecx)  # Anything special going on?
16269    jne         11f                     # yes - handle it
16270    movl        %ecx, OUT_ARG3(%esp)    # push parameter self
16271    movl        %eax, OUT_ARG2(%esp)    # push parameter methodToCall
16272    lea         offThread_retval(%ecx), %ecx # %ecx<- &retval
16273    movl        %ecx, OUT_ARG1(%esp)    # push parameter &retval
16274    movl        rINST, OUT_ARG0(%esp)    # push parameter newFP
16275    call        *offMethod_nativeFunc(%eax) # call methodToCall->nativeFunc
162767:
16277    movl        LOCAL2_OFFSET(%ebp), %ecx    # %ecx<- newSaveArea
16278    movl        rSELF, %eax             # %eax<- self
16279    movl        offStackSaveArea_localRefCookie(%ecx), %edx # %edx<- old top
16280    cmp         $0, offThread_exception(%eax) # check for exception
16281    movl        rFP, offThread_curFrame(%eax) # curFrame<- rFP
16282    movl        %edx, offThread_jniLocal_topCookie(%eax) # new top <- old top
16283    jne         common_exceptionThrown  # handle exception
16284    movl        offThread_curHandlerTable(%eax),rIBASE
16285    FETCH_INST_OPCODE 3 %ecx
16286    ADVANCE_PC 3
16287    GOTO_NEXT_R %ecx                    # jump to next instruction
16288
1628911:
16290    /*
16291     * Handle any special subMode actions
16292     * %eax=methodToCall, rINST=newFP, %ecx=self
16293     */
16294    SPILL_TMP1(%eax)                    # save methodTocall
16295    movl        rPC, offThread_pc(%ecx)
16296    movl        %ecx, OUT_ARG1(%esp)
16297    movl        %eax, OUT_ARG0(%esp)
16298    movl        rFP, OUT_ARG2(%esp)
16299    call        dvmReportPreNativeInvoke # (methodToCall, self, fp)
16300    UNSPILL_TMP1(%eax)                  # restore methodToCall
16301    movl        rSELF,%ecx              # restore self
16302
16303    /* Do the native call */
16304    movl        %ecx, OUT_ARG3(%esp)    # push parameter self
16305    lea         offThread_retval(%ecx), %ecx # %ecx<- &retval
16306    movl        %eax, OUT_ARG2(%esp)    # push parameter methodToCall
16307    movl        %ecx, OUT_ARG1(%esp)    # push parameter &retval
16308    movl        rINST, OUT_ARG0(%esp)   # push parameter newFP
16309    call        *offMethod_nativeFunc(%eax) # call methodToCall->nativeFunc
16310
16311    UNSPILL_TMP1(%eax)                  # restore methodToCall
16312    movl        rSELF, %ecx
16313    movl        %ecx, OUT_ARG1(%esp)
16314    movl        %eax, OUT_ARG0(%esp)
16315    movl        rFP, OUT_ARG2(%esp)
16316    call        dvmReportPostNativeInvoke # (methodToCall, self, fp)
16317    jmp         7b                      # rejoin
16318
16319.LstackOverflow:    # eax=methodToCall
16320    movl        %eax, OUT_ARG1(%esp)    # push parameter methodToCall
16321    movl        rSELF,%eax              # %eax<- self
16322    movl        %eax, OUT_ARG0(%esp)    # push parameter self
16323    call        dvmHandleStackOverflow  # call: (Thread* self, Method* meth)
16324    jmp         common_exceptionThrown  # handle exception
16325
16326
16327/*
16328 * Common code for handling a return instruction
16329 */
16330common_returnFromMethod:
16331    movl    rSELF, %ecx
16332    SAVEAREA_FROM_FP %eax                       # %eax<- saveArea(old)
16333    cmpw    $0, offThread_subMode(%ecx)          # special action needed?
16334    jne     19f                                   # go if so
1633514:
16336
16337    movl        offStackSaveArea_prevFrame(%eax), rFP # rFP<- saveArea->PrevFrame
16338    movl        (offStackSaveArea_method - sizeofStackSaveArea)(rFP), rINST # rINST<- method we are returning to
16339    cmpl        $0, rINST               # check for break frame
16340    je          common_gotoBail         # bail if break frame
16341    movl        offThread_curHandlerTable(%ecx),rIBASE
16342    movl        offStackSaveArea_savedPc(%eax), rPC # rPC<- saveAreaOld->savedPc
16343#if defined(WITH_JIT)
16344    movl        offStackSaveArea_returnAddr(%eax), %ecx
16345#endif
16346    movl        rSELF, %eax
16347    movl        rINST, offThread_method(%eax) # glue->method<- newSave->method
16348    movl        offMethod_clazz(rINST), rINST # rINST<- method->clazz
16349    movl        rFP, offThread_curFrame(%eax) # glue->self->curFrame<- rFP
16350#if defined(WITH_JIT)
16351    //update self->offThread_inJitCodeCache
16352    movl        %ecx, offThread_inJitCodeCache(%eax)
16353#endif
16354    movl        offClassObject_pDvmDex(rINST), rINST # rINST<- method->clazz->pDvmDex
16355    movl        rINST, offThread_methodClassDex(%eax) # glue->pDvmDex<- method->clazz->pDvmDex
16356#if defined(WITH_JIT)
16357    cmp         $0, %ecx
16358    je          .returnToBC
16359    movl        %ecx, %eax
16360    jmp         *%eax
16361#endif
16362
16363.returnToBC:
16364
16365#if defined(WITH_JIT)
16366    FETCH_INST_OPCODE  3, %ecx                 # %eax<- next instruction hi; fetch, advance
16367    // %ecx has the opcode
16368    addl         $6, rPC               # 3*2 = 6
16369    SPILL_TMP1   (%ecx)
16370    movl         rSELF, %ecx
16371    FETCH_INST
16372    UNSPILL_TMP1   (%ecx)
16373    movzbl      1(rPC), rINST
16374    jmp     *(rIBASE,%ecx,4)
16375#else
16376    FETCH_INST_WORD 3
16377    ADVANCE_PC 3
16378    GOTO_NEXT
16379#endif
16380
1638119:
16382    /*
16383     * Handle special subMode actions
16384     * On entry, rFP: prevFP, %ecx: self, %eax: saveArea
16385     */
16386    SPILL_TMP1(%ebx)
16387    movl     offStackSaveArea_prevFrame(%eax), %ebx # %ebx<- saveArea->PrevFrame
16388    movl     rPC, offThread_pc(%ecx)          # update interpSave.pc
16389    movl     %ebx, offThread_curFrame(%ecx)    # update interpSave.curFrame
16390    movl     %ecx, OUT_ARG0(%esp)             # parameter self
16391    call     dvmReportReturn                  # (self)
16392    UNSPILL_TMP1(%ebx)
16393    movl     rSELF, %ecx                      # restore self
16394    SAVEAREA_FROM_FP %eax                     # restore saveArea
16395    jmp      14b
16396
16397
16398/*
16399 * Prepare to strip the current frame and "longjump" back to caller of
16400 * dvmMterpStdRun.
16401 *
16402 * on entry:
16403 *    rINST holds changeInterp
16404 *    ecx holds self pointer
16405 *
16406 * expected profile: dvmMterpStdBail(Thread *self, bool changeInterp)
16407 */
16408common_gotoBail:
16409    movl   rPC,offThread_pc(%ecx)     # export state to self
16410    movl   rFP,offThread_curFrame(%ecx)
16411    movl   %ecx,OUT_ARG0(%esp)      # self in arg0
16412    movl   rINST,OUT_ARG1(%esp)     # changeInterp in arg1
16413    call   dvmMterpStdBail          # bail out....
16414
16415/*
16416 * The JIT's invoke method needs to remember the callsite class and
16417 * target pair.  Save them here so that they are available to
16418 * dvmCheckJit following the interpretation of this invoke.
16419 *
16420 * eax = Method* methodToCall
16421 * ecx = "this"
16422 * edx = rSELF
16423 * ebx = free to use
16424 */
16425#if defined(WITH_JIT)
16426save_callsiteinfo:
16427    cmp     $0, %ecx
16428    je      2f
16429    movl    offObject_clazz(%ecx), %ecx
164302:
16431    movl    rSELF, %ebx
16432    movl    %eax, offThread_methodToCall(%ebx)
16433    movl    %ecx, offThread_callsiteClass(%ebx)
16434    ret
16435#endif
16436
16437#if defined(WITH_JIT)
16438
16439    /*
16440     * If the JIT is actively building a trace we need to make sure
16441     * that the field is fully resolved before including the current
16442     * instruction.
16443     *
16444     * On entry:
16445     *     %ecx: &dvmDex->pResFields[field]
16446     *     %eax:  field pointer (must preserve)
16447     */
16448common_verifyField:
16449    movl    %ebx, TMP_SPILL1(%ebp)
16450    movl     rSELF, %ebx
16451    movzwl   offThread_subMode(%ebx), %ebx
16452    andl     $kSubModeJitTraceBuild, %ebx
16453    movl    TMP_SPILL1(%ebp), %ebx
16454    jne      1f
16455    ret
164561:
16457    movl    (%ecx), %ecx
16458    cmp     $0, %ecx
16459    je      1f
16460    ret
164611:
16462    SPILL_TMP1(%eax)
16463    SPILL_TMP2(%edx)
16464    movl     rSELF, %ecx
16465    # Because we call into this helper from a bytecode, we have
16466    # to be careful not to write over the return address when using
16467    # the OUT_ARG macros
16468    lea      -8(%esp), %esp
16469    movl     %ecx, OUT_ARG0(%esp)
16470    movl     rPC, OUT_ARG1(%esp)
16471    call     dvmJitEndTraceSelect
16472    lea      8(%esp), %esp
16473    UNSPILL_TMP2(%edx)
16474    UNSPILL_TMP1(%eax)
16475    ret
16476#endif
16477
16478/*
16479 * After returning from a "selfd" function, pull out the updated values
16480 * and start executing at the next instruction.
16481 */
16482common_resumeAfterGlueCall:
16483     movl  rSELF, %eax
16484     movl  offThread_pc(%eax),rPC
16485     movl  offThread_curFrame(%eax),rFP
16486     movl  offThread_curHandlerTable(%eax),rIBASE
16487     FETCH_INST
16488     GOTO_NEXT
16489
16490/*
16491 * Integer divide or mod by zero
16492 */
16493common_errDivideByZero:
16494    EXPORT_PC
16495    movl    $.LstrDivideByZero,%eax
16496    movl    %eax,OUT_ARG0(%esp)
16497    call    dvmThrowArithmeticException
16498    jmp     common_exceptionThrown
16499
16500/*
16501 * Attempt to allocate an array with a negative size.
16502 * On entry, len in eax
16503 */
16504common_errNegativeArraySize:
16505    EXPORT_PC
16506    movl    %eax,OUT_ARG0(%esp)                  # arg0<- len
16507    call    dvmThrowNegativeArraySizeException   # (len)
16508    jmp     common_exceptionThrown
16509
16510/*
16511 * Attempt to allocate an array with a negative size.
16512 * On entry, method name in eax
16513 */
16514common_errNoSuchMethod:
16515    EXPORT_PC
16516    movl    %eax,OUT_ARG0(%esp)
16517    call    dvmThrowNoSuchMethodError
16518    jmp     common_exceptionThrown
16519
16520/*
16521 * Hit a null object when we weren't expecting one.  Export the PC, throw a
16522 * NullPointerException and goto the exception processing code.
16523 */
16524common_errNullObject:
16525    EXPORT_PC
16526    xorl    %eax,%eax
16527    movl    %eax,OUT_ARG0(%esp)
16528    call    dvmThrowNullPointerException
16529    jmp     common_exceptionThrown
16530
16531/*
16532 * Array index exceeds max.
16533 * On entry:
16534 *    eax <- array object
16535 *    ecx <- index
16536 */
16537common_errArrayIndex:
16538    EXPORT_PC
16539    movl    offArrayObject_length(%eax), %eax
16540    movl    %eax,OUT_ARG0(%esp)
16541    movl    %ecx,OUT_ARG1(%esp)
16542    call    dvmThrowArrayIndexOutOfBoundsException   # args (length, index)
16543    jmp     common_exceptionThrown
16544
16545/*
16546 * Somebody has thrown an exception.  Handle it.
16547 *
16548 * If the exception processing code returns to us (instead of falling
16549 * out of the interpreter), continue with whatever the next instruction
16550 * now happens to be.
16551 *
16552 * NOTE: special subMode handling done in dvmMterp_exceptionThrown
16553 *
16554 * This does not return.
16555 */
16556common_exceptionThrown:
16557.LexceptionNew:
16558
16559    EXPORT_PC
16560    movl       rSELF, %ecx
16561    movl       %ecx, OUT_ARG0(%esp)
16562    call       dvmCheckSuspendPending
16563
16564    movl       rSELF, %ecx
16565    movl       offThread_exception(%ecx), %edx   # %edx <- self->exception
16566    movl       %edx, OUT_ARG0(%esp)
16567    movl       %ecx, OUT_ARG1(%esp)
16568    SPILL_TMP1(%edx)
16569    call       dvmAddTrackedAlloc      # don't let the exception be GCed
16570    UNSPILL_TMP1(%edx)
16571    movl       rSELF, %ecx
16572    movl       offThread_subMode(%ecx), %eax    # get subMode flags
16573    movl       $0, offThread_exception(%ecx)
16574
16575    # Special subMode?
16576    cmpl       $0, %eax                # any special subMode handling needed?
16577    je         8f                      # go if so
16578
16579    # Manage debugger bookkeeping
16580    movl       rPC, offThread_pc(%ecx) # update interpSave.pc
16581    movl       rFP, offThread_curFrame(%ecx) # update interpSave.curFrame
16582    movl       %ecx, OUT_ARG0(%esp)
16583    movl       %edx, OUT_ARG1(%esp)
16584    SPILL_TMP1(%edx)
16585    call       dvmReportExceptionThrow # (self, exception)
16586    UNSPILL_TMP1(%edx)
16587    movl       rSELF, %ecx
16588
165898:
16590    /*
16591    * set up args and a local for &fp
16592    */
16593    lea        20(%esp), %esp          # raise %esp
16594    movl       rFP, (%esp)               # save fp
16595    movl       %esp, %eax              # %eax = &fp
16596    lea        -20(%esp), %esp         # reset %esp
16597    movl       %eax, OUT_ARG4(%esp)    # Arg 4 = &fp
16598    movl       $0, OUT_ARG3(%esp)      # Arg 3 = false
16599    movl       %edx, OUT_ARG2(%esp)    # Arg 2 = exception
16600    movl       %ecx, OUT_ARG0(%esp)    # Arg 0 = self
16601
16602    movl       offThread_method(%ecx), %eax # %eax = self->method
16603    movl       offMethod_insns(%eax), %eax  # %eax = self->method->insn
16604    movl       rPC, %ecx
16605    subl       %eax, %ecx              # %ecx = pc - self->method->insn
16606    sar        $1, %ecx                # adjust %ecx for code offset
16607    movl       %ecx, OUT_ARG1(%esp)    # Arg 1 = %ecx
16608
16609    /* call, %eax gets catchRelPc (a code-unit offset) */
16610    SPILL_TMP1(%edx)                   # save exception
16611    call       dvmFindCatchBlock       # call(self, relPc, exc, scan?, &fp)
16612    UNSPILL_TMP1(%edx)                 # restore exception
16613
16614    /* fix earlier stack overflow if necessary; may trash rFP */
16615    movl       rSELF, %ecx
16616    cmpl       $0, offThread_stackOverflowed(%ecx) # did we overflow?
16617    je         1f                         # no, skip ahead
16618    movl       %eax, rFP                  # save relPc result in rFP
16619    movl       %ecx, OUT_ARG0(%esp)       # Arg 0 = self
16620    movl       %edx, OUT_ARG1(%esp)       # Arg 1 = exception
16621    SPILL_TMP1(%edx)
16622    call       dvmCleanupStackOverflow    # call(self, exception)
16623    UNSPILL_TMP1(%edx)
16624    movl       rFP, %eax                  # restore result
16625    movl       rSELF, %ecx
166261:
16627
16628    /* update frame pointer and check result from dvmFindCatchBlock */
16629    movl       20(%esp), rFP              # retrieve the updated rFP
16630    cmpl       $0, %eax                  # is catchRelPc < 0?
16631    jl         .LnotCaughtLocally
16632
16633    /* adjust locals to match self->interpSave.curFrame and updated PC */
16634    SAVEAREA_FROM_FP rINST             # rINST<- new save area
16635    movl       offStackSaveArea_method(rINST), rINST # rINST<- new method
16636    movl       rINST, offThread_method(%ecx)         # self->method = new method
16637    movl       offMethod_clazz(rINST), %ecx          # %ecx = method->clazz
16638    movl       offMethod_insns(rINST), rINST         # rINST = method->insn
16639    movl       offClassObject_pDvmDex(%ecx), %ecx    # %ecx = method->clazz->pDvmDex
16640    lea        (rINST, %eax, 2), rPC      # rPC<- method->insns + catchRelPc
16641    movl       rSELF, rINST
16642    movl       %ecx, offThread_methodClassDex(rINST) # self->pDvmDex = method->clazz->pDvmDex
16643
16644    /* release the tracked alloc on the exception */
16645    movl       %edx, OUT_ARG0(%esp)       # Arg 0 = exception
16646    movl       rINST, OUT_ARG1(%esp)      # Arg 1 = self
16647    SPILL_TMP1(%edx)
16648    call       dvmReleaseTrackedAlloc     # release the exception
16649    UNSPILL_TMP1(%edx)
16650
16651    /* restore the exception if the handler wants it */
16652    movl       rSELF, %ecx
16653    FETCH_INST
16654    movzbl     rINSTbl, %eax
16655    cmpl       $OP_MOVE_EXCEPTION, %eax   # is it "move-exception"?
16656    jne        1f
16657    movl       %edx, offThread_exception(%ecx) # restore exception
166581:
16659    movl       offThread_curHandlerTable(%ecx), rIBASE # refresh rIBASE
16660    GOTO_NEXT
16661
16662.LnotCaughtLocally: # %edx = exception
16663    /* fix stack overflow if necessary */
16664    movl       rSELF, %ecx
16665    movl       offThread_stackOverflowed(%ecx), %eax
16666    cmpl       $0, %eax                   # did we overflow earlier?
16667    je         1f
16668    movl       %ecx, OUT_ARG0(%esp)
16669    movl       %edx, OUT_ARG1(%esp)
16670    SPILL_TMP1(%edx)
16671    call       dvmCleanupStackOverflow
16672    UNSPILL_TMP1(%edx)
16673
166741:
16675    movl       rSELF, %ecx
16676    movl       %edx, offThread_exception(%ecx) #restore exception
16677    movl       %edx, OUT_ARG0(%esp)
16678    movl       %ecx, OUT_ARG1(%esp)
16679    call       dvmReleaseTrackedAlloc     # release the exception
16680    movl       rSELF, %ecx
16681    jmp        common_gotoBail            # bail out
16682
16683common_abort:
16684    movl    $0xdeadf00d,%eax
16685    call     *%eax
16686
16687
16688/*
16689 * Strings
16690 */
16691
16692    .section     .rodata
16693.LstrDivideByZero:
16694    .asciz  "divide by zero"
16695.LstrFilledNewArrayNotImplA:
16696    .asciz  "filled-new-array only implemented for 'int'"
16697
16698