InterpAsm-armv7-a.S revision 750d110b62cef538e193b6f91f5239b0c4b63ef1
1/*
2 * This file was generated automatically by gen-mterp.py for 'armv7-a'.
3 *
4 * --> DO NOT EDIT <--
5 */
6
7/* File: armv5te/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/*
25 * ARMv5 definitions and declarations.
26 */
27
28/*
29ARM EABI general notes:
30
31r0-r3 hold first 4 args to a method; they are not preserved across method calls
32r4-r8 are available for general use
33r9 is given special treatment in some situations, but not for us
34r10 (sl) seems to be generally available
35r11 (fp) is used by gcc (unless -fomit-frame-pointer is set)
36r12 (ip) is scratch -- not preserved across method calls
37r13 (sp) should be managed carefully in case a signal arrives
38r14 (lr) must be preserved
39r15 (pc) can be tinkered with directly
40
41r0 holds returns of <= 4 bytes
42r0-r1 hold returns of 8 bytes, low word in r0
43
44Callee must save/restore r4+ (except r12) if it modifies them.  If VFP
45is present, registers s16-s31 (a/k/a d8-d15, a/k/a q4-q7) must be preserved,
46s0-s15 (d0-d7, q0-a3) do not need to be.
47
48Stack is "full descending".  Only the arguments that don't fit in the first 4
49registers are placed on the stack.  "sp" points at the first stacked argument
50(i.e. the 5th arg).
51
52VFP: single-precision results in s0, double-precision results in d0.
53
54In the EABI, "sp" must be 64-bit aligned on entry to a function, and any
5564-bit quantities (long long, double) must be 64-bit aligned.
56*/
57
58/*
59Mterp and ARM notes:
60
61The following registers have fixed assignments:
62
63  reg nick      purpose
64  r4  rPC       interpreted program counter, used for fetching instructions
65  r5  rFP       interpreted frame pointer, used for accessing locals and args
66  r6  rGLUE     MterpGlue pointer
67  r7  rINST     first 16-bit code unit of current instruction
68  r8  rIBASE    interpreted instruction base pointer, used for computed goto
69
70Macros are provided for common operations.  Each macro MUST emit only
71one instruction to make instruction-counting easier.  They MUST NOT alter
72unspecified registers or condition codes.
73*/
74
75/* single-purpose registers, given names for clarity */
76#define rPC     r4
77#define rFP     r5
78#define rGLUE   r6
79#define rINST   r7
80#define rIBASE  r8
81
82/* save/restore the PC and/or FP from the glue struct */
83#define LOAD_PC_FROM_GLUE()     ldr     rPC, [rGLUE, #offGlue_pc]
84#define SAVE_PC_TO_GLUE()       str     rPC, [rGLUE, #offGlue_pc]
85#define LOAD_FP_FROM_GLUE()     ldr     rFP, [rGLUE, #offGlue_fp]
86#define SAVE_FP_TO_GLUE()       str     rFP, [rGLUE, #offGlue_fp]
87#define LOAD_PC_FP_FROM_GLUE()  ldmia   rGLUE, {rPC, rFP}
88#define SAVE_PC_FP_TO_GLUE()    stmia   rGLUE, {rPC, rFP}
89
90/*
91 * "export" the PC to the stack frame, f/b/o future exception objects.  Must
92 * be done *before* something calls dvmThrowException.
93 *
94 * In C this is "SAVEAREA_FROM_FP(fp)->xtra.currentPc = pc", i.e.
95 * fp - sizeof(StackSaveArea) + offsetof(SaveArea, xtra.currentPc)
96 *
97 * It's okay to do this more than once.
98 */
99#define EXPORT_PC() \
100    str     rPC, [rFP, #(-sizeofStackSaveArea + offStackSaveArea_currentPc)]
101
102/*
103 * Given a frame pointer, find the stack save area.
104 *
105 * In C this is "((StackSaveArea*)(_fp) -1)".
106 */
107#define SAVEAREA_FROM_FP(_reg, _fpreg) \
108    sub     _reg, _fpreg, #sizeofStackSaveArea
109
110/*
111 * Fetch the next instruction from rPC into rINST.  Does not advance rPC.
112 */
113#define FETCH_INST()            ldrh    rINST, [rPC]
114
115/*
116 * Fetch the next instruction from the specified offset.  Advances rPC
117 * to point to the next instruction.  "_count" is in 16-bit code units.
118 *
119 * Because of the limited size of immediate constants on ARM, this is only
120 * suitable for small forward movements (i.e. don't try to implement "goto"
121 * with this).
122 *
123 * This must come AFTER anything that can throw an exception, or the
124 * exception catch may miss.  (This also implies that it must come after
125 * EXPORT_PC().)
126 */
127#define FETCH_ADVANCE_INST(_count) ldrh    rINST, [rPC, #(_count*2)]!
128
129/*
130 * The operation performed here is similar to FETCH_ADVANCE_INST, except the
131 * src and dest registers are parameterized (not hard-wired to rPC and rINST).
132 */
133#define PREFETCH_ADVANCE_INST(_dreg, _sreg, _count) \
134        ldrh    _dreg, [_sreg, #(_count*2)]!
135
136/*
137 * Fetch the next instruction from an offset specified by _reg.  Updates
138 * rPC to point to the next instruction.  "_reg" must specify the distance
139 * in bytes, *not* 16-bit code units, and may be a signed value.
140 *
141 * We want to write "ldrh rINST, [rPC, _reg, lsl #2]!", but some of the
142 * bits that hold the shift distance are used for the half/byte/sign flags.
143 * In some cases we can pre-double _reg for free, so we require a byte offset
144 * here.
145 */
146#define FETCH_ADVANCE_INST_RB(_reg) ldrh    rINST, [rPC, _reg]!
147
148/*
149 * Fetch a half-word code unit from an offset past the current PC.  The
150 * "_count" value is in 16-bit code units.  Does not advance rPC.
151 *
152 * The "_S" variant works the same but treats the value as signed.
153 */
154#define FETCH(_reg, _count)     ldrh    _reg, [rPC, #(_count*2)]
155#define FETCH_S(_reg, _count)   ldrsh   _reg, [rPC, #(_count*2)]
156
157/*
158 * Fetch one byte from an offset past the current PC.  Pass in the same
159 * "_count" as you would for FETCH, and an additional 0/1 indicating which
160 * byte of the halfword you want (lo/hi).
161 */
162#define FETCH_B(_reg, _count, _byte) ldrb     _reg, [rPC, #(_count*2+_byte)]
163
164/*
165 * Put the instruction's opcode field into the specified register.
166 */
167#define GET_INST_OPCODE(_reg)   and     _reg, rINST, #255
168
169/*
170 * Put the prefetched instruction's opcode field into the specified register.
171 */
172#define GET_PREFETCHED_OPCODE(_oreg, _ireg)   and     _oreg, _ireg, #255
173
174/*
175 * Begin executing the opcode in _reg.  Because this only jumps within the
176 * interpreter, we don't have to worry about pre-ARMv5 THUMB interwork.
177 */
178#define GOTO_OPCODE(_reg)       add     pc, rIBASE, _reg, lsl #6
179#define GOTO_OPCODE_IFEQ(_reg)  addeq   pc, rIBASE, _reg, lsl #6
180#define GOTO_OPCODE_IFNE(_reg)  addne   pc, rIBASE, _reg, lsl #6
181
182/*
183 * Get/set the 32-bit value from a Dalvik register.
184 */
185#define GET_VREG(_reg, _vreg)   ldr     _reg, [rFP, _vreg, lsl #2]
186#define SET_VREG(_reg, _vreg)   str     _reg, [rFP, _vreg, lsl #2]
187
188#if defined(WITH_JIT)
189#define GET_JIT_PROF_TABLE(_reg)    ldr     _reg,[rGLUE,#offGlue_pJitProfTable]
190#define GET_JIT_THRESHOLD(_reg)     ldr     _reg,[rGLUE,#offGlue_jitThreshold]
191#endif
192
193/*
194 * Convert a virtual register index into an address.
195 */
196#define VREG_INDEX_TO_ADDR(_reg, _vreg) \
197        add     _reg, rFP, _vreg, lsl #2
198
199/*
200 * This is a #include, not a %include, because we want the C pre-processor
201 * to expand the macros into assembler assignment statements.
202 */
203#include "../common/asm-constants.h"
204
205#if defined(WITH_JIT)
206#include "../common/jit-config.h"
207#endif
208
209/* File: armv7-a/platform.S */
210/*
211 * ===========================================================================
212 *  CPU-version-specific defines
213 * ===========================================================================
214 */
215
216#if !defined(ANDROID_SMP)
217# error "Must define ANDROID_SMP"
218#endif
219
220/*
221 * Macro for data memory barrier.
222 */
223.macro  SMP_DMB
224#if ANDROID_SMP != 0
225    dmb
226#else
227    /* not SMP */
228#endif
229.endm
230
231/*
232 * Macro for data memory barrier (store/store variant).
233 */
234.macro  SMP_DMB_ST
235#if ANDROID_SMP != 0
236    dmb     st
237#else
238    /* not SMP */
239#endif
240.endm
241
242/* File: armv5te/entry.S */
243/*
244 * Copyright (C) 2008 The Android Open Source Project
245 *
246 * Licensed under the Apache License, Version 2.0 (the "License");
247 * you may not use this file except in compliance with the License.
248 * You may obtain a copy of the License at
249 *
250 *      http://www.apache.org/licenses/LICENSE-2.0
251 *
252 * Unless required by applicable law or agreed to in writing, software
253 * distributed under the License is distributed on an "AS IS" BASIS,
254 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
255 * See the License for the specific language governing permissions and
256 * limitations under the License.
257 */
258/*
259 * Interpreter entry point.
260 */
261
262/*
263 * We don't have formal stack frames, so gdb scans upward in the code
264 * to find the start of the function (a label with the %function type),
265 * and then looks at the next few instructions to figure out what
266 * got pushed onto the stack.  From this it figures out how to restore
267 * the registers, including PC, for the previous stack frame.  If gdb
268 * sees a non-function label, it stops scanning, so either we need to
269 * have nothing but assembler-local labels between the entry point and
270 * the break, or we need to fake it out.
271 *
272 * When this is defined, we add some stuff to make gdb less confused.
273 */
274#define ASSIST_DEBUGGER 1
275
276    .text
277    .align  2
278    .global dvmMterpStdRun
279    .type   dvmMterpStdRun, %function
280
281/*
282 * On entry:
283 *  r0  MterpGlue* glue
284 *
285 * This function returns a boolean "changeInterp" value.  The return comes
286 * via a call to dvmMterpStdBail().
287 */
288dvmMterpStdRun:
289#define MTERP_ENTRY1 \
290    .save {r4-r10,fp,lr}; \
291    stmfd   sp!, {r4-r10,fp,lr}         @ save 9 regs
292#define MTERP_ENTRY2 \
293    .pad    #4; \
294    sub     sp, sp, #4                  @ align 64
295
296    .fnstart
297    MTERP_ENTRY1
298    MTERP_ENTRY2
299
300    /* save stack pointer, add magic word for debuggerd */
301    str     sp, [r0, #offGlue_bailPtr]  @ save SP for eventual return
302
303    /* set up "named" registers, figure out entry point */
304    mov     rGLUE, r0                   @ set rGLUE
305    ldr     r1, [r0, #offGlue_entryPoint]   @ enum is 4 bytes in aapcs-EABI
306    LOAD_PC_FP_FROM_GLUE()              @ load rPC and rFP from "glue"
307    adr     rIBASE, dvmAsmInstructionStart  @ set rIBASE
308    cmp     r1, #kInterpEntryInstr      @ usual case?
309    bne     .Lnot_instr                 @ no, handle it
310
311#if defined(WITH_JIT)
312.LentryInstr:
313    ldr     r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self
314    /* Entry is always a possible trace start */
315    GET_JIT_PROF_TABLE(r0)
316    FETCH_INST()
317    mov     r1, #0                      @ prepare the value for the new state
318    str     r1, [r10, #offThread_inJitCodeCache] @ back to the interp land
319    cmp     r0,#0                       @ is profiling disabled?
320#if !defined(WITH_SELF_VERIFICATION)
321    bne     common_updateProfile        @ profiling is enabled
322#else
323    ldr     r2, [r10, #offThread_shadowSpace]   @ to find out the jit exit state
324    beq     1f                          @ profiling is disabled
325    ldr     r3, [r2, #offShadowSpace_jitExitState]  @ jit exit state
326    cmp     r3, #kSVSTraceSelect        @ hot trace following?
327    moveq   r2,#kJitTSelectRequestHot   @ ask for trace selection
328    beq     common_selectTrace          @ go build the trace
329    cmp     r3, #kSVSNoProfile          @ don't profile the next instruction?
330    beq     1f                          @ intrepret the next instruction
331    b       common_updateProfile        @ collect profiles
332#endif
3331:
334    GET_INST_OPCODE(ip)
335    GOTO_OPCODE(ip)
336#else
337    /* start executing the instruction at rPC */
338    FETCH_INST()                        @ load rINST from rPC
339    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
340    GOTO_OPCODE(ip)                     @ jump to next instruction
341#endif
342
343.Lnot_instr:
344    cmp     r1, #kInterpEntryReturn     @ were we returning from a method?
345    beq     common_returnFromMethod
346
347.Lnot_return:
348    cmp     r1, #kInterpEntryThrow      @ were we throwing an exception?
349    beq     common_exceptionThrown
350
351#if defined(WITH_JIT)
352.Lnot_throw:
353    ldr     r10,[rGLUE, #offGlue_jitResumeNPC]
354    ldr     r2,[rGLUE, #offGlue_jitResumeDPC]
355    cmp     r1, #kInterpEntryResume     @ resuming after Jit single-step?
356    bne     .Lbad_arg
357    cmp     rPC,r2
358    bne     .LentryInstr                @ must have branched, don't resume
359#if defined(WITH_SELF_VERIFICATION)
360    @ glue->entryPoint will be set in dvmSelfVerificationSaveState
361    b       jitSVShadowRunStart         @ re-enter the translation after the
362                                        @ single-stepped instruction
363    @noreturn
364#endif
365    mov     r1, #kInterpEntryInstr
366    str     r1, [rGLUE, #offGlue_entryPoint]
367    bx      r10                         @ re-enter the translation
368#endif
369
370.Lbad_arg:
371    ldr     r0, strBadEntryPoint
372    @ r1 holds value of entryPoint
373    bl      printf
374    bl      dvmAbort
375    .fnend
376
377
378    .global dvmMterpStdBail
379    .type   dvmMterpStdBail, %function
380
381/*
382 * Restore the stack pointer and PC from the save point established on entry.
383 * This is essentially the same as a longjmp, but should be cheaper.  The
384 * last instruction causes us to return to whoever called dvmMterpStdRun.
385 *
386 * We pushed some registers on the stack in dvmMterpStdRun, then saved
387 * SP and LR.  Here we restore SP, restore the registers, and then restore
388 * LR to PC.
389 *
390 * On entry:
391 *  r0  MterpGlue* glue
392 *  r1  bool changeInterp
393 */
394dvmMterpStdBail:
395    ldr     sp, [r0, #offGlue_bailPtr]      @ sp<- saved SP
396    mov     r0, r1                          @ return the changeInterp value
397    add     sp, sp, #4                      @ un-align 64
398    ldmfd   sp!, {r4-r10,fp,pc}             @ restore 9 regs and return
399
400
401/*
402 * String references.
403 */
404strBadEntryPoint:
405    .word   .LstrBadEntryPoint
406
407
408    .global dvmAsmInstructionStart
409    .type   dvmAsmInstructionStart, %function
410dvmAsmInstructionStart = .L_OP_NOP
411    .text
412
413/* ------------------------------ */
414    .balign 64
415.L_OP_NOP: /* 0x00 */
416/* File: armv5te/OP_NOP.S */
417    FETCH_ADVANCE_INST(1)               @ advance to next instr, load rINST
418    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
419    GOTO_OPCODE(ip)                     @ execute it
420
421#ifdef ASSIST_DEBUGGER
422    /* insert fake function header to help gdb find the stack frame */
423    .type   dalvik_inst, %function
424dalvik_inst:
425    .fnstart
426    MTERP_ENTRY1
427    MTERP_ENTRY2
428    .fnend
429#endif
430
431/* ------------------------------ */
432    .balign 64
433.L_OP_MOVE: /* 0x01 */
434/* File: armv6t2/OP_MOVE.S */
435    /* for move, move-object, long-to-int */
436    /* op vA, vB */
437    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
438    ubfx    r0, rINST, #8, #4           @ r0<- A from 11:8
439    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
440    GET_VREG(r2, r1)                    @ r2<- fp[B]
441    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
442    SET_VREG(r2, r0)                    @ fp[A]<- r2
443    GOTO_OPCODE(ip)                     @ execute next instruction
444
445/* ------------------------------ */
446    .balign 64
447.L_OP_MOVE_FROM16: /* 0x02 */
448/* File: armv5te/OP_MOVE_FROM16.S */
449    /* for: move/from16, move-object/from16 */
450    /* op vAA, vBBBB */
451    FETCH(r1, 1)                        @ r1<- BBBB
452    mov     r0, rINST, lsr #8           @ r0<- AA
453    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
454    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
455    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
456    SET_VREG(r2, r0)                    @ fp[AA]<- r2
457    GOTO_OPCODE(ip)                     @ jump to next instruction
458
459/* ------------------------------ */
460    .balign 64
461.L_OP_MOVE_16: /* 0x03 */
462/* File: armv5te/OP_MOVE_16.S */
463    /* for: move/16, move-object/16 */
464    /* op vAAAA, vBBBB */
465    FETCH(r1, 2)                        @ r1<- BBBB
466    FETCH(r0, 1)                        @ r0<- AAAA
467    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
468    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
469    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
470    SET_VREG(r2, r0)                    @ fp[AAAA]<- r2
471    GOTO_OPCODE(ip)                     @ jump to next instruction
472
473/* ------------------------------ */
474    .balign 64
475.L_OP_MOVE_WIDE: /* 0x04 */
476/* File: armv6t2/OP_MOVE_WIDE.S */
477    /* move-wide vA, vB */
478    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
479    mov     r3, rINST, lsr #12          @ r3<- B
480    ubfx    r2, rINST, #8, #4           @ r2<- A
481    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
482    add     r2, rFP, r2, lsl #2         @ r2<- &fp[A]
483    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[B]
484    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
485    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
486    stmia   r2, {r0-r1}                 @ fp[A]<- r0/r1
487    GOTO_OPCODE(ip)                     @ jump to next instruction
488
489/* ------------------------------ */
490    .balign 64
491.L_OP_MOVE_WIDE_FROM16: /* 0x05 */
492/* File: armv5te/OP_MOVE_WIDE_FROM16.S */
493    /* move-wide/from16 vAA, vBBBB */
494    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
495    FETCH(r3, 1)                        @ r3<- BBBB
496    mov     r2, rINST, lsr #8           @ r2<- AA
497    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BBBB]
498    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
499    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[BBBB]
500    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
501    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
502    stmia   r2, {r0-r1}                 @ fp[AA]<- r0/r1
503    GOTO_OPCODE(ip)                     @ jump to next instruction
504
505/* ------------------------------ */
506    .balign 64
507.L_OP_MOVE_WIDE_16: /* 0x06 */
508/* File: armv5te/OP_MOVE_WIDE_16.S */
509    /* move-wide/16 vAAAA, vBBBB */
510    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
511    FETCH(r3, 2)                        @ r3<- BBBB
512    FETCH(r2, 1)                        @ r2<- AAAA
513    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BBBB]
514    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AAAA]
515    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[BBBB]
516    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
517    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
518    stmia   r2, {r0-r1}                 @ fp[AAAA]<- r0/r1
519    GOTO_OPCODE(ip)                     @ jump to next instruction
520
521/* ------------------------------ */
522    .balign 64
523.L_OP_MOVE_OBJECT: /* 0x07 */
524/* File: armv5te/OP_MOVE_OBJECT.S */
525/* File: armv5te/OP_MOVE.S */
526    /* for move, move-object, long-to-int */
527    /* op vA, vB */
528    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
529    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
530    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
531    GET_VREG(r2, r1)                    @ r2<- fp[B]
532    and     r0, r0, #15
533    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
534    SET_VREG(r2, r0)                    @ fp[A]<- r2
535    GOTO_OPCODE(ip)                     @ execute next instruction
536
537
538/* ------------------------------ */
539    .balign 64
540.L_OP_MOVE_OBJECT_FROM16: /* 0x08 */
541/* File: armv5te/OP_MOVE_OBJECT_FROM16.S */
542/* File: armv5te/OP_MOVE_FROM16.S */
543    /* for: move/from16, move-object/from16 */
544    /* op vAA, vBBBB */
545    FETCH(r1, 1)                        @ r1<- BBBB
546    mov     r0, rINST, lsr #8           @ r0<- AA
547    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
548    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
549    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
550    SET_VREG(r2, r0)                    @ fp[AA]<- r2
551    GOTO_OPCODE(ip)                     @ jump to next instruction
552
553
554/* ------------------------------ */
555    .balign 64
556.L_OP_MOVE_OBJECT_16: /* 0x09 */
557/* File: armv5te/OP_MOVE_OBJECT_16.S */
558/* File: armv5te/OP_MOVE_16.S */
559    /* for: move/16, move-object/16 */
560    /* op vAAAA, vBBBB */
561    FETCH(r1, 2)                        @ r1<- BBBB
562    FETCH(r0, 1)                        @ r0<- AAAA
563    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
564    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
565    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
566    SET_VREG(r2, r0)                    @ fp[AAAA]<- r2
567    GOTO_OPCODE(ip)                     @ jump to next instruction
568
569
570/* ------------------------------ */
571    .balign 64
572.L_OP_MOVE_RESULT: /* 0x0a */
573/* File: armv5te/OP_MOVE_RESULT.S */
574    /* for: move-result, move-result-object */
575    /* op vAA */
576    mov     r2, rINST, lsr #8           @ r2<- AA
577    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
578    ldr     r0, [rGLUE, #offGlue_retval]    @ r0<- glue->retval.i
579    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
580    SET_VREG(r0, r2)                    @ fp[AA]<- r0
581    GOTO_OPCODE(ip)                     @ jump to next instruction
582
583/* ------------------------------ */
584    .balign 64
585.L_OP_MOVE_RESULT_WIDE: /* 0x0b */
586/* File: armv5te/OP_MOVE_RESULT_WIDE.S */
587    /* move-result-wide vAA */
588    mov     r2, rINST, lsr #8           @ r2<- AA
589    add     r3, rGLUE, #offGlue_retval  @ r3<- &glue->retval
590    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
591    ldmia   r3, {r0-r1}                 @ r0/r1<- retval.j
592    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
593    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
594    stmia   r2, {r0-r1}                 @ fp[AA]<- r0/r1
595    GOTO_OPCODE(ip)                     @ jump to next instruction
596
597/* ------------------------------ */
598    .balign 64
599.L_OP_MOVE_RESULT_OBJECT: /* 0x0c */
600/* File: armv5te/OP_MOVE_RESULT_OBJECT.S */
601/* File: armv5te/OP_MOVE_RESULT.S */
602    /* for: move-result, move-result-object */
603    /* op vAA */
604    mov     r2, rINST, lsr #8           @ r2<- AA
605    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
606    ldr     r0, [rGLUE, #offGlue_retval]    @ r0<- glue->retval.i
607    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
608    SET_VREG(r0, r2)                    @ fp[AA]<- r0
609    GOTO_OPCODE(ip)                     @ jump to next instruction
610
611
612/* ------------------------------ */
613    .balign 64
614.L_OP_MOVE_EXCEPTION: /* 0x0d */
615/* File: armv5te/OP_MOVE_EXCEPTION.S */
616    /* move-exception vAA */
617    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
618    mov     r2, rINST, lsr #8           @ r2<- AA
619    ldr     r3, [r0, #offThread_exception]  @ r3<- dvmGetException bypass
620    mov     r1, #0                      @ r1<- 0
621    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
622    SET_VREG(r3, r2)                    @ fp[AA]<- exception obj
623    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
624    str     r1, [r0, #offThread_exception]  @ dvmClearException bypass
625    GOTO_OPCODE(ip)                     @ jump to next instruction
626
627/* ------------------------------ */
628    .balign 64
629.L_OP_RETURN_VOID: /* 0x0e */
630/* File: armv5te/OP_RETURN_VOID.S */
631    b       common_returnFromMethod
632
633/* ------------------------------ */
634    .balign 64
635.L_OP_RETURN: /* 0x0f */
636/* File: armv5te/OP_RETURN.S */
637    /*
638     * Return a 32-bit value.  Copies the return value into the "glue"
639     * structure, then jumps to the return handler.
640     *
641     * for: return, return-object
642     */
643    /* op vAA */
644    mov     r2, rINST, lsr #8           @ r2<- AA
645    GET_VREG(r0, r2)                    @ r0<- vAA
646    str     r0, [rGLUE, #offGlue_retval] @ retval.i <- vAA
647    b       common_returnFromMethod
648
649/* ------------------------------ */
650    .balign 64
651.L_OP_RETURN_WIDE: /* 0x10 */
652/* File: armv5te/OP_RETURN_WIDE.S */
653    /*
654     * Return a 64-bit value.  Copies the return value into the "glue"
655     * structure, then jumps to the return handler.
656     */
657    /* return-wide vAA */
658    mov     r2, rINST, lsr #8           @ r2<- AA
659    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
660    add     r3, rGLUE, #offGlue_retval  @ r3<- &glue->retval
661    ldmia   r2, {r0-r1}                 @ r0/r1 <- vAA/vAA+1
662    stmia   r3, {r0-r1}                 @ retval<- r0/r1
663    b       common_returnFromMethod
664
665/* ------------------------------ */
666    .balign 64
667.L_OP_RETURN_OBJECT: /* 0x11 */
668/* File: armv5te/OP_RETURN_OBJECT.S */
669/* File: armv5te/OP_RETURN.S */
670    /*
671     * Return a 32-bit value.  Copies the return value into the "glue"
672     * structure, then jumps to the return handler.
673     *
674     * for: return, return-object
675     */
676    /* op vAA */
677    mov     r2, rINST, lsr #8           @ r2<- AA
678    GET_VREG(r0, r2)                    @ r0<- vAA
679    str     r0, [rGLUE, #offGlue_retval] @ retval.i <- vAA
680    b       common_returnFromMethod
681
682
683/* ------------------------------ */
684    .balign 64
685.L_OP_CONST_4: /* 0x12 */
686/* File: armv6t2/OP_CONST_4.S */
687    /* const/4 vA, #+B */
688    mov     r1, rINST, lsl #16          @ r1<- Bxxx0000
689    ubfx    r0, rINST, #8, #4           @ r0<- A
690    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
691    mov     r1, r1, asr #28             @ r1<- sssssssB (sign-extended)
692    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
693    SET_VREG(r1, r0)                    @ fp[A]<- r1
694    GOTO_OPCODE(ip)                     @ execute next instruction
695
696/* ------------------------------ */
697    .balign 64
698.L_OP_CONST_16: /* 0x13 */
699/* File: armv5te/OP_CONST_16.S */
700    /* const/16 vAA, #+BBBB */
701    FETCH_S(r0, 1)                      @ r0<- ssssBBBB (sign-extended)
702    mov     r3, rINST, lsr #8           @ r3<- AA
703    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
704    SET_VREG(r0, r3)                    @ vAA<- r0
705    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
706    GOTO_OPCODE(ip)                     @ jump to next instruction
707
708/* ------------------------------ */
709    .balign 64
710.L_OP_CONST: /* 0x14 */
711/* File: armv5te/OP_CONST.S */
712    /* const vAA, #+BBBBbbbb */
713    mov     r3, rINST, lsr #8           @ r3<- AA
714    FETCH(r0, 1)                        @ r0<- bbbb (low)
715    FETCH(r1, 2)                        @ r1<- BBBB (high)
716    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
717    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
718    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
719    SET_VREG(r0, r3)                    @ vAA<- r0
720    GOTO_OPCODE(ip)                     @ jump to next instruction
721
722/* ------------------------------ */
723    .balign 64
724.L_OP_CONST_HIGH16: /* 0x15 */
725/* File: armv5te/OP_CONST_HIGH16.S */
726    /* const/high16 vAA, #+BBBB0000 */
727    FETCH(r0, 1)                        @ r0<- 0000BBBB (zero-extended)
728    mov     r3, rINST, lsr #8           @ r3<- AA
729    mov     r0, r0, lsl #16             @ r0<- BBBB0000
730    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
731    SET_VREG(r0, r3)                    @ vAA<- r0
732    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
733    GOTO_OPCODE(ip)                     @ jump to next instruction
734
735/* ------------------------------ */
736    .balign 64
737.L_OP_CONST_WIDE_16: /* 0x16 */
738/* File: armv5te/OP_CONST_WIDE_16.S */
739    /* const-wide/16 vAA, #+BBBB */
740    FETCH_S(r0, 1)                      @ r0<- ssssBBBB (sign-extended)
741    mov     r3, rINST, lsr #8           @ r3<- AA
742    mov     r1, r0, asr #31             @ r1<- ssssssss
743    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
744    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
745    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
746    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
747    GOTO_OPCODE(ip)                     @ jump to next instruction
748
749/* ------------------------------ */
750    .balign 64
751.L_OP_CONST_WIDE_32: /* 0x17 */
752/* File: armv5te/OP_CONST_WIDE_32.S */
753    /* const-wide/32 vAA, #+BBBBbbbb */
754    FETCH(r0, 1)                        @ r0<- 0000bbbb (low)
755    mov     r3, rINST, lsr #8           @ r3<- AA
756    FETCH_S(r2, 2)                      @ r2<- ssssBBBB (high)
757    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
758    orr     r0, r0, r2, lsl #16         @ r0<- BBBBbbbb
759    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
760    mov     r1, r0, asr #31             @ r1<- ssssssss
761    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
762    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
763    GOTO_OPCODE(ip)                     @ jump to next instruction
764
765/* ------------------------------ */
766    .balign 64
767.L_OP_CONST_WIDE: /* 0x18 */
768/* File: armv5te/OP_CONST_WIDE.S */
769    /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
770    FETCH(r0, 1)                        @ r0<- bbbb (low)
771    FETCH(r1, 2)                        @ r1<- BBBB (low middle)
772    FETCH(r2, 3)                        @ r2<- hhhh (high middle)
773    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb (low word)
774    FETCH(r3, 4)                        @ r3<- HHHH (high)
775    mov     r9, rINST, lsr #8           @ r9<- AA
776    orr     r1, r2, r3, lsl #16         @ r1<- HHHHhhhh (high word)
777    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
778    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
779    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
780    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
781    GOTO_OPCODE(ip)                     @ jump to next instruction
782
783/* ------------------------------ */
784    .balign 64
785.L_OP_CONST_WIDE_HIGH16: /* 0x19 */
786/* File: armv5te/OP_CONST_WIDE_HIGH16.S */
787    /* const-wide/high16 vAA, #+BBBB000000000000 */
788    FETCH(r1, 1)                        @ r1<- 0000BBBB (zero-extended)
789    mov     r3, rINST, lsr #8           @ r3<- AA
790    mov     r0, #0                      @ r0<- 00000000
791    mov     r1, r1, lsl #16             @ r1<- BBBB0000
792    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
793    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
794    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
795    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
796    GOTO_OPCODE(ip)                     @ jump to next instruction
797
798/* ------------------------------ */
799    .balign 64
800.L_OP_CONST_STRING: /* 0x1a */
801/* File: armv5te/OP_CONST_STRING.S */
802    /* const/string vAA, String@BBBB */
803    FETCH(r1, 1)                        @ r1<- BBBB
804    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- glue->methodClassDex
805    mov     r9, rINST, lsr #8           @ r9<- AA
806    ldr     r2, [r2, #offDvmDex_pResStrings]   @ r2<- dvmDex->pResStrings
807    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResStrings[BBBB]
808    cmp     r0, #0                      @ not yet resolved?
809    beq     .LOP_CONST_STRING_resolve
810    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
811    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
812    SET_VREG(r0, r9)                    @ vAA<- r0
813    GOTO_OPCODE(ip)                     @ jump to next instruction
814
815/* ------------------------------ */
816    .balign 64
817.L_OP_CONST_STRING_JUMBO: /* 0x1b */
818/* File: armv5te/OP_CONST_STRING_JUMBO.S */
819    /* const/string vAA, String@BBBBBBBB */
820    FETCH(r0, 1)                        @ r0<- bbbb (low)
821    FETCH(r1, 2)                        @ r1<- BBBB (high)
822    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- glue->methodClassDex
823    mov     r9, rINST, lsr #8           @ r9<- AA
824    ldr     r2, [r2, #offDvmDex_pResStrings]   @ r2<- dvmDex->pResStrings
825    orr     r1, r0, r1, lsl #16         @ r1<- BBBBbbbb
826    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResStrings[BBBB]
827    cmp     r0, #0
828    beq     .LOP_CONST_STRING_JUMBO_resolve
829    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
830    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
831    SET_VREG(r0, r9)                    @ vAA<- r0
832    GOTO_OPCODE(ip)                     @ jump to next instruction
833
834/* ------------------------------ */
835    .balign 64
836.L_OP_CONST_CLASS: /* 0x1c */
837/* File: armv5te/OP_CONST_CLASS.S */
838    /* const/class vAA, Class@BBBB */
839    FETCH(r1, 1)                        @ r1<- BBBB
840    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- glue->methodClassDex
841    mov     r9, rINST, lsr #8           @ r9<- AA
842    ldr     r2, [r2, #offDvmDex_pResClasses]   @ r2<- dvmDex->pResClasses
843    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResClasses[BBBB]
844    cmp     r0, #0                      @ not yet resolved?
845    beq     .LOP_CONST_CLASS_resolve
846    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
847    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
848    SET_VREG(r0, r9)                    @ vAA<- r0
849    GOTO_OPCODE(ip)                     @ jump to next instruction
850
851/* ------------------------------ */
852    .balign 64
853.L_OP_MONITOR_ENTER: /* 0x1d */
854/* File: armv5te/OP_MONITOR_ENTER.S */
855    /*
856     * Synchronize on an object.
857     */
858    /* monitor-enter vAA */
859    mov     r2, rINST, lsr #8           @ r2<- AA
860    GET_VREG(r1, r2)                    @ r1<- vAA (object)
861    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
862    cmp     r1, #0                      @ null object?
863    EXPORT_PC()                         @ need for precise GC
864    beq     common_errNullObject        @ null object, throw an exception
865    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
866    bl      dvmLockObject               @ call(self, obj)
867    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
868    GOTO_OPCODE(ip)                     @ jump to next instruction
869
870/* ------------------------------ */
871    .balign 64
872.L_OP_MONITOR_EXIT: /* 0x1e */
873/* File: armv5te/OP_MONITOR_EXIT.S */
874    /*
875     * Unlock an object.
876     *
877     * Exceptions that occur when unlocking a monitor need to appear as
878     * if they happened at the following instruction.  See the Dalvik
879     * instruction spec.
880     */
881    /* monitor-exit vAA */
882    mov     r2, rINST, lsr #8           @ r2<- AA
883    EXPORT_PC()                         @ before fetch: export the PC
884    GET_VREG(r1, r2)                    @ r1<- vAA (object)
885    cmp     r1, #0                      @ null object?
886    beq     1f                          @ yes
887    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
888    bl      dvmUnlockObject             @ r0<- success for unlock(self, obj)
889    cmp     r0, #0                      @ failed?
890    FETCH_ADVANCE_INST(1)               @ before throw: advance rPC, load rINST
891    beq     common_exceptionThrown      @ yes, exception is pending
892    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
893    GOTO_OPCODE(ip)                     @ jump to next instruction
8941:
895    FETCH_ADVANCE_INST(1)               @ advance before throw
896    b      common_errNullObject
897
898/* ------------------------------ */
899    .balign 64
900.L_OP_CHECK_CAST: /* 0x1f */
901/* File: armv5te/OP_CHECK_CAST.S */
902    /*
903     * Check to see if a cast from one class to another is allowed.
904     */
905    /* check-cast vAA, class@BBBB */
906    mov     r3, rINST, lsr #8           @ r3<- AA
907    FETCH(r2, 1)                        @ r2<- BBBB
908    GET_VREG(r9, r3)                    @ r9<- object
909    ldr     r0, [rGLUE, #offGlue_methodClassDex]    @ r0<- pDvmDex
910    cmp     r9, #0                      @ is object null?
911    ldr     r0, [r0, #offDvmDex_pResClasses]    @ r0<- pDvmDex->pResClasses
912    beq     .LOP_CHECK_CAST_okay            @ null obj, cast always succeeds
913    ldr     r1, [r0, r2, lsl #2]        @ r1<- resolved class
914    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
915    cmp     r1, #0                      @ have we resolved this before?
916    beq     .LOP_CHECK_CAST_resolve         @ not resolved, do it now
917.LOP_CHECK_CAST_resolved:
918    cmp     r0, r1                      @ same class (trivial success)?
919    bne     .LOP_CHECK_CAST_fullcheck       @ no, do full check
920.LOP_CHECK_CAST_okay:
921    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
922    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
923    GOTO_OPCODE(ip)                     @ jump to next instruction
924
925/* ------------------------------ */
926    .balign 64
927.L_OP_INSTANCE_OF: /* 0x20 */
928/* File: armv5te/OP_INSTANCE_OF.S */
929    /*
930     * Check to see if an object reference is an instance of a class.
931     *
932     * Most common situation is a non-null object, being compared against
933     * an already-resolved class.
934     */
935    /* instance-of vA, vB, class@CCCC */
936    mov     r3, rINST, lsr #12          @ r3<- B
937    mov     r9, rINST, lsr #8           @ r9<- A+
938    GET_VREG(r0, r3)                    @ r0<- vB (object)
939    and     r9, r9, #15                 @ r9<- A
940    cmp     r0, #0                      @ is object null?
941    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- pDvmDex
942    beq     .LOP_INSTANCE_OF_store           @ null obj, not an instance, store r0
943    FETCH(r3, 1)                        @ r3<- CCCC
944    ldr     r2, [r2, #offDvmDex_pResClasses]    @ r2<- pDvmDex->pResClasses
945    ldr     r1, [r2, r3, lsl #2]        @ r1<- resolved class
946    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
947    cmp     r1, #0                      @ have we resolved this before?
948    beq     .LOP_INSTANCE_OF_resolve         @ not resolved, do it now
949.LOP_INSTANCE_OF_resolved: @ r0=obj->clazz, r1=resolved class
950    cmp     r0, r1                      @ same class (trivial success)?
951    beq     .LOP_INSTANCE_OF_trivial         @ yes, trivial finish
952    b       .LOP_INSTANCE_OF_fullcheck       @ no, do full check
953
954/* ------------------------------ */
955    .balign 64
956.L_OP_ARRAY_LENGTH: /* 0x21 */
957/* File: armv6t2/OP_ARRAY_LENGTH.S */
958    /*
959     * Return the length of an array.
960     */
961    mov     r1, rINST, lsr #12          @ r1<- B
962    ubfx    r2, rINST, #8, #4           @ r2<- A
963    GET_VREG(r0, r1)                    @ r0<- vB (object ref)
964    cmp     r0, #0                      @ is object null?
965    beq     common_errNullObject        @ yup, fail
966    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
967    ldr     r3, [r0, #offArrayObject_length]    @ r3<- array length
968    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
969    SET_VREG(r3, r2)                    @ vB<- length
970    GOTO_OPCODE(ip)                     @ jump to next instruction
971
972/* ------------------------------ */
973    .balign 64
974.L_OP_NEW_INSTANCE: /* 0x22 */
975/* File: armv5te/OP_NEW_INSTANCE.S */
976    /*
977     * Create a new instance of a class.
978     */
979    /* new-instance vAA, class@BBBB */
980    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
981    FETCH(r1, 1)                        @ r1<- BBBB
982    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
983    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
984    EXPORT_PC()                         @ req'd for init, resolve, alloc
985    cmp     r0, #0                      @ already resolved?
986    beq     .LOP_NEW_INSTANCE_resolve         @ no, resolve it now
987.LOP_NEW_INSTANCE_resolved:   @ r0=class
988    ldrb    r1, [r0, #offClassObject_status]    @ r1<- ClassStatus enum
989    cmp     r1, #CLASS_INITIALIZED      @ has class been initialized?
990    bne     .LOP_NEW_INSTANCE_needinit        @ no, init class now
991.LOP_NEW_INSTANCE_initialized: @ r0=class
992    mov     r1, #ALLOC_DONT_TRACK       @ flags for alloc call
993    bl      dvmAllocObject              @ r0<- new object
994    b       .LOP_NEW_INSTANCE_finish          @ continue
995
996/* ------------------------------ */
997    .balign 64
998.L_OP_NEW_ARRAY: /* 0x23 */
999/* File: armv5te/OP_NEW_ARRAY.S */
1000    /*
1001     * Allocate an array of objects, specified with the array class
1002     * and a count.
1003     *
1004     * The verifier guarantees that this is an array class, so we don't
1005     * check for it here.
1006     */
1007    /* new-array vA, vB, class@CCCC */
1008    mov     r0, rINST, lsr #12          @ r0<- B
1009    FETCH(r2, 1)                        @ r2<- CCCC
1010    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
1011    GET_VREG(r1, r0)                    @ r1<- vB (array length)
1012    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
1013    cmp     r1, #0                      @ check length
1014    ldr     r0, [r3, r2, lsl #2]        @ r0<- resolved class
1015    bmi     common_errNegativeArraySize @ negative length, bail
1016    cmp     r0, #0                      @ already resolved?
1017    EXPORT_PC()                         @ req'd for resolve, alloc
1018    bne     .LOP_NEW_ARRAY_finish          @ resolved, continue
1019    b       .LOP_NEW_ARRAY_resolve         @ do resolve now
1020
1021/* ------------------------------ */
1022    .balign 64
1023.L_OP_FILLED_NEW_ARRAY: /* 0x24 */
1024/* File: armv5te/OP_FILLED_NEW_ARRAY.S */
1025    /*
1026     * Create a new array with elements filled from registers.
1027     *
1028     * for: filled-new-array, filled-new-array/range
1029     */
1030    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1031    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1032    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
1033    FETCH(r1, 1)                        @ r1<- BBBB
1034    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
1035    EXPORT_PC()                         @ need for resolve and alloc
1036    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
1037    mov     r10, rINST, lsr #8          @ r10<- AA or BA
1038    cmp     r0, #0                      @ already resolved?
1039    bne     .LOP_FILLED_NEW_ARRAY_continue        @ yes, continue on
10408:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
1041    mov     r2, #0                      @ r2<- false
1042    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
1043    bl      dvmResolveClass             @ r0<- call(clazz, ref)
1044    cmp     r0, #0                      @ got null?
1045    beq     common_exceptionThrown      @ yes, handle exception
1046    b       .LOP_FILLED_NEW_ARRAY_continue
1047
1048/* ------------------------------ */
1049    .balign 64
1050.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
1051/* File: armv5te/OP_FILLED_NEW_ARRAY_RANGE.S */
1052/* File: armv5te/OP_FILLED_NEW_ARRAY.S */
1053    /*
1054     * Create a new array with elements filled from registers.
1055     *
1056     * for: filled-new-array, filled-new-array/range
1057     */
1058    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1059    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1060    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
1061    FETCH(r1, 1)                        @ r1<- BBBB
1062    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
1063    EXPORT_PC()                         @ need for resolve and alloc
1064    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
1065    mov     r10, rINST, lsr #8          @ r10<- AA or BA
1066    cmp     r0, #0                      @ already resolved?
1067    bne     .LOP_FILLED_NEW_ARRAY_RANGE_continue        @ yes, continue on
10688:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
1069    mov     r2, #0                      @ r2<- false
1070    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
1071    bl      dvmResolveClass             @ r0<- call(clazz, ref)
1072    cmp     r0, #0                      @ got null?
1073    beq     common_exceptionThrown      @ yes, handle exception
1074    b       .LOP_FILLED_NEW_ARRAY_RANGE_continue
1075
1076
1077/* ------------------------------ */
1078    .balign 64
1079.L_OP_FILL_ARRAY_DATA: /* 0x26 */
1080/* File: armv5te/OP_FILL_ARRAY_DATA.S */
1081    /* fill-array-data vAA, +BBBBBBBB */
1082    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1083    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1084    mov     r3, rINST, lsr #8           @ r3<- AA
1085    orr     r1, r0, r1, lsl #16         @ r1<- BBBBbbbb
1086    GET_VREG(r0, r3)                    @ r0<- vAA (array object)
1087    add     r1, rPC, r1, lsl #1         @ r1<- PC + BBBBbbbb*2 (array data off.)
1088    EXPORT_PC();
1089    bl      dvmInterpHandleFillArrayData@ fill the array with predefined data
1090    cmp     r0, #0                      @ 0 means an exception is thrown
1091    beq     common_exceptionThrown      @ has exception
1092    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
1093    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1094    GOTO_OPCODE(ip)                     @ jump to next instruction
1095
1096/* ------------------------------ */
1097    .balign 64
1098.L_OP_THROW: /* 0x27 */
1099/* File: armv5te/OP_THROW.S */
1100    /*
1101     * Throw an exception object in the current thread.
1102     */
1103    /* throw vAA */
1104    mov     r2, rINST, lsr #8           @ r2<- AA
1105    GET_VREG(r1, r2)                    @ r1<- vAA (exception object)
1106    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
1107    EXPORT_PC()                         @ exception handler can throw
1108    cmp     r1, #0                      @ null object?
1109    beq     common_errNullObject        @ yes, throw an NPE instead
1110    @ bypass dvmSetException, just store it
1111    str     r1, [r0, #offThread_exception]  @ thread->exception<- obj
1112    b       common_exceptionThrown
1113
1114/* ------------------------------ */
1115    .balign 64
1116.L_OP_GOTO: /* 0x28 */
1117/* File: armv5te/OP_GOTO.S */
1118    /*
1119     * Unconditional branch, 8-bit offset.
1120     *
1121     * The branch distance is a signed code-unit offset, which we need to
1122     * double to get a byte offset.
1123     */
1124    /* goto +AA */
1125    mov     r0, rINST, lsl #16          @ r0<- AAxx0000
1126    movs    r9, r0, asr #24             @ r9<- ssssssAA (sign-extended)
1127    mov     r9, r9, lsl #1              @ r9<- byte offset
1128    bmi     common_backwardBranch       @ backward branch, do periodic checks
1129#if defined(WITH_JIT)
1130    GET_JIT_PROF_TABLE(r0)
1131    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1132    cmp     r0,#0
1133    bne     common_updateProfile
1134    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1135    GOTO_OPCODE(ip)                     @ jump to next instruction
1136#else
1137    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1138    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1139    GOTO_OPCODE(ip)                     @ jump to next instruction
1140#endif
1141
1142/* ------------------------------ */
1143    .balign 64
1144.L_OP_GOTO_16: /* 0x29 */
1145/* File: armv5te/OP_GOTO_16.S */
1146    /*
1147     * Unconditional branch, 16-bit offset.
1148     *
1149     * The branch distance is a signed code-unit offset, which we need to
1150     * double to get a byte offset.
1151     */
1152    /* goto/16 +AAAA */
1153    FETCH_S(r0, 1)                      @ r0<- ssssAAAA (sign-extended)
1154    movs    r9, r0, asl #1              @ r9<- byte offset, check sign
1155    bmi     common_backwardBranch       @ backward branch, do periodic checks
1156#if defined(WITH_JIT)
1157    GET_JIT_PROF_TABLE(r0)
1158    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1159    cmp     r0,#0
1160    bne     common_updateProfile
1161    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1162    GOTO_OPCODE(ip)                     @ jump to next instruction
1163#else
1164    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1165    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1166    GOTO_OPCODE(ip)                     @ jump to next instruction
1167#endif
1168
1169/* ------------------------------ */
1170    .balign 64
1171.L_OP_GOTO_32: /* 0x2a */
1172/* File: armv5te/OP_GOTO_32.S */
1173    /*
1174     * Unconditional branch, 32-bit offset.
1175     *
1176     * The branch distance is a signed code-unit offset, which we need to
1177     * double to get a byte offset.
1178     *
1179     * Unlike most opcodes, this one is allowed to branch to itself, so
1180     * our "backward branch" test must be "<=0" instead of "<0".  The ORRS
1181     * instruction doesn't affect the V flag, so we need to clear it
1182     * explicitly.
1183     */
1184    /* goto/32 +AAAAAAAA */
1185    FETCH(r0, 1)                        @ r0<- aaaa (lo)
1186    FETCH(r1, 2)                        @ r1<- AAAA (hi)
1187    cmp     ip, ip                      @ (clear V flag during stall)
1188    orrs    r0, r0, r1, lsl #16         @ r0<- AAAAaaaa, check sign
1189    mov     r9, r0, asl #1              @ r9<- byte offset
1190    ble     common_backwardBranch       @ backward branch, do periodic checks
1191#if defined(WITH_JIT)
1192    GET_JIT_PROF_TABLE(r0)
1193    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1194    cmp     r0,#0
1195    bne     common_updateProfile
1196    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1197    GOTO_OPCODE(ip)                     @ jump to next instruction
1198#else
1199    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1200    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1201    GOTO_OPCODE(ip)                     @ jump to next instruction
1202#endif
1203
1204/* ------------------------------ */
1205    .balign 64
1206.L_OP_PACKED_SWITCH: /* 0x2b */
1207/* File: armv5te/OP_PACKED_SWITCH.S */
1208    /*
1209     * Handle a packed-switch or sparse-switch instruction.  In both cases
1210     * we decode it and hand it off to a helper function.
1211     *
1212     * We don't really expect backward branches in a switch statement, but
1213     * they're perfectly legal, so we check for them here.
1214     *
1215     * for: packed-switch, sparse-switch
1216     */
1217    /* op vAA, +BBBB */
1218    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1219    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1220    mov     r3, rINST, lsr #8           @ r3<- AA
1221    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
1222    GET_VREG(r1, r3)                    @ r1<- vAA
1223    add     r0, rPC, r0, lsl #1         @ r0<- PC + BBBBbbbb*2
1224    bl      dvmInterpHandlePackedSwitch                       @ r0<- code-unit branch offset
1225    movs    r9, r0, asl #1              @ r9<- branch byte offset, check sign
1226    bmi     common_backwardBranch       @ backward branch, do periodic checks
1227    beq     common_backwardBranch       @ (want to use BLE but V is unknown)
1228#if defined(WITH_JIT)
1229    GET_JIT_PROF_TABLE(r0)
1230    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1231    cmp     r0,#0
1232    bne     common_updateProfile
1233    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1234    GOTO_OPCODE(ip)                     @ jump to next instruction
1235#else
1236    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1237    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1238    GOTO_OPCODE(ip)                     @ jump to next instruction
1239#endif
1240
1241/* ------------------------------ */
1242    .balign 64
1243.L_OP_SPARSE_SWITCH: /* 0x2c */
1244/* File: armv5te/OP_SPARSE_SWITCH.S */
1245/* File: armv5te/OP_PACKED_SWITCH.S */
1246    /*
1247     * Handle a packed-switch or sparse-switch instruction.  In both cases
1248     * we decode it and hand it off to a helper function.
1249     *
1250     * We don't really expect backward branches in a switch statement, but
1251     * they're perfectly legal, so we check for them here.
1252     *
1253     * for: packed-switch, sparse-switch
1254     */
1255    /* op vAA, +BBBB */
1256    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1257    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1258    mov     r3, rINST, lsr #8           @ r3<- AA
1259    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
1260    GET_VREG(r1, r3)                    @ r1<- vAA
1261    add     r0, rPC, r0, lsl #1         @ r0<- PC + BBBBbbbb*2
1262    bl      dvmInterpHandleSparseSwitch                       @ r0<- code-unit branch offset
1263    movs    r9, r0, asl #1              @ r9<- branch byte offset, check sign
1264    bmi     common_backwardBranch       @ backward branch, do periodic checks
1265    beq     common_backwardBranch       @ (want to use BLE but V is unknown)
1266#if defined(WITH_JIT)
1267    GET_JIT_PROF_TABLE(r0)
1268    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1269    cmp     r0,#0
1270    bne     common_updateProfile
1271    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1272    GOTO_OPCODE(ip)                     @ jump to next instruction
1273#else
1274    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1275    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1276    GOTO_OPCODE(ip)                     @ jump to next instruction
1277#endif
1278
1279
1280/* ------------------------------ */
1281    .balign 64
1282.L_OP_CMPL_FLOAT: /* 0x2d */
1283/* File: arm-vfp/OP_CMPL_FLOAT.S */
1284    /*
1285     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1286     * destination register based on the results of the comparison.
1287     *
1288     * int compare(x, y) {
1289     *     if (x == y) {
1290     *         return 0;
1291     *     } else if (x > y) {
1292     *         return 1;
1293     *     } else if (x < y) {
1294     *         return -1;
1295     *     } else {
1296     *         return -1;
1297     *     }
1298     * }
1299     */
1300    /* op vAA, vBB, vCC */
1301    FETCH(r0, 1)                        @ r0<- CCBB
1302    mov     r9, rINST, lsr #8           @ r9<- AA
1303    and     r2, r0, #255                @ r2<- BB
1304    mov     r3, r0, lsr #8              @ r3<- CC
1305    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1306    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1307    flds    s0, [r2]                    @ s0<- vBB
1308    flds    s1, [r3]                    @ s1<- vCC
1309    fcmpes  s0, s1                      @ compare (vBB, vCC)
1310    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1311    mvn     r0, #0                      @ r0<- -1 (default)
1312    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1313    fmstat                              @ export status flags
1314    movgt   r0, #1                      @ (greater than) r1<- 1
1315    moveq   r0, #0                      @ (equal) r1<- 0
1316    b       .LOP_CMPL_FLOAT_finish          @ argh
1317
1318
1319/* ------------------------------ */
1320    .balign 64
1321.L_OP_CMPG_FLOAT: /* 0x2e */
1322/* File: arm-vfp/OP_CMPG_FLOAT.S */
1323    /*
1324     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1325     * destination register based on the results of the comparison.
1326     *
1327     * int compare(x, y) {
1328     *     if (x == y) {
1329     *         return 0;
1330     *     } else if (x < y) {
1331     *         return -1;
1332     *     } else if (x > y) {
1333     *         return 1;
1334     *     } else {
1335     *         return 1;
1336     *     }
1337     * }
1338     */
1339    /* op vAA, vBB, vCC */
1340    FETCH(r0, 1)                        @ r0<- CCBB
1341    mov     r9, rINST, lsr #8           @ r9<- AA
1342    and     r2, r0, #255                @ r2<- BB
1343    mov     r3, r0, lsr #8              @ r3<- CC
1344    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1345    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1346    flds    s0, [r2]                    @ s0<- vBB
1347    flds    s1, [r3]                    @ s1<- vCC
1348    fcmpes  s0, s1                      @ compare (vBB, vCC)
1349    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1350    mov     r0, #1                      @ r0<- 1 (default)
1351    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1352    fmstat                              @ export status flags
1353    mvnmi   r0, #0                      @ (less than) r1<- -1
1354    moveq   r0, #0                      @ (equal) r1<- 0
1355    b       .LOP_CMPG_FLOAT_finish          @ argh
1356
1357
1358/* ------------------------------ */
1359    .balign 64
1360.L_OP_CMPL_DOUBLE: /* 0x2f */
1361/* File: arm-vfp/OP_CMPL_DOUBLE.S */
1362    /*
1363     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1364     * destination register based on the results of the comparison.
1365     *
1366     * int compare(x, y) {
1367     *     if (x == y) {
1368     *         return 0;
1369     *     } else if (x > y) {
1370     *         return 1;
1371     *     } else if (x < y) {
1372     *         return -1;
1373     *     } else {
1374     *         return -1;
1375     *     }
1376     * }
1377     */
1378    /* op vAA, vBB, vCC */
1379    FETCH(r0, 1)                        @ r0<- CCBB
1380    mov     r9, rINST, lsr #8           @ r9<- AA
1381    and     r2, r0, #255                @ r2<- BB
1382    mov     r3, r0, lsr #8              @ r3<- CC
1383    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1384    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1385    fldd    d0, [r2]                    @ d0<- vBB
1386    fldd    d1, [r3]                    @ d1<- vCC
1387    fcmped  d0, d1                      @ compare (vBB, vCC)
1388    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1389    mvn     r0, #0                      @ r0<- -1 (default)
1390    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1391    fmstat                              @ export status flags
1392    movgt   r0, #1                      @ (greater than) r1<- 1
1393    moveq   r0, #0                      @ (equal) r1<- 0
1394    b       .LOP_CMPL_DOUBLE_finish          @ argh
1395
1396
1397/* ------------------------------ */
1398    .balign 64
1399.L_OP_CMPG_DOUBLE: /* 0x30 */
1400/* File: arm-vfp/OP_CMPG_DOUBLE.S */
1401    /*
1402     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1403     * destination register based on the results of the comparison.
1404     *
1405     * int compare(x, y) {
1406     *     if (x == y) {
1407     *         return 0;
1408     *     } else if (x < y) {
1409     *         return -1;
1410     *     } else if (x > y) {
1411     *         return 1;
1412     *     } else {
1413     *         return 1;
1414     *     }
1415     * }
1416     */
1417    /* op vAA, vBB, vCC */
1418    FETCH(r0, 1)                        @ r0<- CCBB
1419    mov     r9, rINST, lsr #8           @ r9<- AA
1420    and     r2, r0, #255                @ r2<- BB
1421    mov     r3, r0, lsr #8              @ r3<- CC
1422    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1423    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1424    fldd    d0, [r2]                    @ d0<- vBB
1425    fldd    d1, [r3]                    @ d1<- vCC
1426    fcmped  d0, d1                      @ compare (vBB, vCC)
1427    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1428    mov     r0, #1                      @ r0<- 1 (default)
1429    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1430    fmstat                              @ export status flags
1431    mvnmi   r0, #0                      @ (less than) r1<- -1
1432    moveq   r0, #0                      @ (equal) r1<- 0
1433    b       .LOP_CMPG_DOUBLE_finish          @ argh
1434
1435
1436/* ------------------------------ */
1437    .balign 64
1438.L_OP_CMP_LONG: /* 0x31 */
1439/* File: armv5te/OP_CMP_LONG.S */
1440    /*
1441     * Compare two 64-bit values.  Puts 0, 1, or -1 into the destination
1442     * register based on the results of the comparison.
1443     *
1444     * We load the full values with LDM, but in practice many values could
1445     * be resolved by only looking at the high word.  This could be made
1446     * faster or slower by splitting the LDM into a pair of LDRs.
1447     *
1448     * If we just wanted to set condition flags, we could do this:
1449     *  subs    ip, r0, r2
1450     *  sbcs    ip, r1, r3
1451     *  subeqs  ip, r0, r2
1452     * Leaving { <0, 0, >0 } in ip.  However, we have to set it to a specific
1453     * integer value, which we can do with 2 conditional mov/mvn instructions
1454     * (set 1, set -1; if they're equal we already have 0 in ip), giving
1455     * us a constant 5-cycle path plus a branch at the end to the
1456     * instruction epilogue code.  The multi-compare approach below needs
1457     * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch
1458     * in the worst case (the 64-bit values are equal).
1459     */
1460    /* cmp-long vAA, vBB, vCC */
1461    FETCH(r0, 1)                        @ r0<- CCBB
1462    mov     r9, rINST, lsr #8           @ r9<- AA
1463    and     r2, r0, #255                @ r2<- BB
1464    mov     r3, r0, lsr #8              @ r3<- CC
1465    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
1466    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
1467    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
1468    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
1469    cmp     r1, r3                      @ compare (vBB+1, vCC+1)
1470    blt     .LOP_CMP_LONG_less            @ signed compare on high part
1471    bgt     .LOP_CMP_LONG_greater
1472    subs    r1, r0, r2                  @ r1<- r0 - r2
1473    bhi     .LOP_CMP_LONG_greater         @ unsigned compare on low part
1474    bne     .LOP_CMP_LONG_less
1475    b       .LOP_CMP_LONG_finish          @ equal; r1 already holds 0
1476
1477/* ------------------------------ */
1478    .balign 64
1479.L_OP_IF_EQ: /* 0x32 */
1480/* File: armv6t2/OP_IF_EQ.S */
1481/* File: armv6t2/bincmp.S */
1482    /*
1483     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1484     * fragment that specifies the *reverse* comparison to perform, e.g.
1485     * for "if-le" you would use "gt".
1486     *
1487     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1488     */
1489    /* if-cmp vA, vB, +CCCC */
1490    mov     r1, rINST, lsr #12          @ r1<- B
1491    ubfx    r0, rINST, #8, #4           @ r0<- A
1492    GET_VREG(r3, r1)                    @ r3<- vB
1493    GET_VREG(r2, r0)                    @ r2<- vA
1494    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1495    cmp     r2, r3                      @ compare (vA, vB)
1496    bne  1f                      @ branch to 1 if comparison failed
1497    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1498    movs    r9, r9, asl #1              @ convert to bytes, check sign
1499    bmi     common_backwardBranch       @ yes, do periodic checks
15001:
1501#if defined(WITH_JIT)
1502    GET_JIT_PROF_TABLE(r0)
1503    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1504    b        common_testUpdateProfile
1505#else
1506    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1507    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1508    GOTO_OPCODE(ip)                     @ jump to next instruction
1509#endif
1510
1511
1512/* ------------------------------ */
1513    .balign 64
1514.L_OP_IF_NE: /* 0x33 */
1515/* File: armv6t2/OP_IF_NE.S */
1516/* File: armv6t2/bincmp.S */
1517    /*
1518     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1519     * fragment that specifies the *reverse* comparison to perform, e.g.
1520     * for "if-le" you would use "gt".
1521     *
1522     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1523     */
1524    /* if-cmp vA, vB, +CCCC */
1525    mov     r1, rINST, lsr #12          @ r1<- B
1526    ubfx    r0, rINST, #8, #4           @ r0<- A
1527    GET_VREG(r3, r1)                    @ r3<- vB
1528    GET_VREG(r2, r0)                    @ r2<- vA
1529    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1530    cmp     r2, r3                      @ compare (vA, vB)
1531    beq  1f                      @ branch to 1 if comparison failed
1532    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1533    movs    r9, r9, asl #1              @ convert to bytes, check sign
1534    bmi     common_backwardBranch       @ yes, do periodic checks
15351:
1536#if defined(WITH_JIT)
1537    GET_JIT_PROF_TABLE(r0)
1538    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1539    b        common_testUpdateProfile
1540#else
1541    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1542    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1543    GOTO_OPCODE(ip)                     @ jump to next instruction
1544#endif
1545
1546
1547/* ------------------------------ */
1548    .balign 64
1549.L_OP_IF_LT: /* 0x34 */
1550/* File: armv6t2/OP_IF_LT.S */
1551/* File: armv6t2/bincmp.S */
1552    /*
1553     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1554     * fragment that specifies the *reverse* comparison to perform, e.g.
1555     * for "if-le" you would use "gt".
1556     *
1557     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1558     */
1559    /* if-cmp vA, vB, +CCCC */
1560    mov     r1, rINST, lsr #12          @ r1<- B
1561    ubfx    r0, rINST, #8, #4           @ r0<- A
1562    GET_VREG(r3, r1)                    @ r3<- vB
1563    GET_VREG(r2, r0)                    @ r2<- vA
1564    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1565    cmp     r2, r3                      @ compare (vA, vB)
1566    bge  1f                      @ branch to 1 if comparison failed
1567    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1568    movs    r9, r9, asl #1              @ convert to bytes, check sign
1569    bmi     common_backwardBranch       @ yes, do periodic checks
15701:
1571#if defined(WITH_JIT)
1572    GET_JIT_PROF_TABLE(r0)
1573    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1574    b        common_testUpdateProfile
1575#else
1576    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1577    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1578    GOTO_OPCODE(ip)                     @ jump to next instruction
1579#endif
1580
1581
1582/* ------------------------------ */
1583    .balign 64
1584.L_OP_IF_GE: /* 0x35 */
1585/* File: armv6t2/OP_IF_GE.S */
1586/* File: armv6t2/bincmp.S */
1587    /*
1588     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1589     * fragment that specifies the *reverse* comparison to perform, e.g.
1590     * for "if-le" you would use "gt".
1591     *
1592     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1593     */
1594    /* if-cmp vA, vB, +CCCC */
1595    mov     r1, rINST, lsr #12          @ r1<- B
1596    ubfx    r0, rINST, #8, #4           @ r0<- A
1597    GET_VREG(r3, r1)                    @ r3<- vB
1598    GET_VREG(r2, r0)                    @ r2<- vA
1599    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1600    cmp     r2, r3                      @ compare (vA, vB)
1601    blt  1f                      @ branch to 1 if comparison failed
1602    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1603    movs    r9, r9, asl #1              @ convert to bytes, check sign
1604    bmi     common_backwardBranch       @ yes, do periodic checks
16051:
1606#if defined(WITH_JIT)
1607    GET_JIT_PROF_TABLE(r0)
1608    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1609    b        common_testUpdateProfile
1610#else
1611    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1612    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1613    GOTO_OPCODE(ip)                     @ jump to next instruction
1614#endif
1615
1616
1617/* ------------------------------ */
1618    .balign 64
1619.L_OP_IF_GT: /* 0x36 */
1620/* File: armv6t2/OP_IF_GT.S */
1621/* File: armv6t2/bincmp.S */
1622    /*
1623     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1624     * fragment that specifies the *reverse* comparison to perform, e.g.
1625     * for "if-le" you would use "gt".
1626     *
1627     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1628     */
1629    /* if-cmp vA, vB, +CCCC */
1630    mov     r1, rINST, lsr #12          @ r1<- B
1631    ubfx    r0, rINST, #8, #4           @ r0<- A
1632    GET_VREG(r3, r1)                    @ r3<- vB
1633    GET_VREG(r2, r0)                    @ r2<- vA
1634    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1635    cmp     r2, r3                      @ compare (vA, vB)
1636    ble  1f                      @ branch to 1 if comparison failed
1637    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1638    movs    r9, r9, asl #1              @ convert to bytes, check sign
1639    bmi     common_backwardBranch       @ yes, do periodic checks
16401:
1641#if defined(WITH_JIT)
1642    GET_JIT_PROF_TABLE(r0)
1643    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1644    b        common_testUpdateProfile
1645#else
1646    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1647    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1648    GOTO_OPCODE(ip)                     @ jump to next instruction
1649#endif
1650
1651
1652/* ------------------------------ */
1653    .balign 64
1654.L_OP_IF_LE: /* 0x37 */
1655/* File: armv6t2/OP_IF_LE.S */
1656/* File: armv6t2/bincmp.S */
1657    /*
1658     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1659     * fragment that specifies the *reverse* comparison to perform, e.g.
1660     * for "if-le" you would use "gt".
1661     *
1662     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1663     */
1664    /* if-cmp vA, vB, +CCCC */
1665    mov     r1, rINST, lsr #12          @ r1<- B
1666    ubfx    r0, rINST, #8, #4           @ r0<- A
1667    GET_VREG(r3, r1)                    @ r3<- vB
1668    GET_VREG(r2, r0)                    @ r2<- vA
1669    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1670    cmp     r2, r3                      @ compare (vA, vB)
1671    bgt  1f                      @ branch to 1 if comparison failed
1672    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1673    movs    r9, r9, asl #1              @ convert to bytes, check sign
1674    bmi     common_backwardBranch       @ yes, do periodic checks
16751:
1676#if defined(WITH_JIT)
1677    GET_JIT_PROF_TABLE(r0)
1678    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1679    b        common_testUpdateProfile
1680#else
1681    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1682    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1683    GOTO_OPCODE(ip)                     @ jump to next instruction
1684#endif
1685
1686
1687/* ------------------------------ */
1688    .balign 64
1689.L_OP_IF_EQZ: /* 0x38 */
1690/* File: armv5te/OP_IF_EQZ.S */
1691/* File: armv5te/zcmp.S */
1692    /*
1693     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1694     * fragment that specifies the *reverse* comparison to perform, e.g.
1695     * for "if-le" you would use "gt".
1696     *
1697     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1698     */
1699    /* if-cmp vAA, +BBBB */
1700    mov     r0, rINST, lsr #8           @ r0<- AA
1701    GET_VREG(r2, r0)                    @ r2<- vAA
1702    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1703    cmp     r2, #0                      @ compare (vA, 0)
1704    bne  1f                      @ branch to 1 if comparison failed
1705    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1706    movs    r9, r9, asl #1              @ convert to bytes, check sign
1707    bmi     common_backwardBranch       @ backward branch, do periodic checks
17081:
1709#if defined(WITH_JIT)
1710    GET_JIT_PROF_TABLE(r0)
1711    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1712    cmp     r0,#0
1713    bne     common_updateProfile
1714    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1715    GOTO_OPCODE(ip)                     @ jump to next instruction
1716#else
1717    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1718    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1719    GOTO_OPCODE(ip)                     @ jump to next instruction
1720#endif
1721
1722
1723/* ------------------------------ */
1724    .balign 64
1725.L_OP_IF_NEZ: /* 0x39 */
1726/* File: armv5te/OP_IF_NEZ.S */
1727/* File: armv5te/zcmp.S */
1728    /*
1729     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1730     * fragment that specifies the *reverse* comparison to perform, e.g.
1731     * for "if-le" you would use "gt".
1732     *
1733     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1734     */
1735    /* if-cmp vAA, +BBBB */
1736    mov     r0, rINST, lsr #8           @ r0<- AA
1737    GET_VREG(r2, r0)                    @ r2<- vAA
1738    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1739    cmp     r2, #0                      @ compare (vA, 0)
1740    beq  1f                      @ branch to 1 if comparison failed
1741    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1742    movs    r9, r9, asl #1              @ convert to bytes, check sign
1743    bmi     common_backwardBranch       @ backward branch, do periodic checks
17441:
1745#if defined(WITH_JIT)
1746    GET_JIT_PROF_TABLE(r0)
1747    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1748    cmp     r0,#0
1749    bne     common_updateProfile
1750    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1751    GOTO_OPCODE(ip)                     @ jump to next instruction
1752#else
1753    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1754    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1755    GOTO_OPCODE(ip)                     @ jump to next instruction
1756#endif
1757
1758
1759/* ------------------------------ */
1760    .balign 64
1761.L_OP_IF_LTZ: /* 0x3a */
1762/* File: armv5te/OP_IF_LTZ.S */
1763/* File: armv5te/zcmp.S */
1764    /*
1765     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1766     * fragment that specifies the *reverse* comparison to perform, e.g.
1767     * for "if-le" you would use "gt".
1768     *
1769     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1770     */
1771    /* if-cmp vAA, +BBBB */
1772    mov     r0, rINST, lsr #8           @ r0<- AA
1773    GET_VREG(r2, r0)                    @ r2<- vAA
1774    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1775    cmp     r2, #0                      @ compare (vA, 0)
1776    bge  1f                      @ branch to 1 if comparison failed
1777    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1778    movs    r9, r9, asl #1              @ convert to bytes, check sign
1779    bmi     common_backwardBranch       @ backward branch, do periodic checks
17801:
1781#if defined(WITH_JIT)
1782    GET_JIT_PROF_TABLE(r0)
1783    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1784    cmp     r0,#0
1785    bne     common_updateProfile
1786    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1787    GOTO_OPCODE(ip)                     @ jump to next instruction
1788#else
1789    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1790    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1791    GOTO_OPCODE(ip)                     @ jump to next instruction
1792#endif
1793
1794
1795/* ------------------------------ */
1796    .balign 64
1797.L_OP_IF_GEZ: /* 0x3b */
1798/* File: armv5te/OP_IF_GEZ.S */
1799/* File: armv5te/zcmp.S */
1800    /*
1801     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1802     * fragment that specifies the *reverse* comparison to perform, e.g.
1803     * for "if-le" you would use "gt".
1804     *
1805     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1806     */
1807    /* if-cmp vAA, +BBBB */
1808    mov     r0, rINST, lsr #8           @ r0<- AA
1809    GET_VREG(r2, r0)                    @ r2<- vAA
1810    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1811    cmp     r2, #0                      @ compare (vA, 0)
1812    blt  1f                      @ branch to 1 if comparison failed
1813    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1814    movs    r9, r9, asl #1              @ convert to bytes, check sign
1815    bmi     common_backwardBranch       @ backward branch, do periodic checks
18161:
1817#if defined(WITH_JIT)
1818    GET_JIT_PROF_TABLE(r0)
1819    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1820    cmp     r0,#0
1821    bne     common_updateProfile
1822    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1823    GOTO_OPCODE(ip)                     @ jump to next instruction
1824#else
1825    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1826    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1827    GOTO_OPCODE(ip)                     @ jump to next instruction
1828#endif
1829
1830
1831/* ------------------------------ */
1832    .balign 64
1833.L_OP_IF_GTZ: /* 0x3c */
1834/* File: armv5te/OP_IF_GTZ.S */
1835/* File: armv5te/zcmp.S */
1836    /*
1837     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1838     * fragment that specifies the *reverse* comparison to perform, e.g.
1839     * for "if-le" you would use "gt".
1840     *
1841     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1842     */
1843    /* if-cmp vAA, +BBBB */
1844    mov     r0, rINST, lsr #8           @ r0<- AA
1845    GET_VREG(r2, r0)                    @ r2<- vAA
1846    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1847    cmp     r2, #0                      @ compare (vA, 0)
1848    ble  1f                      @ branch to 1 if comparison failed
1849    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1850    movs    r9, r9, asl #1              @ convert to bytes, check sign
1851    bmi     common_backwardBranch       @ backward branch, do periodic checks
18521:
1853#if defined(WITH_JIT)
1854    GET_JIT_PROF_TABLE(r0)
1855    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1856    cmp     r0,#0
1857    bne     common_updateProfile
1858    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1859    GOTO_OPCODE(ip)                     @ jump to next instruction
1860#else
1861    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1862    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1863    GOTO_OPCODE(ip)                     @ jump to next instruction
1864#endif
1865
1866
1867/* ------------------------------ */
1868    .balign 64
1869.L_OP_IF_LEZ: /* 0x3d */
1870/* File: armv5te/OP_IF_LEZ.S */
1871/* File: armv5te/zcmp.S */
1872    /*
1873     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1874     * fragment that specifies the *reverse* comparison to perform, e.g.
1875     * for "if-le" you would use "gt".
1876     *
1877     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1878     */
1879    /* if-cmp vAA, +BBBB */
1880    mov     r0, rINST, lsr #8           @ r0<- AA
1881    GET_VREG(r2, r0)                    @ r2<- vAA
1882    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1883    cmp     r2, #0                      @ compare (vA, 0)
1884    bgt  1f                      @ branch to 1 if comparison failed
1885    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1886    movs    r9, r9, asl #1              @ convert to bytes, check sign
1887    bmi     common_backwardBranch       @ backward branch, do periodic checks
18881:
1889#if defined(WITH_JIT)
1890    GET_JIT_PROF_TABLE(r0)
1891    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1892    cmp     r0,#0
1893    bne     common_updateProfile
1894    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1895    GOTO_OPCODE(ip)                     @ jump to next instruction
1896#else
1897    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1898    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1899    GOTO_OPCODE(ip)                     @ jump to next instruction
1900#endif
1901
1902
1903/* ------------------------------ */
1904    .balign 64
1905.L_OP_UNUSED_3E: /* 0x3e */
1906/* File: armv5te/OP_UNUSED_3E.S */
1907/* File: armv5te/unused.S */
1908    bl      common_abort
1909
1910
1911/* ------------------------------ */
1912    .balign 64
1913.L_OP_UNUSED_3F: /* 0x3f */
1914/* File: armv5te/OP_UNUSED_3F.S */
1915/* File: armv5te/unused.S */
1916    bl      common_abort
1917
1918
1919/* ------------------------------ */
1920    .balign 64
1921.L_OP_UNUSED_40: /* 0x40 */
1922/* File: armv5te/OP_UNUSED_40.S */
1923/* File: armv5te/unused.S */
1924    bl      common_abort
1925
1926
1927/* ------------------------------ */
1928    .balign 64
1929.L_OP_UNUSED_41: /* 0x41 */
1930/* File: armv5te/OP_UNUSED_41.S */
1931/* File: armv5te/unused.S */
1932    bl      common_abort
1933
1934
1935/* ------------------------------ */
1936    .balign 64
1937.L_OP_UNUSED_42: /* 0x42 */
1938/* File: armv5te/OP_UNUSED_42.S */
1939/* File: armv5te/unused.S */
1940    bl      common_abort
1941
1942
1943/* ------------------------------ */
1944    .balign 64
1945.L_OP_UNUSED_43: /* 0x43 */
1946/* File: armv5te/OP_UNUSED_43.S */
1947/* File: armv5te/unused.S */
1948    bl      common_abort
1949
1950
1951/* ------------------------------ */
1952    .balign 64
1953.L_OP_AGET: /* 0x44 */
1954/* File: armv5te/OP_AGET.S */
1955    /*
1956     * Array get, 32 bits or less.  vAA <- vBB[vCC].
1957     *
1958     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
1959     * instructions.  We use a pair of FETCH_Bs instead.
1960     *
1961     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
1962     */
1963    /* op vAA, vBB, vCC */
1964    FETCH_B(r2, 1, 0)                   @ r2<- BB
1965    mov     r9, rINST, lsr #8           @ r9<- AA
1966    FETCH_B(r3, 1, 1)                   @ r3<- CC
1967    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1968    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1969    cmp     r0, #0                      @ null array object?
1970    beq     common_errNullObject        @ yes, bail
1971    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1972    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
1973    cmp     r1, r3                      @ compare unsigned index, length
1974    bcs     common_errArrayIndex        @ index >= length, bail
1975    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1976    ldr   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
1977    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1978    SET_VREG(r2, r9)                    @ vAA<- r2
1979    GOTO_OPCODE(ip)                     @ jump to next instruction
1980
1981/* ------------------------------ */
1982    .balign 64
1983.L_OP_AGET_WIDE: /* 0x45 */
1984/* File: armv5te/OP_AGET_WIDE.S */
1985    /*
1986     * Array get, 64 bits.  vAA <- vBB[vCC].
1987     *
1988     * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD.
1989     */
1990    /* aget-wide vAA, vBB, vCC */
1991    FETCH(r0, 1)                        @ r0<- CCBB
1992    mov     r9, rINST, lsr #8           @ r9<- AA
1993    and     r2, r0, #255                @ r2<- BB
1994    mov     r3, r0, lsr #8              @ r3<- CC
1995    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1996    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1997    cmp     r0, #0                      @ null array object?
1998    beq     common_errNullObject        @ yes, bail
1999    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2000    add     r0, r0, r1, lsl #3          @ r0<- arrayObj + index*width
2001    cmp     r1, r3                      @ compare unsigned index, length
2002    bcc     .LOP_AGET_WIDE_finish          @ okay, continue below
2003    b       common_errArrayIndex        @ index >= length, bail
2004    @ May want to swap the order of these two branches depending on how the
2005    @ branch prediction (if any) handles conditional forward branches vs.
2006    @ unconditional forward branches.
2007
2008/* ------------------------------ */
2009    .balign 64
2010.L_OP_AGET_OBJECT: /* 0x46 */
2011/* File: armv5te/OP_AGET_OBJECT.S */
2012/* File: armv5te/OP_AGET.S */
2013    /*
2014     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2015     *
2016     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2017     * instructions.  We use a pair of FETCH_Bs instead.
2018     *
2019     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2020     */
2021    /* op vAA, vBB, vCC */
2022    FETCH_B(r2, 1, 0)                   @ r2<- BB
2023    mov     r9, rINST, lsr #8           @ r9<- AA
2024    FETCH_B(r3, 1, 1)                   @ r3<- CC
2025    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2026    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2027    cmp     r0, #0                      @ null array object?
2028    beq     common_errNullObject        @ yes, bail
2029    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2030    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
2031    cmp     r1, r3                      @ compare unsigned index, length
2032    bcs     common_errArrayIndex        @ index >= length, bail
2033    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2034    ldr   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2035    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2036    SET_VREG(r2, r9)                    @ vAA<- r2
2037    GOTO_OPCODE(ip)                     @ jump to next instruction
2038
2039
2040/* ------------------------------ */
2041    .balign 64
2042.L_OP_AGET_BOOLEAN: /* 0x47 */
2043/* File: armv5te/OP_AGET_BOOLEAN.S */
2044/* File: armv5te/OP_AGET.S */
2045    /*
2046     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2047     *
2048     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2049     * instructions.  We use a pair of FETCH_Bs instead.
2050     *
2051     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2052     */
2053    /* op vAA, vBB, vCC */
2054    FETCH_B(r2, 1, 0)                   @ r2<- BB
2055    mov     r9, rINST, lsr #8           @ r9<- AA
2056    FETCH_B(r3, 1, 1)                   @ r3<- CC
2057    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2058    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2059    cmp     r0, #0                      @ null array object?
2060    beq     common_errNullObject        @ yes, bail
2061    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2062    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2063    cmp     r1, r3                      @ compare unsigned index, length
2064    bcs     common_errArrayIndex        @ index >= length, bail
2065    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2066    ldrb   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2067    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2068    SET_VREG(r2, r9)                    @ vAA<- r2
2069    GOTO_OPCODE(ip)                     @ jump to next instruction
2070
2071
2072/* ------------------------------ */
2073    .balign 64
2074.L_OP_AGET_BYTE: /* 0x48 */
2075/* File: armv5te/OP_AGET_BYTE.S */
2076/* File: armv5te/OP_AGET.S */
2077    /*
2078     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2079     *
2080     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2081     * instructions.  We use a pair of FETCH_Bs instead.
2082     *
2083     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2084     */
2085    /* op vAA, vBB, vCC */
2086    FETCH_B(r2, 1, 0)                   @ r2<- BB
2087    mov     r9, rINST, lsr #8           @ r9<- AA
2088    FETCH_B(r3, 1, 1)                   @ r3<- CC
2089    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2090    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2091    cmp     r0, #0                      @ null array object?
2092    beq     common_errNullObject        @ yes, bail
2093    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2094    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2095    cmp     r1, r3                      @ compare unsigned index, length
2096    bcs     common_errArrayIndex        @ index >= length, bail
2097    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2098    ldrsb   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2099    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2100    SET_VREG(r2, r9)                    @ vAA<- r2
2101    GOTO_OPCODE(ip)                     @ jump to next instruction
2102
2103
2104/* ------------------------------ */
2105    .balign 64
2106.L_OP_AGET_CHAR: /* 0x49 */
2107/* File: armv5te/OP_AGET_CHAR.S */
2108/* File: armv5te/OP_AGET.S */
2109    /*
2110     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2111     *
2112     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2113     * instructions.  We use a pair of FETCH_Bs instead.
2114     *
2115     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2116     */
2117    /* op vAA, vBB, vCC */
2118    FETCH_B(r2, 1, 0)                   @ r2<- BB
2119    mov     r9, rINST, lsr #8           @ r9<- AA
2120    FETCH_B(r3, 1, 1)                   @ r3<- CC
2121    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2122    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2123    cmp     r0, #0                      @ null array object?
2124    beq     common_errNullObject        @ yes, bail
2125    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2126    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2127    cmp     r1, r3                      @ compare unsigned index, length
2128    bcs     common_errArrayIndex        @ index >= length, bail
2129    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2130    ldrh   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2131    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2132    SET_VREG(r2, r9)                    @ vAA<- r2
2133    GOTO_OPCODE(ip)                     @ jump to next instruction
2134
2135
2136/* ------------------------------ */
2137    .balign 64
2138.L_OP_AGET_SHORT: /* 0x4a */
2139/* File: armv5te/OP_AGET_SHORT.S */
2140/* File: armv5te/OP_AGET.S */
2141    /*
2142     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2143     *
2144     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2145     * instructions.  We use a pair of FETCH_Bs instead.
2146     *
2147     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2148     */
2149    /* op vAA, vBB, vCC */
2150    FETCH_B(r2, 1, 0)                   @ r2<- BB
2151    mov     r9, rINST, lsr #8           @ r9<- AA
2152    FETCH_B(r3, 1, 1)                   @ r3<- CC
2153    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2154    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2155    cmp     r0, #0                      @ null array object?
2156    beq     common_errNullObject        @ yes, bail
2157    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2158    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2159    cmp     r1, r3                      @ compare unsigned index, length
2160    bcs     common_errArrayIndex        @ index >= length, bail
2161    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2162    ldrsh   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2163    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2164    SET_VREG(r2, r9)                    @ vAA<- r2
2165    GOTO_OPCODE(ip)                     @ jump to next instruction
2166
2167
2168/* ------------------------------ */
2169    .balign 64
2170.L_OP_APUT: /* 0x4b */
2171/* File: armv5te/OP_APUT.S */
2172    /*
2173     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2174     *
2175     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2176     * instructions.  We use a pair of FETCH_Bs instead.
2177     *
2178     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2179     */
2180    /* op vAA, vBB, vCC */
2181    FETCH_B(r2, 1, 0)                   @ r2<- BB
2182    mov     r9, rINST, lsr #8           @ r9<- AA
2183    FETCH_B(r3, 1, 1)                   @ r3<- CC
2184    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2185    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2186    cmp     r0, #0                      @ null array object?
2187    beq     common_errNullObject        @ yes, bail
2188    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2189    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
2190    cmp     r1, r3                      @ compare unsigned index, length
2191    bcs     common_errArrayIndex        @ index >= length, bail
2192    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2193    GET_VREG(r2, r9)                    @ r2<- vAA
2194    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2195    str  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2196    GOTO_OPCODE(ip)                     @ jump to next instruction
2197
2198/* ------------------------------ */
2199    .balign 64
2200.L_OP_APUT_WIDE: /* 0x4c */
2201/* File: armv5te/OP_APUT_WIDE.S */
2202    /*
2203     * Array put, 64 bits.  vBB[vCC] <- vAA.
2204     *
2205     * Arrays of long/double are 64-bit aligned, so it's okay to use STRD.
2206     */
2207    /* aput-wide vAA, vBB, vCC */
2208    FETCH(r0, 1)                        @ r0<- CCBB
2209    mov     r9, rINST, lsr #8           @ r9<- AA
2210    and     r2, r0, #255                @ r2<- BB
2211    mov     r3, r0, lsr #8              @ r3<- CC
2212    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2213    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2214    cmp     r0, #0                      @ null array object?
2215    beq     common_errNullObject        @ yes, bail
2216    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2217    add     r0, r0, r1, lsl #3          @ r0<- arrayObj + index*width
2218    cmp     r1, r3                      @ compare unsigned index, length
2219    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2220    bcc     .LOP_APUT_WIDE_finish          @ okay, continue below
2221    b       common_errArrayIndex        @ index >= length, bail
2222    @ May want to swap the order of these two branches depending on how the
2223    @ branch prediction (if any) handles conditional forward branches vs.
2224    @ unconditional forward branches.
2225
2226/* ------------------------------ */
2227    .balign 64
2228.L_OP_APUT_OBJECT: /* 0x4d */
2229/* File: armv5te/OP_APUT_OBJECT.S */
2230    /*
2231     * Store an object into an array.  vBB[vCC] <- vAA.
2232     */
2233    /* op vAA, vBB, vCC */
2234    FETCH(r0, 1)                        @ r0<- CCBB
2235    mov     r9, rINST, lsr #8           @ r9<- AA
2236    and     r2, r0, #255                @ r2<- BB
2237    mov     r3, r0, lsr #8              @ r3<- CC
2238    GET_VREG(rINST, r2)                 @ rINST<- vBB (array object)
2239    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2240    cmp     rINST, #0                   @ null array object?
2241    GET_VREG(r9, r9)                    @ r9<- vAA
2242    beq     common_errNullObject        @ yes, bail
2243    ldr     r3, [rINST, #offArrayObject_length]   @ r3<- arrayObj->length
2244    add     r10, rINST, r1, lsl #2      @ r10<- arrayObj + index*width
2245    cmp     r1, r3                      @ compare unsigned index, length
2246    bcc     .LOP_APUT_OBJECT_finish          @ we're okay, continue on
2247    b       common_errArrayIndex        @ index >= length, bail
2248
2249
2250/* ------------------------------ */
2251    .balign 64
2252.L_OP_APUT_BOOLEAN: /* 0x4e */
2253/* File: armv5te/OP_APUT_BOOLEAN.S */
2254/* File: armv5te/OP_APUT.S */
2255    /*
2256     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2257     *
2258     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2259     * instructions.  We use a pair of FETCH_Bs instead.
2260     *
2261     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2262     */
2263    /* op vAA, vBB, vCC */
2264    FETCH_B(r2, 1, 0)                   @ r2<- BB
2265    mov     r9, rINST, lsr #8           @ r9<- AA
2266    FETCH_B(r3, 1, 1)                   @ r3<- CC
2267    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2268    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2269    cmp     r0, #0                      @ null array object?
2270    beq     common_errNullObject        @ yes, bail
2271    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2272    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2273    cmp     r1, r3                      @ compare unsigned index, length
2274    bcs     common_errArrayIndex        @ index >= length, bail
2275    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2276    GET_VREG(r2, r9)                    @ r2<- vAA
2277    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2278    strb  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2279    GOTO_OPCODE(ip)                     @ jump to next instruction
2280
2281
2282/* ------------------------------ */
2283    .balign 64
2284.L_OP_APUT_BYTE: /* 0x4f */
2285/* File: armv5te/OP_APUT_BYTE.S */
2286/* File: armv5te/OP_APUT.S */
2287    /*
2288     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2289     *
2290     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2291     * instructions.  We use a pair of FETCH_Bs instead.
2292     *
2293     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2294     */
2295    /* op vAA, vBB, vCC */
2296    FETCH_B(r2, 1, 0)                   @ r2<- BB
2297    mov     r9, rINST, lsr #8           @ r9<- AA
2298    FETCH_B(r3, 1, 1)                   @ r3<- CC
2299    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2300    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2301    cmp     r0, #0                      @ null array object?
2302    beq     common_errNullObject        @ yes, bail
2303    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2304    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2305    cmp     r1, r3                      @ compare unsigned index, length
2306    bcs     common_errArrayIndex        @ index >= length, bail
2307    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2308    GET_VREG(r2, r9)                    @ r2<- vAA
2309    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2310    strb  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2311    GOTO_OPCODE(ip)                     @ jump to next instruction
2312
2313
2314/* ------------------------------ */
2315    .balign 64
2316.L_OP_APUT_CHAR: /* 0x50 */
2317/* File: armv5te/OP_APUT_CHAR.S */
2318/* File: armv5te/OP_APUT.S */
2319    /*
2320     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2321     *
2322     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2323     * instructions.  We use a pair of FETCH_Bs instead.
2324     *
2325     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2326     */
2327    /* op vAA, vBB, vCC */
2328    FETCH_B(r2, 1, 0)                   @ r2<- BB
2329    mov     r9, rINST, lsr #8           @ r9<- AA
2330    FETCH_B(r3, 1, 1)                   @ r3<- CC
2331    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2332    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2333    cmp     r0, #0                      @ null array object?
2334    beq     common_errNullObject        @ yes, bail
2335    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2336    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2337    cmp     r1, r3                      @ compare unsigned index, length
2338    bcs     common_errArrayIndex        @ index >= length, bail
2339    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2340    GET_VREG(r2, r9)                    @ r2<- vAA
2341    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2342    strh  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2343    GOTO_OPCODE(ip)                     @ jump to next instruction
2344
2345
2346/* ------------------------------ */
2347    .balign 64
2348.L_OP_APUT_SHORT: /* 0x51 */
2349/* File: armv5te/OP_APUT_SHORT.S */
2350/* File: armv5te/OP_APUT.S */
2351    /*
2352     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2353     *
2354     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2355     * instructions.  We use a pair of FETCH_Bs instead.
2356     *
2357     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2358     */
2359    /* op vAA, vBB, vCC */
2360    FETCH_B(r2, 1, 0)                   @ r2<- BB
2361    mov     r9, rINST, lsr #8           @ r9<- AA
2362    FETCH_B(r3, 1, 1)                   @ r3<- CC
2363    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2364    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2365    cmp     r0, #0                      @ null array object?
2366    beq     common_errNullObject        @ yes, bail
2367    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2368    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2369    cmp     r1, r3                      @ compare unsigned index, length
2370    bcs     common_errArrayIndex        @ index >= length, bail
2371    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2372    GET_VREG(r2, r9)                    @ r2<- vAA
2373    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2374    strh  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2375    GOTO_OPCODE(ip)                     @ jump to next instruction
2376
2377
2378/* ------------------------------ */
2379    .balign 64
2380.L_OP_IGET: /* 0x52 */
2381/* File: armv6t2/OP_IGET.S */
2382    /*
2383     * General 32-bit instance field get.
2384     *
2385     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2386     */
2387    /* op vA, vB, field@CCCC */
2388    mov     r0, rINST, lsr #12          @ r0<- B
2389    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2390    FETCH(r1, 1)                        @ r1<- field ref CCCC
2391    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2392    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2393    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2394    cmp     r0, #0                      @ is resolved entry null?
2395    bne     .LOP_IGET_finish          @ no, already resolved
23968:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2397    EXPORT_PC()                         @ resolve() could throw
2398    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2399    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2400    cmp     r0, #0
2401    bne     .LOP_IGET_finish
2402    b       common_exceptionThrown
2403
2404/* ------------------------------ */
2405    .balign 64
2406.L_OP_IGET_WIDE: /* 0x53 */
2407/* File: armv6t2/OP_IGET_WIDE.S */
2408    /*
2409     * Wide 32-bit instance field get.
2410     */
2411    /* iget-wide vA, vB, field@CCCC */
2412    mov     r0, rINST, lsr #12          @ r0<- B
2413    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2414    FETCH(r1, 1)                        @ r1<- field ref CCCC
2415    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
2416    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2417    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2418    cmp     r0, #0                      @ is resolved entry null?
2419    bne     .LOP_IGET_WIDE_finish          @ no, already resolved
24208:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
2421    EXPORT_PC()                         @ resolve() could throw
2422    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2423    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2424    cmp     r0, #0
2425    bne     .LOP_IGET_WIDE_finish
2426    b       common_exceptionThrown
2427
2428/* ------------------------------ */
2429    .balign 64
2430.L_OP_IGET_OBJECT: /* 0x54 */
2431/* File: armv5te/OP_IGET_OBJECT.S */
2432/* File: armv5te/OP_IGET.S */
2433    /*
2434     * General 32-bit instance field get.
2435     *
2436     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2437     */
2438    /* op vA, vB, field@CCCC */
2439    mov     r0, rINST, lsr #12          @ r0<- B
2440    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2441    FETCH(r1, 1)                        @ r1<- field ref CCCC
2442    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2443    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2444    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2445    cmp     r0, #0                      @ is resolved entry null?
2446    bne     .LOP_IGET_OBJECT_finish          @ no, already resolved
24478:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2448    EXPORT_PC()                         @ resolve() could throw
2449    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2450    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2451    cmp     r0, #0
2452    bne     .LOP_IGET_OBJECT_finish
2453    b       common_exceptionThrown
2454
2455
2456/* ------------------------------ */
2457    .balign 64
2458.L_OP_IGET_BOOLEAN: /* 0x55 */
2459/* File: armv5te/OP_IGET_BOOLEAN.S */
2460@include "armv5te/OP_IGET.S" { "load":"ldrb", "sqnum":"1" }
2461/* File: armv5te/OP_IGET.S */
2462    /*
2463     * General 32-bit instance field get.
2464     *
2465     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2466     */
2467    /* op vA, vB, field@CCCC */
2468    mov     r0, rINST, lsr #12          @ r0<- B
2469    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2470    FETCH(r1, 1)                        @ r1<- field ref CCCC
2471    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2472    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2473    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2474    cmp     r0, #0                      @ is resolved entry null?
2475    bne     .LOP_IGET_BOOLEAN_finish          @ no, already resolved
24768:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2477    EXPORT_PC()                         @ resolve() could throw
2478    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2479    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2480    cmp     r0, #0
2481    bne     .LOP_IGET_BOOLEAN_finish
2482    b       common_exceptionThrown
2483
2484
2485/* ------------------------------ */
2486    .balign 64
2487.L_OP_IGET_BYTE: /* 0x56 */
2488/* File: armv5te/OP_IGET_BYTE.S */
2489@include "armv5te/OP_IGET.S" { "load":"ldrsb", "sqnum":"2" }
2490/* File: armv5te/OP_IGET.S */
2491    /*
2492     * General 32-bit instance field get.
2493     *
2494     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2495     */
2496    /* op vA, vB, field@CCCC */
2497    mov     r0, rINST, lsr #12          @ r0<- B
2498    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2499    FETCH(r1, 1)                        @ r1<- field ref CCCC
2500    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2501    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2502    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2503    cmp     r0, #0                      @ is resolved entry null?
2504    bne     .LOP_IGET_BYTE_finish          @ no, already resolved
25058:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2506    EXPORT_PC()                         @ resolve() could throw
2507    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2508    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2509    cmp     r0, #0
2510    bne     .LOP_IGET_BYTE_finish
2511    b       common_exceptionThrown
2512
2513
2514/* ------------------------------ */
2515    .balign 64
2516.L_OP_IGET_CHAR: /* 0x57 */
2517/* File: armv5te/OP_IGET_CHAR.S */
2518@include "armv5te/OP_IGET.S" { "load":"ldrh", "sqnum":"3" }
2519/* File: armv5te/OP_IGET.S */
2520    /*
2521     * General 32-bit instance field get.
2522     *
2523     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2524     */
2525    /* op vA, vB, field@CCCC */
2526    mov     r0, rINST, lsr #12          @ r0<- B
2527    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2528    FETCH(r1, 1)                        @ r1<- field ref CCCC
2529    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2530    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2531    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2532    cmp     r0, #0                      @ is resolved entry null?
2533    bne     .LOP_IGET_CHAR_finish          @ no, already resolved
25348:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2535    EXPORT_PC()                         @ resolve() could throw
2536    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2537    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2538    cmp     r0, #0
2539    bne     .LOP_IGET_CHAR_finish
2540    b       common_exceptionThrown
2541
2542
2543/* ------------------------------ */
2544    .balign 64
2545.L_OP_IGET_SHORT: /* 0x58 */
2546/* File: armv5te/OP_IGET_SHORT.S */
2547@include "armv5te/OP_IGET.S" { "load":"ldrsh", "sqnum":"4" }
2548/* File: armv5te/OP_IGET.S */
2549    /*
2550     * General 32-bit instance field get.
2551     *
2552     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2553     */
2554    /* op vA, vB, field@CCCC */
2555    mov     r0, rINST, lsr #12          @ r0<- B
2556    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2557    FETCH(r1, 1)                        @ r1<- field ref CCCC
2558    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2559    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2560    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2561    cmp     r0, #0                      @ is resolved entry null?
2562    bne     .LOP_IGET_SHORT_finish          @ no, already resolved
25638:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2564    EXPORT_PC()                         @ resolve() could throw
2565    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2566    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2567    cmp     r0, #0
2568    bne     .LOP_IGET_SHORT_finish
2569    b       common_exceptionThrown
2570
2571
2572/* ------------------------------ */
2573    .balign 64
2574.L_OP_IPUT: /* 0x59 */
2575/* File: armv6t2/OP_IPUT.S */
2576    /*
2577     * General 32-bit instance field put.
2578     *
2579     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
2580     */
2581    /* op vA, vB, field@CCCC */
2582    mov     r0, rINST, lsr #12          @ r0<- B
2583    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2584    FETCH(r1, 1)                        @ r1<- field ref CCCC
2585    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2586    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2587    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2588    cmp     r0, #0                      @ is resolved entry null?
2589    bne     .LOP_IPUT_finish          @ no, already resolved
25908:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2591    EXPORT_PC()                         @ resolve() could throw
2592    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2593    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2594    cmp     r0, #0                      @ success?
2595    bne     .LOP_IPUT_finish          @ yes, finish up
2596    b       common_exceptionThrown
2597
2598/* ------------------------------ */
2599    .balign 64
2600.L_OP_IPUT_WIDE: /* 0x5a */
2601/* File: armv6t2/OP_IPUT_WIDE.S */
2602    /* iput-wide vA, vB, field@CCCC */
2603    mov     r0, rINST, lsr #12          @ r0<- B
2604    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2605    FETCH(r1, 1)                        @ r1<- field ref CCCC
2606    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
2607    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2608    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2609    cmp     r0, #0                      @ is resolved entry null?
2610    bne     .LOP_IPUT_WIDE_finish          @ no, already resolved
26118:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
2612    EXPORT_PC()                         @ resolve() could throw
2613    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2614    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2615    cmp     r0, #0                      @ success?
2616    bne     .LOP_IPUT_WIDE_finish          @ yes, finish up
2617    b       common_exceptionThrown
2618
2619/* ------------------------------ */
2620    .balign 64
2621.L_OP_IPUT_OBJECT: /* 0x5b */
2622/* File: armv5te/OP_IPUT_OBJECT.S */
2623    /*
2624     * 32-bit instance field put.
2625     *
2626     * for: iput-object, iput-object-volatile
2627     */
2628    /* op vA, vB, field@CCCC */
2629    mov     r0, rINST, lsr #12          @ r0<- B
2630    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2631    FETCH(r1, 1)                        @ r1<- field ref CCCC
2632    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2633    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2634    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2635    cmp     r0, #0                      @ is resolved entry null?
2636    bne     .LOP_IPUT_OBJECT_finish          @ no, already resolved
26378:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2638    EXPORT_PC()                         @ resolve() could throw
2639    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2640    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2641    cmp     r0, #0                      @ success?
2642    bne     .LOP_IPUT_OBJECT_finish          @ yes, finish up
2643    b       common_exceptionThrown
2644
2645/* ------------------------------ */
2646    .balign 64
2647.L_OP_IPUT_BOOLEAN: /* 0x5c */
2648/* File: armv5te/OP_IPUT_BOOLEAN.S */
2649@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"1" }
2650/* File: armv5te/OP_IPUT.S */
2651    /*
2652     * General 32-bit instance field put.
2653     *
2654     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2655     */
2656    /* op vA, vB, field@CCCC */
2657    mov     r0, rINST, lsr #12          @ r0<- B
2658    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2659    FETCH(r1, 1)                        @ r1<- field ref CCCC
2660    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2661    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2662    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2663    cmp     r0, #0                      @ is resolved entry null?
2664    bne     .LOP_IPUT_BOOLEAN_finish          @ no, already resolved
26658:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2666    EXPORT_PC()                         @ resolve() could throw
2667    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2668    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2669    cmp     r0, #0                      @ success?
2670    bne     .LOP_IPUT_BOOLEAN_finish          @ yes, finish up
2671    b       common_exceptionThrown
2672
2673
2674/* ------------------------------ */
2675    .balign 64
2676.L_OP_IPUT_BYTE: /* 0x5d */
2677/* File: armv5te/OP_IPUT_BYTE.S */
2678@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"2" }
2679/* File: armv5te/OP_IPUT.S */
2680    /*
2681     * General 32-bit instance field put.
2682     *
2683     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2684     */
2685    /* op vA, vB, field@CCCC */
2686    mov     r0, rINST, lsr #12          @ r0<- B
2687    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2688    FETCH(r1, 1)                        @ r1<- field ref CCCC
2689    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2690    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2691    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2692    cmp     r0, #0                      @ is resolved entry null?
2693    bne     .LOP_IPUT_BYTE_finish          @ no, already resolved
26948:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2695    EXPORT_PC()                         @ resolve() could throw
2696    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2697    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2698    cmp     r0, #0                      @ success?
2699    bne     .LOP_IPUT_BYTE_finish          @ yes, finish up
2700    b       common_exceptionThrown
2701
2702
2703/* ------------------------------ */
2704    .balign 64
2705.L_OP_IPUT_CHAR: /* 0x5e */
2706/* File: armv5te/OP_IPUT_CHAR.S */
2707@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"3" }
2708/* File: armv5te/OP_IPUT.S */
2709    /*
2710     * General 32-bit instance field put.
2711     *
2712     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2713     */
2714    /* op vA, vB, field@CCCC */
2715    mov     r0, rINST, lsr #12          @ r0<- B
2716    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2717    FETCH(r1, 1)                        @ r1<- field ref CCCC
2718    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2719    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2720    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2721    cmp     r0, #0                      @ is resolved entry null?
2722    bne     .LOP_IPUT_CHAR_finish          @ no, already resolved
27238:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2724    EXPORT_PC()                         @ resolve() could throw
2725    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2726    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2727    cmp     r0, #0                      @ success?
2728    bne     .LOP_IPUT_CHAR_finish          @ yes, finish up
2729    b       common_exceptionThrown
2730
2731
2732/* ------------------------------ */
2733    .balign 64
2734.L_OP_IPUT_SHORT: /* 0x5f */
2735/* File: armv5te/OP_IPUT_SHORT.S */
2736@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"4" }
2737/* File: armv5te/OP_IPUT.S */
2738    /*
2739     * General 32-bit instance field put.
2740     *
2741     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2742     */
2743    /* op vA, vB, field@CCCC */
2744    mov     r0, rINST, lsr #12          @ r0<- B
2745    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2746    FETCH(r1, 1)                        @ r1<- field ref CCCC
2747    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2748    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2749    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2750    cmp     r0, #0                      @ is resolved entry null?
2751    bne     .LOP_IPUT_SHORT_finish          @ no, already resolved
27528:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2753    EXPORT_PC()                         @ resolve() could throw
2754    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2755    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2756    cmp     r0, #0                      @ success?
2757    bne     .LOP_IPUT_SHORT_finish          @ yes, finish up
2758    b       common_exceptionThrown
2759
2760
2761/* ------------------------------ */
2762    .balign 64
2763.L_OP_SGET: /* 0x60 */
2764/* File: armv5te/OP_SGET.S */
2765    /*
2766     * General 32-bit SGET handler.
2767     *
2768     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2769     */
2770    /* op vAA, field@BBBB */
2771    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2772    FETCH(r1, 1)                        @ r1<- field ref BBBB
2773    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2774    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2775    cmp     r0, #0                      @ is resolved entry null?
2776    beq     .LOP_SGET_resolve         @ yes, do resolve
2777.LOP_SGET_finish: @ field ptr in r0
2778    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2779    @ no-op                             @ acquiring load
2780    mov     r2, rINST, lsr #8           @ r2<- AA
2781    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2782    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2783    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2784    GOTO_OPCODE(ip)                     @ jump to next instruction
2785
2786/* ------------------------------ */
2787    .balign 64
2788.L_OP_SGET_WIDE: /* 0x61 */
2789/* File: armv5te/OP_SGET_WIDE.S */
2790    /*
2791     * 64-bit SGET handler.
2792     */
2793    /* sget-wide vAA, field@BBBB */
2794    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2795    FETCH(r1, 1)                        @ r1<- field ref BBBB
2796    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2797    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2798    cmp     r0, #0                      @ is resolved entry null?
2799    beq     .LOP_SGET_WIDE_resolve         @ yes, do resolve
2800.LOP_SGET_WIDE_finish:
2801    mov     r9, rINST, lsr #8           @ r9<- AA
2802    .if 0
2803    add     r0, r0, #offStaticField_value @ r0<- pointer to data
2804    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
2805    .else
2806    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
2807    .endif
2808    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2809    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2810    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
2811    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2812    GOTO_OPCODE(ip)                     @ jump to next instruction
2813
2814/* ------------------------------ */
2815    .balign 64
2816.L_OP_SGET_OBJECT: /* 0x62 */
2817/* File: armv5te/OP_SGET_OBJECT.S */
2818/* File: armv5te/OP_SGET.S */
2819    /*
2820     * General 32-bit SGET handler.
2821     *
2822     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2823     */
2824    /* op vAA, field@BBBB */
2825    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2826    FETCH(r1, 1)                        @ r1<- field ref BBBB
2827    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2828    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2829    cmp     r0, #0                      @ is resolved entry null?
2830    beq     .LOP_SGET_OBJECT_resolve         @ yes, do resolve
2831.LOP_SGET_OBJECT_finish: @ field ptr in r0
2832    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2833    @ no-op                             @ acquiring load
2834    mov     r2, rINST, lsr #8           @ r2<- AA
2835    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2836    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2837    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2838    GOTO_OPCODE(ip)                     @ jump to next instruction
2839
2840
2841/* ------------------------------ */
2842    .balign 64
2843.L_OP_SGET_BOOLEAN: /* 0x63 */
2844/* File: armv5te/OP_SGET_BOOLEAN.S */
2845/* File: armv5te/OP_SGET.S */
2846    /*
2847     * General 32-bit SGET handler.
2848     *
2849     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2850     */
2851    /* op vAA, field@BBBB */
2852    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2853    FETCH(r1, 1)                        @ r1<- field ref BBBB
2854    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2855    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2856    cmp     r0, #0                      @ is resolved entry null?
2857    beq     .LOP_SGET_BOOLEAN_resolve         @ yes, do resolve
2858.LOP_SGET_BOOLEAN_finish: @ field ptr in r0
2859    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2860    @ no-op                             @ acquiring load
2861    mov     r2, rINST, lsr #8           @ r2<- AA
2862    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2863    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2864    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2865    GOTO_OPCODE(ip)                     @ jump to next instruction
2866
2867
2868/* ------------------------------ */
2869    .balign 64
2870.L_OP_SGET_BYTE: /* 0x64 */
2871/* File: armv5te/OP_SGET_BYTE.S */
2872/* File: armv5te/OP_SGET.S */
2873    /*
2874     * General 32-bit SGET handler.
2875     *
2876     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2877     */
2878    /* op vAA, field@BBBB */
2879    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2880    FETCH(r1, 1)                        @ r1<- field ref BBBB
2881    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2882    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2883    cmp     r0, #0                      @ is resolved entry null?
2884    beq     .LOP_SGET_BYTE_resolve         @ yes, do resolve
2885.LOP_SGET_BYTE_finish: @ field ptr in r0
2886    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2887    @ no-op                             @ acquiring load
2888    mov     r2, rINST, lsr #8           @ r2<- AA
2889    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2890    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2891    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2892    GOTO_OPCODE(ip)                     @ jump to next instruction
2893
2894
2895/* ------------------------------ */
2896    .balign 64
2897.L_OP_SGET_CHAR: /* 0x65 */
2898/* File: armv5te/OP_SGET_CHAR.S */
2899/* File: armv5te/OP_SGET.S */
2900    /*
2901     * General 32-bit SGET handler.
2902     *
2903     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2904     */
2905    /* op vAA, field@BBBB */
2906    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2907    FETCH(r1, 1)                        @ r1<- field ref BBBB
2908    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2909    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2910    cmp     r0, #0                      @ is resolved entry null?
2911    beq     .LOP_SGET_CHAR_resolve         @ yes, do resolve
2912.LOP_SGET_CHAR_finish: @ field ptr in r0
2913    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2914    @ no-op                             @ acquiring load
2915    mov     r2, rINST, lsr #8           @ r2<- AA
2916    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2917    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2918    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2919    GOTO_OPCODE(ip)                     @ jump to next instruction
2920
2921
2922/* ------------------------------ */
2923    .balign 64
2924.L_OP_SGET_SHORT: /* 0x66 */
2925/* File: armv5te/OP_SGET_SHORT.S */
2926/* File: armv5te/OP_SGET.S */
2927    /*
2928     * General 32-bit SGET handler.
2929     *
2930     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2931     */
2932    /* op vAA, field@BBBB */
2933    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2934    FETCH(r1, 1)                        @ r1<- field ref BBBB
2935    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2936    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2937    cmp     r0, #0                      @ is resolved entry null?
2938    beq     .LOP_SGET_SHORT_resolve         @ yes, do resolve
2939.LOP_SGET_SHORT_finish: @ field ptr in r0
2940    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2941    @ no-op                             @ acquiring load
2942    mov     r2, rINST, lsr #8           @ r2<- AA
2943    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2944    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2945    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2946    GOTO_OPCODE(ip)                     @ jump to next instruction
2947
2948
2949/* ------------------------------ */
2950    .balign 64
2951.L_OP_SPUT: /* 0x67 */
2952/* File: armv5te/OP_SPUT.S */
2953    /*
2954     * General 32-bit SPUT handler.
2955     *
2956     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2957     */
2958    /* op vAA, field@BBBB */
2959    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2960    FETCH(r1, 1)                        @ r1<- field ref BBBB
2961    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2962    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2963    cmp     r0, #0                      @ is resolved entry null?
2964    beq     .LOP_SPUT_resolve         @ yes, do resolve
2965.LOP_SPUT_finish:   @ field ptr in r0
2966    mov     r2, rINST, lsr #8           @ r2<- AA
2967    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2968    GET_VREG(r1, r2)                    @ r1<- fp[AA]
2969    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2970    @ no-op                             @ releasing store
2971    str     r1, [r0, #offStaticField_value] @ field<- vAA
2972    GOTO_OPCODE(ip)                     @ jump to next instruction
2973
2974/* ------------------------------ */
2975    .balign 64
2976.L_OP_SPUT_WIDE: /* 0x68 */
2977/* File: armv5te/OP_SPUT_WIDE.S */
2978    /*
2979     * 64-bit SPUT handler.
2980     */
2981    /* sput-wide vAA, field@BBBB */
2982    ldr     r0, [rGLUE, #offGlue_methodClassDex]  @ r0<- DvmDex
2983    FETCH(r1, 1)                        @ r1<- field ref BBBB
2984    ldr     r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields
2985    mov     r9, rINST, lsr #8           @ r9<- AA
2986    ldr     r2, [r0, r1, lsl #2]        @ r2<- resolved StaticField ptr
2987    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2988    cmp     r2, #0                      @ is resolved entry null?
2989    beq     .LOP_SPUT_WIDE_resolve         @ yes, do resolve
2990.LOP_SPUT_WIDE_finish: @ field ptr in r2, AA in r9
2991    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2992    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
2993    GET_INST_OPCODE(r10)                @ extract opcode from rINST
2994    .if 0
2995    add     r2, r2, #offStaticField_value @ r2<- pointer to data
2996    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
2997    .else
2998    strd    r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1
2999    .endif
3000    GOTO_OPCODE(r10)                    @ jump to next instruction
3001
3002/* ------------------------------ */
3003    .balign 64
3004.L_OP_SPUT_OBJECT: /* 0x69 */
3005/* File: armv5te/OP_SPUT_OBJECT.S */
3006    /*
3007     * 32-bit SPUT handler for objects
3008     *
3009     * for: sput-object, sput-object-volatile
3010     */
3011    /* op vAA, field@BBBB */
3012    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3013    FETCH(r1, 1)                        @ r1<- field ref BBBB
3014    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3015    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3016    cmp     r0, #0                      @ is resolved entry null?
3017    bne     .LOP_SPUT_OBJECT_finish          @ no, continue
3018    ldr     r9, [rGLUE, #offGlue_method]    @ r9<- current method
3019    EXPORT_PC()                         @ resolve() could throw, so export now
3020    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
3021    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
3022    cmp     r0, #0                      @ success?
3023    bne     .LOP_SPUT_OBJECT_finish          @ yes, finish
3024    b       common_exceptionThrown      @ no, handle exception
3025
3026
3027/* ------------------------------ */
3028    .balign 64
3029.L_OP_SPUT_BOOLEAN: /* 0x6a */
3030/* File: armv5te/OP_SPUT_BOOLEAN.S */
3031/* File: armv5te/OP_SPUT.S */
3032    /*
3033     * General 32-bit SPUT handler.
3034     *
3035     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3036     */
3037    /* op vAA, field@BBBB */
3038    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3039    FETCH(r1, 1)                        @ r1<- field ref BBBB
3040    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3041    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3042    cmp     r0, #0                      @ is resolved entry null?
3043    beq     .LOP_SPUT_BOOLEAN_resolve         @ yes, do resolve
3044.LOP_SPUT_BOOLEAN_finish:   @ field ptr in r0
3045    mov     r2, rINST, lsr #8           @ r2<- AA
3046    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3047    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3048    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3049    @ no-op                             @ releasing store
3050    str     r1, [r0, #offStaticField_value] @ field<- vAA
3051    GOTO_OPCODE(ip)                     @ jump to next instruction
3052
3053
3054/* ------------------------------ */
3055    .balign 64
3056.L_OP_SPUT_BYTE: /* 0x6b */
3057/* File: armv5te/OP_SPUT_BYTE.S */
3058/* File: armv5te/OP_SPUT.S */
3059    /*
3060     * General 32-bit SPUT handler.
3061     *
3062     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3063     */
3064    /* op vAA, field@BBBB */
3065    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3066    FETCH(r1, 1)                        @ r1<- field ref BBBB
3067    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3068    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3069    cmp     r0, #0                      @ is resolved entry null?
3070    beq     .LOP_SPUT_BYTE_resolve         @ yes, do resolve
3071.LOP_SPUT_BYTE_finish:   @ field ptr in r0
3072    mov     r2, rINST, lsr #8           @ r2<- AA
3073    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3074    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3075    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3076    @ no-op                             @ releasing store
3077    str     r1, [r0, #offStaticField_value] @ field<- vAA
3078    GOTO_OPCODE(ip)                     @ jump to next instruction
3079
3080
3081/* ------------------------------ */
3082    .balign 64
3083.L_OP_SPUT_CHAR: /* 0x6c */
3084/* File: armv5te/OP_SPUT_CHAR.S */
3085/* File: armv5te/OP_SPUT.S */
3086    /*
3087     * General 32-bit SPUT handler.
3088     *
3089     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3090     */
3091    /* op vAA, field@BBBB */
3092    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3093    FETCH(r1, 1)                        @ r1<- field ref BBBB
3094    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3095    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3096    cmp     r0, #0                      @ is resolved entry null?
3097    beq     .LOP_SPUT_CHAR_resolve         @ yes, do resolve
3098.LOP_SPUT_CHAR_finish:   @ field ptr in r0
3099    mov     r2, rINST, lsr #8           @ r2<- AA
3100    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3101    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3102    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3103    @ no-op                             @ releasing store
3104    str     r1, [r0, #offStaticField_value] @ field<- vAA
3105    GOTO_OPCODE(ip)                     @ jump to next instruction
3106
3107
3108/* ------------------------------ */
3109    .balign 64
3110.L_OP_SPUT_SHORT: /* 0x6d */
3111/* File: armv5te/OP_SPUT_SHORT.S */
3112/* File: armv5te/OP_SPUT.S */
3113    /*
3114     * General 32-bit SPUT handler.
3115     *
3116     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3117     */
3118    /* op vAA, field@BBBB */
3119    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3120    FETCH(r1, 1)                        @ r1<- field ref BBBB
3121    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3122    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3123    cmp     r0, #0                      @ is resolved entry null?
3124    beq     .LOP_SPUT_SHORT_resolve         @ yes, do resolve
3125.LOP_SPUT_SHORT_finish:   @ field ptr in r0
3126    mov     r2, rINST, lsr #8           @ r2<- AA
3127    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3128    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3129    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3130    @ no-op                             @ releasing store
3131    str     r1, [r0, #offStaticField_value] @ field<- vAA
3132    GOTO_OPCODE(ip)                     @ jump to next instruction
3133
3134
3135/* ------------------------------ */
3136    .balign 64
3137.L_OP_INVOKE_VIRTUAL: /* 0x6e */
3138/* File: armv5te/OP_INVOKE_VIRTUAL.S */
3139    /*
3140     * Handle a virtual method call.
3141     *
3142     * for: invoke-virtual, invoke-virtual/range
3143     */
3144    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3145    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3146    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3147    FETCH(r1, 1)                        @ r1<- BBBB
3148    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3149    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3150    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3151    .if     (!0)
3152    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3153    .endif
3154    cmp     r0, #0                      @ already resolved?
3155    EXPORT_PC()                         @ must export for invoke
3156    bne     .LOP_INVOKE_VIRTUAL_continue        @ yes, continue on
3157    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
3158    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3159    mov     r2, #METHOD_VIRTUAL         @ resolver method type
3160    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3161    cmp     r0, #0                      @ got null?
3162    bne     .LOP_INVOKE_VIRTUAL_continue        @ no, continue
3163    b       common_exceptionThrown      @ yes, handle exception
3164
3165/* ------------------------------ */
3166    .balign 64
3167.L_OP_INVOKE_SUPER: /* 0x6f */
3168/* File: armv5te/OP_INVOKE_SUPER.S */
3169    /*
3170     * Handle a "super" method call.
3171     *
3172     * for: invoke-super, invoke-super/range
3173     */
3174    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3175    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3176    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3177    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3178    .if     (!0)
3179    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3180    .endif
3181    FETCH(r1, 1)                        @ r1<- BBBB
3182    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3183    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3184    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3185    cmp     r2, #0                      @ null "this"?
3186    ldr     r9, [rGLUE, #offGlue_method] @ r9<- current method
3187    beq     common_errNullObject        @ null "this", throw exception
3188    cmp     r0, #0                      @ already resolved?
3189    ldr     r9, [r9, #offMethod_clazz]  @ r9<- method->clazz
3190    EXPORT_PC()                         @ must export for invoke
3191    bne     .LOP_INVOKE_SUPER_continue        @ resolved, continue on
3192    b       .LOP_INVOKE_SUPER_resolve         @ do resolve now
3193
3194/* ------------------------------ */
3195    .balign 64
3196.L_OP_INVOKE_DIRECT: /* 0x70 */
3197/* File: armv5te/OP_INVOKE_DIRECT.S */
3198    /*
3199     * Handle a direct method call.
3200     *
3201     * (We could defer the "is 'this' pointer null" test to the common
3202     * method invocation code, and use a flag to indicate that static
3203     * calls don't count.  If we do this as part of copying the arguments
3204     * out we could avoiding loading the first arg twice.)
3205     *
3206     * for: invoke-direct, invoke-direct/range
3207     */
3208    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3209    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3210    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3211    FETCH(r1, 1)                        @ r1<- BBBB
3212    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3213    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3214    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3215    .if     (!0)
3216    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3217    .endif
3218    cmp     r0, #0                      @ already resolved?
3219    EXPORT_PC()                         @ must export for invoke
3220    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3221    beq     .LOP_INVOKE_DIRECT_resolve         @ not resolved, do it now
3222.LOP_INVOKE_DIRECT_finish:
3223    cmp     r2, #0                      @ null "this" ref?
3224    bne     common_invokeMethodNoRange   @ no, continue on
3225    b       common_errNullObject        @ yes, throw exception
3226
3227/* ------------------------------ */
3228    .balign 64
3229.L_OP_INVOKE_STATIC: /* 0x71 */
3230/* File: armv5te/OP_INVOKE_STATIC.S */
3231    /*
3232     * Handle a static method call.
3233     *
3234     * for: invoke-static, invoke-static/range
3235     */
3236    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3237    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3238    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3239    FETCH(r1, 1)                        @ r1<- BBBB
3240    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3241    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3242    cmp     r0, #0                      @ already resolved?
3243    EXPORT_PC()                         @ must export for invoke
3244    bne     common_invokeMethodNoRange @ yes, continue on
32450:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
3246    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3247    mov     r2, #METHOD_STATIC          @ resolver method type
3248    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3249    cmp     r0, #0                      @ got null?
3250    bne     common_invokeMethodNoRange @ no, continue
3251    b       common_exceptionThrown      @ yes, handle exception
3252
3253/* ------------------------------ */
3254    .balign 64
3255.L_OP_INVOKE_INTERFACE: /* 0x72 */
3256/* File: armv5te/OP_INVOKE_INTERFACE.S */
3257    /*
3258     * Handle an interface method call.
3259     *
3260     * for: invoke-interface, invoke-interface/range
3261     */
3262    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3263    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3264    FETCH(r2, 2)                        @ r2<- FEDC or CCCC
3265    FETCH(r1, 1)                        @ r1<- BBBB
3266    .if     (!0)
3267    and     r2, r2, #15                 @ r2<- C (or stays CCCC)
3268    .endif
3269    EXPORT_PC()                         @ must export for invoke
3270    GET_VREG(r0, r2)                    @ r0<- first arg ("this")
3271    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- methodClassDex
3272    cmp     r0, #0                      @ null obj?
3273    ldr     r2, [rGLUE, #offGlue_method]  @ r2<- method
3274    beq     common_errNullObject        @ yes, fail
3275    ldr     r0, [r0, #offObject_clazz]  @ r0<- thisPtr->clazz
3276    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
3277    cmp     r0, #0                      @ failed?
3278    beq     common_exceptionThrown      @ yes, handle exception
3279    b       common_invokeMethodNoRange @ jump to common handler
3280
3281/* ------------------------------ */
3282    .balign 64
3283.L_OP_UNUSED_73: /* 0x73 */
3284/* File: armv5te/OP_UNUSED_73.S */
3285/* File: armv5te/unused.S */
3286    bl      common_abort
3287
3288
3289/* ------------------------------ */
3290    .balign 64
3291.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
3292/* File: armv5te/OP_INVOKE_VIRTUAL_RANGE.S */
3293/* File: armv5te/OP_INVOKE_VIRTUAL.S */
3294    /*
3295     * Handle a virtual method call.
3296     *
3297     * for: invoke-virtual, invoke-virtual/range
3298     */
3299    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3300    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3301    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3302    FETCH(r1, 1)                        @ r1<- BBBB
3303    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3304    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3305    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3306    .if     (!1)
3307    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3308    .endif
3309    cmp     r0, #0                      @ already resolved?
3310    EXPORT_PC()                         @ must export for invoke
3311    bne     .LOP_INVOKE_VIRTUAL_RANGE_continue        @ yes, continue on
3312    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
3313    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3314    mov     r2, #METHOD_VIRTUAL         @ resolver method type
3315    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3316    cmp     r0, #0                      @ got null?
3317    bne     .LOP_INVOKE_VIRTUAL_RANGE_continue        @ no, continue
3318    b       common_exceptionThrown      @ yes, handle exception
3319
3320
3321/* ------------------------------ */
3322    .balign 64
3323.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */
3324/* File: armv5te/OP_INVOKE_SUPER_RANGE.S */
3325/* File: armv5te/OP_INVOKE_SUPER.S */
3326    /*
3327     * Handle a "super" method call.
3328     *
3329     * for: invoke-super, invoke-super/range
3330     */
3331    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3332    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3333    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3334    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3335    .if     (!1)
3336    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3337    .endif
3338    FETCH(r1, 1)                        @ r1<- BBBB
3339    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3340    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3341    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3342    cmp     r2, #0                      @ null "this"?
3343    ldr     r9, [rGLUE, #offGlue_method] @ r9<- current method
3344    beq     common_errNullObject        @ null "this", throw exception
3345    cmp     r0, #0                      @ already resolved?
3346    ldr     r9, [r9, #offMethod_clazz]  @ r9<- method->clazz
3347    EXPORT_PC()                         @ must export for invoke
3348    bne     .LOP_INVOKE_SUPER_RANGE_continue        @ resolved, continue on
3349    b       .LOP_INVOKE_SUPER_RANGE_resolve         @ do resolve now
3350
3351
3352/* ------------------------------ */
3353    .balign 64
3354.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
3355/* File: armv5te/OP_INVOKE_DIRECT_RANGE.S */
3356/* File: armv5te/OP_INVOKE_DIRECT.S */
3357    /*
3358     * Handle a direct method call.
3359     *
3360     * (We could defer the "is 'this' pointer null" test to the common
3361     * method invocation code, and use a flag to indicate that static
3362     * calls don't count.  If we do this as part of copying the arguments
3363     * out we could avoiding loading the first arg twice.)
3364     *
3365     * for: invoke-direct, invoke-direct/range
3366     */
3367    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3368    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3369    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3370    FETCH(r1, 1)                        @ r1<- BBBB
3371    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3372    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3373    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3374    .if     (!1)
3375    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3376    .endif
3377    cmp     r0, #0                      @ already resolved?
3378    EXPORT_PC()                         @ must export for invoke
3379    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3380    beq     .LOP_INVOKE_DIRECT_RANGE_resolve         @ not resolved, do it now
3381.LOP_INVOKE_DIRECT_RANGE_finish:
3382    cmp     r2, #0                      @ null "this" ref?
3383    bne     common_invokeMethodRange   @ no, continue on
3384    b       common_errNullObject        @ yes, throw exception
3385
3386
3387/* ------------------------------ */
3388    .balign 64
3389.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */
3390/* File: armv5te/OP_INVOKE_STATIC_RANGE.S */
3391/* File: armv5te/OP_INVOKE_STATIC.S */
3392    /*
3393     * Handle a static method call.
3394     *
3395     * for: invoke-static, invoke-static/range
3396     */
3397    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3398    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3399    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3400    FETCH(r1, 1)                        @ r1<- BBBB
3401    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3402    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3403    cmp     r0, #0                      @ already resolved?
3404    EXPORT_PC()                         @ must export for invoke
3405    bne     common_invokeMethodRange @ yes, continue on
34060:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
3407    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3408    mov     r2, #METHOD_STATIC          @ resolver method type
3409    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3410    cmp     r0, #0                      @ got null?
3411    bne     common_invokeMethodRange @ no, continue
3412    b       common_exceptionThrown      @ yes, handle exception
3413
3414
3415/* ------------------------------ */
3416    .balign 64
3417.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
3418/* File: armv5te/OP_INVOKE_INTERFACE_RANGE.S */
3419/* File: armv5te/OP_INVOKE_INTERFACE.S */
3420    /*
3421     * Handle an interface method call.
3422     *
3423     * for: invoke-interface, invoke-interface/range
3424     */
3425    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3426    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3427    FETCH(r2, 2)                        @ r2<- FEDC or CCCC
3428    FETCH(r1, 1)                        @ r1<- BBBB
3429    .if     (!1)
3430    and     r2, r2, #15                 @ r2<- C (or stays CCCC)
3431    .endif
3432    EXPORT_PC()                         @ must export for invoke
3433    GET_VREG(r0, r2)                    @ r0<- first arg ("this")
3434    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- methodClassDex
3435    cmp     r0, #0                      @ null obj?
3436    ldr     r2, [rGLUE, #offGlue_method]  @ r2<- method
3437    beq     common_errNullObject        @ yes, fail
3438    ldr     r0, [r0, #offObject_clazz]  @ r0<- thisPtr->clazz
3439    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
3440    cmp     r0, #0                      @ failed?
3441    beq     common_exceptionThrown      @ yes, handle exception
3442    b       common_invokeMethodRange @ jump to common handler
3443
3444
3445/* ------------------------------ */
3446    .balign 64
3447.L_OP_UNUSED_79: /* 0x79 */
3448/* File: armv5te/OP_UNUSED_79.S */
3449/* File: armv5te/unused.S */
3450    bl      common_abort
3451
3452
3453/* ------------------------------ */
3454    .balign 64
3455.L_OP_UNUSED_7A: /* 0x7a */
3456/* File: armv5te/OP_UNUSED_7A.S */
3457/* File: armv5te/unused.S */
3458    bl      common_abort
3459
3460
3461/* ------------------------------ */
3462    .balign 64
3463.L_OP_NEG_INT: /* 0x7b */
3464/* File: armv6t2/OP_NEG_INT.S */
3465/* File: armv6t2/unop.S */
3466    /*
3467     * Generic 32-bit unary operation.  Provide an "instr" line that
3468     * specifies an instruction that performs "result = op r0".
3469     * This could be an ARM instruction or a function call.
3470     *
3471     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3472     *      int-to-byte, int-to-char, int-to-short
3473     */
3474    /* unop vA, vB */
3475    mov     r3, rINST, lsr #12          @ r3<- B
3476    ubfx    r9, rINST, #8, #4           @ r9<- A
3477    GET_VREG(r0, r3)                    @ r0<- vB
3478                               @ optional op; may set condition codes
3479    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3480    rsb     r0, r0, #0                              @ r0<- op, r0-r3 changed
3481    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3482    SET_VREG(r0, r9)                    @ vAA<- r0
3483    GOTO_OPCODE(ip)                     @ jump to next instruction
3484    /* 8-9 instructions */
3485
3486
3487/* ------------------------------ */
3488    .balign 64
3489.L_OP_NOT_INT: /* 0x7c */
3490/* File: armv6t2/OP_NOT_INT.S */
3491/* File: armv6t2/unop.S */
3492    /*
3493     * Generic 32-bit unary operation.  Provide an "instr" line that
3494     * specifies an instruction that performs "result = op r0".
3495     * This could be an ARM instruction or a function call.
3496     *
3497     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3498     *      int-to-byte, int-to-char, int-to-short
3499     */
3500    /* unop vA, vB */
3501    mov     r3, rINST, lsr #12          @ r3<- B
3502    ubfx    r9, rINST, #8, #4           @ r9<- A
3503    GET_VREG(r0, r3)                    @ r0<- vB
3504                               @ optional op; may set condition codes
3505    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3506    mvn     r0, r0                              @ r0<- op, r0-r3 changed
3507    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3508    SET_VREG(r0, r9)                    @ vAA<- r0
3509    GOTO_OPCODE(ip)                     @ jump to next instruction
3510    /* 8-9 instructions */
3511
3512
3513/* ------------------------------ */
3514    .balign 64
3515.L_OP_NEG_LONG: /* 0x7d */
3516/* File: armv6t2/OP_NEG_LONG.S */
3517/* File: armv6t2/unopWide.S */
3518    /*
3519     * Generic 64-bit unary operation.  Provide an "instr" line that
3520     * specifies an instruction that performs "result = op r0/r1".
3521     * This could be an ARM instruction or a function call.
3522     *
3523     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3524     */
3525    /* unop vA, vB */
3526    mov     r3, rINST, lsr #12          @ r3<- B
3527    ubfx    r9, rINST, #8, #4           @ r9<- A
3528    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3529    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3530    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3531    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3532    rsbs    r0, r0, #0                           @ optional op; may set condition codes
3533    rsc     r1, r1, #0                              @ r0/r1<- op, r2-r3 changed
3534    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3535    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3536    GOTO_OPCODE(ip)                     @ jump to next instruction
3537    /* 10-11 instructions */
3538
3539
3540/* ------------------------------ */
3541    .balign 64
3542.L_OP_NOT_LONG: /* 0x7e */
3543/* File: armv6t2/OP_NOT_LONG.S */
3544/* File: armv6t2/unopWide.S */
3545    /*
3546     * Generic 64-bit unary operation.  Provide an "instr" line that
3547     * specifies an instruction that performs "result = op r0/r1".
3548     * This could be an ARM instruction or a function call.
3549     *
3550     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3551     */
3552    /* unop vA, vB */
3553    mov     r3, rINST, lsr #12          @ r3<- B
3554    ubfx    r9, rINST, #8, #4           @ r9<- A
3555    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3556    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3557    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3558    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3559    mvn     r0, r0                           @ optional op; may set condition codes
3560    mvn     r1, r1                              @ r0/r1<- op, r2-r3 changed
3561    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3562    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3563    GOTO_OPCODE(ip)                     @ jump to next instruction
3564    /* 10-11 instructions */
3565
3566
3567/* ------------------------------ */
3568    .balign 64
3569.L_OP_NEG_FLOAT: /* 0x7f */
3570/* File: armv6t2/OP_NEG_FLOAT.S */
3571/* File: armv6t2/unop.S */
3572    /*
3573     * Generic 32-bit unary operation.  Provide an "instr" line that
3574     * specifies an instruction that performs "result = op r0".
3575     * This could be an ARM instruction or a function call.
3576     *
3577     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3578     *      int-to-byte, int-to-char, int-to-short
3579     */
3580    /* unop vA, vB */
3581    mov     r3, rINST, lsr #12          @ r3<- B
3582    ubfx    r9, rINST, #8, #4           @ r9<- A
3583    GET_VREG(r0, r3)                    @ r0<- vB
3584                               @ optional op; may set condition codes
3585    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3586    add     r0, r0, #0x80000000                              @ r0<- op, r0-r3 changed
3587    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3588    SET_VREG(r0, r9)                    @ vAA<- r0
3589    GOTO_OPCODE(ip)                     @ jump to next instruction
3590    /* 8-9 instructions */
3591
3592
3593/* ------------------------------ */
3594    .balign 64
3595.L_OP_NEG_DOUBLE: /* 0x80 */
3596/* File: armv6t2/OP_NEG_DOUBLE.S */
3597/* File: armv6t2/unopWide.S */
3598    /*
3599     * Generic 64-bit unary operation.  Provide an "instr" line that
3600     * specifies an instruction that performs "result = op r0/r1".
3601     * This could be an ARM instruction or a function call.
3602     *
3603     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3604     */
3605    /* unop vA, vB */
3606    mov     r3, rINST, lsr #12          @ r3<- B
3607    ubfx    r9, rINST, #8, #4           @ r9<- A
3608    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3609    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3610    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3611    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3612                               @ optional op; may set condition codes
3613    add     r1, r1, #0x80000000                              @ r0/r1<- op, r2-r3 changed
3614    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3615    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3616    GOTO_OPCODE(ip)                     @ jump to next instruction
3617    /* 10-11 instructions */
3618
3619
3620/* ------------------------------ */
3621    .balign 64
3622.L_OP_INT_TO_LONG: /* 0x81 */
3623/* File: armv6t2/OP_INT_TO_LONG.S */
3624/* File: armv6t2/unopWider.S */
3625    /*
3626     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3627     * that specifies an instruction that performs "result = op r0", where
3628     * "result" is a 64-bit quantity in r0/r1.
3629     *
3630     * For: int-to-long, int-to-double, float-to-long, float-to-double
3631     */
3632    /* unop vA, vB */
3633    mov     r3, rINST, lsr #12          @ r3<- B
3634    ubfx    r9, rINST, #8, #4           @ r9<- A
3635    GET_VREG(r0, r3)                    @ r0<- vB
3636    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3637                               @ optional op; may set condition codes
3638    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3639    mov     r1, r0, asr #31                              @ r0<- op, r0-r3 changed
3640    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3641    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3642    GOTO_OPCODE(ip)                     @ jump to next instruction
3643    /* 9-10 instructions */
3644
3645
3646/* ------------------------------ */
3647    .balign 64
3648.L_OP_INT_TO_FLOAT: /* 0x82 */
3649/* File: arm-vfp/OP_INT_TO_FLOAT.S */
3650/* File: arm-vfp/funop.S */
3651    /*
3652     * Generic 32-bit unary floating-point operation.  Provide an "instr"
3653     * line that specifies an instruction that performs "s1 = op s0".
3654     *
3655     * for: int-to-float, float-to-int
3656     */
3657    /* unop vA, vB */
3658    mov     r3, rINST, lsr #12          @ r3<- B
3659    mov     r9, rINST, lsr #8           @ r9<- A+
3660    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3661    flds    s0, [r3]                    @ s0<- vB
3662    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3663    and     r9, r9, #15                 @ r9<- A
3664    fsitos  s1, s0                              @ s1<- op
3665    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3666    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3667    fsts    s1, [r9]                    @ vA<- s1
3668    GOTO_OPCODE(ip)                     @ jump to next instruction
3669
3670
3671/* ------------------------------ */
3672    .balign 64
3673.L_OP_INT_TO_DOUBLE: /* 0x83 */
3674/* File: arm-vfp/OP_INT_TO_DOUBLE.S */
3675/* File: arm-vfp/funopWider.S */
3676    /*
3677     * Generic 32bit-to-64bit floating point unary operation.  Provide an
3678     * "instr" line that specifies an instruction that performs "d0 = op s0".
3679     *
3680     * For: int-to-double, float-to-double
3681     */
3682    /* unop vA, vB */
3683    mov     r3, rINST, lsr #12          @ r3<- B
3684    mov     r9, rINST, lsr #8           @ r9<- A+
3685    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3686    flds    s0, [r3]                    @ s0<- vB
3687    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3688    and     r9, r9, #15                 @ r9<- A
3689    fsitod  d0, s0                              @ d0<- op
3690    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3691    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3692    fstd    d0, [r9]                    @ vA<- d0
3693    GOTO_OPCODE(ip)                     @ jump to next instruction
3694
3695
3696/* ------------------------------ */
3697    .balign 64
3698.L_OP_LONG_TO_INT: /* 0x84 */
3699/* File: armv5te/OP_LONG_TO_INT.S */
3700/* we ignore the high word, making this equivalent to a 32-bit reg move */
3701/* File: armv5te/OP_MOVE.S */
3702    /* for move, move-object, long-to-int */
3703    /* op vA, vB */
3704    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
3705    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
3706    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3707    GET_VREG(r2, r1)                    @ r2<- fp[B]
3708    and     r0, r0, #15
3709    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
3710    SET_VREG(r2, r0)                    @ fp[A]<- r2
3711    GOTO_OPCODE(ip)                     @ execute next instruction
3712
3713
3714/* ------------------------------ */
3715    .balign 64
3716.L_OP_LONG_TO_FLOAT: /* 0x85 */
3717/* File: armv6t2/OP_LONG_TO_FLOAT.S */
3718/* File: armv6t2/unopNarrower.S */
3719    /*
3720     * Generic 64bit-to-32bit unary operation.  Provide an "instr" line
3721     * that specifies an instruction that performs "result = op r0/r1", where
3722     * "result" is a 32-bit quantity in r0.
3723     *
3724     * For: long-to-float, double-to-int, double-to-float
3725     *
3726     * (This would work for long-to-int, but that instruction is actually
3727     * an exact match for OP_MOVE.)
3728     */
3729    /* unop vA, vB */
3730    mov     r3, rINST, lsr #12          @ r3<- B
3731    ubfx    r9, rINST, #8, #4           @ r9<- A
3732    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3733    ldmia   r3, {r0-r1}                 @ r0/r1<- vB/vB+1
3734    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3735                               @ optional op; may set condition codes
3736    bl      __aeabi_l2f                              @ r0<- op, r0-r3 changed
3737    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3738    SET_VREG(r0, r9)                    @ vA<- r0
3739    GOTO_OPCODE(ip)                     @ jump to next instruction
3740    /* 9-10 instructions */
3741
3742
3743/* ------------------------------ */
3744    .balign 64
3745.L_OP_LONG_TO_DOUBLE: /* 0x86 */
3746/* File: armv6t2/OP_LONG_TO_DOUBLE.S */
3747/* File: armv6t2/unopWide.S */
3748    /*
3749     * Generic 64-bit unary operation.  Provide an "instr" line that
3750     * specifies an instruction that performs "result = op r0/r1".
3751     * This could be an ARM instruction or a function call.
3752     *
3753     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3754     */
3755    /* unop vA, vB */
3756    mov     r3, rINST, lsr #12          @ r3<- B
3757    ubfx    r9, rINST, #8, #4           @ r9<- A
3758    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3759    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3760    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3761    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3762                               @ optional op; may set condition codes
3763    bl      __aeabi_l2d                              @ r0/r1<- op, r2-r3 changed
3764    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3765    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3766    GOTO_OPCODE(ip)                     @ jump to next instruction
3767    /* 10-11 instructions */
3768
3769
3770/* ------------------------------ */
3771    .balign 64
3772.L_OP_FLOAT_TO_INT: /* 0x87 */
3773/* File: arm-vfp/OP_FLOAT_TO_INT.S */
3774/* File: arm-vfp/funop.S */
3775    /*
3776     * Generic 32-bit unary floating-point operation.  Provide an "instr"
3777     * line that specifies an instruction that performs "s1 = op s0".
3778     *
3779     * for: int-to-float, float-to-int
3780     */
3781    /* unop vA, vB */
3782    mov     r3, rINST, lsr #12          @ r3<- B
3783    mov     r9, rINST, lsr #8           @ r9<- A+
3784    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3785    flds    s0, [r3]                    @ s0<- vB
3786    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3787    and     r9, r9, #15                 @ r9<- A
3788    ftosizs s1, s0                              @ s1<- op
3789    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3790    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3791    fsts    s1, [r9]                    @ vA<- s1
3792    GOTO_OPCODE(ip)                     @ jump to next instruction
3793
3794
3795/* ------------------------------ */
3796    .balign 64
3797.L_OP_FLOAT_TO_LONG: /* 0x88 */
3798/* File: armv6t2/OP_FLOAT_TO_LONG.S */
3799@include "armv6t2/unopWider.S" {"instr":"bl      __aeabi_f2lz"}
3800/* File: armv6t2/unopWider.S */
3801    /*
3802     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3803     * that specifies an instruction that performs "result = op r0", where
3804     * "result" is a 64-bit quantity in r0/r1.
3805     *
3806     * For: int-to-long, int-to-double, float-to-long, float-to-double
3807     */
3808    /* unop vA, vB */
3809    mov     r3, rINST, lsr #12          @ r3<- B
3810    ubfx    r9, rINST, #8, #4           @ r9<- A
3811    GET_VREG(r0, r3)                    @ r0<- vB
3812    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3813                               @ optional op; may set condition codes
3814    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3815    bl      f2l_doconv                              @ r0<- op, r0-r3 changed
3816    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3817    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3818    GOTO_OPCODE(ip)                     @ jump to next instruction
3819    /* 9-10 instructions */
3820
3821
3822
3823/* ------------------------------ */
3824    .balign 64
3825.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */
3826/* File: arm-vfp/OP_FLOAT_TO_DOUBLE.S */
3827/* File: arm-vfp/funopWider.S */
3828    /*
3829     * Generic 32bit-to-64bit floating point unary operation.  Provide an
3830     * "instr" line that specifies an instruction that performs "d0 = op s0".
3831     *
3832     * For: int-to-double, float-to-double
3833     */
3834    /* unop vA, vB */
3835    mov     r3, rINST, lsr #12          @ r3<- B
3836    mov     r9, rINST, lsr #8           @ r9<- A+
3837    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3838    flds    s0, [r3]                    @ s0<- vB
3839    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3840    and     r9, r9, #15                 @ r9<- A
3841    fcvtds  d0, s0                              @ d0<- op
3842    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3843    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3844    fstd    d0, [r9]                    @ vA<- d0
3845    GOTO_OPCODE(ip)                     @ jump to next instruction
3846
3847
3848/* ------------------------------ */
3849    .balign 64
3850.L_OP_DOUBLE_TO_INT: /* 0x8a */
3851/* File: arm-vfp/OP_DOUBLE_TO_INT.S */
3852/* File: arm-vfp/funopNarrower.S */
3853    /*
3854     * Generic 64bit-to-32bit unary floating point operation.  Provide an
3855     * "instr" line that specifies an instruction that performs "s0 = op d0".
3856     *
3857     * For: double-to-int, double-to-float
3858     */
3859    /* unop vA, vB */
3860    mov     r3, rINST, lsr #12          @ r3<- B
3861    mov     r9, rINST, lsr #8           @ r9<- A+
3862    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3863    fldd    d0, [r3]                    @ d0<- vB
3864    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3865    and     r9, r9, #15                 @ r9<- A
3866    ftosizd  s0, d0                              @ s0<- op
3867    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3868    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3869    fsts    s0, [r9]                    @ vA<- s0
3870    GOTO_OPCODE(ip)                     @ jump to next instruction
3871
3872
3873/* ------------------------------ */
3874    .balign 64
3875.L_OP_DOUBLE_TO_LONG: /* 0x8b */
3876/* File: armv6t2/OP_DOUBLE_TO_LONG.S */
3877@include "armv6t2/unopWide.S" {"instr":"bl      __aeabi_d2lz"}
3878/* File: armv6t2/unopWide.S */
3879    /*
3880     * Generic 64-bit unary operation.  Provide an "instr" line that
3881     * specifies an instruction that performs "result = op r0/r1".
3882     * This could be an ARM instruction or a function call.
3883     *
3884     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3885     */
3886    /* unop vA, vB */
3887    mov     r3, rINST, lsr #12          @ r3<- B
3888    ubfx    r9, rINST, #8, #4           @ r9<- A
3889    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3890    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3891    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3892    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3893                               @ optional op; may set condition codes
3894    bl      d2l_doconv                              @ r0/r1<- op, r2-r3 changed
3895    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3896    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3897    GOTO_OPCODE(ip)                     @ jump to next instruction
3898    /* 10-11 instructions */
3899
3900
3901
3902/* ------------------------------ */
3903    .balign 64
3904.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */
3905/* File: arm-vfp/OP_DOUBLE_TO_FLOAT.S */
3906/* File: arm-vfp/funopNarrower.S */
3907    /*
3908     * Generic 64bit-to-32bit unary floating point operation.  Provide an
3909     * "instr" line that specifies an instruction that performs "s0 = op d0".
3910     *
3911     * For: double-to-int, double-to-float
3912     */
3913    /* unop vA, vB */
3914    mov     r3, rINST, lsr #12          @ r3<- B
3915    mov     r9, rINST, lsr #8           @ r9<- A+
3916    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3917    fldd    d0, [r3]                    @ d0<- vB
3918    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3919    and     r9, r9, #15                 @ r9<- A
3920    fcvtsd  s0, d0                              @ s0<- op
3921    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3922    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3923    fsts    s0, [r9]                    @ vA<- s0
3924    GOTO_OPCODE(ip)                     @ jump to next instruction
3925
3926
3927/* ------------------------------ */
3928    .balign 64
3929.L_OP_INT_TO_BYTE: /* 0x8d */
3930/* File: armv6t2/OP_INT_TO_BYTE.S */
3931/* File: armv6t2/unop.S */
3932    /*
3933     * Generic 32-bit unary operation.  Provide an "instr" line that
3934     * specifies an instruction that performs "result = op r0".
3935     * This could be an ARM instruction or a function call.
3936     *
3937     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3938     *      int-to-byte, int-to-char, int-to-short
3939     */
3940    /* unop vA, vB */
3941    mov     r3, rINST, lsr #12          @ r3<- B
3942    ubfx    r9, rINST, #8, #4           @ r9<- A
3943    GET_VREG(r0, r3)                    @ r0<- vB
3944                               @ optional op; may set condition codes
3945    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3946    sxtb    r0, r0                              @ r0<- op, r0-r3 changed
3947    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3948    SET_VREG(r0, r9)                    @ vAA<- r0
3949    GOTO_OPCODE(ip)                     @ jump to next instruction
3950    /* 8-9 instructions */
3951
3952
3953/* ------------------------------ */
3954    .balign 64
3955.L_OP_INT_TO_CHAR: /* 0x8e */
3956/* File: armv6t2/OP_INT_TO_CHAR.S */
3957/* File: armv6t2/unop.S */
3958    /*
3959     * Generic 32-bit unary operation.  Provide an "instr" line that
3960     * specifies an instruction that performs "result = op r0".
3961     * This could be an ARM instruction or a function call.
3962     *
3963     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3964     *      int-to-byte, int-to-char, int-to-short
3965     */
3966    /* unop vA, vB */
3967    mov     r3, rINST, lsr #12          @ r3<- B
3968    ubfx    r9, rINST, #8, #4           @ r9<- A
3969    GET_VREG(r0, r3)                    @ r0<- vB
3970                               @ optional op; may set condition codes
3971    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3972    uxth    r0, r0                              @ r0<- op, r0-r3 changed
3973    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3974    SET_VREG(r0, r9)                    @ vAA<- r0
3975    GOTO_OPCODE(ip)                     @ jump to next instruction
3976    /* 8-9 instructions */
3977
3978
3979/* ------------------------------ */
3980    .balign 64
3981.L_OP_INT_TO_SHORT: /* 0x8f */
3982/* File: armv6t2/OP_INT_TO_SHORT.S */
3983/* File: armv6t2/unop.S */
3984    /*
3985     * Generic 32-bit unary operation.  Provide an "instr" line that
3986     * specifies an instruction that performs "result = op r0".
3987     * This could be an ARM instruction or a function call.
3988     *
3989     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3990     *      int-to-byte, int-to-char, int-to-short
3991     */
3992    /* unop vA, vB */
3993    mov     r3, rINST, lsr #12          @ r3<- B
3994    ubfx    r9, rINST, #8, #4           @ r9<- A
3995    GET_VREG(r0, r3)                    @ r0<- vB
3996                               @ optional op; may set condition codes
3997    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3998    sxth    r0, r0                              @ r0<- op, r0-r3 changed
3999    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4000    SET_VREG(r0, r9)                    @ vAA<- r0
4001    GOTO_OPCODE(ip)                     @ jump to next instruction
4002    /* 8-9 instructions */
4003
4004
4005/* ------------------------------ */
4006    .balign 64
4007.L_OP_ADD_INT: /* 0x90 */
4008/* File: armv5te/OP_ADD_INT.S */
4009/* File: armv5te/binop.S */
4010    /*
4011     * Generic 32-bit binary operation.  Provide an "instr" line that
4012     * specifies an instruction that performs "result = r0 op r1".
4013     * This could be an ARM instruction or a function call.  (If the result
4014     * comes back in a register other than r0, you can override "result".)
4015     *
4016     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4017     * vCC (r1).  Useful for integer division and modulus.  Note that we
4018     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4019     * handles it correctly.
4020     *
4021     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4022     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4023     *      mul-float, div-float, rem-float
4024     */
4025    /* binop vAA, vBB, vCC */
4026    FETCH(r0, 1)                        @ r0<- CCBB
4027    mov     r9, rINST, lsr #8           @ r9<- AA
4028    mov     r3, r0, lsr #8              @ r3<- CC
4029    and     r2, r0, #255                @ r2<- BB
4030    GET_VREG(r1, r3)                    @ r1<- vCC
4031    GET_VREG(r0, r2)                    @ r0<- vBB
4032    .if 0
4033    cmp     r1, #0                      @ is second operand zero?
4034    beq     common_errDivideByZero
4035    .endif
4036
4037    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4038                               @ optional op; may set condition codes
4039    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
4040    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4041    SET_VREG(r0, r9)               @ vAA<- r0
4042    GOTO_OPCODE(ip)                     @ jump to next instruction
4043    /* 11-14 instructions */
4044
4045
4046/* ------------------------------ */
4047    .balign 64
4048.L_OP_SUB_INT: /* 0x91 */
4049/* File: armv5te/OP_SUB_INT.S */
4050/* File: armv5te/binop.S */
4051    /*
4052     * Generic 32-bit binary operation.  Provide an "instr" line that
4053     * specifies an instruction that performs "result = r0 op r1".
4054     * This could be an ARM instruction or a function call.  (If the result
4055     * comes back in a register other than r0, you can override "result".)
4056     *
4057     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4058     * vCC (r1).  Useful for integer division and modulus.  Note that we
4059     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4060     * handles it correctly.
4061     *
4062     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4063     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4064     *      mul-float, div-float, rem-float
4065     */
4066    /* binop vAA, vBB, vCC */
4067    FETCH(r0, 1)                        @ r0<- CCBB
4068    mov     r9, rINST, lsr #8           @ r9<- AA
4069    mov     r3, r0, lsr #8              @ r3<- CC
4070    and     r2, r0, #255                @ r2<- BB
4071    GET_VREG(r1, r3)                    @ r1<- vCC
4072    GET_VREG(r0, r2)                    @ r0<- vBB
4073    .if 0
4074    cmp     r1, #0                      @ is second operand zero?
4075    beq     common_errDivideByZero
4076    .endif
4077
4078    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4079                               @ optional op; may set condition codes
4080    sub     r0, r0, r1                              @ r0<- op, r0-r3 changed
4081    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4082    SET_VREG(r0, r9)               @ vAA<- r0
4083    GOTO_OPCODE(ip)                     @ jump to next instruction
4084    /* 11-14 instructions */
4085
4086
4087/* ------------------------------ */
4088    .balign 64
4089.L_OP_MUL_INT: /* 0x92 */
4090/* File: armv5te/OP_MUL_INT.S */
4091/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
4092/* File: armv5te/binop.S */
4093    /*
4094     * Generic 32-bit binary operation.  Provide an "instr" line that
4095     * specifies an instruction that performs "result = r0 op r1".
4096     * This could be an ARM instruction or a function call.  (If the result
4097     * comes back in a register other than r0, you can override "result".)
4098     *
4099     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4100     * vCC (r1).  Useful for integer division and modulus.  Note that we
4101     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4102     * handles it correctly.
4103     *
4104     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4105     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4106     *      mul-float, div-float, rem-float
4107     */
4108    /* binop vAA, vBB, vCC */
4109    FETCH(r0, 1)                        @ r0<- CCBB
4110    mov     r9, rINST, lsr #8           @ r9<- AA
4111    mov     r3, r0, lsr #8              @ r3<- CC
4112    and     r2, r0, #255                @ r2<- BB
4113    GET_VREG(r1, r3)                    @ r1<- vCC
4114    GET_VREG(r0, r2)                    @ r0<- vBB
4115    .if 0
4116    cmp     r1, #0                      @ is second operand zero?
4117    beq     common_errDivideByZero
4118    .endif
4119
4120    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4121                               @ optional op; may set condition codes
4122    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
4123    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4124    SET_VREG(r0, r9)               @ vAA<- r0
4125    GOTO_OPCODE(ip)                     @ jump to next instruction
4126    /* 11-14 instructions */
4127
4128
4129/* ------------------------------ */
4130    .balign 64
4131.L_OP_DIV_INT: /* 0x93 */
4132/* File: armv5te/OP_DIV_INT.S */
4133/* File: armv5te/binop.S */
4134    /*
4135     * Generic 32-bit binary operation.  Provide an "instr" line that
4136     * specifies an instruction that performs "result = r0 op r1".
4137     * This could be an ARM instruction or a function call.  (If the result
4138     * comes back in a register other than r0, you can override "result".)
4139     *
4140     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4141     * vCC (r1).  Useful for integer division and modulus.  Note that we
4142     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4143     * handles it correctly.
4144     *
4145     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4146     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4147     *      mul-float, div-float, rem-float
4148     */
4149    /* binop vAA, vBB, vCC */
4150    FETCH(r0, 1)                        @ r0<- CCBB
4151    mov     r9, rINST, lsr #8           @ r9<- AA
4152    mov     r3, r0, lsr #8              @ r3<- CC
4153    and     r2, r0, #255                @ r2<- BB
4154    GET_VREG(r1, r3)                    @ r1<- vCC
4155    GET_VREG(r0, r2)                    @ r0<- vBB
4156    .if 1
4157    cmp     r1, #0                      @ is second operand zero?
4158    beq     common_errDivideByZero
4159    .endif
4160
4161    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4162                               @ optional op; may set condition codes
4163    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
4164    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4165    SET_VREG(r0, r9)               @ vAA<- r0
4166    GOTO_OPCODE(ip)                     @ jump to next instruction
4167    /* 11-14 instructions */
4168
4169
4170/* ------------------------------ */
4171    .balign 64
4172.L_OP_REM_INT: /* 0x94 */
4173/* File: armv5te/OP_REM_INT.S */
4174/* idivmod returns quotient in r0 and remainder in r1 */
4175/* File: armv5te/binop.S */
4176    /*
4177     * Generic 32-bit binary operation.  Provide an "instr" line that
4178     * specifies an instruction that performs "result = r0 op r1".
4179     * This could be an ARM instruction or a function call.  (If the result
4180     * comes back in a register other than r0, you can override "result".)
4181     *
4182     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4183     * vCC (r1).  Useful for integer division and modulus.  Note that we
4184     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4185     * handles it correctly.
4186     *
4187     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4188     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4189     *      mul-float, div-float, rem-float
4190     */
4191    /* binop vAA, vBB, vCC */
4192    FETCH(r0, 1)                        @ r0<- CCBB
4193    mov     r9, rINST, lsr #8           @ r9<- AA
4194    mov     r3, r0, lsr #8              @ r3<- CC
4195    and     r2, r0, #255                @ r2<- BB
4196    GET_VREG(r1, r3)                    @ r1<- vCC
4197    GET_VREG(r0, r2)                    @ r0<- vBB
4198    .if 1
4199    cmp     r1, #0                      @ is second operand zero?
4200    beq     common_errDivideByZero
4201    .endif
4202
4203    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4204                               @ optional op; may set condition codes
4205    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
4206    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4207    SET_VREG(r1, r9)               @ vAA<- r1
4208    GOTO_OPCODE(ip)                     @ jump to next instruction
4209    /* 11-14 instructions */
4210
4211
4212/* ------------------------------ */
4213    .balign 64
4214.L_OP_AND_INT: /* 0x95 */
4215/* File: armv5te/OP_AND_INT.S */
4216/* File: armv5te/binop.S */
4217    /*
4218     * Generic 32-bit binary operation.  Provide an "instr" line that
4219     * specifies an instruction that performs "result = r0 op r1".
4220     * This could be an ARM instruction or a function call.  (If the result
4221     * comes back in a register other than r0, you can override "result".)
4222     *
4223     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4224     * vCC (r1).  Useful for integer division and modulus.  Note that we
4225     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4226     * handles it correctly.
4227     *
4228     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4229     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4230     *      mul-float, div-float, rem-float
4231     */
4232    /* binop vAA, vBB, vCC */
4233    FETCH(r0, 1)                        @ r0<- CCBB
4234    mov     r9, rINST, lsr #8           @ r9<- AA
4235    mov     r3, r0, lsr #8              @ r3<- CC
4236    and     r2, r0, #255                @ r2<- BB
4237    GET_VREG(r1, r3)                    @ r1<- vCC
4238    GET_VREG(r0, r2)                    @ r0<- vBB
4239    .if 0
4240    cmp     r1, #0                      @ is second operand zero?
4241    beq     common_errDivideByZero
4242    .endif
4243
4244    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4245                               @ optional op; may set condition codes
4246    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
4247    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4248    SET_VREG(r0, r9)               @ vAA<- r0
4249    GOTO_OPCODE(ip)                     @ jump to next instruction
4250    /* 11-14 instructions */
4251
4252
4253/* ------------------------------ */
4254    .balign 64
4255.L_OP_OR_INT: /* 0x96 */
4256/* File: armv5te/OP_OR_INT.S */
4257/* File: armv5te/binop.S */
4258    /*
4259     * Generic 32-bit binary operation.  Provide an "instr" line that
4260     * specifies an instruction that performs "result = r0 op r1".
4261     * This could be an ARM instruction or a function call.  (If the result
4262     * comes back in a register other than r0, you can override "result".)
4263     *
4264     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4265     * vCC (r1).  Useful for integer division and modulus.  Note that we
4266     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4267     * handles it correctly.
4268     *
4269     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4270     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4271     *      mul-float, div-float, rem-float
4272     */
4273    /* binop vAA, vBB, vCC */
4274    FETCH(r0, 1)                        @ r0<- CCBB
4275    mov     r9, rINST, lsr #8           @ r9<- AA
4276    mov     r3, r0, lsr #8              @ r3<- CC
4277    and     r2, r0, #255                @ r2<- BB
4278    GET_VREG(r1, r3)                    @ r1<- vCC
4279    GET_VREG(r0, r2)                    @ r0<- vBB
4280    .if 0
4281    cmp     r1, #0                      @ is second operand zero?
4282    beq     common_errDivideByZero
4283    .endif
4284
4285    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4286                               @ optional op; may set condition codes
4287    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
4288    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4289    SET_VREG(r0, r9)               @ vAA<- r0
4290    GOTO_OPCODE(ip)                     @ jump to next instruction
4291    /* 11-14 instructions */
4292
4293
4294/* ------------------------------ */
4295    .balign 64
4296.L_OP_XOR_INT: /* 0x97 */
4297/* File: armv5te/OP_XOR_INT.S */
4298/* File: armv5te/binop.S */
4299    /*
4300     * Generic 32-bit binary operation.  Provide an "instr" line that
4301     * specifies an instruction that performs "result = r0 op r1".
4302     * This could be an ARM instruction or a function call.  (If the result
4303     * comes back in a register other than r0, you can override "result".)
4304     *
4305     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4306     * vCC (r1).  Useful for integer division and modulus.  Note that we
4307     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4308     * handles it correctly.
4309     *
4310     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4311     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4312     *      mul-float, div-float, rem-float
4313     */
4314    /* binop vAA, vBB, vCC */
4315    FETCH(r0, 1)                        @ r0<- CCBB
4316    mov     r9, rINST, lsr #8           @ r9<- AA
4317    mov     r3, r0, lsr #8              @ r3<- CC
4318    and     r2, r0, #255                @ r2<- BB
4319    GET_VREG(r1, r3)                    @ r1<- vCC
4320    GET_VREG(r0, r2)                    @ r0<- vBB
4321    .if 0
4322    cmp     r1, #0                      @ is second operand zero?
4323    beq     common_errDivideByZero
4324    .endif
4325
4326    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4327                               @ optional op; may set condition codes
4328    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
4329    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4330    SET_VREG(r0, r9)               @ vAA<- r0
4331    GOTO_OPCODE(ip)                     @ jump to next instruction
4332    /* 11-14 instructions */
4333
4334
4335/* ------------------------------ */
4336    .balign 64
4337.L_OP_SHL_INT: /* 0x98 */
4338/* File: armv5te/OP_SHL_INT.S */
4339/* File: armv5te/binop.S */
4340    /*
4341     * Generic 32-bit binary operation.  Provide an "instr" line that
4342     * specifies an instruction that performs "result = r0 op r1".
4343     * This could be an ARM instruction or a function call.  (If the result
4344     * comes back in a register other than r0, you can override "result".)
4345     *
4346     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4347     * vCC (r1).  Useful for integer division and modulus.  Note that we
4348     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4349     * handles it correctly.
4350     *
4351     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4352     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4353     *      mul-float, div-float, rem-float
4354     */
4355    /* binop vAA, vBB, vCC */
4356    FETCH(r0, 1)                        @ r0<- CCBB
4357    mov     r9, rINST, lsr #8           @ r9<- AA
4358    mov     r3, r0, lsr #8              @ r3<- CC
4359    and     r2, r0, #255                @ r2<- BB
4360    GET_VREG(r1, r3)                    @ r1<- vCC
4361    GET_VREG(r0, r2)                    @ r0<- vBB
4362    .if 0
4363    cmp     r1, #0                      @ is second operand zero?
4364    beq     common_errDivideByZero
4365    .endif
4366
4367    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4368    and     r1, r1, #31                           @ optional op; may set condition codes
4369    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
4370    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4371    SET_VREG(r0, r9)               @ vAA<- r0
4372    GOTO_OPCODE(ip)                     @ jump to next instruction
4373    /* 11-14 instructions */
4374
4375
4376/* ------------------------------ */
4377    .balign 64
4378.L_OP_SHR_INT: /* 0x99 */
4379/* File: armv5te/OP_SHR_INT.S */
4380/* File: armv5te/binop.S */
4381    /*
4382     * Generic 32-bit binary operation.  Provide an "instr" line that
4383     * specifies an instruction that performs "result = r0 op r1".
4384     * This could be an ARM instruction or a function call.  (If the result
4385     * comes back in a register other than r0, you can override "result".)
4386     *
4387     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4388     * vCC (r1).  Useful for integer division and modulus.  Note that we
4389     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4390     * handles it correctly.
4391     *
4392     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4393     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4394     *      mul-float, div-float, rem-float
4395     */
4396    /* binop vAA, vBB, vCC */
4397    FETCH(r0, 1)                        @ r0<- CCBB
4398    mov     r9, rINST, lsr #8           @ r9<- AA
4399    mov     r3, r0, lsr #8              @ r3<- CC
4400    and     r2, r0, #255                @ r2<- BB
4401    GET_VREG(r1, r3)                    @ r1<- vCC
4402    GET_VREG(r0, r2)                    @ r0<- vBB
4403    .if 0
4404    cmp     r1, #0                      @ is second operand zero?
4405    beq     common_errDivideByZero
4406    .endif
4407
4408    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4409    and     r1, r1, #31                           @ optional op; may set condition codes
4410    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
4411    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4412    SET_VREG(r0, r9)               @ vAA<- r0
4413    GOTO_OPCODE(ip)                     @ jump to next instruction
4414    /* 11-14 instructions */
4415
4416
4417/* ------------------------------ */
4418    .balign 64
4419.L_OP_USHR_INT: /* 0x9a */
4420/* File: armv5te/OP_USHR_INT.S */
4421/* File: armv5te/binop.S */
4422    /*
4423     * Generic 32-bit binary operation.  Provide an "instr" line that
4424     * specifies an instruction that performs "result = r0 op r1".
4425     * This could be an ARM instruction or a function call.  (If the result
4426     * comes back in a register other than r0, you can override "result".)
4427     *
4428     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4429     * vCC (r1).  Useful for integer division and modulus.  Note that we
4430     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4431     * handles it correctly.
4432     *
4433     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4434     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4435     *      mul-float, div-float, rem-float
4436     */
4437    /* binop vAA, vBB, vCC */
4438    FETCH(r0, 1)                        @ r0<- CCBB
4439    mov     r9, rINST, lsr #8           @ r9<- AA
4440    mov     r3, r0, lsr #8              @ r3<- CC
4441    and     r2, r0, #255                @ r2<- BB
4442    GET_VREG(r1, r3)                    @ r1<- vCC
4443    GET_VREG(r0, r2)                    @ r0<- vBB
4444    .if 0
4445    cmp     r1, #0                      @ is second operand zero?
4446    beq     common_errDivideByZero
4447    .endif
4448
4449    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4450    and     r1, r1, #31                           @ optional op; may set condition codes
4451    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
4452    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4453    SET_VREG(r0, r9)               @ vAA<- r0
4454    GOTO_OPCODE(ip)                     @ jump to next instruction
4455    /* 11-14 instructions */
4456
4457
4458/* ------------------------------ */
4459    .balign 64
4460.L_OP_ADD_LONG: /* 0x9b */
4461/* File: armv5te/OP_ADD_LONG.S */
4462/* File: armv5te/binopWide.S */
4463    /*
4464     * Generic 64-bit binary operation.  Provide an "instr" line that
4465     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4466     * This could be an ARM instruction or a function call.  (If the result
4467     * comes back in a register other than r0, you can override "result".)
4468     *
4469     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4470     * vCC (r1).  Useful for integer division and modulus.
4471     *
4472     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4473     *      xor-long, add-double, sub-double, mul-double, div-double,
4474     *      rem-double
4475     *
4476     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4477     */
4478    /* binop vAA, vBB, vCC */
4479    FETCH(r0, 1)                        @ r0<- CCBB
4480    mov     r9, rINST, lsr #8           @ r9<- AA
4481    and     r2, r0, #255                @ r2<- BB
4482    mov     r3, r0, lsr #8              @ r3<- CC
4483    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4484    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4485    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4486    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4487    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4488    .if 0
4489    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4490    beq     common_errDivideByZero
4491    .endif
4492    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4493
4494    adds    r0, r0, r2                           @ optional op; may set condition codes
4495    adc     r1, r1, r3                              @ result<- op, r0-r3 changed
4496    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4497    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4498    GOTO_OPCODE(ip)                     @ jump to next instruction
4499    /* 14-17 instructions */
4500
4501
4502/* ------------------------------ */
4503    .balign 64
4504.L_OP_SUB_LONG: /* 0x9c */
4505/* File: armv5te/OP_SUB_LONG.S */
4506/* File: armv5te/binopWide.S */
4507    /*
4508     * Generic 64-bit binary operation.  Provide an "instr" line that
4509     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4510     * This could be an ARM instruction or a function call.  (If the result
4511     * comes back in a register other than r0, you can override "result".)
4512     *
4513     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4514     * vCC (r1).  Useful for integer division and modulus.
4515     *
4516     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4517     *      xor-long, add-double, sub-double, mul-double, div-double,
4518     *      rem-double
4519     *
4520     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4521     */
4522    /* binop vAA, vBB, vCC */
4523    FETCH(r0, 1)                        @ r0<- CCBB
4524    mov     r9, rINST, lsr #8           @ r9<- AA
4525    and     r2, r0, #255                @ r2<- BB
4526    mov     r3, r0, lsr #8              @ r3<- CC
4527    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4528    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4529    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4530    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4531    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4532    .if 0
4533    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4534    beq     common_errDivideByZero
4535    .endif
4536    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4537
4538    subs    r0, r0, r2                           @ optional op; may set condition codes
4539    sbc     r1, r1, r3                              @ result<- op, r0-r3 changed
4540    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4541    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4542    GOTO_OPCODE(ip)                     @ jump to next instruction
4543    /* 14-17 instructions */
4544
4545
4546/* ------------------------------ */
4547    .balign 64
4548.L_OP_MUL_LONG: /* 0x9d */
4549/* File: armv5te/OP_MUL_LONG.S */
4550    /*
4551     * Signed 64-bit integer multiply.
4552     *
4553     * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
4554     *        WX
4555     *      x YZ
4556     *  --------
4557     *     ZW ZX
4558     *  YW YX
4559     *
4560     * The low word of the result holds ZX, the high word holds
4561     * (ZW+YX) + (the high overflow from ZX).  YW doesn't matter because
4562     * it doesn't fit in the low 64 bits.
4563     *
4564     * Unlike most ARM math operations, multiply instructions have
4565     * restrictions on using the same register more than once (Rd and Rm
4566     * cannot be the same).
4567     */
4568    /* mul-long vAA, vBB, vCC */
4569    FETCH(r0, 1)                        @ r0<- CCBB
4570    and     r2, r0, #255                @ r2<- BB
4571    mov     r3, r0, lsr #8              @ r3<- CC
4572    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4573    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4574    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4575    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4576    mul     ip, r2, r1                  @  ip<- ZxW
4577    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
4578    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
4579    mov     r0, rINST, lsr #8           @ r0<- AA
4580    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
4581    add     r0, rFP, r0, lsl #2         @ r0<- &fp[AA]
4582    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4583    b       .LOP_MUL_LONG_finish
4584
4585/* ------------------------------ */
4586    .balign 64
4587.L_OP_DIV_LONG: /* 0x9e */
4588/* File: armv5te/OP_DIV_LONG.S */
4589/* File: armv5te/binopWide.S */
4590    /*
4591     * Generic 64-bit binary operation.  Provide an "instr" line that
4592     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4593     * This could be an ARM instruction or a function call.  (If the result
4594     * comes back in a register other than r0, you can override "result".)
4595     *
4596     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4597     * vCC (r1).  Useful for integer division and modulus.
4598     *
4599     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4600     *      xor-long, add-double, sub-double, mul-double, div-double,
4601     *      rem-double
4602     *
4603     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4604     */
4605    /* binop vAA, vBB, vCC */
4606    FETCH(r0, 1)                        @ r0<- CCBB
4607    mov     r9, rINST, lsr #8           @ r9<- AA
4608    and     r2, r0, #255                @ r2<- BB
4609    mov     r3, r0, lsr #8              @ r3<- CC
4610    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4611    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4612    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4613    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4614    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4615    .if 1
4616    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4617    beq     common_errDivideByZero
4618    .endif
4619    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4620
4621                               @ optional op; may set condition codes
4622    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
4623    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4624    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4625    GOTO_OPCODE(ip)                     @ jump to next instruction
4626    /* 14-17 instructions */
4627
4628
4629/* ------------------------------ */
4630    .balign 64
4631.L_OP_REM_LONG: /* 0x9f */
4632/* File: armv5te/OP_REM_LONG.S */
4633/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
4634/* File: armv5te/binopWide.S */
4635    /*
4636     * Generic 64-bit binary operation.  Provide an "instr" line that
4637     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4638     * This could be an ARM instruction or a function call.  (If the result
4639     * comes back in a register other than r0, you can override "result".)
4640     *
4641     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4642     * vCC (r1).  Useful for integer division and modulus.
4643     *
4644     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4645     *      xor-long, add-double, sub-double, mul-double, div-double,
4646     *      rem-double
4647     *
4648     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4649     */
4650    /* binop vAA, vBB, vCC */
4651    FETCH(r0, 1)                        @ r0<- CCBB
4652    mov     r9, rINST, lsr #8           @ r9<- AA
4653    and     r2, r0, #255                @ r2<- BB
4654    mov     r3, r0, lsr #8              @ r3<- CC
4655    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4656    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4657    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4658    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4659    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4660    .if 1
4661    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4662    beq     common_errDivideByZero
4663    .endif
4664    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4665
4666                               @ optional op; may set condition codes
4667    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
4668    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4669    stmia   r9, {r2,r3}     @ vAA/vAA+1<- r2/r3
4670    GOTO_OPCODE(ip)                     @ jump to next instruction
4671    /* 14-17 instructions */
4672
4673
4674/* ------------------------------ */
4675    .balign 64
4676.L_OP_AND_LONG: /* 0xa0 */
4677/* File: armv5te/OP_AND_LONG.S */
4678/* File: armv5te/binopWide.S */
4679    /*
4680     * Generic 64-bit binary operation.  Provide an "instr" line that
4681     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4682     * This could be an ARM instruction or a function call.  (If the result
4683     * comes back in a register other than r0, you can override "result".)
4684     *
4685     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4686     * vCC (r1).  Useful for integer division and modulus.
4687     *
4688     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4689     *      xor-long, add-double, sub-double, mul-double, div-double,
4690     *      rem-double
4691     *
4692     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4693     */
4694    /* binop vAA, vBB, vCC */
4695    FETCH(r0, 1)                        @ r0<- CCBB
4696    mov     r9, rINST, lsr #8           @ r9<- AA
4697    and     r2, r0, #255                @ r2<- BB
4698    mov     r3, r0, lsr #8              @ r3<- CC
4699    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4700    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4701    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4702    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4703    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4704    .if 0
4705    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4706    beq     common_errDivideByZero
4707    .endif
4708    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4709
4710    and     r0, r0, r2                           @ optional op; may set condition codes
4711    and     r1, r1, r3                              @ result<- op, r0-r3 changed
4712    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4713    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4714    GOTO_OPCODE(ip)                     @ jump to next instruction
4715    /* 14-17 instructions */
4716
4717
4718/* ------------------------------ */
4719    .balign 64
4720.L_OP_OR_LONG: /* 0xa1 */
4721/* File: armv5te/OP_OR_LONG.S */
4722/* File: armv5te/binopWide.S */
4723    /*
4724     * Generic 64-bit binary operation.  Provide an "instr" line that
4725     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4726     * This could be an ARM instruction or a function call.  (If the result
4727     * comes back in a register other than r0, you can override "result".)
4728     *
4729     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4730     * vCC (r1).  Useful for integer division and modulus.
4731     *
4732     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4733     *      xor-long, add-double, sub-double, mul-double, div-double,
4734     *      rem-double
4735     *
4736     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4737     */
4738    /* binop vAA, vBB, vCC */
4739    FETCH(r0, 1)                        @ r0<- CCBB
4740    mov     r9, rINST, lsr #8           @ r9<- AA
4741    and     r2, r0, #255                @ r2<- BB
4742    mov     r3, r0, lsr #8              @ r3<- CC
4743    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4744    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4745    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4746    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4747    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4748    .if 0
4749    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4750    beq     common_errDivideByZero
4751    .endif
4752    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4753
4754    orr     r0, r0, r2                           @ optional op; may set condition codes
4755    orr     r1, r1, r3                              @ result<- op, r0-r3 changed
4756    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4757    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4758    GOTO_OPCODE(ip)                     @ jump to next instruction
4759    /* 14-17 instructions */
4760
4761
4762/* ------------------------------ */
4763    .balign 64
4764.L_OP_XOR_LONG: /* 0xa2 */
4765/* File: armv5te/OP_XOR_LONG.S */
4766/* File: armv5te/binopWide.S */
4767    /*
4768     * Generic 64-bit binary operation.  Provide an "instr" line that
4769     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4770     * This could be an ARM instruction or a function call.  (If the result
4771     * comes back in a register other than r0, you can override "result".)
4772     *
4773     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4774     * vCC (r1).  Useful for integer division and modulus.
4775     *
4776     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4777     *      xor-long, add-double, sub-double, mul-double, div-double,
4778     *      rem-double
4779     *
4780     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4781     */
4782    /* binop vAA, vBB, vCC */
4783    FETCH(r0, 1)                        @ r0<- CCBB
4784    mov     r9, rINST, lsr #8           @ r9<- AA
4785    and     r2, r0, #255                @ r2<- BB
4786    mov     r3, r0, lsr #8              @ r3<- CC
4787    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4788    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4789    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4790    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4791    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4792    .if 0
4793    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4794    beq     common_errDivideByZero
4795    .endif
4796    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4797
4798    eor     r0, r0, r2                           @ optional op; may set condition codes
4799    eor     r1, r1, r3                              @ result<- op, r0-r3 changed
4800    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4801    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4802    GOTO_OPCODE(ip)                     @ jump to next instruction
4803    /* 14-17 instructions */
4804
4805
4806/* ------------------------------ */
4807    .balign 64
4808.L_OP_SHL_LONG: /* 0xa3 */
4809/* File: armv5te/OP_SHL_LONG.S */
4810    /*
4811     * Long integer shift.  This is different from the generic 32/64-bit
4812     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4813     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4814     * 6 bits of the shift distance.
4815     */
4816    /* shl-long vAA, vBB, vCC */
4817    FETCH(r0, 1)                        @ r0<- CCBB
4818    mov     r9, rINST, lsr #8           @ r9<- AA
4819    and     r3, r0, #255                @ r3<- BB
4820    mov     r0, r0, lsr #8              @ r0<- CC
4821    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4822    GET_VREG(r2, r0)                    @ r2<- vCC
4823    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4824    and     r2, r2, #63                 @ r2<- r2 & 0x3f
4825    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4826
4827    mov     r1, r1, asl r2              @  r1<- r1 << r2
4828    rsb     r3, r2, #32                 @  r3<- 32 - r2
4829    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
4830    subs    ip, r2, #32                 @  ip<- r2 - 32
4831    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
4832    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4833    b       .LOP_SHL_LONG_finish
4834
4835/* ------------------------------ */
4836    .balign 64
4837.L_OP_SHR_LONG: /* 0xa4 */
4838/* File: armv5te/OP_SHR_LONG.S */
4839    /*
4840     * Long integer shift.  This is different from the generic 32/64-bit
4841     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4842     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4843     * 6 bits of the shift distance.
4844     */
4845    /* shr-long vAA, vBB, vCC */
4846    FETCH(r0, 1)                        @ r0<- CCBB
4847    mov     r9, rINST, lsr #8           @ r9<- AA
4848    and     r3, r0, #255                @ r3<- BB
4849    mov     r0, r0, lsr #8              @ r0<- CC
4850    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4851    GET_VREG(r2, r0)                    @ r2<- vCC
4852    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4853    and     r2, r2, #63                 @ r0<- r0 & 0x3f
4854    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4855
4856    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
4857    rsb     r3, r2, #32                 @  r3<- 32 - r2
4858    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
4859    subs    ip, r2, #32                 @  ip<- r2 - 32
4860    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
4861    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4862    b       .LOP_SHR_LONG_finish
4863
4864/* ------------------------------ */
4865    .balign 64
4866.L_OP_USHR_LONG: /* 0xa5 */
4867/* File: armv5te/OP_USHR_LONG.S */
4868    /*
4869     * Long integer shift.  This is different from the generic 32/64-bit
4870     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4871     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4872     * 6 bits of the shift distance.
4873     */
4874    /* ushr-long vAA, vBB, vCC */
4875    FETCH(r0, 1)                        @ r0<- CCBB
4876    mov     r9, rINST, lsr #8           @ r9<- AA
4877    and     r3, r0, #255                @ r3<- BB
4878    mov     r0, r0, lsr #8              @ r0<- CC
4879    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4880    GET_VREG(r2, r0)                    @ r2<- vCC
4881    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4882    and     r2, r2, #63                 @ r0<- r0 & 0x3f
4883    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4884
4885    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
4886    rsb     r3, r2, #32                 @  r3<- 32 - r2
4887    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
4888    subs    ip, r2, #32                 @  ip<- r2 - 32
4889    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
4890    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4891    b       .LOP_USHR_LONG_finish
4892
4893/* ------------------------------ */
4894    .balign 64
4895.L_OP_ADD_FLOAT: /* 0xa6 */
4896/* File: arm-vfp/OP_ADD_FLOAT.S */
4897/* File: arm-vfp/fbinop.S */
4898    /*
4899     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4900     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4901     * use the "softfp" ABI, this must be an instruction, not a function call.
4902     *
4903     * For: add-float, sub-float, mul-float, div-float
4904     */
4905    /* floatop vAA, vBB, vCC */
4906    FETCH(r0, 1)                        @ r0<- CCBB
4907    mov     r9, rINST, lsr #8           @ r9<- AA
4908    mov     r3, r0, lsr #8              @ r3<- CC
4909    and     r2, r0, #255                @ r2<- BB
4910    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4911    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4912    flds    s1, [r3]                    @ s1<- vCC
4913    flds    s0, [r2]                    @ s0<- vBB
4914
4915    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4916    fadds   s2, s0, s1                              @ s2<- op
4917    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4918    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4919    fsts    s2, [r9]                    @ vAA<- s2
4920    GOTO_OPCODE(ip)                     @ jump to next instruction
4921
4922
4923/* ------------------------------ */
4924    .balign 64
4925.L_OP_SUB_FLOAT: /* 0xa7 */
4926/* File: arm-vfp/OP_SUB_FLOAT.S */
4927/* File: arm-vfp/fbinop.S */
4928    /*
4929     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4930     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4931     * use the "softfp" ABI, this must be an instruction, not a function call.
4932     *
4933     * For: add-float, sub-float, mul-float, div-float
4934     */
4935    /* floatop vAA, vBB, vCC */
4936    FETCH(r0, 1)                        @ r0<- CCBB
4937    mov     r9, rINST, lsr #8           @ r9<- AA
4938    mov     r3, r0, lsr #8              @ r3<- CC
4939    and     r2, r0, #255                @ r2<- BB
4940    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4941    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4942    flds    s1, [r3]                    @ s1<- vCC
4943    flds    s0, [r2]                    @ s0<- vBB
4944
4945    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4946    fsubs   s2, s0, s1                              @ s2<- op
4947    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4948    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4949    fsts    s2, [r9]                    @ vAA<- s2
4950    GOTO_OPCODE(ip)                     @ jump to next instruction
4951
4952
4953/* ------------------------------ */
4954    .balign 64
4955.L_OP_MUL_FLOAT: /* 0xa8 */
4956/* File: arm-vfp/OP_MUL_FLOAT.S */
4957/* File: arm-vfp/fbinop.S */
4958    /*
4959     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4960     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4961     * use the "softfp" ABI, this must be an instruction, not a function call.
4962     *
4963     * For: add-float, sub-float, mul-float, div-float
4964     */
4965    /* floatop vAA, vBB, vCC */
4966    FETCH(r0, 1)                        @ r0<- CCBB
4967    mov     r9, rINST, lsr #8           @ r9<- AA
4968    mov     r3, r0, lsr #8              @ r3<- CC
4969    and     r2, r0, #255                @ r2<- BB
4970    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4971    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4972    flds    s1, [r3]                    @ s1<- vCC
4973    flds    s0, [r2]                    @ s0<- vBB
4974
4975    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4976    fmuls   s2, s0, s1                              @ s2<- op
4977    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4978    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4979    fsts    s2, [r9]                    @ vAA<- s2
4980    GOTO_OPCODE(ip)                     @ jump to next instruction
4981
4982
4983/* ------------------------------ */
4984    .balign 64
4985.L_OP_DIV_FLOAT: /* 0xa9 */
4986/* File: arm-vfp/OP_DIV_FLOAT.S */
4987/* File: arm-vfp/fbinop.S */
4988    /*
4989     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4990     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4991     * use the "softfp" ABI, this must be an instruction, not a function call.
4992     *
4993     * For: add-float, sub-float, mul-float, div-float
4994     */
4995    /* floatop vAA, vBB, vCC */
4996    FETCH(r0, 1)                        @ r0<- CCBB
4997    mov     r9, rINST, lsr #8           @ r9<- AA
4998    mov     r3, r0, lsr #8              @ r3<- CC
4999    and     r2, r0, #255                @ r2<- BB
5000    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5001    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5002    flds    s1, [r3]                    @ s1<- vCC
5003    flds    s0, [r2]                    @ s0<- vBB
5004
5005    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5006    fdivs   s2, s0, s1                              @ s2<- op
5007    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5008    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5009    fsts    s2, [r9]                    @ vAA<- s2
5010    GOTO_OPCODE(ip)                     @ jump to next instruction
5011
5012
5013/* ------------------------------ */
5014    .balign 64
5015.L_OP_REM_FLOAT: /* 0xaa */
5016/* File: armv5te/OP_REM_FLOAT.S */
5017/* EABI doesn't define a float remainder function, but libm does */
5018/* File: armv5te/binop.S */
5019    /*
5020     * Generic 32-bit binary operation.  Provide an "instr" line that
5021     * specifies an instruction that performs "result = r0 op r1".
5022     * This could be an ARM instruction or a function call.  (If the result
5023     * comes back in a register other than r0, you can override "result".)
5024     *
5025     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5026     * vCC (r1).  Useful for integer division and modulus.  Note that we
5027     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
5028     * handles it correctly.
5029     *
5030     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
5031     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
5032     *      mul-float, div-float, rem-float
5033     */
5034    /* binop vAA, vBB, vCC */
5035    FETCH(r0, 1)                        @ r0<- CCBB
5036    mov     r9, rINST, lsr #8           @ r9<- AA
5037    mov     r3, r0, lsr #8              @ r3<- CC
5038    and     r2, r0, #255                @ r2<- BB
5039    GET_VREG(r1, r3)                    @ r1<- vCC
5040    GET_VREG(r0, r2)                    @ r0<- vBB
5041    .if 0
5042    cmp     r1, #0                      @ is second operand zero?
5043    beq     common_errDivideByZero
5044    .endif
5045
5046    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5047                               @ optional op; may set condition codes
5048    bl      fmodf                              @ r0<- op, r0-r3 changed
5049    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5050    SET_VREG(r0, r9)               @ vAA<- r0
5051    GOTO_OPCODE(ip)                     @ jump to next instruction
5052    /* 11-14 instructions */
5053
5054
5055/* ------------------------------ */
5056    .balign 64
5057.L_OP_ADD_DOUBLE: /* 0xab */
5058/* File: arm-vfp/OP_ADD_DOUBLE.S */
5059/* File: arm-vfp/fbinopWide.S */
5060    /*
5061     * Generic 64-bit double-precision floating point binary operation.
5062     * Provide an "instr" line that specifies an instruction that performs
5063     * "d2 = d0 op d1".
5064     *
5065     * for: add-double, sub-double, mul-double, div-double
5066     */
5067    /* doubleop vAA, vBB, vCC */
5068    FETCH(r0, 1)                        @ r0<- CCBB
5069    mov     r9, rINST, lsr #8           @ r9<- AA
5070    mov     r3, r0, lsr #8              @ r3<- CC
5071    and     r2, r0, #255                @ r2<- BB
5072    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5073    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5074    fldd    d1, [r3]                    @ d1<- vCC
5075    fldd    d0, [r2]                    @ d0<- vBB
5076
5077    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5078    faddd   d2, d0, d1                              @ s2<- op
5079    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5080    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5081    fstd    d2, [r9]                    @ vAA<- d2
5082    GOTO_OPCODE(ip)                     @ jump to next instruction
5083
5084
5085/* ------------------------------ */
5086    .balign 64
5087.L_OP_SUB_DOUBLE: /* 0xac */
5088/* File: arm-vfp/OP_SUB_DOUBLE.S */
5089/* File: arm-vfp/fbinopWide.S */
5090    /*
5091     * Generic 64-bit double-precision floating point binary operation.
5092     * Provide an "instr" line that specifies an instruction that performs
5093     * "d2 = d0 op d1".
5094     *
5095     * for: add-double, sub-double, mul-double, div-double
5096     */
5097    /* doubleop vAA, vBB, vCC */
5098    FETCH(r0, 1)                        @ r0<- CCBB
5099    mov     r9, rINST, lsr #8           @ r9<- AA
5100    mov     r3, r0, lsr #8              @ r3<- CC
5101    and     r2, r0, #255                @ r2<- BB
5102    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5103    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5104    fldd    d1, [r3]                    @ d1<- vCC
5105    fldd    d0, [r2]                    @ d0<- vBB
5106
5107    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5108    fsubd   d2, d0, d1                              @ s2<- op
5109    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5110    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5111    fstd    d2, [r9]                    @ vAA<- d2
5112    GOTO_OPCODE(ip)                     @ jump to next instruction
5113
5114
5115/* ------------------------------ */
5116    .balign 64
5117.L_OP_MUL_DOUBLE: /* 0xad */
5118/* File: arm-vfp/OP_MUL_DOUBLE.S */
5119/* File: arm-vfp/fbinopWide.S */
5120    /*
5121     * Generic 64-bit double-precision floating point binary operation.
5122     * Provide an "instr" line that specifies an instruction that performs
5123     * "d2 = d0 op d1".
5124     *
5125     * for: add-double, sub-double, mul-double, div-double
5126     */
5127    /* doubleop vAA, vBB, vCC */
5128    FETCH(r0, 1)                        @ r0<- CCBB
5129    mov     r9, rINST, lsr #8           @ r9<- AA
5130    mov     r3, r0, lsr #8              @ r3<- CC
5131    and     r2, r0, #255                @ r2<- BB
5132    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5133    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5134    fldd    d1, [r3]                    @ d1<- vCC
5135    fldd    d0, [r2]                    @ d0<- vBB
5136
5137    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5138    fmuld   d2, d0, d1                              @ s2<- op
5139    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5140    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5141    fstd    d2, [r9]                    @ vAA<- d2
5142    GOTO_OPCODE(ip)                     @ jump to next instruction
5143
5144
5145/* ------------------------------ */
5146    .balign 64
5147.L_OP_DIV_DOUBLE: /* 0xae */
5148/* File: arm-vfp/OP_DIV_DOUBLE.S */
5149/* File: arm-vfp/fbinopWide.S */
5150    /*
5151     * Generic 64-bit double-precision floating point binary operation.
5152     * Provide an "instr" line that specifies an instruction that performs
5153     * "d2 = d0 op d1".
5154     *
5155     * for: add-double, sub-double, mul-double, div-double
5156     */
5157    /* doubleop vAA, vBB, vCC */
5158    FETCH(r0, 1)                        @ r0<- CCBB
5159    mov     r9, rINST, lsr #8           @ r9<- AA
5160    mov     r3, r0, lsr #8              @ r3<- CC
5161    and     r2, r0, #255                @ r2<- BB
5162    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5163    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5164    fldd    d1, [r3]                    @ d1<- vCC
5165    fldd    d0, [r2]                    @ d0<- vBB
5166
5167    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5168    fdivd   d2, d0, d1                              @ s2<- op
5169    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5170    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5171    fstd    d2, [r9]                    @ vAA<- d2
5172    GOTO_OPCODE(ip)                     @ jump to next instruction
5173
5174
5175/* ------------------------------ */
5176    .balign 64
5177.L_OP_REM_DOUBLE: /* 0xaf */
5178/* File: armv5te/OP_REM_DOUBLE.S */
5179/* EABI doesn't define a double remainder function, but libm does */
5180/* File: armv5te/binopWide.S */
5181    /*
5182     * Generic 64-bit binary operation.  Provide an "instr" line that
5183     * specifies an instruction that performs "result = r0-r1 op r2-r3".
5184     * This could be an ARM instruction or a function call.  (If the result
5185     * comes back in a register other than r0, you can override "result".)
5186     *
5187     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5188     * vCC (r1).  Useful for integer division and modulus.
5189     *
5190     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
5191     *      xor-long, add-double, sub-double, mul-double, div-double,
5192     *      rem-double
5193     *
5194     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
5195     */
5196    /* binop vAA, vBB, vCC */
5197    FETCH(r0, 1)                        @ r0<- CCBB
5198    mov     r9, rINST, lsr #8           @ r9<- AA
5199    and     r2, r0, #255                @ r2<- BB
5200    mov     r3, r0, lsr #8              @ r3<- CC
5201    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
5202    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
5203    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
5204    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
5205    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
5206    .if 0
5207    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5208    beq     common_errDivideByZero
5209    .endif
5210    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5211
5212                               @ optional op; may set condition codes
5213    bl      fmod                              @ result<- op, r0-r3 changed
5214    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5215    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5216    GOTO_OPCODE(ip)                     @ jump to next instruction
5217    /* 14-17 instructions */
5218
5219
5220/* ------------------------------ */
5221    .balign 64
5222.L_OP_ADD_INT_2ADDR: /* 0xb0 */
5223/* File: armv6t2/OP_ADD_INT_2ADDR.S */
5224/* File: armv6t2/binop2addr.S */
5225    /*
5226     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5227     * that specifies an instruction that performs "result = r0 op r1".
5228     * This could be an ARM instruction or a function call.  (If the result
5229     * comes back in a register other than r0, you can override "result".)
5230     *
5231     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5232     * vCC (r1).  Useful for integer division and modulus.
5233     *
5234     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5235     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5236     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5237     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5238     */
5239    /* binop/2addr vA, vB */
5240    mov     r3, rINST, lsr #12          @ r3<- B
5241    ubfx    r9, rINST, #8, #4           @ r9<- A
5242    GET_VREG(r1, r3)                    @ r1<- vB
5243    GET_VREG(r0, r9)                    @ r0<- vA
5244    .if 0
5245    cmp     r1, #0                      @ is second operand zero?
5246    beq     common_errDivideByZero
5247    .endif
5248    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5249
5250                               @ optional op; may set condition codes
5251    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
5252    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5253    SET_VREG(r0, r9)               @ vAA<- r0
5254    GOTO_OPCODE(ip)                     @ jump to next instruction
5255    /* 10-13 instructions */
5256
5257
5258/* ------------------------------ */
5259    .balign 64
5260.L_OP_SUB_INT_2ADDR: /* 0xb1 */
5261/* File: armv6t2/OP_SUB_INT_2ADDR.S */
5262/* File: armv6t2/binop2addr.S */
5263    /*
5264     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5265     * that specifies an instruction that performs "result = r0 op r1".
5266     * This could be an ARM instruction or a function call.  (If the result
5267     * comes back in a register other than r0, you can override "result".)
5268     *
5269     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5270     * vCC (r1).  Useful for integer division and modulus.
5271     *
5272     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5273     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5274     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5275     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5276     */
5277    /* binop/2addr vA, vB */
5278    mov     r3, rINST, lsr #12          @ r3<- B
5279    ubfx    r9, rINST, #8, #4           @ r9<- A
5280    GET_VREG(r1, r3)                    @ r1<- vB
5281    GET_VREG(r0, r9)                    @ r0<- vA
5282    .if 0
5283    cmp     r1, #0                      @ is second operand zero?
5284    beq     common_errDivideByZero
5285    .endif
5286    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5287
5288                               @ optional op; may set condition codes
5289    sub     r0, r0, r1                              @ r0<- op, r0-r3 changed
5290    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5291    SET_VREG(r0, r9)               @ vAA<- r0
5292    GOTO_OPCODE(ip)                     @ jump to next instruction
5293    /* 10-13 instructions */
5294
5295
5296/* ------------------------------ */
5297    .balign 64
5298.L_OP_MUL_INT_2ADDR: /* 0xb2 */
5299/* File: armv6t2/OP_MUL_INT_2ADDR.S */
5300/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
5301/* File: armv6t2/binop2addr.S */
5302    /*
5303     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5304     * that specifies an instruction that performs "result = r0 op r1".
5305     * This could be an ARM instruction or a function call.  (If the result
5306     * comes back in a register other than r0, you can override "result".)
5307     *
5308     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5309     * vCC (r1).  Useful for integer division and modulus.
5310     *
5311     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5312     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5313     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5314     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5315     */
5316    /* binop/2addr vA, vB */
5317    mov     r3, rINST, lsr #12          @ r3<- B
5318    ubfx    r9, rINST, #8, #4           @ r9<- A
5319    GET_VREG(r1, r3)                    @ r1<- vB
5320    GET_VREG(r0, r9)                    @ r0<- vA
5321    .if 0
5322    cmp     r1, #0                      @ is second operand zero?
5323    beq     common_errDivideByZero
5324    .endif
5325    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5326
5327                               @ optional op; may set condition codes
5328    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
5329    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5330    SET_VREG(r0, r9)               @ vAA<- r0
5331    GOTO_OPCODE(ip)                     @ jump to next instruction
5332    /* 10-13 instructions */
5333
5334
5335/* ------------------------------ */
5336    .balign 64
5337.L_OP_DIV_INT_2ADDR: /* 0xb3 */
5338/* File: armv6t2/OP_DIV_INT_2ADDR.S */
5339/* File: armv6t2/binop2addr.S */
5340    /*
5341     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5342     * that specifies an instruction that performs "result = r0 op r1".
5343     * This could be an ARM instruction or a function call.  (If the result
5344     * comes back in a register other than r0, you can override "result".)
5345     *
5346     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5347     * vCC (r1).  Useful for integer division and modulus.
5348     *
5349     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5350     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5351     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5352     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5353     */
5354    /* binop/2addr vA, vB */
5355    mov     r3, rINST, lsr #12          @ r3<- B
5356    ubfx    r9, rINST, #8, #4           @ r9<- A
5357    GET_VREG(r1, r3)                    @ r1<- vB
5358    GET_VREG(r0, r9)                    @ r0<- vA
5359    .if 1
5360    cmp     r1, #0                      @ is second operand zero?
5361    beq     common_errDivideByZero
5362    .endif
5363    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5364
5365                               @ optional op; may set condition codes
5366    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
5367    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5368    SET_VREG(r0, r9)               @ vAA<- r0
5369    GOTO_OPCODE(ip)                     @ jump to next instruction
5370    /* 10-13 instructions */
5371
5372
5373/* ------------------------------ */
5374    .balign 64
5375.L_OP_REM_INT_2ADDR: /* 0xb4 */
5376/* File: armv6t2/OP_REM_INT_2ADDR.S */
5377/* idivmod returns quotient in r0 and remainder in r1 */
5378/* File: armv6t2/binop2addr.S */
5379    /*
5380     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5381     * that specifies an instruction that performs "result = r0 op r1".
5382     * This could be an ARM instruction or a function call.  (If the result
5383     * comes back in a register other than r0, you can override "result".)
5384     *
5385     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5386     * vCC (r1).  Useful for integer division and modulus.
5387     *
5388     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5389     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5390     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5391     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5392     */
5393    /* binop/2addr vA, vB */
5394    mov     r3, rINST, lsr #12          @ r3<- B
5395    ubfx    r9, rINST, #8, #4           @ r9<- A
5396    GET_VREG(r1, r3)                    @ r1<- vB
5397    GET_VREG(r0, r9)                    @ r0<- vA
5398    .if 1
5399    cmp     r1, #0                      @ is second operand zero?
5400    beq     common_errDivideByZero
5401    .endif
5402    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5403
5404                               @ optional op; may set condition codes
5405    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
5406    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5407    SET_VREG(r1, r9)               @ vAA<- r1
5408    GOTO_OPCODE(ip)                     @ jump to next instruction
5409    /* 10-13 instructions */
5410
5411
5412/* ------------------------------ */
5413    .balign 64
5414.L_OP_AND_INT_2ADDR: /* 0xb5 */
5415/* File: armv6t2/OP_AND_INT_2ADDR.S */
5416/* File: armv6t2/binop2addr.S */
5417    /*
5418     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5419     * that specifies an instruction that performs "result = r0 op r1".
5420     * This could be an ARM instruction or a function call.  (If the result
5421     * comes back in a register other than r0, you can override "result".)
5422     *
5423     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5424     * vCC (r1).  Useful for integer division and modulus.
5425     *
5426     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5427     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5428     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5429     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5430     */
5431    /* binop/2addr vA, vB */
5432    mov     r3, rINST, lsr #12          @ r3<- B
5433    ubfx    r9, rINST, #8, #4           @ r9<- A
5434    GET_VREG(r1, r3)                    @ r1<- vB
5435    GET_VREG(r0, r9)                    @ r0<- vA
5436    .if 0
5437    cmp     r1, #0                      @ is second operand zero?
5438    beq     common_errDivideByZero
5439    .endif
5440    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5441
5442                               @ optional op; may set condition codes
5443    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
5444    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5445    SET_VREG(r0, r9)               @ vAA<- r0
5446    GOTO_OPCODE(ip)                     @ jump to next instruction
5447    /* 10-13 instructions */
5448
5449
5450/* ------------------------------ */
5451    .balign 64
5452.L_OP_OR_INT_2ADDR: /* 0xb6 */
5453/* File: armv6t2/OP_OR_INT_2ADDR.S */
5454/* File: armv6t2/binop2addr.S */
5455    /*
5456     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5457     * that specifies an instruction that performs "result = r0 op r1".
5458     * This could be an ARM instruction or a function call.  (If the result
5459     * comes back in a register other than r0, you can override "result".)
5460     *
5461     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5462     * vCC (r1).  Useful for integer division and modulus.
5463     *
5464     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5465     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5466     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5467     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5468     */
5469    /* binop/2addr vA, vB */
5470    mov     r3, rINST, lsr #12          @ r3<- B
5471    ubfx    r9, rINST, #8, #4           @ r9<- A
5472    GET_VREG(r1, r3)                    @ r1<- vB
5473    GET_VREG(r0, r9)                    @ r0<- vA
5474    .if 0
5475    cmp     r1, #0                      @ is second operand zero?
5476    beq     common_errDivideByZero
5477    .endif
5478    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5479
5480                               @ optional op; may set condition codes
5481    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
5482    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5483    SET_VREG(r0, r9)               @ vAA<- r0
5484    GOTO_OPCODE(ip)                     @ jump to next instruction
5485    /* 10-13 instructions */
5486
5487
5488/* ------------------------------ */
5489    .balign 64
5490.L_OP_XOR_INT_2ADDR: /* 0xb7 */
5491/* File: armv6t2/OP_XOR_INT_2ADDR.S */
5492/* File: armv6t2/binop2addr.S */
5493    /*
5494     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5495     * that specifies an instruction that performs "result = r0 op r1".
5496     * This could be an ARM instruction or a function call.  (If the result
5497     * comes back in a register other than r0, you can override "result".)
5498     *
5499     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5500     * vCC (r1).  Useful for integer division and modulus.
5501     *
5502     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5503     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5504     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5505     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5506     */
5507    /* binop/2addr vA, vB */
5508    mov     r3, rINST, lsr #12          @ r3<- B
5509    ubfx    r9, rINST, #8, #4           @ r9<- A
5510    GET_VREG(r1, r3)                    @ r1<- vB
5511    GET_VREG(r0, r9)                    @ r0<- vA
5512    .if 0
5513    cmp     r1, #0                      @ is second operand zero?
5514    beq     common_errDivideByZero
5515    .endif
5516    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5517
5518                               @ optional op; may set condition codes
5519    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
5520    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5521    SET_VREG(r0, r9)               @ vAA<- r0
5522    GOTO_OPCODE(ip)                     @ jump to next instruction
5523    /* 10-13 instructions */
5524
5525
5526/* ------------------------------ */
5527    .balign 64
5528.L_OP_SHL_INT_2ADDR: /* 0xb8 */
5529/* File: armv6t2/OP_SHL_INT_2ADDR.S */
5530/* File: armv6t2/binop2addr.S */
5531    /*
5532     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5533     * that specifies an instruction that performs "result = r0 op r1".
5534     * This could be an ARM instruction or a function call.  (If the result
5535     * comes back in a register other than r0, you can override "result".)
5536     *
5537     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5538     * vCC (r1).  Useful for integer division and modulus.
5539     *
5540     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5541     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5542     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5543     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5544     */
5545    /* binop/2addr vA, vB */
5546    mov     r3, rINST, lsr #12          @ r3<- B
5547    ubfx    r9, rINST, #8, #4           @ r9<- A
5548    GET_VREG(r1, r3)                    @ r1<- vB
5549    GET_VREG(r0, r9)                    @ r0<- vA
5550    .if 0
5551    cmp     r1, #0                      @ is second operand zero?
5552    beq     common_errDivideByZero
5553    .endif
5554    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5555
5556    and     r1, r1, #31                           @ optional op; may set condition codes
5557    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
5558    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5559    SET_VREG(r0, r9)               @ vAA<- r0
5560    GOTO_OPCODE(ip)                     @ jump to next instruction
5561    /* 10-13 instructions */
5562
5563
5564/* ------------------------------ */
5565    .balign 64
5566.L_OP_SHR_INT_2ADDR: /* 0xb9 */
5567/* File: armv6t2/OP_SHR_INT_2ADDR.S */
5568/* File: armv6t2/binop2addr.S */
5569    /*
5570     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5571     * that specifies an instruction that performs "result = r0 op r1".
5572     * This could be an ARM instruction or a function call.  (If the result
5573     * comes back in a register other than r0, you can override "result".)
5574     *
5575     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5576     * vCC (r1).  Useful for integer division and modulus.
5577     *
5578     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5579     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5580     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5581     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5582     */
5583    /* binop/2addr vA, vB */
5584    mov     r3, rINST, lsr #12          @ r3<- B
5585    ubfx    r9, rINST, #8, #4           @ r9<- A
5586    GET_VREG(r1, r3)                    @ r1<- vB
5587    GET_VREG(r0, r9)                    @ r0<- vA
5588    .if 0
5589    cmp     r1, #0                      @ is second operand zero?
5590    beq     common_errDivideByZero
5591    .endif
5592    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5593
5594    and     r1, r1, #31                           @ optional op; may set condition codes
5595    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
5596    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5597    SET_VREG(r0, r9)               @ vAA<- r0
5598    GOTO_OPCODE(ip)                     @ jump to next instruction
5599    /* 10-13 instructions */
5600
5601
5602/* ------------------------------ */
5603    .balign 64
5604.L_OP_USHR_INT_2ADDR: /* 0xba */
5605/* File: armv6t2/OP_USHR_INT_2ADDR.S */
5606/* File: armv6t2/binop2addr.S */
5607    /*
5608     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5609     * that specifies an instruction that performs "result = r0 op r1".
5610     * This could be an ARM instruction or a function call.  (If the result
5611     * comes back in a register other than r0, you can override "result".)
5612     *
5613     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5614     * vCC (r1).  Useful for integer division and modulus.
5615     *
5616     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5617     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5618     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5619     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5620     */
5621    /* binop/2addr vA, vB */
5622    mov     r3, rINST, lsr #12          @ r3<- B
5623    ubfx    r9, rINST, #8, #4           @ r9<- A
5624    GET_VREG(r1, r3)                    @ r1<- vB
5625    GET_VREG(r0, r9)                    @ r0<- vA
5626    .if 0
5627    cmp     r1, #0                      @ is second operand zero?
5628    beq     common_errDivideByZero
5629    .endif
5630    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5631
5632    and     r1, r1, #31                           @ optional op; may set condition codes
5633    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
5634    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5635    SET_VREG(r0, r9)               @ vAA<- r0
5636    GOTO_OPCODE(ip)                     @ jump to next instruction
5637    /* 10-13 instructions */
5638
5639
5640/* ------------------------------ */
5641    .balign 64
5642.L_OP_ADD_LONG_2ADDR: /* 0xbb */
5643/* File: armv6t2/OP_ADD_LONG_2ADDR.S */
5644/* File: armv6t2/binopWide2addr.S */
5645    /*
5646     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5647     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5648     * This could be an ARM instruction or a function call.  (If the result
5649     * comes back in a register other than r0, you can override "result".)
5650     *
5651     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5652     * vCC (r1).  Useful for integer division and modulus.
5653     *
5654     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5655     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5656     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5657     *      rem-double/2addr
5658     */
5659    /* binop/2addr vA, vB */
5660    mov     r1, rINST, lsr #12          @ r1<- B
5661    ubfx    r9, rINST, #8, #4           @ r9<- A
5662    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5663    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5664    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5665    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5666    .if 0
5667    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5668    beq     common_errDivideByZero
5669    .endif
5670    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5671
5672    adds    r0, r0, r2                           @ optional op; may set condition codes
5673    adc     r1, r1, r3                              @ result<- op, r0-r3 changed
5674    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5675    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5676    GOTO_OPCODE(ip)                     @ jump to next instruction
5677    /* 12-15 instructions */
5678
5679
5680/* ------------------------------ */
5681    .balign 64
5682.L_OP_SUB_LONG_2ADDR: /* 0xbc */
5683/* File: armv6t2/OP_SUB_LONG_2ADDR.S */
5684/* File: armv6t2/binopWide2addr.S */
5685    /*
5686     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5687     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5688     * This could be an ARM instruction or a function call.  (If the result
5689     * comes back in a register other than r0, you can override "result".)
5690     *
5691     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5692     * vCC (r1).  Useful for integer division and modulus.
5693     *
5694     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5695     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5696     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5697     *      rem-double/2addr
5698     */
5699    /* binop/2addr vA, vB */
5700    mov     r1, rINST, lsr #12          @ r1<- B
5701    ubfx    r9, rINST, #8, #4           @ r9<- A
5702    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5703    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5704    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5705    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5706    .if 0
5707    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5708    beq     common_errDivideByZero
5709    .endif
5710    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5711
5712    subs    r0, r0, r2                           @ optional op; may set condition codes
5713    sbc     r1, r1, r3                              @ result<- op, r0-r3 changed
5714    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5715    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5716    GOTO_OPCODE(ip)                     @ jump to next instruction
5717    /* 12-15 instructions */
5718
5719
5720/* ------------------------------ */
5721    .balign 64
5722.L_OP_MUL_LONG_2ADDR: /* 0xbd */
5723/* File: armv6t2/OP_MUL_LONG_2ADDR.S */
5724    /*
5725     * Signed 64-bit integer multiply, "/2addr" version.
5726     *
5727     * See OP_MUL_LONG for an explanation.
5728     *
5729     * We get a little tight on registers, so to avoid looking up &fp[A]
5730     * again we stuff it into rINST.
5731     */
5732    /* mul-long/2addr vA, vB */
5733    mov     r1, rINST, lsr #12          @ r1<- B
5734    ubfx    r9, rINST, #8, #4           @ r9<- A
5735    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5736    add     rINST, rFP, r9, lsl #2      @ rINST<- &fp[A]
5737    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5738    ldmia   rINST, {r0-r1}              @ r0/r1<- vAA/vAA+1
5739    mul     ip, r2, r1                  @  ip<- ZxW
5740    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
5741    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
5742    mov     r0, rINST                   @ r0<- &fp[A] (free up rINST)
5743    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5744    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
5745    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5746    stmia   r0, {r9-r10}                @ vAA/vAA+1<- r9/r10
5747    GOTO_OPCODE(ip)                     @ jump to next instruction
5748
5749/* ------------------------------ */
5750    .balign 64
5751.L_OP_DIV_LONG_2ADDR: /* 0xbe */
5752/* File: armv6t2/OP_DIV_LONG_2ADDR.S */
5753/* File: armv6t2/binopWide2addr.S */
5754    /*
5755     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5756     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5757     * This could be an ARM instruction or a function call.  (If the result
5758     * comes back in a register other than r0, you can override "result".)
5759     *
5760     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5761     * vCC (r1).  Useful for integer division and modulus.
5762     *
5763     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5764     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5765     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5766     *      rem-double/2addr
5767     */
5768    /* binop/2addr vA, vB */
5769    mov     r1, rINST, lsr #12          @ r1<- B
5770    ubfx    r9, rINST, #8, #4           @ r9<- A
5771    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5772    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5773    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5774    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5775    .if 1
5776    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5777    beq     common_errDivideByZero
5778    .endif
5779    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5780
5781                               @ optional op; may set condition codes
5782    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
5783    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5784    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5785    GOTO_OPCODE(ip)                     @ jump to next instruction
5786    /* 12-15 instructions */
5787
5788
5789/* ------------------------------ */
5790    .balign 64
5791.L_OP_REM_LONG_2ADDR: /* 0xbf */
5792/* File: armv6t2/OP_REM_LONG_2ADDR.S */
5793/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
5794/* File: armv6t2/binopWide2addr.S */
5795    /*
5796     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5797     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5798     * This could be an ARM instruction or a function call.  (If the result
5799     * comes back in a register other than r0, you can override "result".)
5800     *
5801     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5802     * vCC (r1).  Useful for integer division and modulus.
5803     *
5804     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5805     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5806     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5807     *      rem-double/2addr
5808     */
5809    /* binop/2addr vA, vB */
5810    mov     r1, rINST, lsr #12          @ r1<- B
5811    ubfx    r9, rINST, #8, #4           @ r9<- A
5812    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5813    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5814    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5815    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5816    .if 1
5817    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5818    beq     common_errDivideByZero
5819    .endif
5820    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5821
5822                               @ optional op; may set condition codes
5823    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
5824    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5825    stmia   r9, {r2,r3}     @ vAA/vAA+1<- r2/r3
5826    GOTO_OPCODE(ip)                     @ jump to next instruction
5827    /* 12-15 instructions */
5828
5829
5830/* ------------------------------ */
5831    .balign 64
5832.L_OP_AND_LONG_2ADDR: /* 0xc0 */
5833/* File: armv6t2/OP_AND_LONG_2ADDR.S */
5834/* File: armv6t2/binopWide2addr.S */
5835    /*
5836     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5837     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5838     * This could be an ARM instruction or a function call.  (If the result
5839     * comes back in a register other than r0, you can override "result".)
5840     *
5841     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5842     * vCC (r1).  Useful for integer division and modulus.
5843     *
5844     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5845     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5846     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5847     *      rem-double/2addr
5848     */
5849    /* binop/2addr vA, vB */
5850    mov     r1, rINST, lsr #12          @ r1<- B
5851    ubfx    r9, rINST, #8, #4           @ r9<- A
5852    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5853    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5854    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5855    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5856    .if 0
5857    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5858    beq     common_errDivideByZero
5859    .endif
5860    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5861
5862    and     r0, r0, r2                           @ optional op; may set condition codes
5863    and     r1, r1, r3                              @ result<- op, r0-r3 changed
5864    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5865    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5866    GOTO_OPCODE(ip)                     @ jump to next instruction
5867    /* 12-15 instructions */
5868
5869
5870/* ------------------------------ */
5871    .balign 64
5872.L_OP_OR_LONG_2ADDR: /* 0xc1 */
5873/* File: armv6t2/OP_OR_LONG_2ADDR.S */
5874/* File: armv6t2/binopWide2addr.S */
5875    /*
5876     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5877     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5878     * This could be an ARM instruction or a function call.  (If the result
5879     * comes back in a register other than r0, you can override "result".)
5880     *
5881     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5882     * vCC (r1).  Useful for integer division and modulus.
5883     *
5884     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5885     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5886     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5887     *      rem-double/2addr
5888     */
5889    /* binop/2addr vA, vB */
5890    mov     r1, rINST, lsr #12          @ r1<- B
5891    ubfx    r9, rINST, #8, #4           @ r9<- A
5892    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5893    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5894    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5895    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5896    .if 0
5897    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5898    beq     common_errDivideByZero
5899    .endif
5900    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5901
5902    orr     r0, r0, r2                           @ optional op; may set condition codes
5903    orr     r1, r1, r3                              @ result<- op, r0-r3 changed
5904    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5905    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5906    GOTO_OPCODE(ip)                     @ jump to next instruction
5907    /* 12-15 instructions */
5908
5909
5910/* ------------------------------ */
5911    .balign 64
5912.L_OP_XOR_LONG_2ADDR: /* 0xc2 */
5913/* File: armv6t2/OP_XOR_LONG_2ADDR.S */
5914/* File: armv6t2/binopWide2addr.S */
5915    /*
5916     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5917     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5918     * This could be an ARM instruction or a function call.  (If the result
5919     * comes back in a register other than r0, you can override "result".)
5920     *
5921     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5922     * vCC (r1).  Useful for integer division and modulus.
5923     *
5924     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5925     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5926     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5927     *      rem-double/2addr
5928     */
5929    /* binop/2addr vA, vB */
5930    mov     r1, rINST, lsr #12          @ r1<- B
5931    ubfx    r9, rINST, #8, #4           @ r9<- A
5932    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5933    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5934    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5935    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5936    .if 0
5937    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5938    beq     common_errDivideByZero
5939    .endif
5940    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5941
5942    eor     r0, r0, r2                           @ optional op; may set condition codes
5943    eor     r1, r1, r3                              @ result<- op, r0-r3 changed
5944    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5945    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5946    GOTO_OPCODE(ip)                     @ jump to next instruction
5947    /* 12-15 instructions */
5948
5949
5950/* ------------------------------ */
5951    .balign 64
5952.L_OP_SHL_LONG_2ADDR: /* 0xc3 */
5953/* File: armv6t2/OP_SHL_LONG_2ADDR.S */
5954    /*
5955     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
5956     * 32-bit shift distance.
5957     */
5958    /* shl-long/2addr vA, vB */
5959    mov     r3, rINST, lsr #12          @ r3<- B
5960    ubfx    r9, rINST, #8, #4           @ r9<- A
5961    GET_VREG(r2, r3)                    @ r2<- vB
5962    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5963    and     r2, r2, #63                 @ r2<- r2 & 0x3f
5964    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5965
5966    mov     r1, r1, asl r2              @  r1<- r1 << r2
5967    rsb     r3, r2, #32                 @  r3<- 32 - r2
5968    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
5969    subs    ip, r2, #32                 @  ip<- r2 - 32
5970    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5971    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
5972    mov     r0, r0, asl r2              @  r0<- r0 << r2
5973    b       .LOP_SHL_LONG_2ADDR_finish
5974
5975/* ------------------------------ */
5976    .balign 64
5977.L_OP_SHR_LONG_2ADDR: /* 0xc4 */
5978/* File: armv6t2/OP_SHR_LONG_2ADDR.S */
5979    /*
5980     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
5981     * 32-bit shift distance.
5982     */
5983    /* shr-long/2addr vA, vB */
5984    mov     r3, rINST, lsr #12          @ r3<- B
5985    ubfx    r9, rINST, #8, #4           @ r9<- A
5986    GET_VREG(r2, r3)                    @ r2<- vB
5987    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5988    and     r2, r2, #63                 @ r2<- r2 & 0x3f
5989    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5990
5991    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
5992    rsb     r3, r2, #32                 @  r3<- 32 - r2
5993    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
5994    subs    ip, r2, #32                 @  ip<- r2 - 32
5995    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5996    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
5997    mov     r1, r1, asr r2              @  r1<- r1 >> r2
5998    b       .LOP_SHR_LONG_2ADDR_finish
5999
6000/* ------------------------------ */
6001    .balign 64
6002.L_OP_USHR_LONG_2ADDR: /* 0xc5 */
6003/* File: armv6t2/OP_USHR_LONG_2ADDR.S */
6004    /*
6005     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6006     * 32-bit shift distance.
6007     */
6008    /* ushr-long/2addr vA, vB */
6009    mov     r3, rINST, lsr #12          @ r3<- B
6010    ubfx    r9, rINST, #8, #4           @ r9<- A
6011    GET_VREG(r2, r3)                    @ r2<- vB
6012    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6013    and     r2, r2, #63                 @ r2<- r2 & 0x3f
6014    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6015
6016    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
6017    rsb     r3, r2, #32                 @  r3<- 32 - r2
6018    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
6019    subs    ip, r2, #32                 @  ip<- r2 - 32
6020    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6021    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
6022    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
6023    b       .LOP_USHR_LONG_2ADDR_finish
6024
6025/* ------------------------------ */
6026    .balign 64
6027.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
6028/* File: arm-vfp/OP_ADD_FLOAT_2ADDR.S */
6029/* File: arm-vfp/fbinop2addr.S */
6030    /*
6031     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6032     * an "instr" line that specifies an instruction that performs
6033     * "s2 = s0 op s1".
6034     *
6035     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6036     */
6037    /* binop/2addr vA, vB */
6038    mov     r3, rINST, lsr #12          @ r3<- B
6039    mov     r9, rINST, lsr #8           @ r9<- A+
6040    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6041    and     r9, r9, #15                 @ r9<- A
6042    flds    s1, [r3]                    @ s1<- vB
6043    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6044    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6045    flds    s0, [r9]                    @ s0<- vA
6046
6047    fadds   s2, s0, s1                              @ s2<- op
6048    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6049    fsts    s2, [r9]                    @ vAA<- s2
6050    GOTO_OPCODE(ip)                     @ jump to next instruction
6051
6052
6053/* ------------------------------ */
6054    .balign 64
6055.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
6056/* File: arm-vfp/OP_SUB_FLOAT_2ADDR.S */
6057/* File: arm-vfp/fbinop2addr.S */
6058    /*
6059     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6060     * an "instr" line that specifies an instruction that performs
6061     * "s2 = s0 op s1".
6062     *
6063     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6064     */
6065    /* binop/2addr vA, vB */
6066    mov     r3, rINST, lsr #12          @ r3<- B
6067    mov     r9, rINST, lsr #8           @ r9<- A+
6068    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6069    and     r9, r9, #15                 @ r9<- A
6070    flds    s1, [r3]                    @ s1<- vB
6071    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6072    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6073    flds    s0, [r9]                    @ s0<- vA
6074
6075    fsubs   s2, s0, s1                              @ s2<- op
6076    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6077    fsts    s2, [r9]                    @ vAA<- s2
6078    GOTO_OPCODE(ip)                     @ jump to next instruction
6079
6080
6081/* ------------------------------ */
6082    .balign 64
6083.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
6084/* File: arm-vfp/OP_MUL_FLOAT_2ADDR.S */
6085/* File: arm-vfp/fbinop2addr.S */
6086    /*
6087     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6088     * an "instr" line that specifies an instruction that performs
6089     * "s2 = s0 op s1".
6090     *
6091     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6092     */
6093    /* binop/2addr vA, vB */
6094    mov     r3, rINST, lsr #12          @ r3<- B
6095    mov     r9, rINST, lsr #8           @ r9<- A+
6096    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6097    and     r9, r9, #15                 @ r9<- A
6098    flds    s1, [r3]                    @ s1<- vB
6099    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6100    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6101    flds    s0, [r9]                    @ s0<- vA
6102
6103    fmuls   s2, s0, s1                              @ s2<- op
6104    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6105    fsts    s2, [r9]                    @ vAA<- s2
6106    GOTO_OPCODE(ip)                     @ jump to next instruction
6107
6108
6109/* ------------------------------ */
6110    .balign 64
6111.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
6112/* File: arm-vfp/OP_DIV_FLOAT_2ADDR.S */
6113/* File: arm-vfp/fbinop2addr.S */
6114    /*
6115     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6116     * an "instr" line that specifies an instruction that performs
6117     * "s2 = s0 op s1".
6118     *
6119     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6120     */
6121    /* binop/2addr vA, vB */
6122    mov     r3, rINST, lsr #12          @ r3<- B
6123    mov     r9, rINST, lsr #8           @ r9<- A+
6124    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6125    and     r9, r9, #15                 @ r9<- A
6126    flds    s1, [r3]                    @ s1<- vB
6127    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6128    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6129    flds    s0, [r9]                    @ s0<- vA
6130
6131    fdivs   s2, s0, s1                              @ s2<- op
6132    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6133    fsts    s2, [r9]                    @ vAA<- s2
6134    GOTO_OPCODE(ip)                     @ jump to next instruction
6135
6136
6137/* ------------------------------ */
6138    .balign 64
6139.L_OP_REM_FLOAT_2ADDR: /* 0xca */
6140/* File: armv6t2/OP_REM_FLOAT_2ADDR.S */
6141/* EABI doesn't define a float remainder function, but libm does */
6142/* File: armv6t2/binop2addr.S */
6143    /*
6144     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6145     * that specifies an instruction that performs "result = r0 op r1".
6146     * This could be an ARM instruction or a function call.  (If the result
6147     * comes back in a register other than r0, you can override "result".)
6148     *
6149     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6150     * vCC (r1).  Useful for integer division and modulus.
6151     *
6152     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6153     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6154     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6155     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6156     */
6157    /* binop/2addr vA, vB */
6158    mov     r3, rINST, lsr #12          @ r3<- B
6159    ubfx    r9, rINST, #8, #4           @ r9<- A
6160    GET_VREG(r1, r3)                    @ r1<- vB
6161    GET_VREG(r0, r9)                    @ r0<- vA
6162    .if 0
6163    cmp     r1, #0                      @ is second operand zero?
6164    beq     common_errDivideByZero
6165    .endif
6166    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6167
6168                               @ optional op; may set condition codes
6169    bl      fmodf                              @ r0<- op, r0-r3 changed
6170    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6171    SET_VREG(r0, r9)               @ vAA<- r0
6172    GOTO_OPCODE(ip)                     @ jump to next instruction
6173    /* 10-13 instructions */
6174
6175
6176/* ------------------------------ */
6177    .balign 64
6178.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
6179/* File: arm-vfp/OP_ADD_DOUBLE_2ADDR.S */
6180/* File: arm-vfp/fbinopWide2addr.S */
6181    /*
6182     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6183     * an "instr" line that specifies an instruction that performs
6184     * "d2 = d0 op d1".
6185     *
6186     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6187     *      div-double/2addr
6188     */
6189    /* binop/2addr vA, vB */
6190    mov     r3, rINST, lsr #12          @ r3<- B
6191    mov     r9, rINST, lsr #8           @ r9<- A+
6192    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6193    and     r9, r9, #15                 @ r9<- A
6194    fldd    d1, [r3]                    @ d1<- vB
6195    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6196    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6197    fldd    d0, [r9]                    @ d0<- vA
6198
6199    faddd   d2, d0, d1                              @ d2<- op
6200    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6201    fstd    d2, [r9]                    @ vAA<- d2
6202    GOTO_OPCODE(ip)                     @ jump to next instruction
6203
6204
6205/* ------------------------------ */
6206    .balign 64
6207.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
6208/* File: arm-vfp/OP_SUB_DOUBLE_2ADDR.S */
6209/* File: arm-vfp/fbinopWide2addr.S */
6210    /*
6211     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6212     * an "instr" line that specifies an instruction that performs
6213     * "d2 = d0 op d1".
6214     *
6215     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6216     *      div-double/2addr
6217     */
6218    /* binop/2addr vA, vB */
6219    mov     r3, rINST, lsr #12          @ r3<- B
6220    mov     r9, rINST, lsr #8           @ r9<- A+
6221    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6222    and     r9, r9, #15                 @ r9<- A
6223    fldd    d1, [r3]                    @ d1<- vB
6224    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6225    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6226    fldd    d0, [r9]                    @ d0<- vA
6227
6228    fsubd   d2, d0, d1                              @ d2<- op
6229    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6230    fstd    d2, [r9]                    @ vAA<- d2
6231    GOTO_OPCODE(ip)                     @ jump to next instruction
6232
6233
6234/* ------------------------------ */
6235    .balign 64
6236.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
6237/* File: arm-vfp/OP_MUL_DOUBLE_2ADDR.S */
6238/* File: arm-vfp/fbinopWide2addr.S */
6239    /*
6240     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6241     * an "instr" line that specifies an instruction that performs
6242     * "d2 = d0 op d1".
6243     *
6244     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6245     *      div-double/2addr
6246     */
6247    /* binop/2addr vA, vB */
6248    mov     r3, rINST, lsr #12          @ r3<- B
6249    mov     r9, rINST, lsr #8           @ r9<- A+
6250    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6251    and     r9, r9, #15                 @ r9<- A
6252    fldd    d1, [r3]                    @ d1<- vB
6253    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6254    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6255    fldd    d0, [r9]                    @ d0<- vA
6256
6257    fmuld   d2, d0, d1                              @ d2<- op
6258    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6259    fstd    d2, [r9]                    @ vAA<- d2
6260    GOTO_OPCODE(ip)                     @ jump to next instruction
6261
6262
6263/* ------------------------------ */
6264    .balign 64
6265.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */
6266/* File: arm-vfp/OP_DIV_DOUBLE_2ADDR.S */
6267/* File: arm-vfp/fbinopWide2addr.S */
6268    /*
6269     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6270     * an "instr" line that specifies an instruction that performs
6271     * "d2 = d0 op d1".
6272     *
6273     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6274     *      div-double/2addr
6275     */
6276    /* binop/2addr vA, vB */
6277    mov     r3, rINST, lsr #12          @ r3<- B
6278    mov     r9, rINST, lsr #8           @ r9<- A+
6279    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6280    and     r9, r9, #15                 @ r9<- A
6281    fldd    d1, [r3]                    @ d1<- vB
6282    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6283    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6284    fldd    d0, [r9]                    @ d0<- vA
6285
6286    fdivd   d2, d0, d1                              @ d2<- op
6287    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6288    fstd    d2, [r9]                    @ vAA<- d2
6289    GOTO_OPCODE(ip)                     @ jump to next instruction
6290
6291
6292/* ------------------------------ */
6293    .balign 64
6294.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */
6295/* File: armv6t2/OP_REM_DOUBLE_2ADDR.S */
6296/* EABI doesn't define a double remainder function, but libm does */
6297/* File: armv6t2/binopWide2addr.S */
6298    /*
6299     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6300     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6301     * This could be an ARM instruction or a function call.  (If the result
6302     * comes back in a register other than r0, you can override "result".)
6303     *
6304     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6305     * vCC (r1).  Useful for integer division and modulus.
6306     *
6307     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6308     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6309     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6310     *      rem-double/2addr
6311     */
6312    /* binop/2addr vA, vB */
6313    mov     r1, rINST, lsr #12          @ r1<- B
6314    ubfx    r9, rINST, #8, #4           @ r9<- A
6315    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6316    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6317    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6318    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6319    .if 0
6320    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6321    beq     common_errDivideByZero
6322    .endif
6323    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6324
6325                               @ optional op; may set condition codes
6326    bl      fmod                              @ result<- op, r0-r3 changed
6327    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6328    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6329    GOTO_OPCODE(ip)                     @ jump to next instruction
6330    /* 12-15 instructions */
6331
6332
6333/* ------------------------------ */
6334    .balign 64
6335.L_OP_ADD_INT_LIT16: /* 0xd0 */
6336/* File: armv6t2/OP_ADD_INT_LIT16.S */
6337/* File: armv6t2/binopLit16.S */
6338    /*
6339     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6340     * that specifies an instruction that performs "result = r0 op r1".
6341     * This could be an ARM instruction or a function call.  (If the result
6342     * comes back in a register other than r0, you can override "result".)
6343     *
6344     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6345     * vCC (r1).  Useful for integer division and modulus.
6346     *
6347     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6348     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6349     */
6350    /* binop/lit16 vA, vB, #+CCCC */
6351    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6352    mov     r2, rINST, lsr #12          @ r2<- B
6353    ubfx    r9, rINST, #8, #4           @ r9<- A
6354    GET_VREG(r0, r2)                    @ r0<- vB
6355    .if 0
6356    cmp     r1, #0                      @ is second operand zero?
6357    beq     common_errDivideByZero
6358    .endif
6359    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6360
6361    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
6362    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6363    SET_VREG(r0, r9)               @ vAA<- r0
6364    GOTO_OPCODE(ip)                     @ jump to next instruction
6365    /* 10-13 instructions */
6366
6367
6368/* ------------------------------ */
6369    .balign 64
6370.L_OP_RSUB_INT: /* 0xd1 */
6371/* File: armv6t2/OP_RSUB_INT.S */
6372/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
6373/* File: armv6t2/binopLit16.S */
6374    /*
6375     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6376     * that specifies an instruction that performs "result = r0 op r1".
6377     * This could be an ARM instruction or a function call.  (If the result
6378     * comes back in a register other than r0, you can override "result".)
6379     *
6380     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6381     * vCC (r1).  Useful for integer division and modulus.
6382     *
6383     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6384     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6385     */
6386    /* binop/lit16 vA, vB, #+CCCC */
6387    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6388    mov     r2, rINST, lsr #12          @ r2<- B
6389    ubfx    r9, rINST, #8, #4           @ r9<- A
6390    GET_VREG(r0, r2)                    @ r0<- vB
6391    .if 0
6392    cmp     r1, #0                      @ is second operand zero?
6393    beq     common_errDivideByZero
6394    .endif
6395    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6396
6397    rsb     r0, r0, r1                              @ r0<- op, r0-r3 changed
6398    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6399    SET_VREG(r0, r9)               @ vAA<- r0
6400    GOTO_OPCODE(ip)                     @ jump to next instruction
6401    /* 10-13 instructions */
6402
6403
6404/* ------------------------------ */
6405    .balign 64
6406.L_OP_MUL_INT_LIT16: /* 0xd2 */
6407/* File: armv6t2/OP_MUL_INT_LIT16.S */
6408/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
6409/* File: armv6t2/binopLit16.S */
6410    /*
6411     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6412     * that specifies an instruction that performs "result = r0 op r1".
6413     * This could be an ARM instruction or a function call.  (If the result
6414     * comes back in a register other than r0, you can override "result".)
6415     *
6416     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6417     * vCC (r1).  Useful for integer division and modulus.
6418     *
6419     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6420     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6421     */
6422    /* binop/lit16 vA, vB, #+CCCC */
6423    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6424    mov     r2, rINST, lsr #12          @ r2<- B
6425    ubfx    r9, rINST, #8, #4           @ r9<- A
6426    GET_VREG(r0, r2)                    @ r0<- vB
6427    .if 0
6428    cmp     r1, #0                      @ is second operand zero?
6429    beq     common_errDivideByZero
6430    .endif
6431    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6432
6433    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
6434    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6435    SET_VREG(r0, r9)               @ vAA<- r0
6436    GOTO_OPCODE(ip)                     @ jump to next instruction
6437    /* 10-13 instructions */
6438
6439
6440/* ------------------------------ */
6441    .balign 64
6442.L_OP_DIV_INT_LIT16: /* 0xd3 */
6443/* File: armv6t2/OP_DIV_INT_LIT16.S */
6444/* File: armv6t2/binopLit16.S */
6445    /*
6446     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6447     * that specifies an instruction that performs "result = r0 op r1".
6448     * This could be an ARM instruction or a function call.  (If the result
6449     * comes back in a register other than r0, you can override "result".)
6450     *
6451     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6452     * vCC (r1).  Useful for integer division and modulus.
6453     *
6454     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6455     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6456     */
6457    /* binop/lit16 vA, vB, #+CCCC */
6458    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6459    mov     r2, rINST, lsr #12          @ r2<- B
6460    ubfx    r9, rINST, #8, #4           @ r9<- A
6461    GET_VREG(r0, r2)                    @ r0<- vB
6462    .if 1
6463    cmp     r1, #0                      @ is second operand zero?
6464    beq     common_errDivideByZero
6465    .endif
6466    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6467
6468    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
6469    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6470    SET_VREG(r0, r9)               @ vAA<- r0
6471    GOTO_OPCODE(ip)                     @ jump to next instruction
6472    /* 10-13 instructions */
6473
6474
6475/* ------------------------------ */
6476    .balign 64
6477.L_OP_REM_INT_LIT16: /* 0xd4 */
6478/* File: armv6t2/OP_REM_INT_LIT16.S */
6479/* idivmod returns quotient in r0 and remainder in r1 */
6480/* File: armv6t2/binopLit16.S */
6481    /*
6482     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6483     * that specifies an instruction that performs "result = r0 op r1".
6484     * This could be an ARM instruction or a function call.  (If the result
6485     * comes back in a register other than r0, you can override "result".)
6486     *
6487     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6488     * vCC (r1).  Useful for integer division and modulus.
6489     *
6490     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6491     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6492     */
6493    /* binop/lit16 vA, vB, #+CCCC */
6494    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6495    mov     r2, rINST, lsr #12          @ r2<- B
6496    ubfx    r9, rINST, #8, #4           @ r9<- A
6497    GET_VREG(r0, r2)                    @ r0<- vB
6498    .if 1
6499    cmp     r1, #0                      @ is second operand zero?
6500    beq     common_errDivideByZero
6501    .endif
6502    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6503
6504    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
6505    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6506    SET_VREG(r1, r9)               @ vAA<- r1
6507    GOTO_OPCODE(ip)                     @ jump to next instruction
6508    /* 10-13 instructions */
6509
6510
6511/* ------------------------------ */
6512    .balign 64
6513.L_OP_AND_INT_LIT16: /* 0xd5 */
6514/* File: armv6t2/OP_AND_INT_LIT16.S */
6515/* File: armv6t2/binopLit16.S */
6516    /*
6517     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6518     * that specifies an instruction that performs "result = r0 op r1".
6519     * This could be an ARM instruction or a function call.  (If the result
6520     * comes back in a register other than r0, you can override "result".)
6521     *
6522     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6523     * vCC (r1).  Useful for integer division and modulus.
6524     *
6525     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6526     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6527     */
6528    /* binop/lit16 vA, vB, #+CCCC */
6529    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6530    mov     r2, rINST, lsr #12          @ r2<- B
6531    ubfx    r9, rINST, #8, #4           @ r9<- A
6532    GET_VREG(r0, r2)                    @ r0<- vB
6533    .if 0
6534    cmp     r1, #0                      @ is second operand zero?
6535    beq     common_errDivideByZero
6536    .endif
6537    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6538
6539    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
6540    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6541    SET_VREG(r0, r9)               @ vAA<- r0
6542    GOTO_OPCODE(ip)                     @ jump to next instruction
6543    /* 10-13 instructions */
6544
6545
6546/* ------------------------------ */
6547    .balign 64
6548.L_OP_OR_INT_LIT16: /* 0xd6 */
6549/* File: armv6t2/OP_OR_INT_LIT16.S */
6550/* File: armv6t2/binopLit16.S */
6551    /*
6552     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6553     * that specifies an instruction that performs "result = r0 op r1".
6554     * This could be an ARM instruction or a function call.  (If the result
6555     * comes back in a register other than r0, you can override "result".)
6556     *
6557     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6558     * vCC (r1).  Useful for integer division and modulus.
6559     *
6560     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6561     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6562     */
6563    /* binop/lit16 vA, vB, #+CCCC */
6564    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6565    mov     r2, rINST, lsr #12          @ r2<- B
6566    ubfx    r9, rINST, #8, #4           @ r9<- A
6567    GET_VREG(r0, r2)                    @ r0<- vB
6568    .if 0
6569    cmp     r1, #0                      @ is second operand zero?
6570    beq     common_errDivideByZero
6571    .endif
6572    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6573
6574    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
6575    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6576    SET_VREG(r0, r9)               @ vAA<- r0
6577    GOTO_OPCODE(ip)                     @ jump to next instruction
6578    /* 10-13 instructions */
6579
6580
6581/* ------------------------------ */
6582    .balign 64
6583.L_OP_XOR_INT_LIT16: /* 0xd7 */
6584/* File: armv6t2/OP_XOR_INT_LIT16.S */
6585/* File: armv6t2/binopLit16.S */
6586    /*
6587     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6588     * that specifies an instruction that performs "result = r0 op r1".
6589     * This could be an ARM instruction or a function call.  (If the result
6590     * comes back in a register other than r0, you can override "result".)
6591     *
6592     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6593     * vCC (r1).  Useful for integer division and modulus.
6594     *
6595     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6596     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6597     */
6598    /* binop/lit16 vA, vB, #+CCCC */
6599    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6600    mov     r2, rINST, lsr #12          @ r2<- B
6601    ubfx    r9, rINST, #8, #4           @ r9<- A
6602    GET_VREG(r0, r2)                    @ r0<- vB
6603    .if 0
6604    cmp     r1, #0                      @ is second operand zero?
6605    beq     common_errDivideByZero
6606    .endif
6607    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6608
6609    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
6610    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6611    SET_VREG(r0, r9)               @ vAA<- r0
6612    GOTO_OPCODE(ip)                     @ jump to next instruction
6613    /* 10-13 instructions */
6614
6615
6616/* ------------------------------ */
6617    .balign 64
6618.L_OP_ADD_INT_LIT8: /* 0xd8 */
6619/* File: armv5te/OP_ADD_INT_LIT8.S */
6620/* File: armv5te/binopLit8.S */
6621    /*
6622     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6623     * that specifies an instruction that performs "result = r0 op r1".
6624     * This could be an ARM instruction or a function call.  (If the result
6625     * comes back in a register other than r0, you can override "result".)
6626     *
6627     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6628     * vCC (r1).  Useful for integer division and modulus.
6629     *
6630     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6631     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6632     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6633     */
6634    /* binop/lit8 vAA, vBB, #+CC */
6635    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6636    mov     r9, rINST, lsr #8           @ r9<- AA
6637    and     r2, r3, #255                @ r2<- BB
6638    GET_VREG(r0, r2)                    @ r0<- vBB
6639    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6640    .if 0
6641    @cmp     r1, #0                      @ is second operand zero?
6642    beq     common_errDivideByZero
6643    .endif
6644    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6645
6646                               @ optional op; may set condition codes
6647    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
6648    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6649    SET_VREG(r0, r9)               @ vAA<- r0
6650    GOTO_OPCODE(ip)                     @ jump to next instruction
6651    /* 10-12 instructions */
6652
6653
6654/* ------------------------------ */
6655    .balign 64
6656.L_OP_RSUB_INT_LIT8: /* 0xd9 */
6657/* File: armv5te/OP_RSUB_INT_LIT8.S */
6658/* File: armv5te/binopLit8.S */
6659    /*
6660     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6661     * that specifies an instruction that performs "result = r0 op r1".
6662     * This could be an ARM instruction or a function call.  (If the result
6663     * comes back in a register other than r0, you can override "result".)
6664     *
6665     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6666     * vCC (r1).  Useful for integer division and modulus.
6667     *
6668     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6669     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6670     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6671     */
6672    /* binop/lit8 vAA, vBB, #+CC */
6673    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6674    mov     r9, rINST, lsr #8           @ r9<- AA
6675    and     r2, r3, #255                @ r2<- BB
6676    GET_VREG(r0, r2)                    @ r0<- vBB
6677    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6678    .if 0
6679    @cmp     r1, #0                      @ is second operand zero?
6680    beq     common_errDivideByZero
6681    .endif
6682    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6683
6684                               @ optional op; may set condition codes
6685    rsb     r0, r0, r1                              @ r0<- op, r0-r3 changed
6686    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6687    SET_VREG(r0, r9)               @ vAA<- r0
6688    GOTO_OPCODE(ip)                     @ jump to next instruction
6689    /* 10-12 instructions */
6690
6691
6692/* ------------------------------ */
6693    .balign 64
6694.L_OP_MUL_INT_LIT8: /* 0xda */
6695/* File: armv5te/OP_MUL_INT_LIT8.S */
6696/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
6697/* File: armv5te/binopLit8.S */
6698    /*
6699     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6700     * that specifies an instruction that performs "result = r0 op r1".
6701     * This could be an ARM instruction or a function call.  (If the result
6702     * comes back in a register other than r0, you can override "result".)
6703     *
6704     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6705     * vCC (r1).  Useful for integer division and modulus.
6706     *
6707     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6708     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6709     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6710     */
6711    /* binop/lit8 vAA, vBB, #+CC */
6712    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6713    mov     r9, rINST, lsr #8           @ r9<- AA
6714    and     r2, r3, #255                @ r2<- BB
6715    GET_VREG(r0, r2)                    @ r0<- vBB
6716    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6717    .if 0
6718    @cmp     r1, #0                      @ is second operand zero?
6719    beq     common_errDivideByZero
6720    .endif
6721    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6722
6723                               @ optional op; may set condition codes
6724    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
6725    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6726    SET_VREG(r0, r9)               @ vAA<- r0
6727    GOTO_OPCODE(ip)                     @ jump to next instruction
6728    /* 10-12 instructions */
6729
6730
6731/* ------------------------------ */
6732    .balign 64
6733.L_OP_DIV_INT_LIT8: /* 0xdb */
6734/* File: armv5te/OP_DIV_INT_LIT8.S */
6735/* File: armv5te/binopLit8.S */
6736    /*
6737     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6738     * that specifies an instruction that performs "result = r0 op r1".
6739     * This could be an ARM instruction or a function call.  (If the result
6740     * comes back in a register other than r0, you can override "result".)
6741     *
6742     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6743     * vCC (r1).  Useful for integer division and modulus.
6744     *
6745     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6746     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6747     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6748     */
6749    /* binop/lit8 vAA, vBB, #+CC */
6750    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6751    mov     r9, rINST, lsr #8           @ r9<- AA
6752    and     r2, r3, #255                @ r2<- BB
6753    GET_VREG(r0, r2)                    @ r0<- vBB
6754    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6755    .if 1
6756    @cmp     r1, #0                      @ is second operand zero?
6757    beq     common_errDivideByZero
6758    .endif
6759    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6760
6761                               @ optional op; may set condition codes
6762    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
6763    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6764    SET_VREG(r0, r9)               @ vAA<- r0
6765    GOTO_OPCODE(ip)                     @ jump to next instruction
6766    /* 10-12 instructions */
6767
6768
6769/* ------------------------------ */
6770    .balign 64
6771.L_OP_REM_INT_LIT8: /* 0xdc */
6772/* File: armv5te/OP_REM_INT_LIT8.S */
6773/* idivmod returns quotient in r0 and remainder in r1 */
6774/* File: armv5te/binopLit8.S */
6775    /*
6776     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6777     * that specifies an instruction that performs "result = r0 op r1".
6778     * This could be an ARM instruction or a function call.  (If the result
6779     * comes back in a register other than r0, you can override "result".)
6780     *
6781     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6782     * vCC (r1).  Useful for integer division and modulus.
6783     *
6784     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6785     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6786     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6787     */
6788    /* binop/lit8 vAA, vBB, #+CC */
6789    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6790    mov     r9, rINST, lsr #8           @ r9<- AA
6791    and     r2, r3, #255                @ r2<- BB
6792    GET_VREG(r0, r2)                    @ r0<- vBB
6793    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6794    .if 1
6795    @cmp     r1, #0                      @ is second operand zero?
6796    beq     common_errDivideByZero
6797    .endif
6798    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6799
6800                               @ optional op; may set condition codes
6801    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
6802    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6803    SET_VREG(r1, r9)               @ vAA<- r1
6804    GOTO_OPCODE(ip)                     @ jump to next instruction
6805    /* 10-12 instructions */
6806
6807
6808/* ------------------------------ */
6809    .balign 64
6810.L_OP_AND_INT_LIT8: /* 0xdd */
6811/* File: armv5te/OP_AND_INT_LIT8.S */
6812/* File: armv5te/binopLit8.S */
6813    /*
6814     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6815     * that specifies an instruction that performs "result = r0 op r1".
6816     * This could be an ARM instruction or a function call.  (If the result
6817     * comes back in a register other than r0, you can override "result".)
6818     *
6819     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6820     * vCC (r1).  Useful for integer division and modulus.
6821     *
6822     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6823     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6824     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6825     */
6826    /* binop/lit8 vAA, vBB, #+CC */
6827    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6828    mov     r9, rINST, lsr #8           @ r9<- AA
6829    and     r2, r3, #255                @ r2<- BB
6830    GET_VREG(r0, r2)                    @ r0<- vBB
6831    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6832    .if 0
6833    @cmp     r1, #0                      @ is second operand zero?
6834    beq     common_errDivideByZero
6835    .endif
6836    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6837
6838                               @ optional op; may set condition codes
6839    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
6840    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6841    SET_VREG(r0, r9)               @ vAA<- r0
6842    GOTO_OPCODE(ip)                     @ jump to next instruction
6843    /* 10-12 instructions */
6844
6845
6846/* ------------------------------ */
6847    .balign 64
6848.L_OP_OR_INT_LIT8: /* 0xde */
6849/* File: armv5te/OP_OR_INT_LIT8.S */
6850/* File: armv5te/binopLit8.S */
6851    /*
6852     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6853     * that specifies an instruction that performs "result = r0 op r1".
6854     * This could be an ARM instruction or a function call.  (If the result
6855     * comes back in a register other than r0, you can override "result".)
6856     *
6857     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6858     * vCC (r1).  Useful for integer division and modulus.
6859     *
6860     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6861     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6862     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6863     */
6864    /* binop/lit8 vAA, vBB, #+CC */
6865    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6866    mov     r9, rINST, lsr #8           @ r9<- AA
6867    and     r2, r3, #255                @ r2<- BB
6868    GET_VREG(r0, r2)                    @ r0<- vBB
6869    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6870    .if 0
6871    @cmp     r1, #0                      @ is second operand zero?
6872    beq     common_errDivideByZero
6873    .endif
6874    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6875
6876                               @ optional op; may set condition codes
6877    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
6878    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6879    SET_VREG(r0, r9)               @ vAA<- r0
6880    GOTO_OPCODE(ip)                     @ jump to next instruction
6881    /* 10-12 instructions */
6882
6883
6884/* ------------------------------ */
6885    .balign 64
6886.L_OP_XOR_INT_LIT8: /* 0xdf */
6887/* File: armv5te/OP_XOR_INT_LIT8.S */
6888/* File: armv5te/binopLit8.S */
6889    /*
6890     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6891     * that specifies an instruction that performs "result = r0 op r1".
6892     * This could be an ARM instruction or a function call.  (If the result
6893     * comes back in a register other than r0, you can override "result".)
6894     *
6895     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6896     * vCC (r1).  Useful for integer division and modulus.
6897     *
6898     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6899     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6900     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6901     */
6902    /* binop/lit8 vAA, vBB, #+CC */
6903    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6904    mov     r9, rINST, lsr #8           @ r9<- AA
6905    and     r2, r3, #255                @ r2<- BB
6906    GET_VREG(r0, r2)                    @ r0<- vBB
6907    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6908    .if 0
6909    @cmp     r1, #0                      @ is second operand zero?
6910    beq     common_errDivideByZero
6911    .endif
6912    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6913
6914                               @ optional op; may set condition codes
6915    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
6916    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6917    SET_VREG(r0, r9)               @ vAA<- r0
6918    GOTO_OPCODE(ip)                     @ jump to next instruction
6919    /* 10-12 instructions */
6920
6921
6922/* ------------------------------ */
6923    .balign 64
6924.L_OP_SHL_INT_LIT8: /* 0xe0 */
6925/* File: armv5te/OP_SHL_INT_LIT8.S */
6926/* File: armv5te/binopLit8.S */
6927    /*
6928     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6929     * that specifies an instruction that performs "result = r0 op r1".
6930     * This could be an ARM instruction or a function call.  (If the result
6931     * comes back in a register other than r0, you can override "result".)
6932     *
6933     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6934     * vCC (r1).  Useful for integer division and modulus.
6935     *
6936     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6937     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6938     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6939     */
6940    /* binop/lit8 vAA, vBB, #+CC */
6941    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6942    mov     r9, rINST, lsr #8           @ r9<- AA
6943    and     r2, r3, #255                @ r2<- BB
6944    GET_VREG(r0, r2)                    @ r0<- vBB
6945    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6946    .if 0
6947    @cmp     r1, #0                      @ is second operand zero?
6948    beq     common_errDivideByZero
6949    .endif
6950    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6951
6952    and     r1, r1, #31                           @ optional op; may set condition codes
6953    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
6954    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6955    SET_VREG(r0, r9)               @ vAA<- r0
6956    GOTO_OPCODE(ip)                     @ jump to next instruction
6957    /* 10-12 instructions */
6958
6959
6960/* ------------------------------ */
6961    .balign 64
6962.L_OP_SHR_INT_LIT8: /* 0xe1 */
6963/* File: armv5te/OP_SHR_INT_LIT8.S */
6964/* File: armv5te/binopLit8.S */
6965    /*
6966     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6967     * that specifies an instruction that performs "result = r0 op r1".
6968     * This could be an ARM instruction or a function call.  (If the result
6969     * comes back in a register other than r0, you can override "result".)
6970     *
6971     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6972     * vCC (r1).  Useful for integer division and modulus.
6973     *
6974     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6975     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6976     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6977     */
6978    /* binop/lit8 vAA, vBB, #+CC */
6979    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6980    mov     r9, rINST, lsr #8           @ r9<- AA
6981    and     r2, r3, #255                @ r2<- BB
6982    GET_VREG(r0, r2)                    @ r0<- vBB
6983    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6984    .if 0
6985    @cmp     r1, #0                      @ is second operand zero?
6986    beq     common_errDivideByZero
6987    .endif
6988    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6989
6990    and     r1, r1, #31                           @ optional op; may set condition codes
6991    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
6992    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6993    SET_VREG(r0, r9)               @ vAA<- r0
6994    GOTO_OPCODE(ip)                     @ jump to next instruction
6995    /* 10-12 instructions */
6996
6997
6998/* ------------------------------ */
6999    .balign 64
7000.L_OP_USHR_INT_LIT8: /* 0xe2 */
7001/* File: armv5te/OP_USHR_INT_LIT8.S */
7002/* File: armv5te/binopLit8.S */
7003    /*
7004     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7005     * that specifies an instruction that performs "result = r0 op r1".
7006     * This could be an ARM instruction or a function call.  (If the result
7007     * comes back in a register other than r0, you can override "result".)
7008     *
7009     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7010     * vCC (r1).  Useful for integer division and modulus.
7011     *
7012     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7013     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7014     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7015     */
7016    /* binop/lit8 vAA, vBB, #+CC */
7017    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7018    mov     r9, rINST, lsr #8           @ r9<- AA
7019    and     r2, r3, #255                @ r2<- BB
7020    GET_VREG(r0, r2)                    @ r0<- vBB
7021    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7022    .if 0
7023    @cmp     r1, #0                      @ is second operand zero?
7024    beq     common_errDivideByZero
7025    .endif
7026    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7027
7028    and     r1, r1, #31                           @ optional op; may set condition codes
7029    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
7030    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7031    SET_VREG(r0, r9)               @ vAA<- r0
7032    GOTO_OPCODE(ip)                     @ jump to next instruction
7033    /* 10-12 instructions */
7034
7035
7036/* ------------------------------ */
7037    .balign 64
7038.L_OP_IGET_VOLATILE: /* 0xe3 */
7039/* File: armv5te/OP_IGET_VOLATILE.S */
7040/* File: armv5te/OP_IGET.S */
7041    /*
7042     * General 32-bit instance field get.
7043     *
7044     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7045     */
7046    /* op vA, vB, field@CCCC */
7047    mov     r0, rINST, lsr #12          @ r0<- B
7048    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7049    FETCH(r1, 1)                        @ r1<- field ref CCCC
7050    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7051    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7052    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7053    cmp     r0, #0                      @ is resolved entry null?
7054    bne     .LOP_IGET_VOLATILE_finish          @ no, already resolved
70558:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7056    EXPORT_PC()                         @ resolve() could throw
7057    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7058    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7059    cmp     r0, #0
7060    bne     .LOP_IGET_VOLATILE_finish
7061    b       common_exceptionThrown
7062
7063
7064/* ------------------------------ */
7065    .balign 64
7066.L_OP_IPUT_VOLATILE: /* 0xe4 */
7067/* File: armv5te/OP_IPUT_VOLATILE.S */
7068/* File: armv5te/OP_IPUT.S */
7069    /*
7070     * General 32-bit instance field put.
7071     *
7072     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
7073     */
7074    /* op vA, vB, field@CCCC */
7075    mov     r0, rINST, lsr #12          @ r0<- B
7076    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7077    FETCH(r1, 1)                        @ r1<- field ref CCCC
7078    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7079    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7080    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7081    cmp     r0, #0                      @ is resolved entry null?
7082    bne     .LOP_IPUT_VOLATILE_finish          @ no, already resolved
70838:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7084    EXPORT_PC()                         @ resolve() could throw
7085    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7086    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7087    cmp     r0, #0                      @ success?
7088    bne     .LOP_IPUT_VOLATILE_finish          @ yes, finish up
7089    b       common_exceptionThrown
7090
7091
7092/* ------------------------------ */
7093    .balign 64
7094.L_OP_SGET_VOLATILE: /* 0xe5 */
7095/* File: armv5te/OP_SGET_VOLATILE.S */
7096/* File: armv5te/OP_SGET.S */
7097    /*
7098     * General 32-bit SGET handler.
7099     *
7100     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7101     */
7102    /* op vAA, field@BBBB */
7103    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7104    FETCH(r1, 1)                        @ r1<- field ref BBBB
7105    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7106    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7107    cmp     r0, #0                      @ is resolved entry null?
7108    beq     .LOP_SGET_VOLATILE_resolve         @ yes, do resolve
7109.LOP_SGET_VOLATILE_finish: @ field ptr in r0
7110    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
7111    SMP_DMB                            @ acquiring load
7112    mov     r2, rINST, lsr #8           @ r2<- AA
7113    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7114    SET_VREG(r1, r2)                    @ fp[AA]<- r1
7115    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7116    GOTO_OPCODE(ip)                     @ jump to next instruction
7117
7118
7119/* ------------------------------ */
7120    .balign 64
7121.L_OP_SPUT_VOLATILE: /* 0xe6 */
7122/* File: armv5te/OP_SPUT_VOLATILE.S */
7123/* File: armv5te/OP_SPUT.S */
7124    /*
7125     * General 32-bit SPUT handler.
7126     *
7127     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
7128     */
7129    /* op vAA, field@BBBB */
7130    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7131    FETCH(r1, 1)                        @ r1<- field ref BBBB
7132    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7133    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7134    cmp     r0, #0                      @ is resolved entry null?
7135    beq     .LOP_SPUT_VOLATILE_resolve         @ yes, do resolve
7136.LOP_SPUT_VOLATILE_finish:   @ field ptr in r0
7137    mov     r2, rINST, lsr #8           @ r2<- AA
7138    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7139    GET_VREG(r1, r2)                    @ r1<- fp[AA]
7140    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7141    SMP_DMB                            @ releasing store
7142    str     r1, [r0, #offStaticField_value] @ field<- vAA
7143    GOTO_OPCODE(ip)                     @ jump to next instruction
7144
7145
7146/* ------------------------------ */
7147    .balign 64
7148.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
7149/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */
7150/* File: armv5te/OP_IGET.S */
7151    /*
7152     * General 32-bit instance field get.
7153     *
7154     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7155     */
7156    /* op vA, vB, field@CCCC */
7157    mov     r0, rINST, lsr #12          @ r0<- B
7158    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7159    FETCH(r1, 1)                        @ r1<- field ref CCCC
7160    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7161    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7162    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7163    cmp     r0, #0                      @ is resolved entry null?
7164    bne     .LOP_IGET_OBJECT_VOLATILE_finish          @ no, already resolved
71658:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7166    EXPORT_PC()                         @ resolve() could throw
7167    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7168    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7169    cmp     r0, #0
7170    bne     .LOP_IGET_OBJECT_VOLATILE_finish
7171    b       common_exceptionThrown
7172
7173
7174/* ------------------------------ */
7175    .balign 64
7176.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
7177/* File: armv5te/OP_IGET_WIDE_VOLATILE.S */
7178/* File: armv5te/OP_IGET_WIDE.S */
7179    /*
7180     * Wide 32-bit instance field get.
7181     */
7182    /* iget-wide vA, vB, field@CCCC */
7183    mov     r0, rINST, lsr #12          @ r0<- B
7184    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7185    FETCH(r1, 1)                        @ r1<- field ref CCCC
7186    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7187    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7188    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7189    cmp     r0, #0                      @ is resolved entry null?
7190    bne     .LOP_IGET_WIDE_VOLATILE_finish          @ no, already resolved
71918:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
7192    EXPORT_PC()                         @ resolve() could throw
7193    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7194    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7195    cmp     r0, #0
7196    bne     .LOP_IGET_WIDE_VOLATILE_finish
7197    b       common_exceptionThrown
7198
7199
7200/* ------------------------------ */
7201    .balign 64
7202.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
7203/* File: armv5te/OP_IPUT_WIDE_VOLATILE.S */
7204/* File: armv5te/OP_IPUT_WIDE.S */
7205    /* iput-wide vA, vB, field@CCCC */
7206    mov     r0, rINST, lsr #12          @ r0<- B
7207    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7208    FETCH(r1, 1)                        @ r1<- field ref CCCC
7209    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7210    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7211    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7212    cmp     r0, #0                      @ is resolved entry null?
7213    bne     .LOP_IPUT_WIDE_VOLATILE_finish          @ no, already resolved
72148:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
7215    EXPORT_PC()                         @ resolve() could throw
7216    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7217    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7218    cmp     r0, #0                      @ success?
7219    bne     .LOP_IPUT_WIDE_VOLATILE_finish          @ yes, finish up
7220    b       common_exceptionThrown
7221
7222
7223/* ------------------------------ */
7224    .balign 64
7225.L_OP_SGET_WIDE_VOLATILE: /* 0xea */
7226/* File: armv5te/OP_SGET_WIDE_VOLATILE.S */
7227/* File: armv5te/OP_SGET_WIDE.S */
7228    /*
7229     * 64-bit SGET handler.
7230     */
7231    /* sget-wide vAA, field@BBBB */
7232    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7233    FETCH(r1, 1)                        @ r1<- field ref BBBB
7234    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7235    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7236    cmp     r0, #0                      @ is resolved entry null?
7237    beq     .LOP_SGET_WIDE_VOLATILE_resolve         @ yes, do resolve
7238.LOP_SGET_WIDE_VOLATILE_finish:
7239    mov     r9, rINST, lsr #8           @ r9<- AA
7240    .if 1
7241    add     r0, r0, #offStaticField_value @ r0<- pointer to data
7242    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
7243    .else
7244    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
7245    .endif
7246    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
7247    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7248    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
7249    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7250    GOTO_OPCODE(ip)                     @ jump to next instruction
7251
7252
7253/* ------------------------------ */
7254    .balign 64
7255.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
7256/* File: armv5te/OP_SPUT_WIDE_VOLATILE.S */
7257/* File: armv5te/OP_SPUT_WIDE.S */
7258    /*
7259     * 64-bit SPUT handler.
7260     */
7261    /* sput-wide vAA, field@BBBB */
7262    ldr     r0, [rGLUE, #offGlue_methodClassDex]  @ r0<- DvmDex
7263    FETCH(r1, 1)                        @ r1<- field ref BBBB
7264    ldr     r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields
7265    mov     r9, rINST, lsr #8           @ r9<- AA
7266    ldr     r2, [r0, r1, lsl #2]        @ r2<- resolved StaticField ptr
7267    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
7268    cmp     r2, #0                      @ is resolved entry null?
7269    beq     .LOP_SPUT_WIDE_VOLATILE_resolve         @ yes, do resolve
7270.LOP_SPUT_WIDE_VOLATILE_finish: @ field ptr in r2, AA in r9
7271    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7272    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
7273    GET_INST_OPCODE(r10)                @ extract opcode from rINST
7274    .if 1
7275    add     r2, r2, #offStaticField_value @ r2<- pointer to data
7276    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
7277    .else
7278    strd    r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1
7279    .endif
7280    GOTO_OPCODE(r10)                    @ jump to next instruction
7281
7282
7283/* ------------------------------ */
7284    .balign 64
7285.L_OP_BREAKPOINT: /* 0xec */
7286/* File: armv5te/OP_BREAKPOINT.S */
7287/* File: armv5te/unused.S */
7288    bl      common_abort
7289
7290
7291/* ------------------------------ */
7292    .balign 64
7293.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */
7294/* File: armv5te/OP_THROW_VERIFICATION_ERROR.S */
7295    /*
7296     * Handle a throw-verification-error instruction.  This throws an
7297     * exception for an error discovered during verification.  The
7298     * exception is indicated by AA, with some detail provided by BBBB.
7299     */
7300    /* op AA, ref@BBBB */
7301    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
7302    FETCH(r2, 1)                        @ r2<- BBBB
7303    EXPORT_PC()                         @ export the PC
7304    mov     r1, rINST, lsr #8           @ r1<- AA
7305    bl      dvmThrowVerificationError   @ always throws
7306    b       common_exceptionThrown      @ handle exception
7307
7308/* ------------------------------ */
7309    .balign 64
7310.L_OP_EXECUTE_INLINE: /* 0xee */
7311/* File: armv5te/OP_EXECUTE_INLINE.S */
7312    /*
7313     * Execute a "native inline" instruction.
7314     *
7315     * We need to call an InlineOp4Func:
7316     *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
7317     *
7318     * The first four args are in r0-r3, pointer to return value storage
7319     * is on the stack.  The function's return value is a flag that tells
7320     * us if an exception was thrown.
7321     */
7322    /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */
7323    FETCH(r10, 1)                       @ r10<- BBBB
7324    add     r1, rGLUE, #offGlue_retval  @ r1<- &glue->retval
7325    EXPORT_PC()                         @ can throw
7326    sub     sp, sp, #8                  @ make room for arg, +64 bit align
7327    mov     r0, rINST, lsr #12          @ r0<- B
7328    str     r1, [sp]                    @ push &glue->retval
7329    bl      .LOP_EXECUTE_INLINE_continue        @ make call; will return after
7330    add     sp, sp, #8                  @ pop stack
7331    cmp     r0, #0                      @ test boolean result of inline
7332    beq     common_exceptionThrown      @ returned false, handle exception
7333    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7334    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7335    GOTO_OPCODE(ip)                     @ jump to next instruction
7336
7337/* ------------------------------ */
7338    .balign 64
7339.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */
7340/* File: armv5te/OP_EXECUTE_INLINE_RANGE.S */
7341    /*
7342     * Execute a "native inline" instruction, using "/range" semantics.
7343     * Same idea as execute-inline, but we get the args differently.
7344     *
7345     * We need to call an InlineOp4Func:
7346     *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
7347     *
7348     * The first four args are in r0-r3, pointer to return value storage
7349     * is on the stack.  The function's return value is a flag that tells
7350     * us if an exception was thrown.
7351     */
7352    /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */
7353    FETCH(r10, 1)                       @ r10<- BBBB
7354    add     r1, rGLUE, #offGlue_retval  @ r1<- &glue->retval
7355    EXPORT_PC()                         @ can throw
7356    sub     sp, sp, #8                  @ make room for arg, +64 bit align
7357    mov     r0, rINST, lsr #8           @ r0<- AA
7358    str     r1, [sp]                    @ push &glue->retval
7359    bl      .LOP_EXECUTE_INLINE_RANGE_continue        @ make call; will return after
7360    add     sp, sp, #8                  @ pop stack
7361    cmp     r0, #0                      @ test boolean result of inline
7362    beq     common_exceptionThrown      @ returned false, handle exception
7363    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7364    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7365    GOTO_OPCODE(ip)                     @ jump to next instruction
7366
7367/* ------------------------------ */
7368    .balign 64
7369.L_OP_INVOKE_OBJECT_INIT: /* 0xf0 */
7370/* File: armv5te/OP_INVOKE_OBJECT_INIT.S */
7371    /*
7372     * invoke-object-init is a no-op in a "standard" interpreter.
7373     */
7374    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
7375    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
7376    GOTO_OPCODE(ip)                     @ execute it
7377
7378/* ------------------------------ */
7379    .balign 64
7380.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */
7381/* File: armv5te/OP_RETURN_VOID_BARRIER.S */
7382    SMP_DMB_ST
7383    b       common_returnFromMethod
7384
7385/* ------------------------------ */
7386    .balign 64
7387.L_OP_IGET_QUICK: /* 0xf2 */
7388/* File: armv6t2/OP_IGET_QUICK.S */
7389    /* For: iget-quick, iget-object-quick */
7390    /* op vA, vB, offset@CCCC */
7391    mov     r2, rINST, lsr #12          @ r2<- B
7392    FETCH(r1, 1)                        @ r1<- field byte offset
7393    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7394    ubfx    r2, rINST, #8, #4           @ r2<- A
7395    cmp     r3, #0                      @ check object for null
7396    beq     common_errNullObject        @ object was null
7397    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7398    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7399    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7400    SET_VREG(r0, r2)                    @ fp[A]<- r0
7401    GOTO_OPCODE(ip)                     @ jump to next instruction
7402
7403/* ------------------------------ */
7404    .balign 64
7405.L_OP_IGET_WIDE_QUICK: /* 0xf3 */
7406/* File: armv6t2/OP_IGET_WIDE_QUICK.S */
7407    /* iget-wide-quick vA, vB, offset@CCCC */
7408    mov     r2, rINST, lsr #12          @ r2<- B
7409    FETCH(ip, 1)                        @ ip<- field byte offset
7410    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7411    ubfx    r2, rINST, #8, #4           @ r2<- A
7412    cmp     r3, #0                      @ check object for null
7413    beq     common_errNullObject        @ object was null
7414    ldrd    r0, [r3, ip]                @ r0<- obj.field (64 bits, aligned)
7415    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7416    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
7417    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7418    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
7419    GOTO_OPCODE(ip)                     @ jump to next instruction
7420
7421/* ------------------------------ */
7422    .balign 64
7423.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */
7424/* File: armv5te/OP_IGET_OBJECT_QUICK.S */
7425/* File: armv5te/OP_IGET_QUICK.S */
7426    /* For: iget-quick, iget-object-quick */
7427    /* op vA, vB, offset@CCCC */
7428    mov     r2, rINST, lsr #12          @ r2<- B
7429    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7430    FETCH(r1, 1)                        @ r1<- field byte offset
7431    cmp     r3, #0                      @ check object for null
7432    mov     r2, rINST, lsr #8           @ r2<- A(+)
7433    beq     common_errNullObject        @ object was null
7434    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7435    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7436    and     r2, r2, #15
7437    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7438    SET_VREG(r0, r2)                    @ fp[A]<- r0
7439    GOTO_OPCODE(ip)                     @ jump to next instruction
7440
7441
7442/* ------------------------------ */
7443    .balign 64
7444.L_OP_IPUT_QUICK: /* 0xf5 */
7445/* File: armv6t2/OP_IPUT_QUICK.S */
7446    /* For: iput-quick, iput-object-quick */
7447    /* op vA, vB, offset@CCCC */
7448    mov     r2, rINST, lsr #12          @ r2<- B
7449    FETCH(r1, 1)                        @ r1<- field byte offset
7450    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7451    ubfx    r2, rINST, #8, #4           @ r2<- A
7452    cmp     r3, #0                      @ check object for null
7453    beq     common_errNullObject        @ object was null
7454    GET_VREG(r0, r2)                    @ r0<- fp[A]
7455    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7456    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7457    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7458    GOTO_OPCODE(ip)                     @ jump to next instruction
7459
7460/* ------------------------------ */
7461    .balign 64
7462.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */
7463/* File: armv6t2/OP_IPUT_WIDE_QUICK.S */
7464    /* iput-wide-quick vA, vB, offset@CCCC */
7465    mov     r1, rINST, lsr #12          @ r1<- B
7466    ubfx    r0, rINST, #8, #4           @ r0<- A
7467    GET_VREG(r2, r1)                    @ r2<- fp[B], the object pointer
7468    add     r3, rFP, r0, lsl #2         @ r3<- &fp[A]
7469    cmp     r2, #0                      @ check object for null
7470    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[A]
7471    beq     common_errNullObject        @ object was null
7472    FETCH(r3, 1)                        @ r3<- field byte offset
7473    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7474    strd    r0, [r2, r3]                @ obj.field (64 bits, aligned)<- r0/r1
7475    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7476    GOTO_OPCODE(ip)                     @ jump to next instruction
7477
7478/* ------------------------------ */
7479    .balign 64
7480.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
7481/* File: armv5te/OP_IPUT_OBJECT_QUICK.S */
7482    /* For: iput-object-quick */
7483    /* op vA, vB, offset@CCCC */
7484    mov     r2, rINST, lsr #12          @ r2<- B
7485    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7486    FETCH(r1, 1)                        @ r1<- field byte offset
7487    cmp     r3, #0                      @ check object for null
7488    mov     r2, rINST, lsr #8           @ r2<- A(+)
7489    beq     common_errNullObject        @ object was null
7490    and     r2, r2, #15
7491    GET_VREG(r0, r2)                    @ r0<- fp[A]
7492    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
7493    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7494    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7495    cmp     r0, #0
7496    strneb  r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head
7497    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7498    GOTO_OPCODE(ip)                     @ jump to next instruction
7499
7500/* ------------------------------ */
7501    .balign 64
7502.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
7503/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7504    /*
7505     * Handle an optimized virtual method call.
7506     *
7507     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7508     */
7509    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7510    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7511    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7512    FETCH(r1, 1)                        @ r1<- BBBB
7513    .if     (!0)
7514    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7515    .endif
7516    GET_VREG(r2, r3)                    @ r2<- vC ("this" ptr)
7517    cmp     r2, #0                      @ is "this" null?
7518    beq     common_errNullObject        @ null "this", throw exception
7519    ldr     r2, [r2, #offObject_clazz]  @ r2<- thisPtr->clazz
7520    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7521    EXPORT_PC()                         @ invoke must export
7522    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7523    bl      common_invokeMethodNoRange @ continue on
7524
7525/* ------------------------------ */
7526    .balign 64
7527.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
7528/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */
7529/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7530    /*
7531     * Handle an optimized virtual method call.
7532     *
7533     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7534     */
7535    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7536    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7537    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7538    FETCH(r1, 1)                        @ r1<- BBBB
7539    .if     (!1)
7540    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7541    .endif
7542    GET_VREG(r2, r3)                    @ r2<- vC ("this" ptr)
7543    cmp     r2, #0                      @ is "this" null?
7544    beq     common_errNullObject        @ null "this", throw exception
7545    ldr     r2, [r2, #offObject_clazz]  @ r2<- thisPtr->clazz
7546    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7547    EXPORT_PC()                         @ invoke must export
7548    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7549    bl      common_invokeMethodRange @ continue on
7550
7551
7552/* ------------------------------ */
7553    .balign 64
7554.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */
7555/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7556    /*
7557     * Handle an optimized "super" method call.
7558     *
7559     * for: [opt] invoke-super-quick, invoke-super-quick/range
7560     */
7561    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7562    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7563    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7564    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7565    .if     (!0)
7566    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7567    .endif
7568    FETCH(r1, 1)                        @ r1<- BBBB
7569    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7570    EXPORT_PC()                         @ must export for invoke
7571    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7572    GET_VREG(r3, r10)                   @ r3<- "this"
7573    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7574    cmp     r3, #0                      @ null "this" ref?
7575    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7576    beq     common_errNullObject        @ "this" is null, throw exception
7577    bl      common_invokeMethodNoRange @ continue on
7578
7579/* ------------------------------ */
7580    .balign 64
7581.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
7582/* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */
7583/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7584    /*
7585     * Handle an optimized "super" method call.
7586     *
7587     * for: [opt] invoke-super-quick, invoke-super-quick/range
7588     */
7589    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7590    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7591    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7592    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7593    .if     (!1)
7594    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7595    .endif
7596    FETCH(r1, 1)                        @ r1<- BBBB
7597    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7598    EXPORT_PC()                         @ must export for invoke
7599    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7600    GET_VREG(r3, r10)                   @ r3<- "this"
7601    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7602    cmp     r3, #0                      @ null "this" ref?
7603    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7604    beq     common_errNullObject        @ "this" is null, throw exception
7605    bl      common_invokeMethodRange @ continue on
7606
7607
7608/* ------------------------------ */
7609    .balign 64
7610.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
7611/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */
7612/* File: armv5te/OP_IPUT_OBJECT.S */
7613    /*
7614     * 32-bit instance field put.
7615     *
7616     * for: iput-object, iput-object-volatile
7617     */
7618    /* op vA, vB, field@CCCC */
7619    mov     r0, rINST, lsr #12          @ r0<- B
7620    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7621    FETCH(r1, 1)                        @ r1<- field ref CCCC
7622    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7623    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7624    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7625    cmp     r0, #0                      @ is resolved entry null?
7626    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ no, already resolved
76278:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7628    EXPORT_PC()                         @ resolve() could throw
7629    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7630    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7631    cmp     r0, #0                      @ success?
7632    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ yes, finish up
7633    b       common_exceptionThrown
7634
7635
7636/* ------------------------------ */
7637    .balign 64
7638.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
7639/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */
7640/* File: armv5te/OP_SGET.S */
7641    /*
7642     * General 32-bit SGET handler.
7643     *
7644     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7645     */
7646    /* op vAA, field@BBBB */
7647    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7648    FETCH(r1, 1)                        @ r1<- field ref BBBB
7649    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7650    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7651    cmp     r0, #0                      @ is resolved entry null?
7652    beq     .LOP_SGET_OBJECT_VOLATILE_resolve         @ yes, do resolve
7653.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0
7654    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
7655    SMP_DMB                            @ acquiring load
7656    mov     r2, rINST, lsr #8           @ r2<- AA
7657    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7658    SET_VREG(r1, r2)                    @ fp[AA]<- r1
7659    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7660    GOTO_OPCODE(ip)                     @ jump to next instruction
7661
7662
7663/* ------------------------------ */
7664    .balign 64
7665.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
7666/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */
7667/* File: armv5te/OP_SPUT_OBJECT.S */
7668    /*
7669     * 32-bit SPUT handler for objects
7670     *
7671     * for: sput-object, sput-object-volatile
7672     */
7673    /* op vAA, field@BBBB */
7674    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7675    FETCH(r1, 1)                        @ r1<- field ref BBBB
7676    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7677    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7678    cmp     r0, #0                      @ is resolved entry null?
7679    bne     .LOP_SPUT_OBJECT_VOLATILE_finish          @ no, continue
7680    ldr     r9, [rGLUE, #offGlue_method]    @ r9<- current method
7681    EXPORT_PC()                         @ resolve() could throw, so export now
7682    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
7683    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
7684    cmp     r0, #0                      @ success?
7685    bne     .LOP_SPUT_OBJECT_VOLATILE_finish          @ yes, finish
7686    b       common_exceptionThrown      @ no, handle exception
7687
7688
7689
7690/* ------------------------------ */
7691    .balign 64
7692.L_OP_DISPATCH_FF: /* 0xff */
7693/* File: armv5te/OP_DISPATCH_FF.S */
7694    mov     ip, rINST, lsr #8           @ r9<- extended opcode
7695    add     ip, ip, #256                @ add offset for extended opcodes
7696    GOTO_OPCODE(ip)                     @ go to proper extended handler
7697
7698
7699/* ------------------------------ */
7700    .balign 64
7701.L_OP_CONST_CLASS_JUMBO: /* 0x100 */
7702/* File: armv5te/OP_CONST_CLASS_JUMBO.S */
7703    /* const-class/jumbo vBBBB, Class@AAAAAAAA */
7704    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7705    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- glue->methodClassDex
7706    FETCH(r1, 2)                        @ r1<- AAAA (hi)
7707    ldr     r2, [r2, #offDvmDex_pResClasses]   @ r2<- dvmDex->pResClasses
7708    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
7709    FETCH(r9, 3)                        @ r9<- BBBB
7710    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResClasses[AAAAaaaa]
7711    cmp     r0, #0                      @ not yet resolved?
7712    beq     .LOP_CONST_CLASS_JUMBO_resolve
7713    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
7714    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7715    SET_VREG(r0, r9)                    @ vBBBB<- r0
7716    GOTO_OPCODE(ip)                     @ jump to next instruction
7717
7718/* ------------------------------ */
7719    .balign 64
7720.L_OP_CHECK_CAST_JUMBO: /* 0x101 */
7721/* File: armv5te/OP_CHECK_CAST_JUMBO.S */
7722    /*
7723     * Check to see if a cast from one class to another is allowed.
7724     */
7725    /* check-cast/jumbo vBBBB, class@AAAAAAAA */
7726    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7727    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7728    FETCH(r3, 3)                        @ r3<- BBBB
7729    orr     r2, r0, r2, lsl #16         @ r2<- AAAAaaaa
7730    GET_VREG(r9, r3)                    @ r9<- object
7731    ldr     r0, [rGLUE, #offGlue_methodClassDex]    @ r0<- pDvmDex
7732    cmp     r9, #0                      @ is object null?
7733    ldr     r0, [r0, #offDvmDex_pResClasses]    @ r0<- pDvmDex->pResClasses
7734    beq     .LOP_CHECK_CAST_JUMBO_okay            @ null obj, cast always succeeds
7735    ldr     r1, [r0, r2, lsl #2]        @ r1<- resolved class
7736    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
7737    cmp     r1, #0                      @ have we resolved this before?
7738    beq     .LOP_CHECK_CAST_JUMBO_resolve         @ not resolved, do it now
7739.LOP_CHECK_CAST_JUMBO_resolved:
7740    cmp     r0, r1                      @ same class (trivial success)?
7741    bne     .LOP_CHECK_CAST_JUMBO_fullcheck       @ no, do full check
7742    b       .LOP_CHECK_CAST_JUMBO_okay            @ yes, finish up
7743
7744/* ------------------------------ */
7745    .balign 64
7746.L_OP_INSTANCE_OF_JUMBO: /* 0x102 */
7747/* File: armv5te/OP_INSTANCE_OF_JUMBO.S */
7748    /*
7749     * Check to see if an object reference is an instance of a class.
7750     *
7751     * Most common situation is a non-null object, being compared against
7752     * an already-resolved class.
7753     *
7754     * TODO: convert most of this into a common subroutine, shared with
7755     *       OP_INSTANCE_OF.S.
7756     */
7757    /* instance-of/jumbo vBBBB, vCCCC, class@AAAAAAAA */
7758    FETCH(r3, 4)                        @ r3<- vCCCC
7759    FETCH(r9, 3)                        @ r9<- vBBBB
7760    GET_VREG(r0, r3)                    @ r0<- vCCCC (object)
7761    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- pDvmDex
7762    cmp     r0, #0                      @ is object null?
7763    beq     .LOP_INSTANCE_OF_JUMBO_store           @ null obj, not an instance, store r0
7764    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7765    FETCH(r3, 2)                        @ r3<- AAAA (hi)
7766    ldr     r2, [r2, #offDvmDex_pResClasses]    @ r2<- pDvmDex->pResClasses
7767    orr     r3, r1, r3, lsl #16         @ r3<- AAAAaaaa
7768    ldr     r1, [r2, r3, lsl #2]        @ r1<- resolved class
7769    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
7770    cmp     r1, #0                      @ have we resolved this before?
7771    beq     .LOP_INSTANCE_OF_JUMBO_resolve         @ not resolved, do it now
7772    b       .LOP_INSTANCE_OF_JUMBO_resolved        @ resolved, continue
7773
7774/* ------------------------------ */
7775    .balign 64
7776.L_OP_NEW_INSTANCE_JUMBO: /* 0x103 */
7777/* File: armv5te/OP_NEW_INSTANCE_JUMBO.S */
7778    /*
7779     * Create a new instance of a class.
7780     */
7781    /* new-instance/jumbo vBBBB, class@AAAAAAAA */
7782    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7783    FETCH(r1, 2)                        @ r1<- AAAA (hi)
7784    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
7785    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
7786    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
7787    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
7788    EXPORT_PC()                         @ req'd for init, resolve, alloc
7789    cmp     r0, #0                      @ already resolved?
7790    beq     .LOP_NEW_INSTANCE_JUMBO_resolve         @ no, resolve it now
7791.LOP_NEW_INSTANCE_JUMBO_resolved:   @ r0=class
7792    ldrb    r1, [r0, #offClassObject_status]    @ r1<- ClassStatus enum
7793    cmp     r1, #CLASS_INITIALIZED      @ has class been initialized?
7794    bne     .LOP_NEW_INSTANCE_JUMBO_needinit        @ no, init class now
7795.LOP_NEW_INSTANCE_JUMBO_initialized: @ r0=class
7796    mov     r1, #ALLOC_DONT_TRACK       @ flags for alloc call
7797    bl      dvmAllocObject              @ r0<- new object
7798    b       .LOP_NEW_INSTANCE_JUMBO_finish          @ continue
7799
7800/* ------------------------------ */
7801    .balign 64
7802.L_OP_NEW_ARRAY_JUMBO: /* 0x104 */
7803/* File: armv5te/OP_NEW_ARRAY_JUMBO.S */
7804    /*
7805     * Allocate an array of objects, specified with the array class
7806     * and a count.
7807     *
7808     * The verifier guarantees that this is an array class, so we don't
7809     * check for it here.
7810     */
7811    /* new-array/jumbo vBBBB, vCCCC, class@AAAAAAAA */
7812    FETCH(r2, 1)                        @ r2<- aaaa (lo)
7813    FETCH(r3, 2)                        @ r3<- AAAA (hi)
7814    FETCH(r0, 4)                        @ r0<- vCCCC
7815    orr     r2, r2, r3, lsl #16         @ r2<- AAAAaaaa
7816    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
7817    GET_VREG(r1, r0)                    @ r1<- vCCCC (array length)
7818    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
7819    cmp     r1, #0                      @ check length
7820    ldr     r0, [r3, r2, lsl #2]        @ r0<- resolved class
7821    bmi     common_errNegativeArraySize @ negative length, bail
7822    cmp     r0, #0                      @ already resolved?
7823    EXPORT_PC()                         @ req'd for resolve, alloc
7824    bne     .LOP_NEW_ARRAY_JUMBO_finish          @ resolved, continue
7825    b       .LOP_NEW_ARRAY_JUMBO_resolve         @ do resolve now
7826
7827/* ------------------------------ */
7828    .balign 64
7829.L_OP_FILLED_NEW_ARRAY_JUMBO: /* 0x105 */
7830/* File: armv5te/OP_FILLED_NEW_ARRAY_JUMBO.S */
7831    /*
7832     * Create a new array with elements filled from registers.
7833     *
7834     * TODO: convert most of this into a common subroutine, shared with
7835     *       OP_FILLED_NEW_ARRAY.S.
7836     */
7837    /* filled-new-array/jumbo {vCCCC..v(CCCC+BBBB-1)}, type@AAAAAAAA */
7838    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
7839    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7840    FETCH(r1, 2)                        @ r1<- AAAA (hi)
7841    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
7842    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
7843    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
7844    EXPORT_PC()                         @ need for resolve and alloc
7845    cmp     r0, #0                      @ already resolved?
7846    bne     .LOP_FILLED_NEW_ARRAY_JUMBO_continue        @ yes, continue on
78478:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
7848    mov     r2, #0                      @ r2<- false
7849    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
7850    bl      dvmResolveClass             @ r0<- call(clazz, ref)
7851    cmp     r0, #0                      @ got null?
7852    beq     common_exceptionThrown      @ yes, handle exception
7853    b       .LOP_FILLED_NEW_ARRAY_JUMBO_continue
7854
7855/* ------------------------------ */
7856    .balign 64
7857.L_OP_IGET_JUMBO: /* 0x106 */
7858/* File: armv5te/OP_IGET_JUMBO.S */
7859    /*
7860     * Jumbo 32-bit instance field get.
7861     *
7862     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
7863     *      iget-char/jumbo, iget-short/jumbo
7864     */
7865    /* exop vBBBB, vCCCC, field@AAAAAAAA */
7866    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7867    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7868    FETCH(r0, 4)                        @ r0<- CCCC
7869    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7870    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7871    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7872    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7873    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7874    cmp     r0, #0                      @ is resolved entry null?
7875    bne     .LOP_IGET_JUMBO_finish          @ no, already resolved
78768:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7877    EXPORT_PC()                         @ resolve() could throw
7878    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7879    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7880    b       .LOP_IGET_JUMBO_resolved        @ resolved, continue
7881
7882/* ------------------------------ */
7883    .balign 64
7884.L_OP_IGET_WIDE_JUMBO: /* 0x107 */
7885/* File: armv5te/OP_IGET_WIDE_JUMBO.S */
7886    /*
7887     * Jumbo 64-bit instance field get.
7888     */
7889    /* iget-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */
7890    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7891    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7892    FETCH(r0, 4)                        @ r0<- CCCC
7893    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7894    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7895    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7896    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7897    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7898    cmp     r0, #0                      @ is resolved entry null?
7899    bne     .LOP_IGET_WIDE_JUMBO_finish          @ no, already resolved
79008:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
7901    EXPORT_PC()                         @ resolve() could throw
7902    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7903    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7904    b       .LOP_IGET_WIDE_JUMBO_resolved        @ resolved, continue
7905
7906/* ------------------------------ */
7907    .balign 64
7908.L_OP_IGET_OBJECT_JUMBO: /* 0x108 */
7909/* File: armv5te/OP_IGET_OBJECT_JUMBO.S */
7910/* File: armv5te/OP_IGET_JUMBO.S */
7911    /*
7912     * Jumbo 32-bit instance field get.
7913     *
7914     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
7915     *      iget-char/jumbo, iget-short/jumbo
7916     */
7917    /* exop vBBBB, vCCCC, field@AAAAAAAA */
7918    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7919    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7920    FETCH(r0, 4)                        @ r0<- CCCC
7921    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7922    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7923    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7924    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7925    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7926    cmp     r0, #0                      @ is resolved entry null?
7927    bne     .LOP_IGET_OBJECT_JUMBO_finish          @ no, already resolved
79288:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7929    EXPORT_PC()                         @ resolve() could throw
7930    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7931    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7932    b       .LOP_IGET_OBJECT_JUMBO_resolved        @ resolved, continue
7933
7934
7935/* ------------------------------ */
7936    .balign 64
7937.L_OP_IGET_BOOLEAN_JUMBO: /* 0x109 */
7938/* File: armv5te/OP_IGET_BOOLEAN_JUMBO.S */
7939@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrb", "sqnum":"1" }
7940/* File: armv5te/OP_IGET_JUMBO.S */
7941    /*
7942     * Jumbo 32-bit instance field get.
7943     *
7944     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
7945     *      iget-char/jumbo, iget-short/jumbo
7946     */
7947    /* exop vBBBB, vCCCC, field@AAAAAAAA */
7948    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7949    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7950    FETCH(r0, 4)                        @ r0<- CCCC
7951    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7952    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7953    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7954    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7955    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7956    cmp     r0, #0                      @ is resolved entry null?
7957    bne     .LOP_IGET_BOOLEAN_JUMBO_finish          @ no, already resolved
79588:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7959    EXPORT_PC()                         @ resolve() could throw
7960    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7961    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7962    b       .LOP_IGET_BOOLEAN_JUMBO_resolved        @ resolved, continue
7963
7964
7965/* ------------------------------ */
7966    .balign 64
7967.L_OP_IGET_BYTE_JUMBO: /* 0x10a */
7968/* File: armv5te/OP_IGET_BYTE_JUMBO.S */
7969@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsb", "sqnum":"2" }
7970/* File: armv5te/OP_IGET_JUMBO.S */
7971    /*
7972     * Jumbo 32-bit instance field get.
7973     *
7974     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
7975     *      iget-char/jumbo, iget-short/jumbo
7976     */
7977    /* exop vBBBB, vCCCC, field@AAAAAAAA */
7978    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7979    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7980    FETCH(r0, 4)                        @ r0<- CCCC
7981    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7982    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7983    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7984    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7985    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7986    cmp     r0, #0                      @ is resolved entry null?
7987    bne     .LOP_IGET_BYTE_JUMBO_finish          @ no, already resolved
79888:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7989    EXPORT_PC()                         @ resolve() could throw
7990    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7991    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7992    b       .LOP_IGET_BYTE_JUMBO_resolved        @ resolved, continue
7993
7994
7995/* ------------------------------ */
7996    .balign 64
7997.L_OP_IGET_CHAR_JUMBO: /* 0x10b */
7998/* File: armv5te/OP_IGET_CHAR_JUMBO.S */
7999@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrh", "sqnum":"3" }
8000/* File: armv5te/OP_IGET_JUMBO.S */
8001    /*
8002     * Jumbo 32-bit instance field get.
8003     *
8004     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8005     *      iget-char/jumbo, iget-short/jumbo
8006     */
8007    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8008    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8009    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8010    FETCH(r0, 4)                        @ r0<- CCCC
8011    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8012    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8013    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8014    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8015    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8016    cmp     r0, #0                      @ is resolved entry null?
8017    bne     .LOP_IGET_CHAR_JUMBO_finish          @ no, already resolved
80188:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8019    EXPORT_PC()                         @ resolve() could throw
8020    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8021    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8022    b       .LOP_IGET_CHAR_JUMBO_resolved        @ resolved, continue
8023
8024
8025/* ------------------------------ */
8026    .balign 64
8027.L_OP_IGET_SHORT_JUMBO: /* 0x10c */
8028/* File: armv5te/OP_IGET_SHORT_JUMBO.S */
8029@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsh", "sqnum":"4" }
8030/* File: armv5te/OP_IGET_JUMBO.S */
8031    /*
8032     * Jumbo 32-bit instance field get.
8033     *
8034     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8035     *      iget-char/jumbo, iget-short/jumbo
8036     */
8037    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8038    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8039    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8040    FETCH(r0, 4)                        @ r0<- CCCC
8041    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8042    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8043    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8044    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8045    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8046    cmp     r0, #0                      @ is resolved entry null?
8047    bne     .LOP_IGET_SHORT_JUMBO_finish          @ no, already resolved
80488:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8049    EXPORT_PC()                         @ resolve() could throw
8050    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8051    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8052    b       .LOP_IGET_SHORT_JUMBO_resolved        @ resolved, continue
8053
8054
8055/* ------------------------------ */
8056    .balign 64
8057.L_OP_IPUT_JUMBO: /* 0x10d */
8058/* File: armv5te/OP_IPUT_JUMBO.S */
8059    /*
8060     * Jumbo 32-bit instance field put.
8061     *
8062     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8063     *      iput-short/jumbo
8064     */
8065    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8066    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8067    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8068    FETCH(r0, 4)                        @ r0<- CCCC
8069    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8070    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8071    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8072    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8073    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8074    cmp     r0, #0                      @ is resolved entry null?
8075    bne     .LOP_IPUT_JUMBO_finish          @ no, already resolved
80768:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8077    EXPORT_PC()                         @ resolve() could throw
8078    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8079    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8080    b       .LOP_IPUT_JUMBO_resolved        @ resolved, continue
8081
8082/* ------------------------------ */
8083    .balign 64
8084.L_OP_IPUT_WIDE_JUMBO: /* 0x10e */
8085/* File: armv5te/OP_IPUT_WIDE_JUMBO.S */
8086    /* iput-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */
8087    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8088    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8089    FETCH(r0, 4)                        @ r0<- CCCC
8090    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8091    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8092    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
8093    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
8094    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8095    cmp     r0, #0                      @ is resolved entry null?
8096    bne     .LOP_IPUT_WIDE_JUMBO_finish          @ no, already resolved
80978:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
8098    EXPORT_PC()                         @ resolve() could throw
8099    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8100    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8101    b       .LOP_IPUT_WIDE_JUMBO_resolved        @ resolved, continue
8102
8103/* ------------------------------ */
8104    .balign 64
8105.L_OP_IPUT_OBJECT_JUMBO: /* 0x10f */
8106/* File: armv5te/OP_IPUT_OBJECT_JUMBO.S */
8107    /*
8108     * Jumbo 32-bit instance field put.
8109     */
8110    /* iput-object/jumbo vBBBB, vCCCC, field@AAAAAAAA */
8111    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8112    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8113    FETCH(r0, 4)                        @ r0<- CCCC
8114    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8115    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8116    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8117    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8118    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8119    cmp     r0, #0                      @ is resolved entry null?
8120    bne     .LOP_IPUT_OBJECT_JUMBO_finish          @ no, already resolved
81218:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8122    EXPORT_PC()                         @ resolve() could throw
8123    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8124    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8125    b       .LOP_IPUT_OBJECT_JUMBO_resolved        @ resolved, continue
8126
8127/* ------------------------------ */
8128    .balign 64
8129.L_OP_IPUT_BOOLEAN_JUMBO: /* 0x110 */
8130/* File: armv5te/OP_IPUT_BOOLEAN_JUMBO.S */
8131@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"1" }
8132/* File: armv5te/OP_IPUT_JUMBO.S */
8133    /*
8134     * Jumbo 32-bit instance field put.
8135     *
8136     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8137     *      iput-short/jumbo
8138     */
8139    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8140    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8141    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8142    FETCH(r0, 4)                        @ r0<- CCCC
8143    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8144    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8145    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8146    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8147    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8148    cmp     r0, #0                      @ is resolved entry null?
8149    bne     .LOP_IPUT_BOOLEAN_JUMBO_finish          @ no, already resolved
81508:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8151    EXPORT_PC()                         @ resolve() could throw
8152    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8153    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8154    b       .LOP_IPUT_BOOLEAN_JUMBO_resolved        @ resolved, continue
8155
8156
8157/* ------------------------------ */
8158    .balign 64
8159.L_OP_IPUT_BYTE_JUMBO: /* 0x111 */
8160/* File: armv5te/OP_IPUT_BYTE_JUMBO.S */
8161@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"2" }
8162/* File: armv5te/OP_IPUT_JUMBO.S */
8163    /*
8164     * Jumbo 32-bit instance field put.
8165     *
8166     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8167     *      iput-short/jumbo
8168     */
8169    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8170    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8171    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8172    FETCH(r0, 4)                        @ r0<- CCCC
8173    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8174    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8175    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8176    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8177    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8178    cmp     r0, #0                      @ is resolved entry null?
8179    bne     .LOP_IPUT_BYTE_JUMBO_finish          @ no, already resolved
81808:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8181    EXPORT_PC()                         @ resolve() could throw
8182    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8183    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8184    b       .LOP_IPUT_BYTE_JUMBO_resolved        @ resolved, continue
8185
8186
8187/* ------------------------------ */
8188    .balign 64
8189.L_OP_IPUT_CHAR_JUMBO: /* 0x112 */
8190/* File: armv5te/OP_IPUT_CHAR_JUMBO.S */
8191@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"3" }
8192/* File: armv5te/OP_IPUT_JUMBO.S */
8193    /*
8194     * Jumbo 32-bit instance field put.
8195     *
8196     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8197     *      iput-short/jumbo
8198     */
8199    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8200    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8201    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8202    FETCH(r0, 4)                        @ r0<- CCCC
8203    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8204    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8205    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8206    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8207    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8208    cmp     r0, #0                      @ is resolved entry null?
8209    bne     .LOP_IPUT_CHAR_JUMBO_finish          @ no, already resolved
82108:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8211    EXPORT_PC()                         @ resolve() could throw
8212    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8213    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8214    b       .LOP_IPUT_CHAR_JUMBO_resolved        @ resolved, continue
8215
8216
8217/* ------------------------------ */
8218    .balign 64
8219.L_OP_IPUT_SHORT_JUMBO: /* 0x113 */
8220/* File: armv5te/OP_IPUT_SHORT_JUMBO.S */
8221@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"4" }
8222/* File: armv5te/OP_IPUT_JUMBO.S */
8223    /*
8224     * Jumbo 32-bit instance field put.
8225     *
8226     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8227     *      iput-short/jumbo
8228     */
8229    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8230    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8231    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8232    FETCH(r0, 4)                        @ r0<- CCCC
8233    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8234    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8235    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8236    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8237    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8238    cmp     r0, #0                      @ is resolved entry null?
8239    bne     .LOP_IPUT_SHORT_JUMBO_finish          @ no, already resolved
82408:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8241    EXPORT_PC()                         @ resolve() could throw
8242    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8243    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8244    b       .LOP_IPUT_SHORT_JUMBO_resolved        @ resolved, continue
8245
8246
8247/* ------------------------------ */
8248    .balign 64
8249.L_OP_SGET_JUMBO: /* 0x114 */
8250/* File: armv5te/OP_SGET_JUMBO.S */
8251    /*
8252     * Jumbo 32-bit SGET handler.
8253     *
8254     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8255     *      sget-char/jumbo, sget-short/jumbo
8256     */
8257    /* exop vBBBB, field@AAAAAAAA */
8258    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8259    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8260    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8261    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8262    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8263    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8264    cmp     r0, #0                      @ is resolved entry null?
8265    beq     .LOP_SGET_JUMBO_resolve         @ yes, do resolve
8266.LOP_SGET_JUMBO_finish: @ field ptr in r0
8267    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8268    @ no-op                             @ acquiring load
8269    FETCH(r2, 3)                        @ r2<- BBBB
8270    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8271    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8272    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8273    GOTO_OPCODE(ip)                     @ jump to next instruction
8274
8275/* ------------------------------ */
8276    .balign 64
8277.L_OP_SGET_WIDE_JUMBO: /* 0x115 */
8278/* File: armv5te/OP_SGET_WIDE_JUMBO.S */
8279    /*
8280     * Jumbo 64-bit SGET handler.
8281     */
8282    /* sget-wide/jumbo vBBBB, field@AAAAAAAA */
8283    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8284    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8285    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8286    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8287    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8288    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8289    cmp     r0, #0                      @ is resolved entry null?
8290    beq     .LOP_SGET_WIDE_JUMBO_resolve         @ yes, do resolve
8291.LOP_SGET_WIDE_JUMBO_finish:
8292    FETCH(r9, 3)                        @ r9<- BBBB
8293    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
8294    add     r9, rFP, r9, lsl #2         @ r9<- &fp[BBBB]
8295    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8296    stmia   r9, {r0-r1}                 @ vBBBB/vBBBB+1<- r0/r1
8297    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8298    GOTO_OPCODE(ip)                     @ jump to next instruction
8299
8300/* ------------------------------ */
8301    .balign 64
8302.L_OP_SGET_OBJECT_JUMBO: /* 0x116 */
8303/* File: armv5te/OP_SGET_OBJECT_JUMBO.S */
8304/* File: armv5te/OP_SGET_JUMBO.S */
8305    /*
8306     * Jumbo 32-bit SGET handler.
8307     *
8308     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8309     *      sget-char/jumbo, sget-short/jumbo
8310     */
8311    /* exop vBBBB, field@AAAAAAAA */
8312    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8313    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8314    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8315    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8316    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8317    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8318    cmp     r0, #0                      @ is resolved entry null?
8319    beq     .LOP_SGET_OBJECT_JUMBO_resolve         @ yes, do resolve
8320.LOP_SGET_OBJECT_JUMBO_finish: @ field ptr in r0
8321    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8322    @ no-op                             @ acquiring load
8323    FETCH(r2, 3)                        @ r2<- BBBB
8324    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8325    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8326    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8327    GOTO_OPCODE(ip)                     @ jump to next instruction
8328
8329
8330/* ------------------------------ */
8331    .balign 64
8332.L_OP_SGET_BOOLEAN_JUMBO: /* 0x117 */
8333/* File: armv5te/OP_SGET_BOOLEAN_JUMBO.S */
8334/* File: armv5te/OP_SGET_JUMBO.S */
8335    /*
8336     * Jumbo 32-bit SGET handler.
8337     *
8338     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8339     *      sget-char/jumbo, sget-short/jumbo
8340     */
8341    /* exop vBBBB, field@AAAAAAAA */
8342    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8343    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8344    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8345    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8346    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8347    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8348    cmp     r0, #0                      @ is resolved entry null?
8349    beq     .LOP_SGET_BOOLEAN_JUMBO_resolve         @ yes, do resolve
8350.LOP_SGET_BOOLEAN_JUMBO_finish: @ field ptr in r0
8351    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8352    @ no-op                             @ acquiring load
8353    FETCH(r2, 3)                        @ r2<- BBBB
8354    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8355    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8356    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8357    GOTO_OPCODE(ip)                     @ jump to next instruction
8358
8359
8360/* ------------------------------ */
8361    .balign 64
8362.L_OP_SGET_BYTE_JUMBO: /* 0x118 */
8363/* File: armv5te/OP_SGET_BYTE_JUMBO.S */
8364/* File: armv5te/OP_SGET_JUMBO.S */
8365    /*
8366     * Jumbo 32-bit SGET handler.
8367     *
8368     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8369     *      sget-char/jumbo, sget-short/jumbo
8370     */
8371    /* exop vBBBB, field@AAAAAAAA */
8372    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8373    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8374    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8375    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8376    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8377    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8378    cmp     r0, #0                      @ is resolved entry null?
8379    beq     .LOP_SGET_BYTE_JUMBO_resolve         @ yes, do resolve
8380.LOP_SGET_BYTE_JUMBO_finish: @ field ptr in r0
8381    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8382    @ no-op                             @ acquiring load
8383    FETCH(r2, 3)                        @ r2<- BBBB
8384    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8385    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8386    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8387    GOTO_OPCODE(ip)                     @ jump to next instruction
8388
8389
8390/* ------------------------------ */
8391    .balign 64
8392.L_OP_SGET_CHAR_JUMBO: /* 0x119 */
8393/* File: armv5te/OP_SGET_CHAR_JUMBO.S */
8394/* File: armv5te/OP_SGET_JUMBO.S */
8395    /*
8396     * Jumbo 32-bit SGET handler.
8397     *
8398     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8399     *      sget-char/jumbo, sget-short/jumbo
8400     */
8401    /* exop vBBBB, field@AAAAAAAA */
8402    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8403    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8404    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8405    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8406    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8407    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8408    cmp     r0, #0                      @ is resolved entry null?
8409    beq     .LOP_SGET_CHAR_JUMBO_resolve         @ yes, do resolve
8410.LOP_SGET_CHAR_JUMBO_finish: @ field ptr in r0
8411    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8412    @ no-op                             @ acquiring load
8413    FETCH(r2, 3)                        @ r2<- BBBB
8414    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8415    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8416    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8417    GOTO_OPCODE(ip)                     @ jump to next instruction
8418
8419
8420/* ------------------------------ */
8421    .balign 64
8422.L_OP_SGET_SHORT_JUMBO: /* 0x11a */
8423/* File: armv5te/OP_SGET_SHORT_JUMBO.S */
8424/* File: armv5te/OP_SGET_JUMBO.S */
8425    /*
8426     * Jumbo 32-bit SGET handler.
8427     *
8428     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8429     *      sget-char/jumbo, sget-short/jumbo
8430     */
8431    /* exop vBBBB, field@AAAAAAAA */
8432    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8433    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8434    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8435    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8436    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8437    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8438    cmp     r0, #0                      @ is resolved entry null?
8439    beq     .LOP_SGET_SHORT_JUMBO_resolve         @ yes, do resolve
8440.LOP_SGET_SHORT_JUMBO_finish: @ field ptr in r0
8441    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8442    @ no-op                             @ acquiring load
8443    FETCH(r2, 3)                        @ r2<- BBBB
8444    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8445    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8446    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8447    GOTO_OPCODE(ip)                     @ jump to next instruction
8448
8449
8450/* ------------------------------ */
8451    .balign 64
8452.L_OP_SPUT_JUMBO: /* 0x11b */
8453/* File: armv5te/OP_SPUT_JUMBO.S */
8454    /*
8455     * Jumbo 32-bit SPUT handler.
8456     *
8457     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8458     *      sput-short/jumbo
8459     */
8460    /* exop vBBBB, field@AAAAAAAA */
8461    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8462    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8463    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8464    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8465    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8466    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8467    cmp     r0, #0                      @ is resolved entry null?
8468    beq     .LOP_SPUT_JUMBO_resolve         @ yes, do resolve
8469.LOP_SPUT_JUMBO_finish:   @ field ptr in r0
8470    FETCH(r2, 3)                        @ r2<- BBBB
8471    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8472    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8473    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8474    @ no-op                             @ releasing store
8475    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8476    GOTO_OPCODE(ip)                     @ jump to next instruction
8477
8478/* ------------------------------ */
8479    .balign 64
8480.L_OP_SPUT_WIDE_JUMBO: /* 0x11c */
8481/* File: armv5te/OP_SPUT_WIDE_JUMBO.S */
8482    /*
8483     * Jumbo 64-bit SPUT handler.
8484     */
8485    /* sput-wide/jumbo vBBBB, field@AAAAAAAA */
8486    ldr     r0, [rGLUE, #offGlue_methodClassDex]  @ r0<- DvmDex
8487    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8488    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8489    ldr     r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields
8490    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8491    FETCH(r9, 3)                        @ r9<- BBBB
8492    ldr     r2, [r0, r1, lsl #2]        @ r2<- resolved StaticField ptr
8493    add     r9, rFP, r9, lsl #2         @ r9<- &fp[BBBB]
8494    cmp     r2, #0                      @ is resolved entry null?
8495    beq     .LOP_SPUT_WIDE_JUMBO_resolve         @ yes, do resolve
8496.LOP_SPUT_WIDE_JUMBO_finish: @ field ptr in r2, BBBB in r9
8497    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8498    ldmia   r9, {r0-r1}                 @ r0/r1<- vBBBB/vBBBB+1
8499    GET_INST_OPCODE(r10)                @ extract opcode from rINST
8500    strd    r0, [r2, #offStaticField_value] @ field<- vBBBB/vBBBB+1
8501    GOTO_OPCODE(r10)                    @ jump to next instruction
8502
8503/* ------------------------------ */
8504    .balign 64
8505.L_OP_SPUT_OBJECT_JUMBO: /* 0x11d */
8506/* File: armv5te/OP_SPUT_OBJECT_JUMBO.S */
8507    /*
8508     * Jumbo 32-bit SPUT handler for objects
8509     */
8510    /* sput-object/jumbo vBBBB, field@AAAAAAAA */
8511    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8512    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8513    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8514    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8515    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8516    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8517    cmp     r0, #0                      @ is resolved entry null?
8518    bne     .LOP_SPUT_OBJECT_JUMBO_finish          @ no, continue
8519    ldr     r9, [rGLUE, #offGlue_method]    @ r9<- current method
8520    EXPORT_PC()                         @ resolve() could throw, so export now
8521    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
8522    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8523    cmp     r0, #0                      @ success?
8524    bne     .LOP_SPUT_OBJECT_JUMBO_finish          @ yes, finish
8525    b       common_exceptionThrown      @ no, handle exception
8526
8527/* ------------------------------ */
8528    .balign 64
8529.L_OP_SPUT_BOOLEAN_JUMBO: /* 0x11e */
8530/* File: armv5te/OP_SPUT_BOOLEAN_JUMBO.S */
8531/* File: armv5te/OP_SPUT_JUMBO.S */
8532    /*
8533     * Jumbo 32-bit SPUT handler.
8534     *
8535     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8536     *      sput-short/jumbo
8537     */
8538    /* exop vBBBB, field@AAAAAAAA */
8539    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8540    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8541    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8542    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8543    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8544    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8545    cmp     r0, #0                      @ is resolved entry null?
8546    beq     .LOP_SPUT_BOOLEAN_JUMBO_resolve         @ yes, do resolve
8547.LOP_SPUT_BOOLEAN_JUMBO_finish:   @ field ptr in r0
8548    FETCH(r2, 3)                        @ r2<- BBBB
8549    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8550    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8551    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8552    @ no-op                             @ releasing store
8553    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8554    GOTO_OPCODE(ip)                     @ jump to next instruction
8555
8556
8557/* ------------------------------ */
8558    .balign 64
8559.L_OP_SPUT_BYTE_JUMBO: /* 0x11f */
8560/* File: armv5te/OP_SPUT_BYTE_JUMBO.S */
8561/* File: armv5te/OP_SPUT_JUMBO.S */
8562    /*
8563     * Jumbo 32-bit SPUT handler.
8564     *
8565     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8566     *      sput-short/jumbo
8567     */
8568    /* exop vBBBB, field@AAAAAAAA */
8569    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8570    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8571    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8572    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8573    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8574    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8575    cmp     r0, #0                      @ is resolved entry null?
8576    beq     .LOP_SPUT_BYTE_JUMBO_resolve         @ yes, do resolve
8577.LOP_SPUT_BYTE_JUMBO_finish:   @ field ptr in r0
8578    FETCH(r2, 3)                        @ r2<- BBBB
8579    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8580    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8581    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8582    @ no-op                             @ releasing store
8583    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8584    GOTO_OPCODE(ip)                     @ jump to next instruction
8585
8586
8587/* ------------------------------ */
8588    .balign 64
8589.L_OP_SPUT_CHAR_JUMBO: /* 0x120 */
8590/* File: armv5te/OP_SPUT_CHAR_JUMBO.S */
8591/* File: armv5te/OP_SPUT_JUMBO.S */
8592    /*
8593     * Jumbo 32-bit SPUT handler.
8594     *
8595     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8596     *      sput-short/jumbo
8597     */
8598    /* exop vBBBB, field@AAAAAAAA */
8599    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8600    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8601    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8602    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8603    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8604    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8605    cmp     r0, #0                      @ is resolved entry null?
8606    beq     .LOP_SPUT_CHAR_JUMBO_resolve         @ yes, do resolve
8607.LOP_SPUT_CHAR_JUMBO_finish:   @ field ptr in r0
8608    FETCH(r2, 3)                        @ r2<- BBBB
8609    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8610    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8611    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8612    @ no-op                             @ releasing store
8613    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8614    GOTO_OPCODE(ip)                     @ jump to next instruction
8615
8616
8617/* ------------------------------ */
8618    .balign 64
8619.L_OP_SPUT_SHORT_JUMBO: /* 0x121 */
8620/* File: armv5te/OP_SPUT_SHORT_JUMBO.S */
8621/* File: armv5te/OP_SPUT_JUMBO.S */
8622    /*
8623     * Jumbo 32-bit SPUT handler.
8624     *
8625     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8626     *      sput-short/jumbo
8627     */
8628    /* exop vBBBB, field@AAAAAAAA */
8629    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8630    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8631    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8632    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8633    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8634    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8635    cmp     r0, #0                      @ is resolved entry null?
8636    beq     .LOP_SPUT_SHORT_JUMBO_resolve         @ yes, do resolve
8637.LOP_SPUT_SHORT_JUMBO_finish:   @ field ptr in r0
8638    FETCH(r2, 3)                        @ r2<- BBBB
8639    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8640    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8641    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8642    @ no-op                             @ releasing store
8643    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8644    GOTO_OPCODE(ip)                     @ jump to next instruction
8645
8646
8647/* ------------------------------ */
8648    .balign 64
8649.L_OP_INVOKE_VIRTUAL_JUMBO: /* 0x122 */
8650/* File: armv5te/OP_INVOKE_VIRTUAL_JUMBO.S */
8651    /*
8652     * Handle a virtual method call.
8653     */
8654    /* invoke-virtual/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8655    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
8656    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8657    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8658    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8659    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8660    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
8661    cmp     r0, #0                      @ already resolved?
8662    EXPORT_PC()                         @ must export for invoke
8663    bne     .LOP_INVOKE_VIRTUAL_JUMBO_continue        @ yes, continue on
8664    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
8665    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8666    mov     r2, #METHOD_VIRTUAL         @ resolver method type
8667    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
8668    cmp     r0, #0                      @ got null?
8669    bne     .LOP_INVOKE_VIRTUAL_JUMBO_continue        @ no, continue
8670    b       common_exceptionThrown      @ yes, handle exception
8671
8672/* ------------------------------ */
8673    .balign 64
8674.L_OP_INVOKE_SUPER_JUMBO: /* 0x123 */
8675/* File: armv5te/OP_INVOKE_SUPER_JUMBO.S */
8676    /*
8677     * Handle a "super" method call.
8678     */
8679    /* invoke-super/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8680    FETCH(r10, 4)                       @ r10<- CCCC
8681    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
8682    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8683    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8684    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8685    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8686    GET_VREG(r2, r10)                   @ r2<- "this" ptr
8687    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
8688    cmp     r2, #0                      @ null "this"?
8689    ldr     r9, [rGLUE, #offGlue_method] @ r9<- current method
8690    beq     common_errNullObject        @ null "this", throw exception
8691    cmp     r0, #0                      @ already resolved?
8692    ldr     r9, [r9, #offMethod_clazz]  @ r9<- method->clazz
8693    EXPORT_PC()                         @ must export for invoke
8694    bne     .LOP_INVOKE_SUPER_JUMBO_continue        @ resolved, continue on
8695    b       .LOP_INVOKE_SUPER_JUMBO_resolve         @ do resolve now
8696
8697/* ------------------------------ */
8698    .balign 64
8699.L_OP_INVOKE_DIRECT_JUMBO: /* 0x124 */
8700/* File: armv5te/OP_INVOKE_DIRECT_JUMBO.S */
8701    /*
8702     * Handle a direct method call.
8703     *
8704     * (We could defer the "is 'this' pointer null" test to the common
8705     * method invocation code, and use a flag to indicate that static
8706     * calls don't count.  If we do this as part of copying the arguments
8707     * out we could avoiding loading the first arg twice.)
8708     *
8709     */
8710    /* invoke-direct/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8711    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
8712    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8713    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8714    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8715    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8716    FETCH(r10, 4)                       @ r10<- CCCC
8717    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
8718    cmp     r0, #0                      @ already resolved?
8719    EXPORT_PC()                         @ must export for invoke
8720    GET_VREG(r2, r10)                   @ r2<- "this" ptr
8721    beq     .LOP_INVOKE_DIRECT_JUMBO_resolve         @ not resolved, do it now
8722.LOP_INVOKE_DIRECT_JUMBO_finish:
8723    cmp     r2, #0                      @ null "this" ref?
8724    bne     common_invokeMethodJumbo    @ no, continue on
8725    b       common_errNullObject        @ yes, throw exception
8726
8727/* ------------------------------ */
8728    .balign 64
8729.L_OP_INVOKE_STATIC_JUMBO: /* 0x125 */
8730/* File: armv5te/OP_INVOKE_STATIC_JUMBO.S */
8731    /*
8732     * Handle a static method call.
8733     */
8734    /* invoke-static/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8735    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
8736    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8737    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8738    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8739    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8740    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
8741    cmp     r0, #0                      @ already resolved?
8742    EXPORT_PC()                         @ must export for invoke
8743    bne     common_invokeMethodJumbo    @ yes, continue on
87440:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
8745    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8746    mov     r2, #METHOD_STATIC          @ resolver method type
8747    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
8748    cmp     r0, #0                      @ got null?
8749    bne     common_invokeMethodJumbo    @ no, continue
8750    b       common_exceptionThrown      @ yes, handle exception
8751
8752/* ------------------------------ */
8753    .balign 64
8754.L_OP_INVOKE_INTERFACE_JUMBO: /* 0x126 */
8755/* File: armv5te/OP_INVOKE_INTERFACE_JUMBO.S */
8756    /*
8757     * Handle an interface method call.
8758     */
8759    /* invoke-interface/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8760    FETCH(r2, 4)                        @ r2<- CCCC
8761    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8762    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8763    EXPORT_PC()                         @ must export for invoke
8764    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8765    GET_VREG(r0, r2)                    @ r0<- first arg ("this")
8766    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- methodClassDex
8767    cmp     r0, #0                      @ null obj?
8768    ldr     r2, [rGLUE, #offGlue_method]  @ r2<- method
8769    beq     common_errNullObject        @ yes, fail
8770    ldr     r0, [r0, #offObject_clazz]  @ r0<- thisPtr->clazz
8771    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
8772    cmp     r0, #0                      @ failed?
8773    beq     common_exceptionThrown      @ yes, handle exception
8774    b       common_invokeMethodJumbo    @ jump to common handler
8775
8776/* ------------------------------ */
8777    .balign 64
8778.L_OP_UNUSED_27FF: /* 0x127 */
8779/* File: armv5te/OP_UNUSED_27FF.S */
8780/* File: armv5te/unused.S */
8781    bl      common_abort
8782
8783
8784/* ------------------------------ */
8785    .balign 64
8786.L_OP_UNUSED_28FF: /* 0x128 */
8787/* File: armv5te/OP_UNUSED_28FF.S */
8788/* File: armv5te/unused.S */
8789    bl      common_abort
8790
8791
8792/* ------------------------------ */
8793    .balign 64
8794.L_OP_UNUSED_29FF: /* 0x129 */
8795/* File: armv5te/OP_UNUSED_29FF.S */
8796/* File: armv5te/unused.S */
8797    bl      common_abort
8798
8799
8800/* ------------------------------ */
8801    .balign 64
8802.L_OP_UNUSED_2AFF: /* 0x12a */
8803/* File: armv5te/OP_UNUSED_2AFF.S */
8804/* File: armv5te/unused.S */
8805    bl      common_abort
8806
8807
8808/* ------------------------------ */
8809    .balign 64
8810.L_OP_UNUSED_2BFF: /* 0x12b */
8811/* File: armv5te/OP_UNUSED_2BFF.S */
8812/* File: armv5te/unused.S */
8813    bl      common_abort
8814
8815
8816/* ------------------------------ */
8817    .balign 64
8818.L_OP_UNUSED_2CFF: /* 0x12c */
8819/* File: armv5te/OP_UNUSED_2CFF.S */
8820/* File: armv5te/unused.S */
8821    bl      common_abort
8822
8823
8824/* ------------------------------ */
8825    .balign 64
8826.L_OP_UNUSED_2DFF: /* 0x12d */
8827/* File: armv5te/OP_UNUSED_2DFF.S */
8828/* File: armv5te/unused.S */
8829    bl      common_abort
8830
8831
8832/* ------------------------------ */
8833    .balign 64
8834.L_OP_UNUSED_2EFF: /* 0x12e */
8835/* File: armv5te/OP_UNUSED_2EFF.S */
8836/* File: armv5te/unused.S */
8837    bl      common_abort
8838
8839
8840/* ------------------------------ */
8841    .balign 64
8842.L_OP_UNUSED_2FFF: /* 0x12f */
8843/* File: armv5te/OP_UNUSED_2FFF.S */
8844/* File: armv5te/unused.S */
8845    bl      common_abort
8846
8847
8848/* ------------------------------ */
8849    .balign 64
8850.L_OP_UNUSED_30FF: /* 0x130 */
8851/* File: armv5te/OP_UNUSED_30FF.S */
8852/* File: armv5te/unused.S */
8853    bl      common_abort
8854
8855
8856/* ------------------------------ */
8857    .balign 64
8858.L_OP_UNUSED_31FF: /* 0x131 */
8859/* File: armv5te/OP_UNUSED_31FF.S */
8860/* File: armv5te/unused.S */
8861    bl      common_abort
8862
8863
8864/* ------------------------------ */
8865    .balign 64
8866.L_OP_UNUSED_32FF: /* 0x132 */
8867/* File: armv5te/OP_UNUSED_32FF.S */
8868/* File: armv5te/unused.S */
8869    bl      common_abort
8870
8871
8872/* ------------------------------ */
8873    .balign 64
8874.L_OP_UNUSED_33FF: /* 0x133 */
8875/* File: armv5te/OP_UNUSED_33FF.S */
8876/* File: armv5te/unused.S */
8877    bl      common_abort
8878
8879
8880/* ------------------------------ */
8881    .balign 64
8882.L_OP_UNUSED_34FF: /* 0x134 */
8883/* File: armv5te/OP_UNUSED_34FF.S */
8884/* File: armv5te/unused.S */
8885    bl      common_abort
8886
8887
8888/* ------------------------------ */
8889    .balign 64
8890.L_OP_UNUSED_35FF: /* 0x135 */
8891/* File: armv5te/OP_UNUSED_35FF.S */
8892/* File: armv5te/unused.S */
8893    bl      common_abort
8894
8895
8896/* ------------------------------ */
8897    .balign 64
8898.L_OP_UNUSED_36FF: /* 0x136 */
8899/* File: armv5te/OP_UNUSED_36FF.S */
8900/* File: armv5te/unused.S */
8901    bl      common_abort
8902
8903
8904/* ------------------------------ */
8905    .balign 64
8906.L_OP_UNUSED_37FF: /* 0x137 */
8907/* File: armv5te/OP_UNUSED_37FF.S */
8908/* File: armv5te/unused.S */
8909    bl      common_abort
8910
8911
8912/* ------------------------------ */
8913    .balign 64
8914.L_OP_UNUSED_38FF: /* 0x138 */
8915/* File: armv5te/OP_UNUSED_38FF.S */
8916/* File: armv5te/unused.S */
8917    bl      common_abort
8918
8919
8920/* ------------------------------ */
8921    .balign 64
8922.L_OP_UNUSED_39FF: /* 0x139 */
8923/* File: armv5te/OP_UNUSED_39FF.S */
8924/* File: armv5te/unused.S */
8925    bl      common_abort
8926
8927
8928/* ------------------------------ */
8929    .balign 64
8930.L_OP_UNUSED_3AFF: /* 0x13a */
8931/* File: armv5te/OP_UNUSED_3AFF.S */
8932/* File: armv5te/unused.S */
8933    bl      common_abort
8934
8935
8936/* ------------------------------ */
8937    .balign 64
8938.L_OP_UNUSED_3BFF: /* 0x13b */
8939/* File: armv5te/OP_UNUSED_3BFF.S */
8940/* File: armv5te/unused.S */
8941    bl      common_abort
8942
8943
8944/* ------------------------------ */
8945    .balign 64
8946.L_OP_UNUSED_3CFF: /* 0x13c */
8947/* File: armv5te/OP_UNUSED_3CFF.S */
8948/* File: armv5te/unused.S */
8949    bl      common_abort
8950
8951
8952/* ------------------------------ */
8953    .balign 64
8954.L_OP_UNUSED_3DFF: /* 0x13d */
8955/* File: armv5te/OP_UNUSED_3DFF.S */
8956/* File: armv5te/unused.S */
8957    bl      common_abort
8958
8959
8960/* ------------------------------ */
8961    .balign 64
8962.L_OP_UNUSED_3EFF: /* 0x13e */
8963/* File: armv5te/OP_UNUSED_3EFF.S */
8964/* File: armv5te/unused.S */
8965    bl      common_abort
8966
8967
8968/* ------------------------------ */
8969    .balign 64
8970.L_OP_UNUSED_3FFF: /* 0x13f */
8971/* File: armv5te/OP_UNUSED_3FFF.S */
8972/* File: armv5te/unused.S */
8973    bl      common_abort
8974
8975
8976/* ------------------------------ */
8977    .balign 64
8978.L_OP_UNUSED_40FF: /* 0x140 */
8979/* File: armv5te/OP_UNUSED_40FF.S */
8980/* File: armv5te/unused.S */
8981    bl      common_abort
8982
8983
8984/* ------------------------------ */
8985    .balign 64
8986.L_OP_UNUSED_41FF: /* 0x141 */
8987/* File: armv5te/OP_UNUSED_41FF.S */
8988/* File: armv5te/unused.S */
8989    bl      common_abort
8990
8991
8992/* ------------------------------ */
8993    .balign 64
8994.L_OP_UNUSED_42FF: /* 0x142 */
8995/* File: armv5te/OP_UNUSED_42FF.S */
8996/* File: armv5te/unused.S */
8997    bl      common_abort
8998
8999
9000/* ------------------------------ */
9001    .balign 64
9002.L_OP_UNUSED_43FF: /* 0x143 */
9003/* File: armv5te/OP_UNUSED_43FF.S */
9004/* File: armv5te/unused.S */
9005    bl      common_abort
9006
9007
9008/* ------------------------------ */
9009    .balign 64
9010.L_OP_UNUSED_44FF: /* 0x144 */
9011/* File: armv5te/OP_UNUSED_44FF.S */
9012/* File: armv5te/unused.S */
9013    bl      common_abort
9014
9015
9016/* ------------------------------ */
9017    .balign 64
9018.L_OP_UNUSED_45FF: /* 0x145 */
9019/* File: armv5te/OP_UNUSED_45FF.S */
9020/* File: armv5te/unused.S */
9021    bl      common_abort
9022
9023
9024/* ------------------------------ */
9025    .balign 64
9026.L_OP_UNUSED_46FF: /* 0x146 */
9027/* File: armv5te/OP_UNUSED_46FF.S */
9028/* File: armv5te/unused.S */
9029    bl      common_abort
9030
9031
9032/* ------------------------------ */
9033    .balign 64
9034.L_OP_UNUSED_47FF: /* 0x147 */
9035/* File: armv5te/OP_UNUSED_47FF.S */
9036/* File: armv5te/unused.S */
9037    bl      common_abort
9038
9039
9040/* ------------------------------ */
9041    .balign 64
9042.L_OP_UNUSED_48FF: /* 0x148 */
9043/* File: armv5te/OP_UNUSED_48FF.S */
9044/* File: armv5te/unused.S */
9045    bl      common_abort
9046
9047
9048/* ------------------------------ */
9049    .balign 64
9050.L_OP_UNUSED_49FF: /* 0x149 */
9051/* File: armv5te/OP_UNUSED_49FF.S */
9052/* File: armv5te/unused.S */
9053    bl      common_abort
9054
9055
9056/* ------------------------------ */
9057    .balign 64
9058.L_OP_UNUSED_4AFF: /* 0x14a */
9059/* File: armv5te/OP_UNUSED_4AFF.S */
9060/* File: armv5te/unused.S */
9061    bl      common_abort
9062
9063
9064/* ------------------------------ */
9065    .balign 64
9066.L_OP_UNUSED_4BFF: /* 0x14b */
9067/* File: armv5te/OP_UNUSED_4BFF.S */
9068/* File: armv5te/unused.S */
9069    bl      common_abort
9070
9071
9072/* ------------------------------ */
9073    .balign 64
9074.L_OP_UNUSED_4CFF: /* 0x14c */
9075/* File: armv5te/OP_UNUSED_4CFF.S */
9076/* File: armv5te/unused.S */
9077    bl      common_abort
9078
9079
9080/* ------------------------------ */
9081    .balign 64
9082.L_OP_UNUSED_4DFF: /* 0x14d */
9083/* File: armv5te/OP_UNUSED_4DFF.S */
9084/* File: armv5te/unused.S */
9085    bl      common_abort
9086
9087
9088/* ------------------------------ */
9089    .balign 64
9090.L_OP_UNUSED_4EFF: /* 0x14e */
9091/* File: armv5te/OP_UNUSED_4EFF.S */
9092/* File: armv5te/unused.S */
9093    bl      common_abort
9094
9095
9096/* ------------------------------ */
9097    .balign 64
9098.L_OP_UNUSED_4FFF: /* 0x14f */
9099/* File: armv5te/OP_UNUSED_4FFF.S */
9100/* File: armv5te/unused.S */
9101    bl      common_abort
9102
9103
9104/* ------------------------------ */
9105    .balign 64
9106.L_OP_UNUSED_50FF: /* 0x150 */
9107/* File: armv5te/OP_UNUSED_50FF.S */
9108/* File: armv5te/unused.S */
9109    bl      common_abort
9110
9111
9112/* ------------------------------ */
9113    .balign 64
9114.L_OP_UNUSED_51FF: /* 0x151 */
9115/* File: armv5te/OP_UNUSED_51FF.S */
9116/* File: armv5te/unused.S */
9117    bl      common_abort
9118
9119
9120/* ------------------------------ */
9121    .balign 64
9122.L_OP_UNUSED_52FF: /* 0x152 */
9123/* File: armv5te/OP_UNUSED_52FF.S */
9124/* File: armv5te/unused.S */
9125    bl      common_abort
9126
9127
9128/* ------------------------------ */
9129    .balign 64
9130.L_OP_UNUSED_53FF: /* 0x153 */
9131/* File: armv5te/OP_UNUSED_53FF.S */
9132/* File: armv5te/unused.S */
9133    bl      common_abort
9134
9135
9136/* ------------------------------ */
9137    .balign 64
9138.L_OP_UNUSED_54FF: /* 0x154 */
9139/* File: armv5te/OP_UNUSED_54FF.S */
9140/* File: armv5te/unused.S */
9141    bl      common_abort
9142
9143
9144/* ------------------------------ */
9145    .balign 64
9146.L_OP_UNUSED_55FF: /* 0x155 */
9147/* File: armv5te/OP_UNUSED_55FF.S */
9148/* File: armv5te/unused.S */
9149    bl      common_abort
9150
9151
9152/* ------------------------------ */
9153    .balign 64
9154.L_OP_UNUSED_56FF: /* 0x156 */
9155/* File: armv5te/OP_UNUSED_56FF.S */
9156/* File: armv5te/unused.S */
9157    bl      common_abort
9158
9159
9160/* ------------------------------ */
9161    .balign 64
9162.L_OP_UNUSED_57FF: /* 0x157 */
9163/* File: armv5te/OP_UNUSED_57FF.S */
9164/* File: armv5te/unused.S */
9165    bl      common_abort
9166
9167
9168/* ------------------------------ */
9169    .balign 64
9170.L_OP_UNUSED_58FF: /* 0x158 */
9171/* File: armv5te/OP_UNUSED_58FF.S */
9172/* File: armv5te/unused.S */
9173    bl      common_abort
9174
9175
9176/* ------------------------------ */
9177    .balign 64
9178.L_OP_UNUSED_59FF: /* 0x159 */
9179/* File: armv5te/OP_UNUSED_59FF.S */
9180/* File: armv5te/unused.S */
9181    bl      common_abort
9182
9183
9184/* ------------------------------ */
9185    .balign 64
9186.L_OP_UNUSED_5AFF: /* 0x15a */
9187/* File: armv5te/OP_UNUSED_5AFF.S */
9188/* File: armv5te/unused.S */
9189    bl      common_abort
9190
9191
9192/* ------------------------------ */
9193    .balign 64
9194.L_OP_UNUSED_5BFF: /* 0x15b */
9195/* File: armv5te/OP_UNUSED_5BFF.S */
9196/* File: armv5te/unused.S */
9197    bl      common_abort
9198
9199
9200/* ------------------------------ */
9201    .balign 64
9202.L_OP_UNUSED_5CFF: /* 0x15c */
9203/* File: armv5te/OP_UNUSED_5CFF.S */
9204/* File: armv5te/unused.S */
9205    bl      common_abort
9206
9207
9208/* ------------------------------ */
9209    .balign 64
9210.L_OP_UNUSED_5DFF: /* 0x15d */
9211/* File: armv5te/OP_UNUSED_5DFF.S */
9212/* File: armv5te/unused.S */
9213    bl      common_abort
9214
9215
9216/* ------------------------------ */
9217    .balign 64
9218.L_OP_UNUSED_5EFF: /* 0x15e */
9219/* File: armv5te/OP_UNUSED_5EFF.S */
9220/* File: armv5te/unused.S */
9221    bl      common_abort
9222
9223
9224/* ------------------------------ */
9225    .balign 64
9226.L_OP_UNUSED_5FFF: /* 0x15f */
9227/* File: armv5te/OP_UNUSED_5FFF.S */
9228/* File: armv5te/unused.S */
9229    bl      common_abort
9230
9231
9232/* ------------------------------ */
9233    .balign 64
9234.L_OP_UNUSED_60FF: /* 0x160 */
9235/* File: armv5te/OP_UNUSED_60FF.S */
9236/* File: armv5te/unused.S */
9237    bl      common_abort
9238
9239
9240/* ------------------------------ */
9241    .balign 64
9242.L_OP_UNUSED_61FF: /* 0x161 */
9243/* File: armv5te/OP_UNUSED_61FF.S */
9244/* File: armv5te/unused.S */
9245    bl      common_abort
9246
9247
9248/* ------------------------------ */
9249    .balign 64
9250.L_OP_UNUSED_62FF: /* 0x162 */
9251/* File: armv5te/OP_UNUSED_62FF.S */
9252/* File: armv5te/unused.S */
9253    bl      common_abort
9254
9255
9256/* ------------------------------ */
9257    .balign 64
9258.L_OP_UNUSED_63FF: /* 0x163 */
9259/* File: armv5te/OP_UNUSED_63FF.S */
9260/* File: armv5te/unused.S */
9261    bl      common_abort
9262
9263
9264/* ------------------------------ */
9265    .balign 64
9266.L_OP_UNUSED_64FF: /* 0x164 */
9267/* File: armv5te/OP_UNUSED_64FF.S */
9268/* File: armv5te/unused.S */
9269    bl      common_abort
9270
9271
9272/* ------------------------------ */
9273    .balign 64
9274.L_OP_UNUSED_65FF: /* 0x165 */
9275/* File: armv5te/OP_UNUSED_65FF.S */
9276/* File: armv5te/unused.S */
9277    bl      common_abort
9278
9279
9280/* ------------------------------ */
9281    .balign 64
9282.L_OP_UNUSED_66FF: /* 0x166 */
9283/* File: armv5te/OP_UNUSED_66FF.S */
9284/* File: armv5te/unused.S */
9285    bl      common_abort
9286
9287
9288/* ------------------------------ */
9289    .balign 64
9290.L_OP_UNUSED_67FF: /* 0x167 */
9291/* File: armv5te/OP_UNUSED_67FF.S */
9292/* File: armv5te/unused.S */
9293    bl      common_abort
9294
9295
9296/* ------------------------------ */
9297    .balign 64
9298.L_OP_UNUSED_68FF: /* 0x168 */
9299/* File: armv5te/OP_UNUSED_68FF.S */
9300/* File: armv5te/unused.S */
9301    bl      common_abort
9302
9303
9304/* ------------------------------ */
9305    .balign 64
9306.L_OP_UNUSED_69FF: /* 0x169 */
9307/* File: armv5te/OP_UNUSED_69FF.S */
9308/* File: armv5te/unused.S */
9309    bl      common_abort
9310
9311
9312/* ------------------------------ */
9313    .balign 64
9314.L_OP_UNUSED_6AFF: /* 0x16a */
9315/* File: armv5te/OP_UNUSED_6AFF.S */
9316/* File: armv5te/unused.S */
9317    bl      common_abort
9318
9319
9320/* ------------------------------ */
9321    .balign 64
9322.L_OP_UNUSED_6BFF: /* 0x16b */
9323/* File: armv5te/OP_UNUSED_6BFF.S */
9324/* File: armv5te/unused.S */
9325    bl      common_abort
9326
9327
9328/* ------------------------------ */
9329    .balign 64
9330.L_OP_UNUSED_6CFF: /* 0x16c */
9331/* File: armv5te/OP_UNUSED_6CFF.S */
9332/* File: armv5te/unused.S */
9333    bl      common_abort
9334
9335
9336/* ------------------------------ */
9337    .balign 64
9338.L_OP_UNUSED_6DFF: /* 0x16d */
9339/* File: armv5te/OP_UNUSED_6DFF.S */
9340/* File: armv5te/unused.S */
9341    bl      common_abort
9342
9343
9344/* ------------------------------ */
9345    .balign 64
9346.L_OP_UNUSED_6EFF: /* 0x16e */
9347/* File: armv5te/OP_UNUSED_6EFF.S */
9348/* File: armv5te/unused.S */
9349    bl      common_abort
9350
9351
9352/* ------------------------------ */
9353    .balign 64
9354.L_OP_UNUSED_6FFF: /* 0x16f */
9355/* File: armv5te/OP_UNUSED_6FFF.S */
9356/* File: armv5te/unused.S */
9357    bl      common_abort
9358
9359
9360/* ------------------------------ */
9361    .balign 64
9362.L_OP_UNUSED_70FF: /* 0x170 */
9363/* File: armv5te/OP_UNUSED_70FF.S */
9364/* File: armv5te/unused.S */
9365    bl      common_abort
9366
9367
9368/* ------------------------------ */
9369    .balign 64
9370.L_OP_UNUSED_71FF: /* 0x171 */
9371/* File: armv5te/OP_UNUSED_71FF.S */
9372/* File: armv5te/unused.S */
9373    bl      common_abort
9374
9375
9376/* ------------------------------ */
9377    .balign 64
9378.L_OP_UNUSED_72FF: /* 0x172 */
9379/* File: armv5te/OP_UNUSED_72FF.S */
9380/* File: armv5te/unused.S */
9381    bl      common_abort
9382
9383
9384/* ------------------------------ */
9385    .balign 64
9386.L_OP_UNUSED_73FF: /* 0x173 */
9387/* File: armv5te/OP_UNUSED_73FF.S */
9388/* File: armv5te/unused.S */
9389    bl      common_abort
9390
9391
9392/* ------------------------------ */
9393    .balign 64
9394.L_OP_UNUSED_74FF: /* 0x174 */
9395/* File: armv5te/OP_UNUSED_74FF.S */
9396/* File: armv5te/unused.S */
9397    bl      common_abort
9398
9399
9400/* ------------------------------ */
9401    .balign 64
9402.L_OP_UNUSED_75FF: /* 0x175 */
9403/* File: armv5te/OP_UNUSED_75FF.S */
9404/* File: armv5te/unused.S */
9405    bl      common_abort
9406
9407
9408/* ------------------------------ */
9409    .balign 64
9410.L_OP_UNUSED_76FF: /* 0x176 */
9411/* File: armv5te/OP_UNUSED_76FF.S */
9412/* File: armv5te/unused.S */
9413    bl      common_abort
9414
9415
9416/* ------------------------------ */
9417    .balign 64
9418.L_OP_UNUSED_77FF: /* 0x177 */
9419/* File: armv5te/OP_UNUSED_77FF.S */
9420/* File: armv5te/unused.S */
9421    bl      common_abort
9422
9423
9424/* ------------------------------ */
9425    .balign 64
9426.L_OP_UNUSED_78FF: /* 0x178 */
9427/* File: armv5te/OP_UNUSED_78FF.S */
9428/* File: armv5te/unused.S */
9429    bl      common_abort
9430
9431
9432/* ------------------------------ */
9433    .balign 64
9434.L_OP_UNUSED_79FF: /* 0x179 */
9435/* File: armv5te/OP_UNUSED_79FF.S */
9436/* File: armv5te/unused.S */
9437    bl      common_abort
9438
9439
9440/* ------------------------------ */
9441    .balign 64
9442.L_OP_UNUSED_7AFF: /* 0x17a */
9443/* File: armv5te/OP_UNUSED_7AFF.S */
9444/* File: armv5te/unused.S */
9445    bl      common_abort
9446
9447
9448/* ------------------------------ */
9449    .balign 64
9450.L_OP_UNUSED_7BFF: /* 0x17b */
9451/* File: armv5te/OP_UNUSED_7BFF.S */
9452/* File: armv5te/unused.S */
9453    bl      common_abort
9454
9455
9456/* ------------------------------ */
9457    .balign 64
9458.L_OP_UNUSED_7CFF: /* 0x17c */
9459/* File: armv5te/OP_UNUSED_7CFF.S */
9460/* File: armv5te/unused.S */
9461    bl      common_abort
9462
9463
9464/* ------------------------------ */
9465    .balign 64
9466.L_OP_UNUSED_7DFF: /* 0x17d */
9467/* File: armv5te/OP_UNUSED_7DFF.S */
9468/* File: armv5te/unused.S */
9469    bl      common_abort
9470
9471
9472/* ------------------------------ */
9473    .balign 64
9474.L_OP_UNUSED_7EFF: /* 0x17e */
9475/* File: armv5te/OP_UNUSED_7EFF.S */
9476/* File: armv5te/unused.S */
9477    bl      common_abort
9478
9479
9480/* ------------------------------ */
9481    .balign 64
9482.L_OP_UNUSED_7FFF: /* 0x17f */
9483/* File: armv5te/OP_UNUSED_7FFF.S */
9484/* File: armv5te/unused.S */
9485    bl      common_abort
9486
9487
9488/* ------------------------------ */
9489    .balign 64
9490.L_OP_UNUSED_80FF: /* 0x180 */
9491/* File: armv5te/OP_UNUSED_80FF.S */
9492/* File: armv5te/unused.S */
9493    bl      common_abort
9494
9495
9496/* ------------------------------ */
9497    .balign 64
9498.L_OP_UNUSED_81FF: /* 0x181 */
9499/* File: armv5te/OP_UNUSED_81FF.S */
9500/* File: armv5te/unused.S */
9501    bl      common_abort
9502
9503
9504/* ------------------------------ */
9505    .balign 64
9506.L_OP_UNUSED_82FF: /* 0x182 */
9507/* File: armv5te/OP_UNUSED_82FF.S */
9508/* File: armv5te/unused.S */
9509    bl      common_abort
9510
9511
9512/* ------------------------------ */
9513    .balign 64
9514.L_OP_UNUSED_83FF: /* 0x183 */
9515/* File: armv5te/OP_UNUSED_83FF.S */
9516/* File: armv5te/unused.S */
9517    bl      common_abort
9518
9519
9520/* ------------------------------ */
9521    .balign 64
9522.L_OP_UNUSED_84FF: /* 0x184 */
9523/* File: armv5te/OP_UNUSED_84FF.S */
9524/* File: armv5te/unused.S */
9525    bl      common_abort
9526
9527
9528/* ------------------------------ */
9529    .balign 64
9530.L_OP_UNUSED_85FF: /* 0x185 */
9531/* File: armv5te/OP_UNUSED_85FF.S */
9532/* File: armv5te/unused.S */
9533    bl      common_abort
9534
9535
9536/* ------------------------------ */
9537    .balign 64
9538.L_OP_UNUSED_86FF: /* 0x186 */
9539/* File: armv5te/OP_UNUSED_86FF.S */
9540/* File: armv5te/unused.S */
9541    bl      common_abort
9542
9543
9544/* ------------------------------ */
9545    .balign 64
9546.L_OP_UNUSED_87FF: /* 0x187 */
9547/* File: armv5te/OP_UNUSED_87FF.S */
9548/* File: armv5te/unused.S */
9549    bl      common_abort
9550
9551
9552/* ------------------------------ */
9553    .balign 64
9554.L_OP_UNUSED_88FF: /* 0x188 */
9555/* File: armv5te/OP_UNUSED_88FF.S */
9556/* File: armv5te/unused.S */
9557    bl      common_abort
9558
9559
9560/* ------------------------------ */
9561    .balign 64
9562.L_OP_UNUSED_89FF: /* 0x189 */
9563/* File: armv5te/OP_UNUSED_89FF.S */
9564/* File: armv5te/unused.S */
9565    bl      common_abort
9566
9567
9568/* ------------------------------ */
9569    .balign 64
9570.L_OP_UNUSED_8AFF: /* 0x18a */
9571/* File: armv5te/OP_UNUSED_8AFF.S */
9572/* File: armv5te/unused.S */
9573    bl      common_abort
9574
9575
9576/* ------------------------------ */
9577    .balign 64
9578.L_OP_UNUSED_8BFF: /* 0x18b */
9579/* File: armv5te/OP_UNUSED_8BFF.S */
9580/* File: armv5te/unused.S */
9581    bl      common_abort
9582
9583
9584/* ------------------------------ */
9585    .balign 64
9586.L_OP_UNUSED_8CFF: /* 0x18c */
9587/* File: armv5te/OP_UNUSED_8CFF.S */
9588/* File: armv5te/unused.S */
9589    bl      common_abort
9590
9591
9592/* ------------------------------ */
9593    .balign 64
9594.L_OP_UNUSED_8DFF: /* 0x18d */
9595/* File: armv5te/OP_UNUSED_8DFF.S */
9596/* File: armv5te/unused.S */
9597    bl      common_abort
9598
9599
9600/* ------------------------------ */
9601    .balign 64
9602.L_OP_UNUSED_8EFF: /* 0x18e */
9603/* File: armv5te/OP_UNUSED_8EFF.S */
9604/* File: armv5te/unused.S */
9605    bl      common_abort
9606
9607
9608/* ------------------------------ */
9609    .balign 64
9610.L_OP_UNUSED_8FFF: /* 0x18f */
9611/* File: armv5te/OP_UNUSED_8FFF.S */
9612/* File: armv5te/unused.S */
9613    bl      common_abort
9614
9615
9616/* ------------------------------ */
9617    .balign 64
9618.L_OP_UNUSED_90FF: /* 0x190 */
9619/* File: armv5te/OP_UNUSED_90FF.S */
9620/* File: armv5te/unused.S */
9621    bl      common_abort
9622
9623
9624/* ------------------------------ */
9625    .balign 64
9626.L_OP_UNUSED_91FF: /* 0x191 */
9627/* File: armv5te/OP_UNUSED_91FF.S */
9628/* File: armv5te/unused.S */
9629    bl      common_abort
9630
9631
9632/* ------------------------------ */
9633    .balign 64
9634.L_OP_UNUSED_92FF: /* 0x192 */
9635/* File: armv5te/OP_UNUSED_92FF.S */
9636/* File: armv5te/unused.S */
9637    bl      common_abort
9638
9639
9640/* ------------------------------ */
9641    .balign 64
9642.L_OP_UNUSED_93FF: /* 0x193 */
9643/* File: armv5te/OP_UNUSED_93FF.S */
9644/* File: armv5te/unused.S */
9645    bl      common_abort
9646
9647
9648/* ------------------------------ */
9649    .balign 64
9650.L_OP_UNUSED_94FF: /* 0x194 */
9651/* File: armv5te/OP_UNUSED_94FF.S */
9652/* File: armv5te/unused.S */
9653    bl      common_abort
9654
9655
9656/* ------------------------------ */
9657    .balign 64
9658.L_OP_UNUSED_95FF: /* 0x195 */
9659/* File: armv5te/OP_UNUSED_95FF.S */
9660/* File: armv5te/unused.S */
9661    bl      common_abort
9662
9663
9664/* ------------------------------ */
9665    .balign 64
9666.L_OP_UNUSED_96FF: /* 0x196 */
9667/* File: armv5te/OP_UNUSED_96FF.S */
9668/* File: armv5te/unused.S */
9669    bl      common_abort
9670
9671
9672/* ------------------------------ */
9673    .balign 64
9674.L_OP_UNUSED_97FF: /* 0x197 */
9675/* File: armv5te/OP_UNUSED_97FF.S */
9676/* File: armv5te/unused.S */
9677    bl      common_abort
9678
9679
9680/* ------------------------------ */
9681    .balign 64
9682.L_OP_UNUSED_98FF: /* 0x198 */
9683/* File: armv5te/OP_UNUSED_98FF.S */
9684/* File: armv5te/unused.S */
9685    bl      common_abort
9686
9687
9688/* ------------------------------ */
9689    .balign 64
9690.L_OP_UNUSED_99FF: /* 0x199 */
9691/* File: armv5te/OP_UNUSED_99FF.S */
9692/* File: armv5te/unused.S */
9693    bl      common_abort
9694
9695
9696/* ------------------------------ */
9697    .balign 64
9698.L_OP_UNUSED_9AFF: /* 0x19a */
9699/* File: armv5te/OP_UNUSED_9AFF.S */
9700/* File: armv5te/unused.S */
9701    bl      common_abort
9702
9703
9704/* ------------------------------ */
9705    .balign 64
9706.L_OP_UNUSED_9BFF: /* 0x19b */
9707/* File: armv5te/OP_UNUSED_9BFF.S */
9708/* File: armv5te/unused.S */
9709    bl      common_abort
9710
9711
9712/* ------------------------------ */
9713    .balign 64
9714.L_OP_UNUSED_9CFF: /* 0x19c */
9715/* File: armv5te/OP_UNUSED_9CFF.S */
9716/* File: armv5te/unused.S */
9717    bl      common_abort
9718
9719
9720/* ------------------------------ */
9721    .balign 64
9722.L_OP_UNUSED_9DFF: /* 0x19d */
9723/* File: armv5te/OP_UNUSED_9DFF.S */
9724/* File: armv5te/unused.S */
9725    bl      common_abort
9726
9727
9728/* ------------------------------ */
9729    .balign 64
9730.L_OP_UNUSED_9EFF: /* 0x19e */
9731/* File: armv5te/OP_UNUSED_9EFF.S */
9732/* File: armv5te/unused.S */
9733    bl      common_abort
9734
9735
9736/* ------------------------------ */
9737    .balign 64
9738.L_OP_UNUSED_9FFF: /* 0x19f */
9739/* File: armv5te/OP_UNUSED_9FFF.S */
9740/* File: armv5te/unused.S */
9741    bl      common_abort
9742
9743
9744/* ------------------------------ */
9745    .balign 64
9746.L_OP_UNUSED_A0FF: /* 0x1a0 */
9747/* File: armv5te/OP_UNUSED_A0FF.S */
9748/* File: armv5te/unused.S */
9749    bl      common_abort
9750
9751
9752/* ------------------------------ */
9753    .balign 64
9754.L_OP_UNUSED_A1FF: /* 0x1a1 */
9755/* File: armv5te/OP_UNUSED_A1FF.S */
9756/* File: armv5te/unused.S */
9757    bl      common_abort
9758
9759
9760/* ------------------------------ */
9761    .balign 64
9762.L_OP_UNUSED_A2FF: /* 0x1a2 */
9763/* File: armv5te/OP_UNUSED_A2FF.S */
9764/* File: armv5te/unused.S */
9765    bl      common_abort
9766
9767
9768/* ------------------------------ */
9769    .balign 64
9770.L_OP_UNUSED_A3FF: /* 0x1a3 */
9771/* File: armv5te/OP_UNUSED_A3FF.S */
9772/* File: armv5te/unused.S */
9773    bl      common_abort
9774
9775
9776/* ------------------------------ */
9777    .balign 64
9778.L_OP_UNUSED_A4FF: /* 0x1a4 */
9779/* File: armv5te/OP_UNUSED_A4FF.S */
9780/* File: armv5te/unused.S */
9781    bl      common_abort
9782
9783
9784/* ------------------------------ */
9785    .balign 64
9786.L_OP_UNUSED_A5FF: /* 0x1a5 */
9787/* File: armv5te/OP_UNUSED_A5FF.S */
9788/* File: armv5te/unused.S */
9789    bl      common_abort
9790
9791
9792/* ------------------------------ */
9793    .balign 64
9794.L_OP_UNUSED_A6FF: /* 0x1a6 */
9795/* File: armv5te/OP_UNUSED_A6FF.S */
9796/* File: armv5te/unused.S */
9797    bl      common_abort
9798
9799
9800/* ------------------------------ */
9801    .balign 64
9802.L_OP_UNUSED_A7FF: /* 0x1a7 */
9803/* File: armv5te/OP_UNUSED_A7FF.S */
9804/* File: armv5te/unused.S */
9805    bl      common_abort
9806
9807
9808/* ------------------------------ */
9809    .balign 64
9810.L_OP_UNUSED_A8FF: /* 0x1a8 */
9811/* File: armv5te/OP_UNUSED_A8FF.S */
9812/* File: armv5te/unused.S */
9813    bl      common_abort
9814
9815
9816/* ------------------------------ */
9817    .balign 64
9818.L_OP_UNUSED_A9FF: /* 0x1a9 */
9819/* File: armv5te/OP_UNUSED_A9FF.S */
9820/* File: armv5te/unused.S */
9821    bl      common_abort
9822
9823
9824/* ------------------------------ */
9825    .balign 64
9826.L_OP_UNUSED_AAFF: /* 0x1aa */
9827/* File: armv5te/OP_UNUSED_AAFF.S */
9828/* File: armv5te/unused.S */
9829    bl      common_abort
9830
9831
9832/* ------------------------------ */
9833    .balign 64
9834.L_OP_UNUSED_ABFF: /* 0x1ab */
9835/* File: armv5te/OP_UNUSED_ABFF.S */
9836/* File: armv5te/unused.S */
9837    bl      common_abort
9838
9839
9840/* ------------------------------ */
9841    .balign 64
9842.L_OP_UNUSED_ACFF: /* 0x1ac */
9843/* File: armv5te/OP_UNUSED_ACFF.S */
9844/* File: armv5te/unused.S */
9845    bl      common_abort
9846
9847
9848/* ------------------------------ */
9849    .balign 64
9850.L_OP_UNUSED_ADFF: /* 0x1ad */
9851/* File: armv5te/OP_UNUSED_ADFF.S */
9852/* File: armv5te/unused.S */
9853    bl      common_abort
9854
9855
9856/* ------------------------------ */
9857    .balign 64
9858.L_OP_UNUSED_AEFF: /* 0x1ae */
9859/* File: armv5te/OP_UNUSED_AEFF.S */
9860/* File: armv5te/unused.S */
9861    bl      common_abort
9862
9863
9864/* ------------------------------ */
9865    .balign 64
9866.L_OP_UNUSED_AFFF: /* 0x1af */
9867/* File: armv5te/OP_UNUSED_AFFF.S */
9868/* File: armv5te/unused.S */
9869    bl      common_abort
9870
9871
9872/* ------------------------------ */
9873    .balign 64
9874.L_OP_UNUSED_B0FF: /* 0x1b0 */
9875/* File: armv5te/OP_UNUSED_B0FF.S */
9876/* File: armv5te/unused.S */
9877    bl      common_abort
9878
9879
9880/* ------------------------------ */
9881    .balign 64
9882.L_OP_UNUSED_B1FF: /* 0x1b1 */
9883/* File: armv5te/OP_UNUSED_B1FF.S */
9884/* File: armv5te/unused.S */
9885    bl      common_abort
9886
9887
9888/* ------------------------------ */
9889    .balign 64
9890.L_OP_UNUSED_B2FF: /* 0x1b2 */
9891/* File: armv5te/OP_UNUSED_B2FF.S */
9892/* File: armv5te/unused.S */
9893    bl      common_abort
9894
9895
9896/* ------------------------------ */
9897    .balign 64
9898.L_OP_UNUSED_B3FF: /* 0x1b3 */
9899/* File: armv5te/OP_UNUSED_B3FF.S */
9900/* File: armv5te/unused.S */
9901    bl      common_abort
9902
9903
9904/* ------------------------------ */
9905    .balign 64
9906.L_OP_UNUSED_B4FF: /* 0x1b4 */
9907/* File: armv5te/OP_UNUSED_B4FF.S */
9908/* File: armv5te/unused.S */
9909    bl      common_abort
9910
9911
9912/* ------------------------------ */
9913    .balign 64
9914.L_OP_UNUSED_B5FF: /* 0x1b5 */
9915/* File: armv5te/OP_UNUSED_B5FF.S */
9916/* File: armv5te/unused.S */
9917    bl      common_abort
9918
9919
9920/* ------------------------------ */
9921    .balign 64
9922.L_OP_UNUSED_B6FF: /* 0x1b6 */
9923/* File: armv5te/OP_UNUSED_B6FF.S */
9924/* File: armv5te/unused.S */
9925    bl      common_abort
9926
9927
9928/* ------------------------------ */
9929    .balign 64
9930.L_OP_UNUSED_B7FF: /* 0x1b7 */
9931/* File: armv5te/OP_UNUSED_B7FF.S */
9932/* File: armv5te/unused.S */
9933    bl      common_abort
9934
9935
9936/* ------------------------------ */
9937    .balign 64
9938.L_OP_UNUSED_B8FF: /* 0x1b8 */
9939/* File: armv5te/OP_UNUSED_B8FF.S */
9940/* File: armv5te/unused.S */
9941    bl      common_abort
9942
9943
9944/* ------------------------------ */
9945    .balign 64
9946.L_OP_UNUSED_B9FF: /* 0x1b9 */
9947/* File: armv5te/OP_UNUSED_B9FF.S */
9948/* File: armv5te/unused.S */
9949    bl      common_abort
9950
9951
9952/* ------------------------------ */
9953    .balign 64
9954.L_OP_UNUSED_BAFF: /* 0x1ba */
9955/* File: armv5te/OP_UNUSED_BAFF.S */
9956/* File: armv5te/unused.S */
9957    bl      common_abort
9958
9959
9960/* ------------------------------ */
9961    .balign 64
9962.L_OP_UNUSED_BBFF: /* 0x1bb */
9963/* File: armv5te/OP_UNUSED_BBFF.S */
9964/* File: armv5te/unused.S */
9965    bl      common_abort
9966
9967
9968/* ------------------------------ */
9969    .balign 64
9970.L_OP_UNUSED_BCFF: /* 0x1bc */
9971/* File: armv5te/OP_UNUSED_BCFF.S */
9972/* File: armv5te/unused.S */
9973    bl      common_abort
9974
9975
9976/* ------------------------------ */
9977    .balign 64
9978.L_OP_UNUSED_BDFF: /* 0x1bd */
9979/* File: armv5te/OP_UNUSED_BDFF.S */
9980/* File: armv5te/unused.S */
9981    bl      common_abort
9982
9983
9984/* ------------------------------ */
9985    .balign 64
9986.L_OP_UNUSED_BEFF: /* 0x1be */
9987/* File: armv5te/OP_UNUSED_BEFF.S */
9988/* File: armv5te/unused.S */
9989    bl      common_abort
9990
9991
9992/* ------------------------------ */
9993    .balign 64
9994.L_OP_UNUSED_BFFF: /* 0x1bf */
9995/* File: armv5te/OP_UNUSED_BFFF.S */
9996/* File: armv5te/unused.S */
9997    bl      common_abort
9998
9999
10000/* ------------------------------ */
10001    .balign 64
10002.L_OP_UNUSED_C0FF: /* 0x1c0 */
10003/* File: armv5te/OP_UNUSED_C0FF.S */
10004/* File: armv5te/unused.S */
10005    bl      common_abort
10006
10007
10008/* ------------------------------ */
10009    .balign 64
10010.L_OP_UNUSED_C1FF: /* 0x1c1 */
10011/* File: armv5te/OP_UNUSED_C1FF.S */
10012/* File: armv5te/unused.S */
10013    bl      common_abort
10014
10015
10016/* ------------------------------ */
10017    .balign 64
10018.L_OP_UNUSED_C2FF: /* 0x1c2 */
10019/* File: armv5te/OP_UNUSED_C2FF.S */
10020/* File: armv5te/unused.S */
10021    bl      common_abort
10022
10023
10024/* ------------------------------ */
10025    .balign 64
10026.L_OP_UNUSED_C3FF: /* 0x1c3 */
10027/* File: armv5te/OP_UNUSED_C3FF.S */
10028/* File: armv5te/unused.S */
10029    bl      common_abort
10030
10031
10032/* ------------------------------ */
10033    .balign 64
10034.L_OP_UNUSED_C4FF: /* 0x1c4 */
10035/* File: armv5te/OP_UNUSED_C4FF.S */
10036/* File: armv5te/unused.S */
10037    bl      common_abort
10038
10039
10040/* ------------------------------ */
10041    .balign 64
10042.L_OP_UNUSED_C5FF: /* 0x1c5 */
10043/* File: armv5te/OP_UNUSED_C5FF.S */
10044/* File: armv5te/unused.S */
10045    bl      common_abort
10046
10047
10048/* ------------------------------ */
10049    .balign 64
10050.L_OP_UNUSED_C6FF: /* 0x1c6 */
10051/* File: armv5te/OP_UNUSED_C6FF.S */
10052/* File: armv5te/unused.S */
10053    bl      common_abort
10054
10055
10056/* ------------------------------ */
10057    .balign 64
10058.L_OP_UNUSED_C7FF: /* 0x1c7 */
10059/* File: armv5te/OP_UNUSED_C7FF.S */
10060/* File: armv5te/unused.S */
10061    bl      common_abort
10062
10063
10064/* ------------------------------ */
10065    .balign 64
10066.L_OP_UNUSED_C8FF: /* 0x1c8 */
10067/* File: armv5te/OP_UNUSED_C8FF.S */
10068/* File: armv5te/unused.S */
10069    bl      common_abort
10070
10071
10072/* ------------------------------ */
10073    .balign 64
10074.L_OP_UNUSED_C9FF: /* 0x1c9 */
10075/* File: armv5te/OP_UNUSED_C9FF.S */
10076/* File: armv5te/unused.S */
10077    bl      common_abort
10078
10079
10080/* ------------------------------ */
10081    .balign 64
10082.L_OP_UNUSED_CAFF: /* 0x1ca */
10083/* File: armv5te/OP_UNUSED_CAFF.S */
10084/* File: armv5te/unused.S */
10085    bl      common_abort
10086
10087
10088/* ------------------------------ */
10089    .balign 64
10090.L_OP_UNUSED_CBFF: /* 0x1cb */
10091/* File: armv5te/OP_UNUSED_CBFF.S */
10092/* File: armv5te/unused.S */
10093    bl      common_abort
10094
10095
10096/* ------------------------------ */
10097    .balign 64
10098.L_OP_UNUSED_CCFF: /* 0x1cc */
10099/* File: armv5te/OP_UNUSED_CCFF.S */
10100/* File: armv5te/unused.S */
10101    bl      common_abort
10102
10103
10104/* ------------------------------ */
10105    .balign 64
10106.L_OP_UNUSED_CDFF: /* 0x1cd */
10107/* File: armv5te/OP_UNUSED_CDFF.S */
10108/* File: armv5te/unused.S */
10109    bl      common_abort
10110
10111
10112/* ------------------------------ */
10113    .balign 64
10114.L_OP_UNUSED_CEFF: /* 0x1ce */
10115/* File: armv5te/OP_UNUSED_CEFF.S */
10116/* File: armv5te/unused.S */
10117    bl      common_abort
10118
10119
10120/* ------------------------------ */
10121    .balign 64
10122.L_OP_UNUSED_CFFF: /* 0x1cf */
10123/* File: armv5te/OP_UNUSED_CFFF.S */
10124/* File: armv5te/unused.S */
10125    bl      common_abort
10126
10127
10128/* ------------------------------ */
10129    .balign 64
10130.L_OP_UNUSED_D0FF: /* 0x1d0 */
10131/* File: armv5te/OP_UNUSED_D0FF.S */
10132/* File: armv5te/unused.S */
10133    bl      common_abort
10134
10135
10136/* ------------------------------ */
10137    .balign 64
10138.L_OP_UNUSED_D1FF: /* 0x1d1 */
10139/* File: armv5te/OP_UNUSED_D1FF.S */
10140/* File: armv5te/unused.S */
10141    bl      common_abort
10142
10143
10144/* ------------------------------ */
10145    .balign 64
10146.L_OP_UNUSED_D2FF: /* 0x1d2 */
10147/* File: armv5te/OP_UNUSED_D2FF.S */
10148/* File: armv5te/unused.S */
10149    bl      common_abort
10150
10151
10152/* ------------------------------ */
10153    .balign 64
10154.L_OP_UNUSED_D3FF: /* 0x1d3 */
10155/* File: armv5te/OP_UNUSED_D3FF.S */
10156/* File: armv5te/unused.S */
10157    bl      common_abort
10158
10159
10160/* ------------------------------ */
10161    .balign 64
10162.L_OP_UNUSED_D4FF: /* 0x1d4 */
10163/* File: armv5te/OP_UNUSED_D4FF.S */
10164/* File: armv5te/unused.S */
10165    bl      common_abort
10166
10167
10168/* ------------------------------ */
10169    .balign 64
10170.L_OP_UNUSED_D5FF: /* 0x1d5 */
10171/* File: armv5te/OP_UNUSED_D5FF.S */
10172/* File: armv5te/unused.S */
10173    bl      common_abort
10174
10175
10176/* ------------------------------ */
10177    .balign 64
10178.L_OP_UNUSED_D6FF: /* 0x1d6 */
10179/* File: armv5te/OP_UNUSED_D6FF.S */
10180/* File: armv5te/unused.S */
10181    bl      common_abort
10182
10183
10184/* ------------------------------ */
10185    .balign 64
10186.L_OP_UNUSED_D7FF: /* 0x1d7 */
10187/* File: armv5te/OP_UNUSED_D7FF.S */
10188/* File: armv5te/unused.S */
10189    bl      common_abort
10190
10191
10192/* ------------------------------ */
10193    .balign 64
10194.L_OP_UNUSED_D8FF: /* 0x1d8 */
10195/* File: armv5te/OP_UNUSED_D8FF.S */
10196/* File: armv5te/unused.S */
10197    bl      common_abort
10198
10199
10200/* ------------------------------ */
10201    .balign 64
10202.L_OP_UNUSED_D9FF: /* 0x1d9 */
10203/* File: armv5te/OP_UNUSED_D9FF.S */
10204/* File: armv5te/unused.S */
10205    bl      common_abort
10206
10207
10208/* ------------------------------ */
10209    .balign 64
10210.L_OP_UNUSED_DAFF: /* 0x1da */
10211/* File: armv5te/OP_UNUSED_DAFF.S */
10212/* File: armv5te/unused.S */
10213    bl      common_abort
10214
10215
10216/* ------------------------------ */
10217    .balign 64
10218.L_OP_UNUSED_DBFF: /* 0x1db */
10219/* File: armv5te/OP_UNUSED_DBFF.S */
10220/* File: armv5te/unused.S */
10221    bl      common_abort
10222
10223
10224/* ------------------------------ */
10225    .balign 64
10226.L_OP_UNUSED_DCFF: /* 0x1dc */
10227/* File: armv5te/OP_UNUSED_DCFF.S */
10228/* File: armv5te/unused.S */
10229    bl      common_abort
10230
10231
10232/* ------------------------------ */
10233    .balign 64
10234.L_OP_UNUSED_DDFF: /* 0x1dd */
10235/* File: armv5te/OP_UNUSED_DDFF.S */
10236/* File: armv5te/unused.S */
10237    bl      common_abort
10238
10239
10240/* ------------------------------ */
10241    .balign 64
10242.L_OP_UNUSED_DEFF: /* 0x1de */
10243/* File: armv5te/OP_UNUSED_DEFF.S */
10244/* File: armv5te/unused.S */
10245    bl      common_abort
10246
10247
10248/* ------------------------------ */
10249    .balign 64
10250.L_OP_UNUSED_DFFF: /* 0x1df */
10251/* File: armv5te/OP_UNUSED_DFFF.S */
10252/* File: armv5te/unused.S */
10253    bl      common_abort
10254
10255
10256/* ------------------------------ */
10257    .balign 64
10258.L_OP_UNUSED_E0FF: /* 0x1e0 */
10259/* File: armv5te/OP_UNUSED_E0FF.S */
10260/* File: armv5te/unused.S */
10261    bl      common_abort
10262
10263
10264/* ------------------------------ */
10265    .balign 64
10266.L_OP_UNUSED_E1FF: /* 0x1e1 */
10267/* File: armv5te/OP_UNUSED_E1FF.S */
10268/* File: armv5te/unused.S */
10269    bl      common_abort
10270
10271
10272/* ------------------------------ */
10273    .balign 64
10274.L_OP_UNUSED_E2FF: /* 0x1e2 */
10275/* File: armv5te/OP_UNUSED_E2FF.S */
10276/* File: armv5te/unused.S */
10277    bl      common_abort
10278
10279
10280/* ------------------------------ */
10281    .balign 64
10282.L_OP_UNUSED_E3FF: /* 0x1e3 */
10283/* File: armv5te/OP_UNUSED_E3FF.S */
10284/* File: armv5te/unused.S */
10285    bl      common_abort
10286
10287
10288/* ------------------------------ */
10289    .balign 64
10290.L_OP_UNUSED_E4FF: /* 0x1e4 */
10291/* File: armv5te/OP_UNUSED_E4FF.S */
10292/* File: armv5te/unused.S */
10293    bl      common_abort
10294
10295
10296/* ------------------------------ */
10297    .balign 64
10298.L_OP_UNUSED_E5FF: /* 0x1e5 */
10299/* File: armv5te/OP_UNUSED_E5FF.S */
10300/* File: armv5te/unused.S */
10301    bl      common_abort
10302
10303
10304/* ------------------------------ */
10305    .balign 64
10306.L_OP_UNUSED_E6FF: /* 0x1e6 */
10307/* File: armv5te/OP_UNUSED_E6FF.S */
10308/* File: armv5te/unused.S */
10309    bl      common_abort
10310
10311
10312/* ------------------------------ */
10313    .balign 64
10314.L_OP_UNUSED_E7FF: /* 0x1e7 */
10315/* File: armv5te/OP_UNUSED_E7FF.S */
10316/* File: armv5te/unused.S */
10317    bl      common_abort
10318
10319
10320/* ------------------------------ */
10321    .balign 64
10322.L_OP_UNUSED_E8FF: /* 0x1e8 */
10323/* File: armv5te/OP_UNUSED_E8FF.S */
10324/* File: armv5te/unused.S */
10325    bl      common_abort
10326
10327
10328/* ------------------------------ */
10329    .balign 64
10330.L_OP_UNUSED_E9FF: /* 0x1e9 */
10331/* File: armv5te/OP_UNUSED_E9FF.S */
10332/* File: armv5te/unused.S */
10333    bl      common_abort
10334
10335
10336/* ------------------------------ */
10337    .balign 64
10338.L_OP_UNUSED_EAFF: /* 0x1ea */
10339/* File: armv5te/OP_UNUSED_EAFF.S */
10340/* File: armv5te/unused.S */
10341    bl      common_abort
10342
10343
10344/* ------------------------------ */
10345    .balign 64
10346.L_OP_UNUSED_EBFF: /* 0x1eb */
10347/* File: armv5te/OP_UNUSED_EBFF.S */
10348/* File: armv5te/unused.S */
10349    bl      common_abort
10350
10351
10352/* ------------------------------ */
10353    .balign 64
10354.L_OP_UNUSED_ECFF: /* 0x1ec */
10355/* File: armv5te/OP_UNUSED_ECFF.S */
10356/* File: armv5te/unused.S */
10357    bl      common_abort
10358
10359
10360/* ------------------------------ */
10361    .balign 64
10362.L_OP_UNUSED_EDFF: /* 0x1ed */
10363/* File: armv5te/OP_UNUSED_EDFF.S */
10364/* File: armv5te/unused.S */
10365    bl      common_abort
10366
10367
10368/* ------------------------------ */
10369    .balign 64
10370.L_OP_UNUSED_EEFF: /* 0x1ee */
10371/* File: armv5te/OP_UNUSED_EEFF.S */
10372/* File: armv5te/unused.S */
10373    bl      common_abort
10374
10375
10376/* ------------------------------ */
10377    .balign 64
10378.L_OP_UNUSED_EFFF: /* 0x1ef */
10379/* File: armv5te/OP_UNUSED_EFFF.S */
10380/* File: armv5te/unused.S */
10381    bl      common_abort
10382
10383
10384/* ------------------------------ */
10385    .balign 64
10386.L_OP_UNUSED_F0FF: /* 0x1f0 */
10387/* File: armv5te/OP_UNUSED_F0FF.S */
10388/* File: armv5te/unused.S */
10389    bl      common_abort
10390
10391
10392/* ------------------------------ */
10393    .balign 64
10394.L_OP_UNUSED_F1FF: /* 0x1f1 */
10395/* File: armv5te/OP_UNUSED_F1FF.S */
10396/* File: armv5te/unused.S */
10397    bl      common_abort
10398
10399
10400/* ------------------------------ */
10401    .balign 64
10402.L_OP_UNUSED_F2FF: /* 0x1f2 */
10403/* File: armv5te/OP_UNUSED_F2FF.S */
10404/* File: armv5te/unused.S */
10405    bl      common_abort
10406
10407
10408/* ------------------------------ */
10409    .balign 64
10410.L_OP_UNUSED_F3FF: /* 0x1f3 */
10411/* File: armv5te/OP_UNUSED_F3FF.S */
10412/* File: armv5te/unused.S */
10413    bl      common_abort
10414
10415
10416/* ------------------------------ */
10417    .balign 64
10418.L_OP_UNUSED_F4FF: /* 0x1f4 */
10419/* File: armv5te/OP_UNUSED_F4FF.S */
10420/* File: armv5te/unused.S */
10421    bl      common_abort
10422
10423
10424/* ------------------------------ */
10425    .balign 64
10426.L_OP_UNUSED_F5FF: /* 0x1f5 */
10427/* File: armv5te/OP_UNUSED_F5FF.S */
10428/* File: armv5te/unused.S */
10429    bl      common_abort
10430
10431
10432/* ------------------------------ */
10433    .balign 64
10434.L_OP_UNUSED_F6FF: /* 0x1f6 */
10435/* File: armv5te/OP_UNUSED_F6FF.S */
10436/* File: armv5te/unused.S */
10437    bl      common_abort
10438
10439
10440/* ------------------------------ */
10441    .balign 64
10442.L_OP_UNUSED_F7FF: /* 0x1f7 */
10443/* File: armv5te/OP_UNUSED_F7FF.S */
10444/* File: armv5te/unused.S */
10445    bl      common_abort
10446
10447
10448/* ------------------------------ */
10449    .balign 64
10450.L_OP_UNUSED_F8FF: /* 0x1f8 */
10451/* File: armv5te/OP_UNUSED_F8FF.S */
10452/* File: armv5te/unused.S */
10453    bl      common_abort
10454
10455
10456/* ------------------------------ */
10457    .balign 64
10458.L_OP_UNUSED_F9FF: /* 0x1f9 */
10459/* File: armv5te/OP_UNUSED_F9FF.S */
10460/* File: armv5te/unused.S */
10461    bl      common_abort
10462
10463
10464/* ------------------------------ */
10465    .balign 64
10466.L_OP_UNUSED_FAFF: /* 0x1fa */
10467/* File: armv5te/OP_UNUSED_FAFF.S */
10468/* File: armv5te/unused.S */
10469    bl      common_abort
10470
10471
10472/* ------------------------------ */
10473    .balign 64
10474.L_OP_UNUSED_FBFF: /* 0x1fb */
10475/* File: armv5te/OP_UNUSED_FBFF.S */
10476/* File: armv5te/unused.S */
10477    bl      common_abort
10478
10479
10480/* ------------------------------ */
10481    .balign 64
10482.L_OP_UNUSED_FCFF: /* 0x1fc */
10483/* File: armv5te/OP_UNUSED_FCFF.S */
10484/* File: armv5te/unused.S */
10485    bl      common_abort
10486
10487
10488/* ------------------------------ */
10489    .balign 64
10490.L_OP_UNUSED_FDFF: /* 0x1fd */
10491/* File: armv5te/OP_UNUSED_FDFF.S */
10492/* File: armv5te/unused.S */
10493    bl      common_abort
10494
10495
10496/* ------------------------------ */
10497    .balign 64
10498.L_OP_UNUSED_FEFF: /* 0x1fe */
10499/* File: armv5te/OP_UNUSED_FEFF.S */
10500/* File: armv5te/unused.S */
10501    bl      common_abort
10502
10503
10504/* ------------------------------ */
10505    .balign 64
10506.L_OP_THROW_VERIFICATION_ERROR_JUMBO: /* 0x1ff */
10507/* File: armv5te/OP_THROW_VERIFICATION_ERROR_JUMBO.S */
10508    /*
10509     * Handle a jumbo throw-verification-error instruction.  This throws an
10510     * exception for an error discovered during verification.  The
10511     * exception is indicated by BBBB, with some detail provided by AAAAAAAA.
10512     */
10513    /* exop BBBB, Class@AAAAAAAA */
10514    FETCH(r1, 1)                        @ r1<- aaaa (lo)
10515    FETCH(r2, 2)                        @ r2<- AAAA (hi)
10516    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
10517    orr     r2, r1, r2, lsl #16         @ r2<- AAAAaaaa
10518    EXPORT_PC()                         @ export the PC
10519    FETCH(r1, 3)                        @ r1<- BBBB
10520    bl      dvmThrowVerificationError   @ always throws
10521    b       common_exceptionThrown      @ handle exception
10522
10523
10524    .balign 64
10525    .size   dvmAsmInstructionStart, .-dvmAsmInstructionStart
10526    .global dvmAsmInstructionEnd
10527dvmAsmInstructionEnd:
10528
10529/*
10530 * ===========================================================================
10531 *  Sister implementations
10532 * ===========================================================================
10533 */
10534    .global dvmAsmSisterStart
10535    .type   dvmAsmSisterStart, %function
10536    .text
10537    .balign 4
10538dvmAsmSisterStart:
10539
10540/* continuation for OP_CONST_STRING */
10541
10542    /*
10543     * Continuation if the String has not yet been resolved.
10544     *  r1: BBBB (String ref)
10545     *  r9: target register
10546     */
10547.LOP_CONST_STRING_resolve:
10548    EXPORT_PC()
10549    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
10550    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10551    bl      dvmResolveString            @ r0<- String reference
10552    cmp     r0, #0                      @ failed?
10553    beq     common_exceptionThrown      @ yup, handle the exception
10554    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10555    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10556    SET_VREG(r0, r9)                    @ vAA<- r0
10557    GOTO_OPCODE(ip)                     @ jump to next instruction
10558
10559/* continuation for OP_CONST_STRING_JUMBO */
10560
10561    /*
10562     * Continuation if the String has not yet been resolved.
10563     *  r1: BBBBBBBB (String ref)
10564     *  r9: target register
10565     */
10566.LOP_CONST_STRING_JUMBO_resolve:
10567    EXPORT_PC()
10568    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
10569    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10570    bl      dvmResolveString            @ r0<- String reference
10571    cmp     r0, #0                      @ failed?
10572    beq     common_exceptionThrown      @ yup, handle the exception
10573    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
10574    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10575    SET_VREG(r0, r9)                    @ vAA<- r0
10576    GOTO_OPCODE(ip)                     @ jump to next instruction
10577
10578/* continuation for OP_CONST_CLASS */
10579
10580    /*
10581     * Continuation if the Class has not yet been resolved.
10582     *  r1: BBBB (Class ref)
10583     *  r9: target register
10584     */
10585.LOP_CONST_CLASS_resolve:
10586    EXPORT_PC()
10587    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
10588    mov     r2, #1                      @ r2<- true
10589    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10590    bl      dvmResolveClass             @ r0<- Class reference
10591    cmp     r0, #0                      @ failed?
10592    beq     common_exceptionThrown      @ yup, handle the exception
10593    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10594    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10595    SET_VREG(r0, r9)                    @ vAA<- r0
10596    GOTO_OPCODE(ip)                     @ jump to next instruction
10597
10598/* continuation for OP_CHECK_CAST */
10599
10600    /*
10601     * Trivial test failed, need to perform full check.  This is common.
10602     *  r0 holds obj->clazz
10603     *  r1 holds desired class resolved from BBBB
10604     *  r9 holds object
10605     */
10606.LOP_CHECK_CAST_fullcheck:
10607    mov     r10, r1                     @ avoid ClassObject getting clobbered
10608    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
10609    cmp     r0, #0                      @ failed?
10610    bne     .LOP_CHECK_CAST_okay            @ no, success
10611
10612    @ A cast has failed.  We need to throw a ClassCastException.
10613    EXPORT_PC()                         @ about to throw
10614    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz (actual class)
10615    mov     r1, r10                     @ r1<- desired class
10616    bl      dvmThrowClassCastException
10617    b       common_exceptionThrown
10618
10619    /*
10620     * Resolution required.  This is the least-likely path.
10621     *
10622     *  r2 holds BBBB
10623     *  r9 holds object
10624     */
10625.LOP_CHECK_CAST_resolve:
10626    EXPORT_PC()                         @ resolve() could throw
10627    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
10628    mov     r1, r2                      @ r1<- BBBB
10629    mov     r2, #0                      @ r2<- false
10630    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
10631    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
10632    cmp     r0, #0                      @ got null?
10633    beq     common_exceptionThrown      @ yes, handle exception
10634    mov     r1, r0                      @ r1<- class resolved from BBB
10635    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
10636    b       .LOP_CHECK_CAST_resolved        @ pick up where we left off
10637
10638/* continuation for OP_INSTANCE_OF */
10639
10640    /*
10641     * Trivial test failed, need to perform full check.  This is common.
10642     *  r0 holds obj->clazz
10643     *  r1 holds class resolved from BBBB
10644     *  r9 holds A
10645     */
10646.LOP_INSTANCE_OF_fullcheck:
10647    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
10648    @ fall through to OP_INSTANCE_OF_store
10649
10650    /*
10651     * r0 holds boolean result
10652     * r9 holds A
10653     */
10654.LOP_INSTANCE_OF_store:
10655    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10656    SET_VREG(r0, r9)                    @ vA<- r0
10657    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10658    GOTO_OPCODE(ip)                     @ jump to next instruction
10659
10660    /*
10661     * Trivial test succeeded, save and bail.
10662     *  r9 holds A
10663     */
10664.LOP_INSTANCE_OF_trivial:
10665    mov     r0, #1                      @ indicate success
10666    @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper
10667    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10668    SET_VREG(r0, r9)                    @ vA<- r0
10669    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10670    GOTO_OPCODE(ip)                     @ jump to next instruction
10671
10672    /*
10673     * Resolution required.  This is the least-likely path.
10674     *
10675     *  r3 holds BBBB
10676     *  r9 holds A
10677     */
10678.LOP_INSTANCE_OF_resolve:
10679    EXPORT_PC()                         @ resolve() could throw
10680    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
10681    mov     r1, r3                      @ r1<- BBBB
10682    mov     r2, #1                      @ r2<- true
10683    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10684    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
10685    cmp     r0, #0                      @ got null?
10686    beq     common_exceptionThrown      @ yes, handle exception
10687    mov     r1, r0                      @ r1<- class resolved from BBB
10688    mov     r3, rINST, lsr #12          @ r3<- B
10689    GET_VREG(r0, r3)                    @ r0<- vB (object)
10690    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
10691    b       .LOP_INSTANCE_OF_resolved        @ pick up where we left off
10692
10693/* continuation for OP_NEW_INSTANCE */
10694
10695    .balign 32                          @ minimize cache lines
10696.LOP_NEW_INSTANCE_finish: @ r0=new object
10697    mov     r3, rINST, lsr #8           @ r3<- AA
10698    cmp     r0, #0                      @ failed?
10699    beq     common_exceptionThrown      @ yes, handle the exception
10700    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10701    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10702    SET_VREG(r0, r3)                    @ vAA<- r0
10703    GOTO_OPCODE(ip)                     @ jump to next instruction
10704
10705    /*
10706     * Class initialization required.
10707     *
10708     *  r0 holds class object
10709     */
10710.LOP_NEW_INSTANCE_needinit:
10711    mov     r9, r0                      @ save r0
10712    bl      dvmInitClass                @ initialize class
10713    cmp     r0, #0                      @ check boolean result
10714    mov     r0, r9                      @ restore r0
10715    bne     .LOP_NEW_INSTANCE_initialized     @ success, continue
10716    b       common_exceptionThrown      @ failed, deal with init exception
10717
10718    /*
10719     * Resolution required.  This is the least-likely path.
10720     *
10721     *  r1 holds BBBB
10722     */
10723.LOP_NEW_INSTANCE_resolve:
10724    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
10725    mov     r2, #0                      @ r2<- false
10726    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
10727    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
10728    cmp     r0, #0                      @ got null?
10729    bne     .LOP_NEW_INSTANCE_resolved        @ no, continue
10730    b       common_exceptionThrown      @ yes, handle exception
10731
10732.LstrInstantiationErrorPtr:
10733    .word   .LstrInstantiationError
10734
10735/* continuation for OP_NEW_ARRAY */
10736
10737
10738    /*
10739     * Resolve class.  (This is an uncommon case.)
10740     *
10741     *  r1 holds array length
10742     *  r2 holds class ref CCCC
10743     */
10744.LOP_NEW_ARRAY_resolve:
10745    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
10746    mov     r9, r1                      @ r9<- length (save)
10747    mov     r1, r2                      @ r1<- CCCC
10748    mov     r2, #0                      @ r2<- false
10749    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
10750    bl      dvmResolveClass             @ r0<- call(clazz, ref)
10751    cmp     r0, #0                      @ got null?
10752    mov     r1, r9                      @ r1<- length (restore)
10753    beq     common_exceptionThrown      @ yes, handle exception
10754    @ fall through to OP_NEW_ARRAY_finish
10755
10756    /*
10757     * Finish allocation.
10758     *
10759     *  r0 holds class
10760     *  r1 holds array length
10761     */
10762.LOP_NEW_ARRAY_finish:
10763    mov     r2, #ALLOC_DONT_TRACK       @ don't track in local refs table
10764    bl      dvmAllocArrayByClass        @ r0<- call(clazz, length, flags)
10765    cmp     r0, #0                      @ failed?
10766    mov     r2, rINST, lsr #8           @ r2<- A+
10767    beq     common_exceptionThrown      @ yes, handle the exception
10768    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10769    and     r2, r2, #15                 @ r2<- A
10770    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10771    SET_VREG(r0, r2)                    @ vA<- r0
10772    GOTO_OPCODE(ip)                     @ jump to next instruction
10773
10774/* continuation for OP_FILLED_NEW_ARRAY */
10775
10776    /*
10777     * On entry:
10778     *  r0 holds array class
10779     *  r10 holds AA or BA
10780     */
10781.LOP_FILLED_NEW_ARRAY_continue:
10782    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
10783    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
10784    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
10785    .if     0
10786    mov     r1, r10                     @ r1<- AA (length)
10787    .else
10788    mov     r1, r10, lsr #4             @ r1<- B (length)
10789    .endif
10790    cmp     rINST, #'I'                 @ array of ints?
10791    cmpne   rINST, #'L'                 @ array of objects?
10792    cmpne   rINST, #'['                 @ array of arrays?
10793    mov     r9, r1                      @ save length in r9
10794    bne     .LOP_FILLED_NEW_ARRAY_notimpl         @ no, not handled yet
10795    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
10796    cmp     r0, #0                      @ null return?
10797    beq     common_exceptionThrown      @ alloc failed, handle exception
10798
10799    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
10800    str     r0, [rGLUE, #offGlue_retval]      @ retval.l <- new array
10801    str     rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type
10802    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
10803    subs    r9, r9, #1                  @ length--, check for neg
10804    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
10805    bmi     2f                          @ was zero, bail
10806
10807    @ copy values from registers into the array
10808    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
10809    .if     0
10810    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
108111:  ldr     r3, [r2], #4                @ r3<- *r2++
10812    subs    r9, r9, #1                  @ count--
10813    str     r3, [r0], #4                @ *contents++ = vX
10814    bpl     1b
10815    @ continue at 2
10816    .else
10817    cmp     r9, #4                      @ length was initially 5?
10818    and     r2, r10, #15                @ r2<- A
10819    bne     1f                          @ <= 4 args, branch
10820    GET_VREG(r3, r2)                    @ r3<- vA
10821    sub     r9, r9, #1                  @ count--
10822    str     r3, [r0, #16]               @ contents[4] = vA
108231:  and     r2, r1, #15                 @ r2<- F/E/D/C
10824    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
10825    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
10826    subs    r9, r9, #1                  @ count--
10827    str     r3, [r0], #4                @ *contents++ = vX
10828    bpl     1b
10829    @ continue at 2
10830    .endif
10831
108322:
10833    ldr     r0, [rGLUE, #offGlue_retval]     @ r0<- object
10834    ldr     r1, [rGLUE, #offGlue_retval+4]   @ r1<- type
10835    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
10836    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
10837    cmp     r1, #'I'                         @ Is int array?
10838    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
10839    GOTO_OPCODE(ip)                          @ execute it
10840
10841    /*
10842     * Throw an exception indicating that we have not implemented this
10843     * mode of filled-new-array.
10844     */
10845.LOP_FILLED_NEW_ARRAY_notimpl:
10846    ldr     r0, .L_strInternalError
10847    ldr     r1, .L_strFilledNewArrayNotImpl
10848    bl      dvmThrowException
10849    b       common_exceptionThrown
10850
10851    .if     (!0)                 @ define in one or the other, not both
10852.L_strFilledNewArrayNotImpl:
10853    .word   .LstrFilledNewArrayNotImpl
10854.L_strInternalError:
10855    .word   .LstrInternalError
10856    .endif
10857
10858/* continuation for OP_FILLED_NEW_ARRAY_RANGE */
10859
10860    /*
10861     * On entry:
10862     *  r0 holds array class
10863     *  r10 holds AA or BA
10864     */
10865.LOP_FILLED_NEW_ARRAY_RANGE_continue:
10866    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
10867    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
10868    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
10869    .if     1
10870    mov     r1, r10                     @ r1<- AA (length)
10871    .else
10872    mov     r1, r10, lsr #4             @ r1<- B (length)
10873    .endif
10874    cmp     rINST, #'I'                 @ array of ints?
10875    cmpne   rINST, #'L'                 @ array of objects?
10876    cmpne   rINST, #'['                 @ array of arrays?
10877    mov     r9, r1                      @ save length in r9
10878    bne     .LOP_FILLED_NEW_ARRAY_RANGE_notimpl         @ no, not handled yet
10879    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
10880    cmp     r0, #0                      @ null return?
10881    beq     common_exceptionThrown      @ alloc failed, handle exception
10882
10883    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
10884    str     r0, [rGLUE, #offGlue_retval]      @ retval.l <- new array
10885    str     rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type
10886    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
10887    subs    r9, r9, #1                  @ length--, check for neg
10888    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
10889    bmi     2f                          @ was zero, bail
10890
10891    @ copy values from registers into the array
10892    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
10893    .if     1
10894    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
108951:  ldr     r3, [r2], #4                @ r3<- *r2++
10896    subs    r9, r9, #1                  @ count--
10897    str     r3, [r0], #4                @ *contents++ = vX
10898    bpl     1b
10899    @ continue at 2
10900    .else
10901    cmp     r9, #4                      @ length was initially 5?
10902    and     r2, r10, #15                @ r2<- A
10903    bne     1f                          @ <= 4 args, branch
10904    GET_VREG(r3, r2)                    @ r3<- vA
10905    sub     r9, r9, #1                  @ count--
10906    str     r3, [r0, #16]               @ contents[4] = vA
109071:  and     r2, r1, #15                 @ r2<- F/E/D/C
10908    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
10909    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
10910    subs    r9, r9, #1                  @ count--
10911    str     r3, [r0], #4                @ *contents++ = vX
10912    bpl     1b
10913    @ continue at 2
10914    .endif
10915
109162:
10917    ldr     r0, [rGLUE, #offGlue_retval]     @ r0<- object
10918    ldr     r1, [rGLUE, #offGlue_retval+4]   @ r1<- type
10919    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
10920    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
10921    cmp     r1, #'I'                         @ Is int array?
10922    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
10923    GOTO_OPCODE(ip)                          @ execute it
10924
10925    /*
10926     * Throw an exception indicating that we have not implemented this
10927     * mode of filled-new-array.
10928     */
10929.LOP_FILLED_NEW_ARRAY_RANGE_notimpl:
10930    ldr     r0, .L_strInternalError
10931    ldr     r1, .L_strFilledNewArrayNotImpl
10932    bl      dvmThrowException
10933    b       common_exceptionThrown
10934
10935    .if     (!1)                 @ define in one or the other, not both
10936.L_strFilledNewArrayNotImpl:
10937    .word   .LstrFilledNewArrayNotImpl
10938.L_strInternalError:
10939    .word   .LstrInternalError
10940    .endif
10941
10942/* continuation for OP_CMPL_FLOAT */
10943.LOP_CMPL_FLOAT_finish:
10944    SET_VREG(r0, r9)                    @ vAA<- r0
10945    GOTO_OPCODE(ip)                     @ jump to next instruction
10946
10947/* continuation for OP_CMPG_FLOAT */
10948.LOP_CMPG_FLOAT_finish:
10949    SET_VREG(r0, r9)                    @ vAA<- r0
10950    GOTO_OPCODE(ip)                     @ jump to next instruction
10951
10952/* continuation for OP_CMPL_DOUBLE */
10953.LOP_CMPL_DOUBLE_finish:
10954    SET_VREG(r0, r9)                    @ vAA<- r0
10955    GOTO_OPCODE(ip)                     @ jump to next instruction
10956
10957/* continuation for OP_CMPG_DOUBLE */
10958.LOP_CMPG_DOUBLE_finish:
10959    SET_VREG(r0, r9)                    @ vAA<- r0
10960    GOTO_OPCODE(ip)                     @ jump to next instruction
10961
10962/* continuation for OP_CMP_LONG */
10963
10964.LOP_CMP_LONG_less:
10965    mvn     r1, #0                      @ r1<- -1
10966    @ Want to cond code the next mov so we can avoid branch, but don't see it;
10967    @ instead, we just replicate the tail end.
10968    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10969    SET_VREG(r1, r9)                    @ vAA<- r1
10970    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10971    GOTO_OPCODE(ip)                     @ jump to next instruction
10972
10973.LOP_CMP_LONG_greater:
10974    mov     r1, #1                      @ r1<- 1
10975    @ fall through to _finish
10976
10977.LOP_CMP_LONG_finish:
10978    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10979    SET_VREG(r1, r9)                    @ vAA<- r1
10980    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10981    GOTO_OPCODE(ip)                     @ jump to next instruction
10982
10983/* continuation for OP_AGET_WIDE */
10984
10985.LOP_AGET_WIDE_finish:
10986    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10987    ldrd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
10988    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
10989    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10990    stmia   r9, {r2-r3}                 @ vAA/vAA+1<- r2/r3
10991    GOTO_OPCODE(ip)                     @ jump to next instruction
10992
10993/* continuation for OP_APUT_WIDE */
10994
10995.LOP_APUT_WIDE_finish:
10996    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10997    ldmia   r9, {r2-r3}                 @ r2/r3<- vAA/vAA+1
10998    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10999    strd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
11000    GOTO_OPCODE(ip)                     @ jump to next instruction
11001
11002/* continuation for OP_APUT_OBJECT */
11003    /*
11004     * On entry:
11005     *  rINST = vBB (arrayObj)
11006     *  r9 = vAA (obj)
11007     *  r10 = offset into array (vBB + vCC * width)
11008     */
11009.LOP_APUT_OBJECT_finish:
11010    cmp     r9, #0                      @ storing null reference?
11011    beq     .LOP_APUT_OBJECT_skip_check      @ yes, skip type checks
11012    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
11013    ldr     r1, [rINST, #offObject_clazz]  @ r1<- arrayObj->clazz
11014    bl      dvmCanPutArrayElement       @ test object type vs. array type
11015    cmp     r0, #0                      @ okay?
11016    beq     .LOP_APUT_OBJECT_throw           @ no
11017    mov     r1, rINST                   @ r1<- arrayObj
11018    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11019    ldr     r2, [rGLUE, #offGlue_cardTable]     @ get biased CT base
11020    add     r10, #offArrayObject_contents   @ r0<- pointer to slot
11021    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11022    str     r9, [r10]                   @ vBB[vCC]<- vAA
11023    strb    r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head
11024    GOTO_OPCODE(ip)                     @ jump to next instruction
11025.LOP_APUT_OBJECT_skip_check:
11026    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11027    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11028    str     r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA
11029    GOTO_OPCODE(ip)                     @ jump to next instruction
11030.LOP_APUT_OBJECT_throw:
11031    @ The types don't match.  We need to throw an ArrayStoreException.
11032    ldr     r0, [r9, #offObject_clazz]
11033    ldr     r1, [rINST, #offObject_clazz]
11034    EXPORT_PC()
11035    bl      dvmThrowArrayStoreException
11036    b       common_exceptionThrown
11037
11038/* continuation for OP_IGET */
11039
11040    /*
11041     * Currently:
11042     *  r0 holds resolved field
11043     *  r9 holds object
11044     */
11045.LOP_IGET_finish:
11046    @bl      common_squeak0
11047    cmp     r9, #0                      @ check object for null
11048    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11049    beq     common_errNullObject        @ object was null
11050    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11051    ubfx    r2, rINST, #8, #4           @ r2<- A
11052    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11053    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11054    SET_VREG(r0, r2)                    @ fp[A]<- r0
11055    GOTO_OPCODE(ip)                     @ jump to next instruction
11056
11057/* continuation for OP_IGET_WIDE */
11058
11059    /*
11060     * Currently:
11061     *  r0 holds resolved field
11062     *  r9 holds object
11063     */
11064.LOP_IGET_WIDE_finish:
11065    cmp     r9, #0                      @ check object for null
11066    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11067    beq     common_errNullObject        @ object was null
11068    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
11069    ubfx    r2, rINST, #8, #4           @ r2<- A
11070    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11071    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
11072    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11073    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
11074    GOTO_OPCODE(ip)                     @ jump to next instruction
11075
11076/* continuation for OP_IGET_OBJECT */
11077
11078    /*
11079     * Currently:
11080     *  r0 holds resolved field
11081     *  r9 holds object
11082     */
11083.LOP_IGET_OBJECT_finish:
11084    @bl      common_squeak0
11085    cmp     r9, #0                      @ check object for null
11086    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11087    beq     common_errNullObject        @ object was null
11088    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11089    @ no-op                             @ acquiring load
11090    mov     r2, rINST, lsr #8           @ r2<- A+
11091    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11092    and     r2, r2, #15                 @ r2<- A
11093    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11094    SET_VREG(r0, r2)                    @ fp[A]<- r0
11095    GOTO_OPCODE(ip)                     @ jump to next instruction
11096
11097/* continuation for OP_IGET_BOOLEAN */
11098
11099    /*
11100     * Currently:
11101     *  r0 holds resolved field
11102     *  r9 holds object
11103     */
11104.LOP_IGET_BOOLEAN_finish:
11105    @bl      common_squeak1
11106    cmp     r9, #0                      @ check object for null
11107    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11108    beq     common_errNullObject        @ object was null
11109    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11110    @ no-op                             @ acquiring load
11111    mov     r2, rINST, lsr #8           @ r2<- A+
11112    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11113    and     r2, r2, #15                 @ r2<- A
11114    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11115    SET_VREG(r0, r2)                    @ fp[A]<- r0
11116    GOTO_OPCODE(ip)                     @ jump to next instruction
11117
11118/* continuation for OP_IGET_BYTE */
11119
11120    /*
11121     * Currently:
11122     *  r0 holds resolved field
11123     *  r9 holds object
11124     */
11125.LOP_IGET_BYTE_finish:
11126    @bl      common_squeak2
11127    cmp     r9, #0                      @ check object for null
11128    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11129    beq     common_errNullObject        @ object was null
11130    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11131    @ no-op                             @ acquiring load
11132    mov     r2, rINST, lsr #8           @ r2<- A+
11133    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11134    and     r2, r2, #15                 @ r2<- A
11135    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11136    SET_VREG(r0, r2)                    @ fp[A]<- r0
11137    GOTO_OPCODE(ip)                     @ jump to next instruction
11138
11139/* continuation for OP_IGET_CHAR */
11140
11141    /*
11142     * Currently:
11143     *  r0 holds resolved field
11144     *  r9 holds object
11145     */
11146.LOP_IGET_CHAR_finish:
11147    @bl      common_squeak3
11148    cmp     r9, #0                      @ check object for null
11149    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11150    beq     common_errNullObject        @ object was null
11151    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11152    @ no-op                             @ acquiring load
11153    mov     r2, rINST, lsr #8           @ r2<- A+
11154    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11155    and     r2, r2, #15                 @ r2<- A
11156    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11157    SET_VREG(r0, r2)                    @ fp[A]<- r0
11158    GOTO_OPCODE(ip)                     @ jump to next instruction
11159
11160/* continuation for OP_IGET_SHORT */
11161
11162    /*
11163     * Currently:
11164     *  r0 holds resolved field
11165     *  r9 holds object
11166     */
11167.LOP_IGET_SHORT_finish:
11168    @bl      common_squeak4
11169    cmp     r9, #0                      @ check object for null
11170    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11171    beq     common_errNullObject        @ object was null
11172    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11173    @ no-op                             @ acquiring load
11174    mov     r2, rINST, lsr #8           @ r2<- A+
11175    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11176    and     r2, r2, #15                 @ r2<- A
11177    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11178    SET_VREG(r0, r2)                    @ fp[A]<- r0
11179    GOTO_OPCODE(ip)                     @ jump to next instruction
11180
11181/* continuation for OP_IPUT */
11182
11183    /*
11184     * Currently:
11185     *  r0 holds resolved field
11186     *  r9 holds object
11187     */
11188.LOP_IPUT_finish:
11189    @bl      common_squeak0
11190    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11191    ubfx    r1, rINST, #8, #4           @ r1<- A
11192    cmp     r9, #0                      @ check object for null
11193    GET_VREG(r0, r1)                    @ r0<- fp[A]
11194    beq     common_errNullObject        @ object was null
11195    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11196    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11197    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11198    GOTO_OPCODE(ip)                     @ jump to next instruction
11199
11200/* continuation for OP_IPUT_WIDE */
11201
11202    /*
11203     * Currently:
11204     *  r0 holds resolved field
11205     *  r9 holds object
11206     */
11207.LOP_IPUT_WIDE_finish:
11208    ubfx    r2, rINST, #8, #4           @ r2<- A
11209    cmp     r9, #0                      @ check object for null
11210    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11211    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
11212    beq     common_errNullObject        @ object was null
11213    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11214    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
11215    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11216    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0
11217    GOTO_OPCODE(ip)                     @ jump to next instruction
11218
11219/* continuation for OP_IPUT_OBJECT */
11220
11221    /*
11222     * Currently:
11223     *  r0 holds resolved field
11224     *  r9 holds object
11225     */
11226.LOP_IPUT_OBJECT_finish:
11227    @bl      common_squeak0
11228    mov     r1, rINST, lsr #8           @ r1<- A+
11229    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11230    and     r1, r1, #15                 @ r1<- A
11231    cmp     r9, #0                      @ check object for null
11232    GET_VREG(r0, r1)                    @ r0<- fp[A]
11233    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
11234    beq     common_errNullObject        @ object was null
11235    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11236    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11237    @ no-op                             @ releasing store
11238    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
11239    cmp     r0, #0                      @ stored a null reference?
11240    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
11241    GOTO_OPCODE(ip)                     @ jump to next instruction
11242
11243/* continuation for OP_IPUT_BOOLEAN */
11244
11245    /*
11246     * Currently:
11247     *  r0 holds resolved field
11248     *  r9 holds object
11249     */
11250.LOP_IPUT_BOOLEAN_finish:
11251    @bl      common_squeak1
11252    mov     r1, rINST, lsr #8           @ r1<- A+
11253    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11254    and     r1, r1, #15                 @ r1<- A
11255    cmp     r9, #0                      @ check object for null
11256    GET_VREG(r0, r1)                    @ r0<- fp[A]
11257    beq     common_errNullObject        @ object was null
11258    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11259    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11260    @ no-op                             @ releasing store
11261    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11262    GOTO_OPCODE(ip)                     @ jump to next instruction
11263
11264/* continuation for OP_IPUT_BYTE */
11265
11266    /*
11267     * Currently:
11268     *  r0 holds resolved field
11269     *  r9 holds object
11270     */
11271.LOP_IPUT_BYTE_finish:
11272    @bl      common_squeak2
11273    mov     r1, rINST, lsr #8           @ r1<- A+
11274    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11275    and     r1, r1, #15                 @ r1<- A
11276    cmp     r9, #0                      @ check object for null
11277    GET_VREG(r0, r1)                    @ r0<- fp[A]
11278    beq     common_errNullObject        @ object was null
11279    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11280    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11281    @ no-op                             @ releasing store
11282    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11283    GOTO_OPCODE(ip)                     @ jump to next instruction
11284
11285/* continuation for OP_IPUT_CHAR */
11286
11287    /*
11288     * Currently:
11289     *  r0 holds resolved field
11290     *  r9 holds object
11291     */
11292.LOP_IPUT_CHAR_finish:
11293    @bl      common_squeak3
11294    mov     r1, rINST, lsr #8           @ r1<- A+
11295    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11296    and     r1, r1, #15                 @ r1<- A
11297    cmp     r9, #0                      @ check object for null
11298    GET_VREG(r0, r1)                    @ r0<- fp[A]
11299    beq     common_errNullObject        @ object was null
11300    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11301    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11302    @ no-op                             @ releasing store
11303    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11304    GOTO_OPCODE(ip)                     @ jump to next instruction
11305
11306/* continuation for OP_IPUT_SHORT */
11307
11308    /*
11309     * Currently:
11310     *  r0 holds resolved field
11311     *  r9 holds object
11312     */
11313.LOP_IPUT_SHORT_finish:
11314    @bl      common_squeak4
11315    mov     r1, rINST, lsr #8           @ r1<- A+
11316    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11317    and     r1, r1, #15                 @ r1<- A
11318    cmp     r9, #0                      @ check object for null
11319    GET_VREG(r0, r1)                    @ r0<- fp[A]
11320    beq     common_errNullObject        @ object was null
11321    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11322    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11323    @ no-op                             @ releasing store
11324    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11325    GOTO_OPCODE(ip)                     @ jump to next instruction
11326
11327/* continuation for OP_SGET */
11328
11329    /*
11330     * Continuation if the field has not yet been resolved.
11331     *  r1: BBBB field ref
11332     */
11333.LOP_SGET_resolve:
11334    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11335    EXPORT_PC()                         @ resolve() could throw, so export now
11336    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11337    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11338    cmp     r0, #0                      @ success?
11339    bne     .LOP_SGET_finish          @ yes, finish
11340    b       common_exceptionThrown      @ no, handle exception
11341
11342/* continuation for OP_SGET_WIDE */
11343
11344    /*
11345     * Continuation if the field has not yet been resolved.
11346     *  r1: BBBB field ref
11347     *
11348     * Returns StaticField pointer in r0.
11349     */
11350.LOP_SGET_WIDE_resolve:
11351    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11352    EXPORT_PC()                         @ resolve() could throw, so export now
11353    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11354    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11355    cmp     r0, #0                      @ success?
11356    bne     .LOP_SGET_WIDE_finish          @ yes, finish
11357    b       common_exceptionThrown      @ no, handle exception
11358
11359/* continuation for OP_SGET_OBJECT */
11360
11361    /*
11362     * Continuation if the field has not yet been resolved.
11363     *  r1: BBBB field ref
11364     */
11365.LOP_SGET_OBJECT_resolve:
11366    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11367    EXPORT_PC()                         @ resolve() could throw, so export now
11368    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11369    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11370    cmp     r0, #0                      @ success?
11371    bne     .LOP_SGET_OBJECT_finish          @ yes, finish
11372    b       common_exceptionThrown      @ no, handle exception
11373
11374/* continuation for OP_SGET_BOOLEAN */
11375
11376    /*
11377     * Continuation if the field has not yet been resolved.
11378     *  r1: BBBB field ref
11379     */
11380.LOP_SGET_BOOLEAN_resolve:
11381    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11382    EXPORT_PC()                         @ resolve() could throw, so export now
11383    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11384    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11385    cmp     r0, #0                      @ success?
11386    bne     .LOP_SGET_BOOLEAN_finish          @ yes, finish
11387    b       common_exceptionThrown      @ no, handle exception
11388
11389/* continuation for OP_SGET_BYTE */
11390
11391    /*
11392     * Continuation if the field has not yet been resolved.
11393     *  r1: BBBB field ref
11394     */
11395.LOP_SGET_BYTE_resolve:
11396    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11397    EXPORT_PC()                         @ resolve() could throw, so export now
11398    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11399    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11400    cmp     r0, #0                      @ success?
11401    bne     .LOP_SGET_BYTE_finish          @ yes, finish
11402    b       common_exceptionThrown      @ no, handle exception
11403
11404/* continuation for OP_SGET_CHAR */
11405
11406    /*
11407     * Continuation if the field has not yet been resolved.
11408     *  r1: BBBB field ref
11409     */
11410.LOP_SGET_CHAR_resolve:
11411    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11412    EXPORT_PC()                         @ resolve() could throw, so export now
11413    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11414    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11415    cmp     r0, #0                      @ success?
11416    bne     .LOP_SGET_CHAR_finish          @ yes, finish
11417    b       common_exceptionThrown      @ no, handle exception
11418
11419/* continuation for OP_SGET_SHORT */
11420
11421    /*
11422     * Continuation if the field has not yet been resolved.
11423     *  r1: BBBB field ref
11424     */
11425.LOP_SGET_SHORT_resolve:
11426    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11427    EXPORT_PC()                         @ resolve() could throw, so export now
11428    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11429    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11430    cmp     r0, #0                      @ success?
11431    bne     .LOP_SGET_SHORT_finish          @ yes, finish
11432    b       common_exceptionThrown      @ no, handle exception
11433
11434/* continuation for OP_SPUT */
11435
11436    /*
11437     * Continuation if the field has not yet been resolved.
11438     *  r1: BBBB field ref
11439     */
11440.LOP_SPUT_resolve:
11441    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11442    EXPORT_PC()                         @ resolve() could throw, so export now
11443    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11444    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11445    cmp     r0, #0                      @ success?
11446    bne     .LOP_SPUT_finish          @ yes, finish
11447    b       common_exceptionThrown      @ no, handle exception
11448
11449/* continuation for OP_SPUT_WIDE */
11450
11451    /*
11452     * Continuation if the field has not yet been resolved.
11453     *  r1: BBBB field ref
11454     *  r9: &fp[AA]
11455     *
11456     * Returns StaticField pointer in r2.
11457     */
11458.LOP_SPUT_WIDE_resolve:
11459    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11460    EXPORT_PC()                         @ resolve() could throw, so export now
11461    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11462    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11463    cmp     r0, #0                      @ success?
11464    mov     r2, r0                      @ copy to r2
11465    bne     .LOP_SPUT_WIDE_finish          @ yes, finish
11466    b       common_exceptionThrown      @ no, handle exception
11467
11468/* continuation for OP_SPUT_OBJECT */
11469.LOP_SPUT_OBJECT_finish:   @ field ptr in r0
11470    mov     r2, rINST, lsr #8           @ r2<- AA
11471    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11472    GET_VREG(r1, r2)                    @ r1<- fp[AA]
11473    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
11474    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
11475    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11476    @ no-op                             @ releasing store
11477    str     r1, [r0, #offStaticField_value]  @ field<- vAA
11478    cmp     r1, #0                      @ stored a null object?
11479    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
11480    GOTO_OPCODE(ip)                     @ jump to next instruction
11481
11482/* continuation for OP_SPUT_BOOLEAN */
11483
11484    /*
11485     * Continuation if the field has not yet been resolved.
11486     *  r1: BBBB field ref
11487     */
11488.LOP_SPUT_BOOLEAN_resolve:
11489    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11490    EXPORT_PC()                         @ resolve() could throw, so export now
11491    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11492    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11493    cmp     r0, #0                      @ success?
11494    bne     .LOP_SPUT_BOOLEAN_finish          @ yes, finish
11495    b       common_exceptionThrown      @ no, handle exception
11496
11497/* continuation for OP_SPUT_BYTE */
11498
11499    /*
11500     * Continuation if the field has not yet been resolved.
11501     *  r1: BBBB field ref
11502     */
11503.LOP_SPUT_BYTE_resolve:
11504    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11505    EXPORT_PC()                         @ resolve() could throw, so export now
11506    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11507    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11508    cmp     r0, #0                      @ success?
11509    bne     .LOP_SPUT_BYTE_finish          @ yes, finish
11510    b       common_exceptionThrown      @ no, handle exception
11511
11512/* continuation for OP_SPUT_CHAR */
11513
11514    /*
11515     * Continuation if the field has not yet been resolved.
11516     *  r1: BBBB field ref
11517     */
11518.LOP_SPUT_CHAR_resolve:
11519    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11520    EXPORT_PC()                         @ resolve() could throw, so export now
11521    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11522    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11523    cmp     r0, #0                      @ success?
11524    bne     .LOP_SPUT_CHAR_finish          @ yes, finish
11525    b       common_exceptionThrown      @ no, handle exception
11526
11527/* continuation for OP_SPUT_SHORT */
11528
11529    /*
11530     * Continuation if the field has not yet been resolved.
11531     *  r1: BBBB field ref
11532     */
11533.LOP_SPUT_SHORT_resolve:
11534    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11535    EXPORT_PC()                         @ resolve() could throw, so export now
11536    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11537    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11538    cmp     r0, #0                      @ success?
11539    bne     .LOP_SPUT_SHORT_finish          @ yes, finish
11540    b       common_exceptionThrown      @ no, handle exception
11541
11542/* continuation for OP_INVOKE_VIRTUAL */
11543
11544    /*
11545     * At this point:
11546     *  r0 = resolved base method
11547     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
11548     */
11549.LOP_INVOKE_VIRTUAL_continue:
11550    GET_VREG(r1, r10)                   @ r1<- "this" ptr
11551    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11552    cmp     r1, #0                      @ is "this" null?
11553    beq     common_errNullObject        @ null "this", throw exception
11554    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
11555    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
11556    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
11557    bl      common_invokeMethodNoRange @ continue on
11558
11559/* continuation for OP_INVOKE_SUPER */
11560
11561    /*
11562     * At this point:
11563     *  r0 = resolved base method
11564     *  r9 = method->clazz
11565     */
11566.LOP_INVOKE_SUPER_continue:
11567    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
11568    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11569    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
11570    EXPORT_PC()                         @ must export for invoke
11571    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
11572    bcs     .LOP_INVOKE_SUPER_nsm             @ method not present in superclass
11573    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
11574    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
11575    bl      common_invokeMethodNoRange @ continue on
11576
11577.LOP_INVOKE_SUPER_resolve:
11578    mov     r0, r9                      @ r0<- method->clazz
11579    mov     r2, #METHOD_VIRTUAL         @ resolver method type
11580    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11581    cmp     r0, #0                      @ got null?
11582    bne     .LOP_INVOKE_SUPER_continue        @ no, continue
11583    b       common_exceptionThrown      @ yes, handle exception
11584
11585    /*
11586     * Throw a NoSuchMethodError with the method name as the message.
11587     *  r0 = resolved base method
11588     */
11589.LOP_INVOKE_SUPER_nsm:
11590    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
11591    b       common_errNoSuchMethod
11592
11593/* continuation for OP_INVOKE_DIRECT */
11594
11595    /*
11596     * On entry:
11597     *  r1 = reference (BBBB or CCCC)
11598     *  r10 = "this" register
11599     */
11600.LOP_INVOKE_DIRECT_resolve:
11601    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
11602    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
11603    mov     r2, #METHOD_DIRECT          @ resolver method type
11604    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11605    cmp     r0, #0                      @ got null?
11606    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
11607    bne     .LOP_INVOKE_DIRECT_finish          @ no, continue
11608    b       common_exceptionThrown      @ yes, handle exception
11609
11610/* continuation for OP_INVOKE_VIRTUAL_RANGE */
11611
11612    /*
11613     * At this point:
11614     *  r0 = resolved base method
11615     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
11616     */
11617.LOP_INVOKE_VIRTUAL_RANGE_continue:
11618    GET_VREG(r1, r10)                   @ r1<- "this" ptr
11619    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11620    cmp     r1, #0                      @ is "this" null?
11621    beq     common_errNullObject        @ null "this", throw exception
11622    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
11623    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
11624    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
11625    bl      common_invokeMethodRange @ continue on
11626
11627/* continuation for OP_INVOKE_SUPER_RANGE */
11628
11629    /*
11630     * At this point:
11631     *  r0 = resolved base method
11632     *  r9 = method->clazz
11633     */
11634.LOP_INVOKE_SUPER_RANGE_continue:
11635    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
11636    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11637    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
11638    EXPORT_PC()                         @ must export for invoke
11639    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
11640    bcs     .LOP_INVOKE_SUPER_RANGE_nsm             @ method not present in superclass
11641    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
11642    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
11643    bl      common_invokeMethodRange @ continue on
11644
11645.LOP_INVOKE_SUPER_RANGE_resolve:
11646    mov     r0, r9                      @ r0<- method->clazz
11647    mov     r2, #METHOD_VIRTUAL         @ resolver method type
11648    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11649    cmp     r0, #0                      @ got null?
11650    bne     .LOP_INVOKE_SUPER_RANGE_continue        @ no, continue
11651    b       common_exceptionThrown      @ yes, handle exception
11652
11653    /*
11654     * Throw a NoSuchMethodError with the method name as the message.
11655     *  r0 = resolved base method
11656     */
11657.LOP_INVOKE_SUPER_RANGE_nsm:
11658    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
11659    b       common_errNoSuchMethod
11660
11661/* continuation for OP_INVOKE_DIRECT_RANGE */
11662
11663    /*
11664     * On entry:
11665     *  r1 = reference (BBBB or CCCC)
11666     *  r10 = "this" register
11667     */
11668.LOP_INVOKE_DIRECT_RANGE_resolve:
11669    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
11670    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
11671    mov     r2, #METHOD_DIRECT          @ resolver method type
11672    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11673    cmp     r0, #0                      @ got null?
11674    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
11675    bne     .LOP_INVOKE_DIRECT_RANGE_finish          @ no, continue
11676    b       common_exceptionThrown      @ yes, handle exception
11677
11678/* continuation for OP_FLOAT_TO_LONG */
11679/*
11680 * Convert the float in r0 to a long in r0/r1.
11681 *
11682 * We have to clip values to long min/max per the specification.  The
11683 * expected common case is a "reasonable" value that converts directly
11684 * to modest integer.  The EABI convert function isn't doing this for us.
11685 */
11686f2l_doconv:
11687    stmfd   sp!, {r4, lr}
11688    mov     r1, #0x5f000000             @ (float)maxlong
11689    mov     r4, r0
11690    bl      __aeabi_fcmpge              @ is arg >= maxlong?
11691    cmp     r0, #0                      @ nonzero == yes
11692    mvnne   r0, #0                      @ return maxlong (7fffffff)
11693    mvnne   r1, #0x80000000
11694    ldmnefd sp!, {r4, pc}
11695
11696    mov     r0, r4                      @ recover arg
11697    mov     r1, #0xdf000000             @ (float)minlong
11698    bl      __aeabi_fcmple              @ is arg <= minlong?
11699    cmp     r0, #0                      @ nonzero == yes
11700    movne   r0, #0                      @ return minlong (80000000)
11701    movne   r1, #0x80000000
11702    ldmnefd sp!, {r4, pc}
11703
11704    mov     r0, r4                      @ recover arg
11705    mov     r1, r4
11706    bl      __aeabi_fcmpeq              @ is arg == self?
11707    cmp     r0, #0                      @ zero == no
11708    moveq   r1, #0                      @ return zero for NaN
11709    ldmeqfd sp!, {r4, pc}
11710
11711    mov     r0, r4                      @ recover arg
11712    bl      __aeabi_f2lz                @ convert float to long
11713    ldmfd   sp!, {r4, pc}
11714
11715/* continuation for OP_DOUBLE_TO_LONG */
11716/*
11717 * Convert the double in r0/r1 to a long in r0/r1.
11718 *
11719 * We have to clip values to long min/max per the specification.  The
11720 * expected common case is a "reasonable" value that converts directly
11721 * to modest integer.  The EABI convert function isn't doing this for us.
11722 */
11723d2l_doconv:
11724    stmfd   sp!, {r4, r5, lr}           @ save regs
11725    mov     r3, #0x43000000             @ maxlong, as a double (high word)
11726    add     r3, #0x00e00000             @  0x43e00000
11727    mov     r2, #0                      @ maxlong, as a double (low word)
11728    sub     sp, sp, #4                  @ align for EABI
11729    mov     r4, r0                      @ save a copy of r0
11730    mov     r5, r1                      @  and r1
11731    bl      __aeabi_dcmpge              @ is arg >= maxlong?
11732    cmp     r0, #0                      @ nonzero == yes
11733    mvnne   r0, #0                      @ return maxlong (7fffffffffffffff)
11734    mvnne   r1, #0x80000000
11735    bne     1f
11736
11737    mov     r0, r4                      @ recover arg
11738    mov     r1, r5
11739    mov     r3, #0xc3000000             @ minlong, as a double (high word)
11740    add     r3, #0x00e00000             @  0xc3e00000
11741    mov     r2, #0                      @ minlong, as a double (low word)
11742    bl      __aeabi_dcmple              @ is arg <= minlong?
11743    cmp     r0, #0                      @ nonzero == yes
11744    movne   r0, #0                      @ return minlong (8000000000000000)
11745    movne   r1, #0x80000000
11746    bne     1f
11747
11748    mov     r0, r4                      @ recover arg
11749    mov     r1, r5
11750    mov     r2, r4                      @ compare against self
11751    mov     r3, r5
11752    bl      __aeabi_dcmpeq              @ is arg == self?
11753    cmp     r0, #0                      @ zero == no
11754    moveq   r1, #0                      @ return zero for NaN
11755    beq     1f
11756
11757    mov     r0, r4                      @ recover arg
11758    mov     r1, r5
11759    bl      __aeabi_d2lz                @ convert double to long
11760
117611:
11762    add     sp, sp, #4
11763    ldmfd   sp!, {r4, r5, pc}
11764
11765/* continuation for OP_MUL_LONG */
11766
11767.LOP_MUL_LONG_finish:
11768    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11769    stmia   r0, {r9-r10}                @ vAA/vAA+1<- r9/r10
11770    GOTO_OPCODE(ip)                     @ jump to next instruction
11771
11772/* continuation for OP_SHL_LONG */
11773
11774.LOP_SHL_LONG_finish:
11775    mov     r0, r0, asl r2              @  r0<- r0 << r2
11776    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11777    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11778    GOTO_OPCODE(ip)                     @ jump to next instruction
11779
11780/* continuation for OP_SHR_LONG */
11781
11782.LOP_SHR_LONG_finish:
11783    mov     r1, r1, asr r2              @  r1<- r1 >> r2
11784    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11785    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11786    GOTO_OPCODE(ip)                     @ jump to next instruction
11787
11788/* continuation for OP_USHR_LONG */
11789
11790.LOP_USHR_LONG_finish:
11791    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
11792    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11793    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11794    GOTO_OPCODE(ip)                     @ jump to next instruction
11795
11796/* continuation for OP_SHL_LONG_2ADDR */
11797
11798.LOP_SHL_LONG_2ADDR_finish:
11799    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11800    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11801    GOTO_OPCODE(ip)                     @ jump to next instruction
11802
11803/* continuation for OP_SHR_LONG_2ADDR */
11804
11805.LOP_SHR_LONG_2ADDR_finish:
11806    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11807    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11808    GOTO_OPCODE(ip)                     @ jump to next instruction
11809
11810/* continuation for OP_USHR_LONG_2ADDR */
11811
11812.LOP_USHR_LONG_2ADDR_finish:
11813    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11814    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11815    GOTO_OPCODE(ip)                     @ jump to next instruction
11816
11817/* continuation for OP_IGET_VOLATILE */
11818
11819    /*
11820     * Currently:
11821     *  r0 holds resolved field
11822     *  r9 holds object
11823     */
11824.LOP_IGET_VOLATILE_finish:
11825    @bl      common_squeak0
11826    cmp     r9, #0                      @ check object for null
11827    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11828    beq     common_errNullObject        @ object was null
11829    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11830    SMP_DMB                            @ acquiring load
11831    mov     r2, rINST, lsr #8           @ r2<- A+
11832    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11833    and     r2, r2, #15                 @ r2<- A
11834    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11835    SET_VREG(r0, r2)                    @ fp[A]<- r0
11836    GOTO_OPCODE(ip)                     @ jump to next instruction
11837
11838/* continuation for OP_IPUT_VOLATILE */
11839
11840    /*
11841     * Currently:
11842     *  r0 holds resolved field
11843     *  r9 holds object
11844     */
11845.LOP_IPUT_VOLATILE_finish:
11846    @bl      common_squeak0
11847    mov     r1, rINST, lsr #8           @ r1<- A+
11848    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11849    and     r1, r1, #15                 @ r1<- A
11850    cmp     r9, #0                      @ check object for null
11851    GET_VREG(r0, r1)                    @ r0<- fp[A]
11852    beq     common_errNullObject        @ object was null
11853    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11854    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11855    SMP_DMB                            @ releasing store
11856    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11857    GOTO_OPCODE(ip)                     @ jump to next instruction
11858
11859/* continuation for OP_SGET_VOLATILE */
11860
11861    /*
11862     * Continuation if the field has not yet been resolved.
11863     *  r1: BBBB field ref
11864     */
11865.LOP_SGET_VOLATILE_resolve:
11866    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11867    EXPORT_PC()                         @ resolve() could throw, so export now
11868    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11869    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11870    cmp     r0, #0                      @ success?
11871    bne     .LOP_SGET_VOLATILE_finish          @ yes, finish
11872    b       common_exceptionThrown      @ no, handle exception
11873
11874/* continuation for OP_SPUT_VOLATILE */
11875
11876    /*
11877     * Continuation if the field has not yet been resolved.
11878     *  r1: BBBB field ref
11879     */
11880.LOP_SPUT_VOLATILE_resolve:
11881    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11882    EXPORT_PC()                         @ resolve() could throw, so export now
11883    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11884    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11885    cmp     r0, #0                      @ success?
11886    bne     .LOP_SPUT_VOLATILE_finish          @ yes, finish
11887    b       common_exceptionThrown      @ no, handle exception
11888
11889/* continuation for OP_IGET_OBJECT_VOLATILE */
11890
11891    /*
11892     * Currently:
11893     *  r0 holds resolved field
11894     *  r9 holds object
11895     */
11896.LOP_IGET_OBJECT_VOLATILE_finish:
11897    @bl      common_squeak0
11898    cmp     r9, #0                      @ check object for null
11899    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11900    beq     common_errNullObject        @ object was null
11901    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11902    SMP_DMB                            @ acquiring load
11903    mov     r2, rINST, lsr #8           @ r2<- A+
11904    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11905    and     r2, r2, #15                 @ r2<- A
11906    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11907    SET_VREG(r0, r2)                    @ fp[A]<- r0
11908    GOTO_OPCODE(ip)                     @ jump to next instruction
11909
11910/* continuation for OP_IGET_WIDE_VOLATILE */
11911
11912    /*
11913     * Currently:
11914     *  r0 holds resolved field
11915     *  r9 holds object
11916     */
11917.LOP_IGET_WIDE_VOLATILE_finish:
11918    cmp     r9, #0                      @ check object for null
11919    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11920    beq     common_errNullObject        @ object was null
11921    .if     1
11922    add     r0, r9, r3                  @ r0<- address of field
11923    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
11924    .else
11925    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
11926    .endif
11927    mov     r2, rINST, lsr #8           @ r2<- A+
11928    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11929    and     r2, r2, #15                 @ r2<- A
11930    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
11931    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11932    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
11933    GOTO_OPCODE(ip)                     @ jump to next instruction
11934
11935/* continuation for OP_IPUT_WIDE_VOLATILE */
11936
11937    /*
11938     * Currently:
11939     *  r0 holds resolved field
11940     *  r9 holds object
11941     */
11942.LOP_IPUT_WIDE_VOLATILE_finish:
11943    mov     r2, rINST, lsr #8           @ r2<- A+
11944    cmp     r9, #0                      @ check object for null
11945    and     r2, r2, #15                 @ r2<- A
11946    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11947    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
11948    beq     common_errNullObject        @ object was null
11949    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11950    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
11951    GET_INST_OPCODE(r10)                @ extract opcode from rINST
11952    .if     1
11953    add     r2, r9, r3                  @ r2<- target address
11954    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
11955    .else
11956    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
11957    .endif
11958    GOTO_OPCODE(r10)                    @ jump to next instruction
11959
11960/* continuation for OP_SGET_WIDE_VOLATILE */
11961
11962    /*
11963     * Continuation if the field has not yet been resolved.
11964     *  r1: BBBB field ref
11965     *
11966     * Returns StaticField pointer in r0.
11967     */
11968.LOP_SGET_WIDE_VOLATILE_resolve:
11969    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11970    EXPORT_PC()                         @ resolve() could throw, so export now
11971    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11972    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11973    cmp     r0, #0                      @ success?
11974    bne     .LOP_SGET_WIDE_VOLATILE_finish          @ yes, finish
11975    b       common_exceptionThrown      @ no, handle exception
11976
11977/* continuation for OP_SPUT_WIDE_VOLATILE */
11978
11979    /*
11980     * Continuation if the field has not yet been resolved.
11981     *  r1: BBBB field ref
11982     *  r9: &fp[AA]
11983     *
11984     * Returns StaticField pointer in r2.
11985     */
11986.LOP_SPUT_WIDE_VOLATILE_resolve:
11987    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11988    EXPORT_PC()                         @ resolve() could throw, so export now
11989    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11990    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11991    cmp     r0, #0                      @ success?
11992    mov     r2, r0                      @ copy to r2
11993    bne     .LOP_SPUT_WIDE_VOLATILE_finish          @ yes, finish
11994    b       common_exceptionThrown      @ no, handle exception
11995
11996/* continuation for OP_EXECUTE_INLINE */
11997
11998    /*
11999     * Extract args, call function.
12000     *  r0 = #of args (0-4)
12001     *  r10 = call index
12002     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
12003     *
12004     * Other ideas:
12005     * - Use a jump table from the main piece to jump directly into the
12006     *   AND/LDR pairs.  Costs a data load, saves a branch.
12007     * - Have five separate pieces that do the loading, so we can work the
12008     *   interleave a little better.  Increases code size.
12009     */
12010.LOP_EXECUTE_INLINE_continue:
12011    rsb     r0, r0, #4                  @ r0<- 4-r0
12012    FETCH(r9, 2)                        @ r9<- FEDC
12013    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
12014    bl      common_abort                @ (skipped due to ARM prefetch)
120154:  and     ip, r9, #0xf000             @ isolate F
12016    ldr     r3, [rFP, ip, lsr #10]      @ r3<- vF (shift right 12, left 2)
120173:  and     ip, r9, #0x0f00             @ isolate E
12018    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vE
120192:  and     ip, r9, #0x00f0             @ isolate D
12020    ldr     r1, [rFP, ip, lsr #2]       @ r1<- vD
120211:  and     ip, r9, #0x000f             @ isolate C
12022    ldr     r0, [rFP, ip, lsl #2]       @ r0<- vC
120230:
12024    ldr     r9, .LOP_EXECUTE_INLINE_table       @ table of InlineOperation
12025    ldr     pc, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
12026    @ (not reached)
12027
12028.LOP_EXECUTE_INLINE_table:
12029    .word   gDvmInlineOpsTable
12030
12031/* continuation for OP_EXECUTE_INLINE_RANGE */
12032
12033    /*
12034     * Extract args, call function.
12035     *  r0 = #of args (0-4)
12036     *  r10 = call index
12037     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
12038     */
12039.LOP_EXECUTE_INLINE_RANGE_continue:
12040    rsb     r0, r0, #4                  @ r0<- 4-r0
12041    FETCH(r9, 2)                        @ r9<- CCCC
12042    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
12043    bl      common_abort                @ (skipped due to ARM prefetch)
120444:  add     ip, r9, #3                  @ base+3
12045    GET_VREG(r3, ip)                    @ r3<- vBase[3]
120463:  add     ip, r9, #2                  @ base+2
12047    GET_VREG(r2, ip)                    @ r2<- vBase[2]
120482:  add     ip, r9, #1                  @ base+1
12049    GET_VREG(r1, ip)                    @ r1<- vBase[1]
120501:  add     ip, r9, #0                  @ (nop)
12051    GET_VREG(r0, ip)                    @ r0<- vBase[0]
120520:
12053    ldr     r9, .LOP_EXECUTE_INLINE_RANGE_table       @ table of InlineOperation
12054    ldr     pc, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
12055    @ (not reached)
12056
12057.LOP_EXECUTE_INLINE_RANGE_table:
12058    .word   gDvmInlineOpsTable
12059
12060/* continuation for OP_IPUT_OBJECT_VOLATILE */
12061
12062    /*
12063     * Currently:
12064     *  r0 holds resolved field
12065     *  r9 holds object
12066     */
12067.LOP_IPUT_OBJECT_VOLATILE_finish:
12068    @bl      common_squeak0
12069    mov     r1, rINST, lsr #8           @ r1<- A+
12070    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12071    and     r1, r1, #15                 @ r1<- A
12072    cmp     r9, #0                      @ check object for null
12073    GET_VREG(r0, r1)                    @ r0<- fp[A]
12074    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
12075    beq     common_errNullObject        @ object was null
12076    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12077    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12078    SMP_DMB                            @ releasing store
12079    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
12080    cmp     r0, #0                      @ stored a null reference?
12081    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
12082    GOTO_OPCODE(ip)                     @ jump to next instruction
12083
12084/* continuation for OP_SGET_OBJECT_VOLATILE */
12085
12086    /*
12087     * Continuation if the field has not yet been resolved.
12088     *  r1: BBBB field ref
12089     */
12090.LOP_SGET_OBJECT_VOLATILE_resolve:
12091    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12092    EXPORT_PC()                         @ resolve() could throw, so export now
12093    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12094    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12095    cmp     r0, #0                      @ success?
12096    bne     .LOP_SGET_OBJECT_VOLATILE_finish          @ yes, finish
12097    b       common_exceptionThrown      @ no, handle exception
12098
12099/* continuation for OP_SPUT_OBJECT_VOLATILE */
12100.LOP_SPUT_OBJECT_VOLATILE_finish:   @ field ptr in r0
12101    mov     r2, rINST, lsr #8           @ r2<- AA
12102    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12103    GET_VREG(r1, r2)                    @ r1<- fp[AA]
12104    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
12105    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
12106    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12107    SMP_DMB                            @ releasing store
12108    str     r1, [r0, #offStaticField_value]  @ field<- vAA
12109    cmp     r1, #0                      @ stored a null object?
12110    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
12111    GOTO_OPCODE(ip)                     @ jump to next instruction
12112
12113/* continuation for OP_CONST_CLASS_JUMBO */
12114
12115    /*
12116     * Continuation if the Class has not yet been resolved.
12117     *  r1: AAAAAAAA (Class ref)
12118     *  r9: target register
12119     */
12120.LOP_CONST_CLASS_JUMBO_resolve:
12121    EXPORT_PC()
12122    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
12123    mov     r2, #1                      @ r2<- true
12124    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
12125    bl      dvmResolveClass             @ r0<- Class reference
12126    cmp     r0, #0                      @ failed?
12127    beq     common_exceptionThrown      @ yup, handle the exception
12128    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12129    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12130    SET_VREG(r0, r9)                    @ vBBBB<- r0
12131    GOTO_OPCODE(ip)                     @ jump to next instruction
12132
12133/* continuation for OP_CHECK_CAST_JUMBO */
12134
12135    /*
12136     * Trivial test failed, need to perform full check.  This is common.
12137     *  r0 holds obj->clazz
12138     *  r1 holds desired class resolved from AAAAAAAA
12139     *  r9 holds object
12140     */
12141.LOP_CHECK_CAST_JUMBO_fullcheck:
12142    mov     r10, r1                     @ avoid ClassObject getting clobbered
12143    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
12144    cmp     r0, #0                      @ failed?
12145    bne     .LOP_CHECK_CAST_JUMBO_okay            @ no, success
12146
12147    @ A cast has failed.  We need to throw a ClassCastException.
12148    EXPORT_PC()                         @ about to throw
12149    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz (actual class)
12150    mov     r1, r10                     @ r1<- desired class
12151    bl      dvmThrowClassCastException
12152    b       common_exceptionThrown
12153
12154    /*
12155     * Advance PC and get the next opcode.
12156     */
12157.LOP_CHECK_CAST_JUMBO_okay:
12158    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12159    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12160    GOTO_OPCODE(ip)                     @ jump to next instruction
12161
12162    /*
12163     * Resolution required.  This is the least-likely path.
12164     *
12165     *  r2 holds AAAAAAAA
12166     *  r9 holds object
12167     */
12168.LOP_CHECK_CAST_JUMBO_resolve:
12169    EXPORT_PC()                         @ resolve() could throw
12170    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
12171    mov     r1, r2                      @ r1<- AAAAAAAA
12172    mov     r2, #0                      @ r2<- false
12173    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12174    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12175    cmp     r0, #0                      @ got null?
12176    beq     common_exceptionThrown      @ yes, handle exception
12177    mov     r1, r0                      @ r1<- class resolved from AAAAAAAA
12178    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
12179    b       .LOP_CHECK_CAST_JUMBO_resolved        @ pick up where we left off
12180
12181/* continuation for OP_INSTANCE_OF_JUMBO */
12182
12183    /*
12184     * Class resolved, determine type of check necessary.  This is common.
12185     *  r0 holds obj->clazz
12186     *  r1 holds class resolved from AAAAAAAA
12187     *  r9 holds BBBB
12188     */
12189.LOP_INSTANCE_OF_JUMBO_resolved:
12190    cmp     r0, r1                      @ same class (trivial success)?
12191    beq     .LOP_INSTANCE_OF_JUMBO_trivial         @ yes, trivial finish
12192    @ fall through to OP_INSTANCE_OF_JUMBO_fullcheck
12193
12194    /*
12195     * Trivial test failed, need to perform full check.  This is common.
12196     *  r0 holds obj->clazz
12197     *  r1 holds class resolved from AAAAAAAA
12198     *  r9 holds BBBB
12199     */
12200.LOP_INSTANCE_OF_JUMBO_fullcheck:
12201    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
12202    @ fall through to OP_INSTANCE_OF_JUMBO_store
12203
12204    /*
12205     * r0 holds boolean result
12206     * r9 holds BBBB
12207     */
12208.LOP_INSTANCE_OF_JUMBO_store:
12209    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12210    SET_VREG(r0, r9)                    @ vBBBB<- r0
12211    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12212    GOTO_OPCODE(ip)                     @ jump to next instruction
12213
12214    /*
12215     * Trivial test succeeded, save and bail.
12216     *  r9 holds BBBB
12217     */
12218.LOP_INSTANCE_OF_JUMBO_trivial:
12219    mov     r0, #1                      @ indicate success
12220    @ could b OP_INSTANCE_OF_JUMBO_store, but copying is faster and cheaper
12221    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12222    SET_VREG(r0, r9)                    @ vBBBB<- r0
12223    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12224    GOTO_OPCODE(ip)                     @ jump to next instruction
12225
12226    /*
12227     * Resolution required.  This is the least-likely path.
12228     *
12229     *  r3 holds AAAAAAAA
12230     *  r9 holds BBBB
12231     */
12232
12233.LOP_INSTANCE_OF_JUMBO_resolve:
12234    EXPORT_PC()                         @ resolve() could throw
12235    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
12236    mov     r1, r3                      @ r1<- AAAAAAAA
12237    mov     r2, #1                      @ r2<- true
12238    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
12239    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12240    cmp     r0, #0                      @ got null?
12241    beq     common_exceptionThrown      @ yes, handle exception
12242    FETCH(r3, 4)                        @ r3<- vCCCC
12243    mov     r1, r0                      @ r1<- class resolved from AAAAAAAA
12244    GET_VREG(r0, r3)                    @ r0<- vCCCC (object)
12245    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
12246    b       .LOP_INSTANCE_OF_JUMBO_resolved        @ pick up where we left off
12247
12248/* continuation for OP_NEW_INSTANCE_JUMBO */
12249
12250    .balign 32                          @ minimize cache lines
12251.LOP_NEW_INSTANCE_JUMBO_finish: @ r0=new object
12252    FETCH(r3, 3)                        @ r3<- BBBB
12253    cmp     r0, #0                      @ failed?
12254    beq     common_exceptionThrown      @ yes, handle the exception
12255    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12256    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12257    SET_VREG(r0, r3)                    @ vBBBB<- r0
12258    GOTO_OPCODE(ip)                     @ jump to next instruction
12259
12260    /*
12261     * Class initialization required.
12262     *
12263     *  r0 holds class object
12264     */
12265.LOP_NEW_INSTANCE_JUMBO_needinit:
12266    mov     r9, r0                      @ save r0
12267    bl      dvmInitClass                @ initialize class
12268    cmp     r0, #0                      @ check boolean result
12269    mov     r0, r9                      @ restore r0
12270    bne     .LOP_NEW_INSTANCE_JUMBO_initialized     @ success, continue
12271    b       common_exceptionThrown      @ failed, deal with init exception
12272
12273    /*
12274     * Resolution required.  This is the least-likely path.
12275     *
12276     *  r1 holds AAAAAAAA
12277     */
12278.LOP_NEW_INSTANCE_JUMBO_resolve:
12279    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
12280    mov     r2, #0                      @ r2<- false
12281    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12282    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12283    cmp     r0, #0                      @ got null?
12284    bne     .LOP_NEW_INSTANCE_JUMBO_resolved        @ no, continue
12285    b       common_exceptionThrown      @ yes, handle exception
12286
12287/* continuation for OP_NEW_ARRAY_JUMBO */
12288
12289
12290    /*
12291     * Resolve class.  (This is an uncommon case.)
12292     *
12293     *  r1 holds array length
12294     *  r2 holds class ref AAAAAAAA
12295     */
12296.LOP_NEW_ARRAY_JUMBO_resolve:
12297    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
12298    mov     r9, r1                      @ r9<- length (save)
12299    mov     r1, r2                      @ r1<- AAAAAAAA
12300    mov     r2, #0                      @ r2<- false
12301    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12302    bl      dvmResolveClass             @ r0<- call(clazz, ref)
12303    cmp     r0, #0                      @ got null?
12304    mov     r1, r9                      @ r1<- length (restore)
12305    beq     common_exceptionThrown      @ yes, handle exception
12306    @ fall through to OP_NEW_ARRAY_JUMBO_finish
12307
12308    /*
12309     * Finish allocation.
12310     *
12311     *  r0 holds class
12312     *  r1 holds array length
12313     */
12314.LOP_NEW_ARRAY_JUMBO_finish:
12315    mov     r2, #ALLOC_DONT_TRACK       @ don't track in local refs table
12316    bl      dvmAllocArrayByClass        @ r0<- call(clazz, length, flags)
12317    cmp     r0, #0                      @ failed?
12318    FETCH(r2, 3)                        @ r2<- vBBBB
12319    beq     common_exceptionThrown      @ yes, handle the exception
12320    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12321    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12322    SET_VREG(r0, r2)                    @ vBBBB<- r0
12323    GOTO_OPCODE(ip)                     @ jump to next instruction
12324
12325/* continuation for OP_FILLED_NEW_ARRAY_JUMBO */
12326
12327    /*
12328     * On entry:
12329     *  r0 holds array class
12330     */
12331.LOP_FILLED_NEW_ARRAY_JUMBO_continue:
12332    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
12333    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
12334    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
12335    FETCH(r1, 3)                        @ r1<- BBBB (length)
12336    cmp     rINST, #'I'                 @ array of ints?
12337    cmpne   rINST, #'L'                 @ array of objects?
12338    cmpne   rINST, #'['                 @ array of arrays?
12339    mov     r9, r1                      @ save length in r9
12340    bne     .LOP_FILLED_NEW_ARRAY_JUMBO_notimpl         @ no, not handled yet
12341    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
12342    cmp     r0, #0                      @ null return?
12343    beq     common_exceptionThrown      @ alloc failed, handle exception
12344
12345    FETCH(r1, 4)                        @ r1<- CCCC
12346    str     r0, [rGLUE, #offGlue_retval]      @ retval.l <- new array
12347    str     rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type
12348    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
12349    subs    r9, r9, #1                  @ length--, check for neg
12350    FETCH_ADVANCE_INST(5)               @ advance to next instr, load rINST
12351    bmi     2f                          @ was zero, bail
12352
12353    @ copy values from registers into the array
12354    @ r0=array, r1=CCCC, r9=BBBB (length)
12355    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
123561:  ldr     r3, [r2], #4                @ r3<- *r2++
12357    subs    r9, r9, #1                  @ count--
12358    str     r3, [r0], #4                @ *contents++ = vX
12359    bpl     1b
12360
123612:  ldr     r0, [rGLUE, #offGlue_retval]     @ r0<- object
12362    ldr     r1, [rGLUE, #offGlue_retval+4]   @ r1<- type
12363    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
12364    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
12365    cmp     r1, #'I'                         @ Is int array?
12366    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
12367    GOTO_OPCODE(ip)                          @ execute it
12368
12369    /*
12370     * Throw an exception indicating that we have not implemented this
12371     * mode of filled-new-array.
12372     */
12373.LOP_FILLED_NEW_ARRAY_JUMBO_notimpl:
12374    ldr     r0, .L_strInternalError
12375    ldr     r1, .L_strFilledNewArrayNotImpl
12376    bl      dvmThrowException
12377    b       common_exceptionThrown
12378
12379/* continuation for OP_IGET_JUMBO */
12380
12381    /*
12382     * Currently:
12383     *  r0 holds resolved field
12384     *  r9 holds object
12385     */
12386.LOP_IGET_JUMBO_resolved:
12387    cmp     r0, #0                      @ resolution unsuccessful?
12388    beq     common_exceptionThrown      @ yes, throw exception
12389    @ fall through to OP_IGET_JUMBO_finish
12390
12391    /*
12392     * Currently:
12393     *  r0 holds resolved field
12394     *  r9 holds object
12395     */
12396.LOP_IGET_JUMBO_finish:
12397    @bl      common_squeak0
12398    cmp     r9, #0                      @ check object for null
12399    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12400    beq     common_errNullObject        @ object was null
12401    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12402    @ no-op                             @ acquiring load
12403    FETCH(r2, 3)                        @ r2<- BBBB
12404    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12405    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12406    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12407    GOTO_OPCODE(ip)                     @ jump to next instruction
12408
12409/* continuation for OP_IGET_WIDE_JUMBO */
12410
12411    /*
12412     * Currently:
12413     *  r0 holds resolved field
12414     *  r9 holds object
12415     */
12416.LOP_IGET_WIDE_JUMBO_resolved:
12417    cmp     r0, #0                      @ resolution unsuccessful?
12418    beq     common_exceptionThrown      @ yes, throw exception
12419    @ fall through to OP_IGET_WIDE_JUMBO_finish
12420
12421    /*
12422     * Currently:
12423     *  r0 holds resolved field
12424     *  r9 holds object
12425     */
12426.LOP_IGET_WIDE_JUMBO_finish:
12427    cmp     r9, #0                      @ check object for null
12428    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12429    beq     common_errNullObject        @ object was null
12430    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
12431    FETCH(r2, 3)                        @ r2<- BBBB
12432    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12433    add     r3, rFP, r2, lsl #2         @ r3<- &fp[BBBB]
12434    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12435    stmia   r3, {r0-r1}                 @ fp[BBBB]<- r0/r1
12436    GOTO_OPCODE(ip)                     @ jump to next instruction
12437
12438/* continuation for OP_IGET_OBJECT_JUMBO */
12439
12440    /*
12441     * Currently:
12442     *  r0 holds resolved field
12443     *  r9 holds object
12444     */
12445.LOP_IGET_OBJECT_JUMBO_resolved:
12446    cmp     r0, #0                      @ resolution unsuccessful?
12447    beq     common_exceptionThrown      @ yes, throw exception
12448    @ fall through to OP_IGET_OBJECT_JUMBO_finish
12449
12450    /*
12451     * Currently:
12452     *  r0 holds resolved field
12453     *  r9 holds object
12454     */
12455.LOP_IGET_OBJECT_JUMBO_finish:
12456    @bl      common_squeak0
12457    cmp     r9, #0                      @ check object for null
12458    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12459    beq     common_errNullObject        @ object was null
12460    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12461    @ no-op                             @ acquiring load
12462    FETCH(r2, 3)                        @ r2<- BBBB
12463    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12464    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12465    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12466    GOTO_OPCODE(ip)                     @ jump to next instruction
12467
12468/* continuation for OP_IGET_BOOLEAN_JUMBO */
12469
12470    /*
12471     * Currently:
12472     *  r0 holds resolved field
12473     *  r9 holds object
12474     */
12475.LOP_IGET_BOOLEAN_JUMBO_resolved:
12476    cmp     r0, #0                      @ resolution unsuccessful?
12477    beq     common_exceptionThrown      @ yes, throw exception
12478    @ fall through to OP_IGET_BOOLEAN_JUMBO_finish
12479
12480    /*
12481     * Currently:
12482     *  r0 holds resolved field
12483     *  r9 holds object
12484     */
12485.LOP_IGET_BOOLEAN_JUMBO_finish:
12486    @bl      common_squeak1
12487    cmp     r9, #0                      @ check object for null
12488    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12489    beq     common_errNullObject        @ object was null
12490    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12491    @ no-op                             @ acquiring load
12492    FETCH(r2, 3)                        @ r2<- BBBB
12493    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12494    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12495    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12496    GOTO_OPCODE(ip)                     @ jump to next instruction
12497
12498/* continuation for OP_IGET_BYTE_JUMBO */
12499
12500    /*
12501     * Currently:
12502     *  r0 holds resolved field
12503     *  r9 holds object
12504     */
12505.LOP_IGET_BYTE_JUMBO_resolved:
12506    cmp     r0, #0                      @ resolution unsuccessful?
12507    beq     common_exceptionThrown      @ yes, throw exception
12508    @ fall through to OP_IGET_BYTE_JUMBO_finish
12509
12510    /*
12511     * Currently:
12512     *  r0 holds resolved field
12513     *  r9 holds object
12514     */
12515.LOP_IGET_BYTE_JUMBO_finish:
12516    @bl      common_squeak2
12517    cmp     r9, #0                      @ check object for null
12518    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12519    beq     common_errNullObject        @ object was null
12520    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12521    @ no-op                             @ acquiring load
12522    FETCH(r2, 3)                        @ r2<- BBBB
12523    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12524    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12525    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12526    GOTO_OPCODE(ip)                     @ jump to next instruction
12527
12528/* continuation for OP_IGET_CHAR_JUMBO */
12529
12530    /*
12531     * Currently:
12532     *  r0 holds resolved field
12533     *  r9 holds object
12534     */
12535.LOP_IGET_CHAR_JUMBO_resolved:
12536    cmp     r0, #0                      @ resolution unsuccessful?
12537    beq     common_exceptionThrown      @ yes, throw exception
12538    @ fall through to OP_IGET_CHAR_JUMBO_finish
12539
12540    /*
12541     * Currently:
12542     *  r0 holds resolved field
12543     *  r9 holds object
12544     */
12545.LOP_IGET_CHAR_JUMBO_finish:
12546    @bl      common_squeak3
12547    cmp     r9, #0                      @ check object for null
12548    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12549    beq     common_errNullObject        @ object was null
12550    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12551    @ no-op                             @ acquiring load
12552    FETCH(r2, 3)                        @ r2<- BBBB
12553    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12554    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12555    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12556    GOTO_OPCODE(ip)                     @ jump to next instruction
12557
12558/* continuation for OP_IGET_SHORT_JUMBO */
12559
12560    /*
12561     * Currently:
12562     *  r0 holds resolved field
12563     *  r9 holds object
12564     */
12565.LOP_IGET_SHORT_JUMBO_resolved:
12566    cmp     r0, #0                      @ resolution unsuccessful?
12567    beq     common_exceptionThrown      @ yes, throw exception
12568    @ fall through to OP_IGET_SHORT_JUMBO_finish
12569
12570    /*
12571     * Currently:
12572     *  r0 holds resolved field
12573     *  r9 holds object
12574     */
12575.LOP_IGET_SHORT_JUMBO_finish:
12576    @bl      common_squeak4
12577    cmp     r9, #0                      @ check object for null
12578    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12579    beq     common_errNullObject        @ object was null
12580    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12581    @ no-op                             @ acquiring load
12582    FETCH(r2, 3)                        @ r2<- BBBB
12583    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12584    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12585    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12586    GOTO_OPCODE(ip)                     @ jump to next instruction
12587
12588/* continuation for OP_IPUT_JUMBO */
12589
12590    /*
12591     * Currently:
12592     *  r0 holds resolved field
12593     *  r9 holds object
12594     */
12595.LOP_IPUT_JUMBO_resolved:
12596     cmp     r0, #0                     @ resolution unsuccessful?
12597     beq     common_exceptionThrown     @ yes, throw exception
12598     @ fall through to OP_IPUT_JUMBO_finish
12599
12600    /*
12601     * Currently:
12602     *  r0 holds resolved field
12603     *  r9 holds object
12604     */
12605.LOP_IPUT_JUMBO_finish:
12606    @bl      common_squeak0
12607    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12608    FETCH(r1, 3)                        @ r1<- BBBB
12609    cmp     r9, #0                      @ check object for null
12610    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12611    beq     common_errNullObject        @ object was null
12612    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12613    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12614    @ no-op                             @ releasing store
12615    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12616    GOTO_OPCODE(ip)                     @ jump to next instruction
12617
12618/* continuation for OP_IPUT_WIDE_JUMBO */
12619
12620    /*
12621     * Currently:
12622     *  r0 holds resolved field
12623     *  r9 holds object
12624     */
12625.LOP_IPUT_WIDE_JUMBO_resolved:
12626     cmp     r0, #0                     @ resolution unsuccessful?
12627     beq     common_exceptionThrown     @ yes, throw exception
12628     @ fall through to OP_IPUT_WIDE_JUMBO_finish
12629
12630    /*
12631     * Currently:
12632     *  r0 holds resolved field
12633     *  r9 holds object
12634     */
12635.LOP_IPUT_WIDE_JUMBO_finish:
12636    cmp     r9, #0                      @ check object for null
12637    FETCH(r2, 3)                        @ r1<- BBBB
12638    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12639    add     r2, rFP, r2, lsl #2         @ r3<- &fp[BBBB]
12640    beq     common_errNullObject        @ object was null
12641    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12642    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[BBBB]
12643    GET_INST_OPCODE(r10)                @ extract opcode from rINST
12644    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
12645    GOTO_OPCODE(r10)                    @ jump to next instruction
12646
12647/* continuation for OP_IPUT_OBJECT_JUMBO */
12648
12649    /*
12650     * Currently:
12651     *  r0 holds resolved field
12652     *  r9 holds object
12653     */
12654.LOP_IPUT_OBJECT_JUMBO_resolved:
12655     cmp     r0, #0                     @ resolution unsuccessful?
12656     beq     common_exceptionThrown     @ yes, throw exception
12657     @ fall through to OP_IPUT_OBJECT_JUMBO_finish
12658
12659    /*
12660     * Currently:
12661     *  r0 holds resolved field
12662     *  r9 holds object
12663     */
12664.LOP_IPUT_OBJECT_JUMBO_finish:
12665    @bl      common_squeak0
12666    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12667    FETCH(r1, 3)                        @ r1<- BBBB
12668    cmp     r9, #0                      @ check object for null
12669    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12670    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
12671    beq     common_errNullObject        @ object was null
12672    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12673    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12674    @ no-op                             @ releasing store
12675    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
12676    cmp     r0, #0                      @ stored a null reference?
12677    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
12678    GOTO_OPCODE(ip)                     @ jump to next instruction
12679
12680/* continuation for OP_IPUT_BOOLEAN_JUMBO */
12681
12682    /*
12683     * Currently:
12684     *  r0 holds resolved field
12685     *  r9 holds object
12686     */
12687.LOP_IPUT_BOOLEAN_JUMBO_resolved:
12688     cmp     r0, #0                     @ resolution unsuccessful?
12689     beq     common_exceptionThrown     @ yes, throw exception
12690     @ fall through to OP_IPUT_BOOLEAN_JUMBO_finish
12691
12692    /*
12693     * Currently:
12694     *  r0 holds resolved field
12695     *  r9 holds object
12696     */
12697.LOP_IPUT_BOOLEAN_JUMBO_finish:
12698    @bl      common_squeak1
12699    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12700    FETCH(r1, 3)                        @ r1<- BBBB
12701    cmp     r9, #0                      @ check object for null
12702    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12703    beq     common_errNullObject        @ object was null
12704    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12705    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12706    @ no-op                             @ releasing store
12707    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12708    GOTO_OPCODE(ip)                     @ jump to next instruction
12709
12710/* continuation for OP_IPUT_BYTE_JUMBO */
12711
12712    /*
12713     * Currently:
12714     *  r0 holds resolved field
12715     *  r9 holds object
12716     */
12717.LOP_IPUT_BYTE_JUMBO_resolved:
12718     cmp     r0, #0                     @ resolution unsuccessful?
12719     beq     common_exceptionThrown     @ yes, throw exception
12720     @ fall through to OP_IPUT_BYTE_JUMBO_finish
12721
12722    /*
12723     * Currently:
12724     *  r0 holds resolved field
12725     *  r9 holds object
12726     */
12727.LOP_IPUT_BYTE_JUMBO_finish:
12728    @bl      common_squeak2
12729    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12730    FETCH(r1, 3)                        @ r1<- BBBB
12731    cmp     r9, #0                      @ check object for null
12732    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12733    beq     common_errNullObject        @ object was null
12734    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12735    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12736    @ no-op                             @ releasing store
12737    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12738    GOTO_OPCODE(ip)                     @ jump to next instruction
12739
12740/* continuation for OP_IPUT_CHAR_JUMBO */
12741
12742    /*
12743     * Currently:
12744     *  r0 holds resolved field
12745     *  r9 holds object
12746     */
12747.LOP_IPUT_CHAR_JUMBO_resolved:
12748     cmp     r0, #0                     @ resolution unsuccessful?
12749     beq     common_exceptionThrown     @ yes, throw exception
12750     @ fall through to OP_IPUT_CHAR_JUMBO_finish
12751
12752    /*
12753     * Currently:
12754     *  r0 holds resolved field
12755     *  r9 holds object
12756     */
12757.LOP_IPUT_CHAR_JUMBO_finish:
12758    @bl      common_squeak3
12759    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12760    FETCH(r1, 3)                        @ r1<- BBBB
12761    cmp     r9, #0                      @ check object for null
12762    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12763    beq     common_errNullObject        @ object was null
12764    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12765    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12766    @ no-op                             @ releasing store
12767    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12768    GOTO_OPCODE(ip)                     @ jump to next instruction
12769
12770/* continuation for OP_IPUT_SHORT_JUMBO */
12771
12772    /*
12773     * Currently:
12774     *  r0 holds resolved field
12775     *  r9 holds object
12776     */
12777.LOP_IPUT_SHORT_JUMBO_resolved:
12778     cmp     r0, #0                     @ resolution unsuccessful?
12779     beq     common_exceptionThrown     @ yes, throw exception
12780     @ fall through to OP_IPUT_SHORT_JUMBO_finish
12781
12782    /*
12783     * Currently:
12784     *  r0 holds resolved field
12785     *  r9 holds object
12786     */
12787.LOP_IPUT_SHORT_JUMBO_finish:
12788    @bl      common_squeak4
12789    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12790    FETCH(r1, 3)                        @ r1<- BBBB
12791    cmp     r9, #0                      @ check object for null
12792    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12793    beq     common_errNullObject        @ object was null
12794    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12795    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12796    @ no-op                             @ releasing store
12797    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12798    GOTO_OPCODE(ip)                     @ jump to next instruction
12799
12800/* continuation for OP_SGET_JUMBO */
12801
12802    /*
12803     * Continuation if the field has not yet been resolved.
12804     *  r1: AAAAAAAA field ref
12805     */
12806.LOP_SGET_JUMBO_resolve:
12807    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12808    EXPORT_PC()                         @ resolve() could throw, so export now
12809    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12810    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12811    cmp     r0, #0                      @ success?
12812    bne     .LOP_SGET_JUMBO_finish          @ yes, finish
12813    b       common_exceptionThrown      @ no, handle exception
12814
12815/* continuation for OP_SGET_WIDE_JUMBO */
12816
12817    /*
12818     * Continuation if the field has not yet been resolved.
12819     *  r1: BBBB field ref
12820     *
12821     * Returns StaticField pointer in r0.
12822     */
12823.LOP_SGET_WIDE_JUMBO_resolve:
12824    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12825    EXPORT_PC()                         @ resolve() could throw, so export now
12826    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12827    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12828    cmp     r0, #0                      @ success?
12829    bne     .LOP_SGET_WIDE_JUMBO_finish          @ yes, finish
12830    b       common_exceptionThrown      @ no, handle exception
12831
12832/* continuation for OP_SGET_OBJECT_JUMBO */
12833
12834    /*
12835     * Continuation if the field has not yet been resolved.
12836     *  r1: AAAAAAAA field ref
12837     */
12838.LOP_SGET_OBJECT_JUMBO_resolve:
12839    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12840    EXPORT_PC()                         @ resolve() could throw, so export now
12841    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12842    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12843    cmp     r0, #0                      @ success?
12844    bne     .LOP_SGET_OBJECT_JUMBO_finish          @ yes, finish
12845    b       common_exceptionThrown      @ no, handle exception
12846
12847/* continuation for OP_SGET_BOOLEAN_JUMBO */
12848
12849    /*
12850     * Continuation if the field has not yet been resolved.
12851     *  r1: AAAAAAAA field ref
12852     */
12853.LOP_SGET_BOOLEAN_JUMBO_resolve:
12854    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12855    EXPORT_PC()                         @ resolve() could throw, so export now
12856    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12857    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12858    cmp     r0, #0                      @ success?
12859    bne     .LOP_SGET_BOOLEAN_JUMBO_finish          @ yes, finish
12860    b       common_exceptionThrown      @ no, handle exception
12861
12862/* continuation for OP_SGET_BYTE_JUMBO */
12863
12864    /*
12865     * Continuation if the field has not yet been resolved.
12866     *  r1: AAAAAAAA field ref
12867     */
12868.LOP_SGET_BYTE_JUMBO_resolve:
12869    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12870    EXPORT_PC()                         @ resolve() could throw, so export now
12871    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12872    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12873    cmp     r0, #0                      @ success?
12874    bne     .LOP_SGET_BYTE_JUMBO_finish          @ yes, finish
12875    b       common_exceptionThrown      @ no, handle exception
12876
12877/* continuation for OP_SGET_CHAR_JUMBO */
12878
12879    /*
12880     * Continuation if the field has not yet been resolved.
12881     *  r1: AAAAAAAA field ref
12882     */
12883.LOP_SGET_CHAR_JUMBO_resolve:
12884    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12885    EXPORT_PC()                         @ resolve() could throw, so export now
12886    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12887    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12888    cmp     r0, #0                      @ success?
12889    bne     .LOP_SGET_CHAR_JUMBO_finish          @ yes, finish
12890    b       common_exceptionThrown      @ no, handle exception
12891
12892/* continuation for OP_SGET_SHORT_JUMBO */
12893
12894    /*
12895     * Continuation if the field has not yet been resolved.
12896     *  r1: AAAAAAAA field ref
12897     */
12898.LOP_SGET_SHORT_JUMBO_resolve:
12899    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12900    EXPORT_PC()                         @ resolve() could throw, so export now
12901    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12902    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12903    cmp     r0, #0                      @ success?
12904    bne     .LOP_SGET_SHORT_JUMBO_finish          @ yes, finish
12905    b       common_exceptionThrown      @ no, handle exception
12906
12907/* continuation for OP_SPUT_JUMBO */
12908
12909    /*
12910     * Continuation if the field has not yet been resolved.
12911     *  r1: AAAAAAAA field ref
12912     */
12913.LOP_SPUT_JUMBO_resolve:
12914    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12915    EXPORT_PC()                         @ resolve() could throw, so export now
12916    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12917    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12918    cmp     r0, #0                      @ success?
12919    bne     .LOP_SPUT_JUMBO_finish          @ yes, finish
12920    b       common_exceptionThrown      @ no, handle exception
12921
12922/* continuation for OP_SPUT_WIDE_JUMBO */
12923
12924    /*
12925     * Continuation if the field has not yet been resolved.
12926     *  r1: BBBB field ref
12927     *  r9: &fp[AA]
12928     *
12929     * Returns StaticField pointer in r2.
12930     */
12931.LOP_SPUT_WIDE_JUMBO_resolve:
12932    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12933    EXPORT_PC()                         @ resolve() could throw, so export now
12934    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12935    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12936    cmp     r0, #0                      @ success?
12937    mov     r2, r0                      @ copy to r2
12938    bne     .LOP_SPUT_WIDE_JUMBO_finish          @ yes, finish
12939    b       common_exceptionThrown      @ no, handle exception
12940
12941/* continuation for OP_SPUT_OBJECT_JUMBO */
12942
12943.LOP_SPUT_OBJECT_JUMBO_finish:   @ field ptr in r0
12944    FETCH(r2, 3)                        @ r2<- BBBB
12945    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12946    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
12947    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
12948    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
12949    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12950    @ no-op                             @ releasing store
12951    str     r1, [r0, #offStaticField_value]  @ field<- vBBBB
12952    cmp     r1, #0                      @ stored a null object?
12953    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
12954    GOTO_OPCODE(ip)                     @ jump to next instruction
12955
12956/* continuation for OP_SPUT_BOOLEAN_JUMBO */
12957
12958    /*
12959     * Continuation if the field has not yet been resolved.
12960     *  r1: AAAAAAAA field ref
12961     */
12962.LOP_SPUT_BOOLEAN_JUMBO_resolve:
12963    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12964    EXPORT_PC()                         @ resolve() could throw, so export now
12965    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12966    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12967    cmp     r0, #0                      @ success?
12968    bne     .LOP_SPUT_BOOLEAN_JUMBO_finish          @ yes, finish
12969    b       common_exceptionThrown      @ no, handle exception
12970
12971/* continuation for OP_SPUT_BYTE_JUMBO */
12972
12973    /*
12974     * Continuation if the field has not yet been resolved.
12975     *  r1: AAAAAAAA field ref
12976     */
12977.LOP_SPUT_BYTE_JUMBO_resolve:
12978    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12979    EXPORT_PC()                         @ resolve() could throw, so export now
12980    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12981    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12982    cmp     r0, #0                      @ success?
12983    bne     .LOP_SPUT_BYTE_JUMBO_finish          @ yes, finish
12984    b       common_exceptionThrown      @ no, handle exception
12985
12986/* continuation for OP_SPUT_CHAR_JUMBO */
12987
12988    /*
12989     * Continuation if the field has not yet been resolved.
12990     *  r1: AAAAAAAA field ref
12991     */
12992.LOP_SPUT_CHAR_JUMBO_resolve:
12993    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12994    EXPORT_PC()                         @ resolve() could throw, so export now
12995    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12996    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12997    cmp     r0, #0                      @ success?
12998    bne     .LOP_SPUT_CHAR_JUMBO_finish          @ yes, finish
12999    b       common_exceptionThrown      @ no, handle exception
13000
13001/* continuation for OP_SPUT_SHORT_JUMBO */
13002
13003    /*
13004     * Continuation if the field has not yet been resolved.
13005     *  r1: AAAAAAAA field ref
13006     */
13007.LOP_SPUT_SHORT_JUMBO_resolve:
13008    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13009    EXPORT_PC()                         @ resolve() could throw, so export now
13010    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13011    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13012    cmp     r0, #0                      @ success?
13013    bne     .LOP_SPUT_SHORT_JUMBO_finish          @ yes, finish
13014    b       common_exceptionThrown      @ no, handle exception
13015
13016/* continuation for OP_INVOKE_VIRTUAL_JUMBO */
13017
13018    /*
13019     * At this point:
13020     *  r0 = resolved base method
13021     */
13022.LOP_INVOKE_VIRTUAL_JUMBO_continue:
13023    FETCH(r10, 4)                       @ r10<- CCCC
13024    GET_VREG(r1, r10)                   @ r1<- "this" ptr
13025    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
13026    cmp     r1, #0                      @ is "this" null?
13027    beq     common_errNullObject        @ null "this", throw exception
13028    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
13029    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
13030    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
13031    bl      common_invokeMethodJumbo    @ continue on
13032
13033/* continuation for OP_INVOKE_SUPER_JUMBO */
13034
13035    /*
13036     * At this point:
13037     *  r0 = resolved base method
13038     *  r9 = method->clazz
13039     */
13040.LOP_INVOKE_SUPER_JUMBO_continue:
13041    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
13042    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
13043    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
13044    EXPORT_PC()                         @ must export for invoke
13045    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
13046    bcs     .LOP_INVOKE_SUPER_JUMBO_nsm             @ method not present in superclass
13047    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
13048    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
13049    bl      common_invokeMethodJumbo    @ continue on
13050
13051.LOP_INVOKE_SUPER_JUMBO_resolve:
13052    mov     r0, r9                      @ r0<- method->clazz
13053    mov     r2, #METHOD_VIRTUAL         @ resolver method type
13054    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
13055    cmp     r0, #0                      @ got null?
13056    bne     .LOP_INVOKE_SUPER_JUMBO_continue        @ no, continue
13057    b       common_exceptionThrown      @ yes, handle exception
13058
13059    /*
13060     * Throw a NoSuchMethodError with the method name as the message.
13061     *  r0 = resolved base method
13062     */
13063.LOP_INVOKE_SUPER_JUMBO_nsm:
13064    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
13065    b       common_errNoSuchMethod
13066
13067/* continuation for OP_INVOKE_DIRECT_JUMBO */
13068
13069    /*
13070     * On entry:
13071     *  r1 = reference (CCCC)
13072     *  r10 = "this" register
13073     */
13074.LOP_INVOKE_DIRECT_JUMBO_resolve:
13075    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
13076    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
13077    mov     r2, #METHOD_DIRECT          @ resolver method type
13078    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
13079    cmp     r0, #0                      @ got null?
13080    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
13081    bne     .LOP_INVOKE_DIRECT_JUMBO_finish          @ no, continue
13082    b       common_exceptionThrown      @ yes, handle exception
13083
13084    .size   dvmAsmSisterStart, .-dvmAsmSisterStart
13085    .global dvmAsmSisterEnd
13086dvmAsmSisterEnd:
13087
13088/* File: armv5te/footer.S */
13089
13090/*
13091 * ===========================================================================
13092 *  Common subroutines and data
13093 * ===========================================================================
13094 */
13095
13096
13097
13098    .text
13099    .align  2
13100
13101#if defined(WITH_JIT)
13102#if defined(WITH_SELF_VERIFICATION)
13103    .global dvmJitToInterpPunt
13104dvmJitToInterpPunt:
13105    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13106    mov    r2,#kSVSPunt                 @ r2<- interpreter entry point
13107    mov    r3, #0
13108    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13109    b      jitSVShadowRunEnd            @ doesn't return
13110
13111    .global dvmJitToInterpSingleStep
13112dvmJitToInterpSingleStep:
13113    str    lr,[rGLUE,#offGlue_jitResumeNPC]
13114    str    r1,[rGLUE,#offGlue_jitResumeDPC]
13115    mov    r2,#kSVSSingleStep           @ r2<- interpreter entry point
13116    b      jitSVShadowRunEnd            @ doesn't return
13117
13118    .global dvmJitToInterpNoChainNoProfile
13119dvmJitToInterpNoChainNoProfile:
13120    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13121    mov    r0,rPC                       @ pass our target PC
13122    mov    r2,#kSVSNoProfile            @ r2<- interpreter entry point
13123    mov    r3, #0                       @ 0 means !inJitCodeCache
13124    str    r3, [r10, #offThread_inJitCodeCache] @ back to the interp land
13125    b      jitSVShadowRunEnd            @ doesn't return
13126
13127    .global dvmJitToInterpTraceSelectNoChain
13128dvmJitToInterpTraceSelectNoChain:
13129    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13130    mov    r0,rPC                       @ pass our target PC
13131    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
13132    mov    r3, #0                       @ 0 means !inJitCodeCache
13133    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13134    b      jitSVShadowRunEnd            @ doesn't return
13135
13136    .global dvmJitToInterpTraceSelect
13137dvmJitToInterpTraceSelect:
13138    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13139    ldr    r0,[lr, #-1]                 @ pass our target PC
13140    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
13141    mov    r3, #0                       @ 0 means !inJitCodeCache
13142    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13143    b      jitSVShadowRunEnd            @ doesn't return
13144
13145    .global dvmJitToInterpBackwardBranch
13146dvmJitToInterpBackwardBranch:
13147    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13148    ldr    r0,[lr, #-1]                 @ pass our target PC
13149    mov    r2,#kSVSBackwardBranch       @ r2<- interpreter entry point
13150    mov    r3, #0                       @ 0 means !inJitCodeCache
13151    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13152    b      jitSVShadowRunEnd            @ doesn't return
13153
13154    .global dvmJitToInterpNormal
13155dvmJitToInterpNormal:
13156    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13157    ldr    r0,[lr, #-1]                 @ pass our target PC
13158    mov    r2,#kSVSNormal               @ r2<- interpreter entry point
13159    mov    r3, #0                       @ 0 means !inJitCodeCache
13160    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13161    b      jitSVShadowRunEnd            @ doesn't return
13162
13163    .global dvmJitToInterpNoChain
13164dvmJitToInterpNoChain:
13165    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13166    mov    r0,rPC                       @ pass our target PC
13167    mov    r2,#kSVSNoChain              @ r2<- interpreter entry point
13168    mov    r3, #0                       @ 0 means !inJitCodeCache
13169    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13170    b      jitSVShadowRunEnd            @ doesn't return
13171#else
13172/*
13173 * Return from the translation cache to the interpreter when the compiler is
13174 * having issues translating/executing a Dalvik instruction. We have to skip
13175 * the code cache lookup otherwise it is possible to indefinitely bouce
13176 * between the interpreter and the code cache if the instruction that fails
13177 * to be compiled happens to be at a trace start.
13178 */
13179    .global dvmJitToInterpPunt
13180dvmJitToInterpPunt:
13181    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13182    mov    rPC, r0
13183#if defined(WITH_JIT_TUNING)
13184    mov    r0,lr
13185    bl     dvmBumpPunt;
13186#endif
13187    EXPORT_PC()
13188    mov    r0, #0
13189    str    r0, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13190    adrl   rIBASE, dvmAsmInstructionStart
13191    FETCH_INST()
13192    GET_INST_OPCODE(ip)
13193    GOTO_OPCODE(ip)
13194
13195/*
13196 * Return to the interpreter to handle a single instruction.
13197 * On entry:
13198 *    r0 <= PC
13199 *    r1 <= PC of resume instruction
13200 *    lr <= resume point in translation
13201 */
13202    .global dvmJitToInterpSingleStep
13203dvmJitToInterpSingleStep:
13204    str    lr,[rGLUE,#offGlue_jitResumeNPC]
13205    str    r1,[rGLUE,#offGlue_jitResumeDPC]
13206    mov    r1,#kInterpEntryInstr
13207    @ enum is 4 byte in aapcs-EABI
13208    str    r1, [rGLUE, #offGlue_entryPoint]
13209    mov    rPC,r0
13210    EXPORT_PC()
13211
13212    adrl   rIBASE, dvmAsmInstructionStart
13213    mov    r2,#kJitSingleStep     @ Ask for single step and then revert
13214    str    r2,[rGLUE,#offGlue_jitState]
13215    mov    r1,#1                  @ set changeInterp to bail to debug interp
13216    b      common_gotoBail
13217
13218/*
13219 * Return from the translation cache and immediately request
13220 * a translation for the exit target.  Commonly used for callees.
13221 */
13222    .global dvmJitToInterpTraceSelectNoChain
13223dvmJitToInterpTraceSelectNoChain:
13224#if defined(WITH_JIT_TUNING)
13225    bl     dvmBumpNoChain
13226#endif
13227    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13228    mov    r0,rPC
13229    bl     dvmJitGetTraceAddr       @ Is there a translation?
13230    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13231    mov    r1, rPC                  @ arg1 of translation may need this
13232    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13233    cmp    r0,#0                    @ !0 means translation exists
13234    bxne   r0                       @ continue native execution if so
13235    b      2f                       @ branch over to use the interpreter
13236
13237/*
13238 * Return from the translation cache and immediately request
13239 * a translation for the exit target.  Commonly used following
13240 * invokes.
13241 */
13242    .global dvmJitToInterpTraceSelect
13243dvmJitToInterpTraceSelect:
13244    ldr    rPC,[lr, #-1]           @ get our target PC
13245    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13246    add    rINST,lr,#-5            @ save start of chain branch
13247    add    rINST, #-4              @  .. which is 9 bytes back
13248    mov    r0,rPC
13249    bl     dvmJitGetTraceAddr      @ Is there a translation?
13250    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13251    cmp    r0,#0
13252    beq    2f
13253    mov    r1,rINST
13254    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
13255    mov    r1, rPC                  @ arg1 of translation may need this
13256    mov    lr, #0                   @ in case target is HANDLER_INTERPRET
13257    cmp    r0,#0                    @ successful chain?
13258    bxne   r0                       @ continue native execution
13259    b      toInterpreter            @ didn't chain - resume with interpreter
13260
13261/* No translation, so request one if profiling isn't disabled*/
132622:
13263    adrl   rIBASE, dvmAsmInstructionStart
13264    GET_JIT_PROF_TABLE(r0)
13265    FETCH_INST()
13266    cmp    r0, #0
13267    movne  r2,#kJitTSelectRequestHot   @ ask for trace selection
13268    bne    common_selectTrace
13269    GET_INST_OPCODE(ip)
13270    GOTO_OPCODE(ip)
13271
13272/*
13273 * Return from the translation cache to the interpreter.
13274 * The return was done with a BLX from thumb mode, and
13275 * the following 32-bit word contains the target rPC value.
13276 * Note that lr (r14) will have its low-order bit set to denote
13277 * its thumb-mode origin.
13278 *
13279 * We'll need to stash our lr origin away, recover the new
13280 * target and then check to see if there is a translation available
13281 * for our new target.  If so, we do a translation chain and
13282 * go back to native execution.  Otherwise, it's back to the
13283 * interpreter (after treating this entry as a potential
13284 * trace start).
13285 */
13286    .global dvmJitToInterpNormal
13287dvmJitToInterpNormal:
13288    ldr    rPC,[lr, #-1]           @ get our target PC
13289    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13290    add    rINST,lr,#-5            @ save start of chain branch
13291    add    rINST,#-4               @ .. which is 9 bytes back
13292#if defined(WITH_JIT_TUNING)
13293    bl     dvmBumpNormal
13294#endif
13295    mov    r0,rPC
13296    bl     dvmJitGetTraceAddr      @ Is there a translation?
13297    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13298    cmp    r0,#0
13299    beq    toInterpreter            @ go if not, otherwise do chain
13300    mov    r1,rINST
13301    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
13302    mov    r1, rPC                  @ arg1 of translation may need this
13303    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13304    cmp    r0,#0                    @ successful chain?
13305    bxne   r0                       @ continue native execution
13306    b      toInterpreter            @ didn't chain - resume with interpreter
13307
13308/*
13309 * Return from the translation cache to the interpreter to do method invocation.
13310 * Check if translation exists for the callee, but don't chain to it.
13311 */
13312    .global dvmJitToInterpNoChainNoProfile
13313dvmJitToInterpNoChainNoProfile:
13314#if defined(WITH_JIT_TUNING)
13315    bl     dvmBumpNoChain
13316#endif
13317    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13318    mov    r0,rPC
13319    bl     dvmJitGetTraceAddr       @ Is there a translation?
13320    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13321    mov    r1, rPC                  @ arg1 of translation may need this
13322    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13323    cmp    r0,#0
13324    bxne   r0                       @ continue native execution if so
13325    EXPORT_PC()
13326    adrl   rIBASE, dvmAsmInstructionStart
13327    FETCH_INST()
13328    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13329    GOTO_OPCODE(ip)                     @ jump to next instruction
13330
13331/*
13332 * Return from the translation cache to the interpreter to do method invocation.
13333 * Check if translation exists for the callee, but don't chain to it.
13334 */
13335    .global dvmJitToInterpNoChain
13336dvmJitToInterpNoChain:
13337#if defined(WITH_JIT_TUNING)
13338    bl     dvmBumpNoChain
13339#endif
13340    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13341    mov    r0,rPC
13342    bl     dvmJitGetTraceAddr       @ Is there a translation?
13343    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13344    mov    r1, rPC                  @ arg1 of translation may need this
13345    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13346    cmp    r0,#0
13347    bxne   r0                       @ continue native execution if so
13348#endif
13349
13350/*
13351 * No translation, restore interpreter regs and start interpreting.
13352 * rGLUE & rFP were preserved in the translated code, and rPC has
13353 * already been restored by the time we get here.  We'll need to set
13354 * up rIBASE & rINST, and load the address of the JitTable into r0.
13355 */
13356toInterpreter:
13357    EXPORT_PC()
13358    adrl   rIBASE, dvmAsmInstructionStart
13359    FETCH_INST()
13360    GET_JIT_PROF_TABLE(r0)
13361    @ NOTE: intended fallthrough
13362
13363/*
13364 * Common code to update potential trace start counter, and initiate
13365 * a trace-build if appropriate.  On entry, rPC should point to the
13366 * next instruction to execute, and rINST should be already loaded with
13367 * the next opcode word, and r0 holds a pointer to the jit profile
13368 * table (pJitProfTable).
13369 */
13370common_testUpdateProfile:
13371    cmp     r0,#0
13372    GET_INST_OPCODE(ip)
13373    GOTO_OPCODE_IFEQ(ip)       @ if not profiling, fallthrough otherwise */
13374
13375common_updateProfile:
13376    eor     r3,rPC,rPC,lsr #12 @ cheap, but fast hash function
13377    lsl     r3,r3,#(32 - JIT_PROF_SIZE_LOG_2)          @ shift out excess bits
13378    ldrb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter
13379    GET_INST_OPCODE(ip)
13380    subs    r1,r1,#1           @ decrement counter
13381    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it
13382    GOTO_OPCODE_IFNE(ip)       @ if not threshold, fallthrough otherwise */
13383
13384/*
13385 * Here, we switch to the debug interpreter to request
13386 * trace selection.  First, though, check to see if there
13387 * is already a native translation in place (and, if so,
13388 * jump to it now).
13389 */
13390    GET_JIT_THRESHOLD(r1)
13391    ldr     r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self
13392    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter
13393    EXPORT_PC()
13394    mov     r0,rPC
13395    bl      dvmJitGetTraceAddr          @ r0<- dvmJitGetTraceAddr(rPC)
13396    str     r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13397    mov     r1, rPC                     @ arg1 of translation may need this
13398    mov     lr, #0                      @  in case target is HANDLER_INTERPRET
13399    cmp     r0,#0
13400#if !defined(WITH_SELF_VERIFICATION)
13401    bxne    r0                          @ jump to the translation
13402    mov     r2,#kJitTSelectRequest      @ ask for trace selection
13403    @ fall-through to common_selectTrace
13404#else
13405    moveq   r2,#kJitTSelectRequest      @ ask for trace selection
13406    beq     common_selectTrace
13407    /*
13408     * At this point, we have a target translation.  However, if
13409     * that translation is actually the interpret-only pseudo-translation
13410     * we want to treat it the same as no translation.
13411     */
13412    mov     r10, r0                     @ save target
13413    bl      dvmCompilerGetInterpretTemplate
13414    cmp     r0, r10                     @ special case?
13415    bne     jitSVShadowRunStart         @ set up self verification shadow space
13416    @ Need to clear the inJitCodeCache flag
13417    ldr    r10, [rGLUE, #offGlue_self]  @ r10 <- glue->self
13418    mov    r3, #0                       @ 0 means not in the JIT code cache
13419    str    r3, [r10, #offThread_inJitCodeCache] @ back to the interp land
13420    GET_INST_OPCODE(ip)
13421    GOTO_OPCODE(ip)
13422    /* no return */
13423#endif
13424
13425/*
13426 * On entry:
13427 *  r2 is jit state, e.g. kJitTSelectRequest or kJitTSelectRequestHot
13428 */
13429common_selectTrace:
13430    str     r2,[rGLUE,#offGlue_jitState]
13431    mov     r2,#kInterpEntryInstr       @ normal entry reason
13432    str     r2,[rGLUE,#offGlue_entryPoint]
13433    mov     r1,#1                       @ set changeInterp
13434    b       common_gotoBail
13435
13436#if defined(WITH_SELF_VERIFICATION)
13437/*
13438 * Save PC and registers to shadow memory for self verification mode
13439 * before jumping to native translation.
13440 * On entry:
13441 *    rPC, rFP, rGLUE: the values that they should contain
13442 *    r10: the address of the target translation.
13443 */
13444jitSVShadowRunStart:
13445    mov     r0,rPC                      @ r0<- program counter
13446    mov     r1,rFP                      @ r1<- frame pointer
13447    mov     r2,rGLUE                    @ r2<- InterpState pointer
13448    mov     r3,r10                      @ r3<- target translation
13449    bl      dvmSelfVerificationSaveState @ save registers to shadow space
13450    ldr     rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space
13451    add     rGLUE,r0,#offShadowSpace_interpState @ rGLUE<- rGLUE in shadow space
13452    bx      r10                         @ jump to the translation
13453
13454/*
13455 * Restore PC, registers, and interpState to original values
13456 * before jumping back to the interpreter.
13457 */
13458jitSVShadowRunEnd:
13459    mov    r1,rFP                        @ pass ending fp
13460    bl     dvmSelfVerificationRestoreState @ restore pc and fp values
13461    ldr    rPC,[r0,#offShadowSpace_startPC] @ restore PC
13462    ldr    rFP,[r0,#offShadowSpace_fp]   @ restore FP
13463    ldr    rGLUE,[r0,#offShadowSpace_glue] @ restore InterpState
13464    ldr    r1,[r0,#offShadowSpace_svState] @ get self verification state
13465    cmp    r1,#0                         @ check for punt condition
13466    beq    1f
13467    mov    r2,#kJitSelfVerification      @ ask for self verification
13468    str    r2,[rGLUE,#offGlue_jitState]
13469    mov    r2,#kInterpEntryInstr         @ normal entry reason
13470    str    r2,[rGLUE,#offGlue_entryPoint]
13471    mov    r1,#1                         @ set changeInterp
13472    b      common_gotoBail
13473
134741:                                       @ exit to interpreter without check
13475    EXPORT_PC()
13476    adrl   rIBASE, dvmAsmInstructionStart
13477    FETCH_INST()
13478    GET_INST_OPCODE(ip)
13479    GOTO_OPCODE(ip)
13480#endif
13481
13482#endif
13483
13484/*
13485 * Common code when a backward branch is taken.
13486 *
13487 * TODO: we could avoid a branch by just setting r0 and falling through
13488 * into the common_periodicChecks code, and having a test on r0 at the
13489 * end determine if we should return to the caller or update & branch to
13490 * the next instr.
13491 *
13492 * On entry:
13493 *  r9 is PC adjustment *in bytes*
13494 */
13495common_backwardBranch:
13496    mov     r0, #kInterpEntryInstr
13497    bl      common_periodicChecks
13498#if defined(WITH_JIT)
13499    GET_JIT_PROF_TABLE(r0)
13500    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
13501    cmp     r0,#0
13502    bne     common_updateProfile
13503    GET_INST_OPCODE(ip)
13504    GOTO_OPCODE(ip)
13505#else
13506    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
13507    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13508    GOTO_OPCODE(ip)                     @ jump to next instruction
13509#endif
13510
13511
13512/*
13513 * Need to see if the thread needs to be suspended or debugger/profiler
13514 * activity has begun.  If so, we suspend the thread or side-exit to
13515 * the debug interpreter as appropriate.
13516 *
13517 * The common case is no activity on any of these, so we want to figure
13518 * that out quickly.  If something is up, we can then sort out what.
13519 *
13520 * We want to be fast if the VM was built without debugger or profiler
13521 * support, but we also need to recognize that the system is usually
13522 * shipped with both of these enabled.
13523 *
13524 * TODO: reduce this so we're just checking a single location.
13525 *
13526 * On entry:
13527 *  r0 is reentry type, e.g. kInterpEntryInstr (for debugger/profiling)
13528 *  r9 is trampoline PC adjustment *in bytes*
13529 */
13530common_periodicChecks:
13531    ldr     r1, [rGLUE, #offGlue_pInterpBreak] @ r3<- &interpBreak
13532    /* speculatively load address of thread-specific suspend count */
13533    ldr     r3, [rGLUE, #offGlue_pSelfSuspendCount] @ r3<- &suspendCount
13534    ldr     r1, [r1]                                @ r1<- interpBreak
13535    /* speculatively load thread-specific suspend count */
13536    ldr     ip, [r3]                    @ ip<- suspendCount (int)
13537    cmp     r1, #0                                  @ anything unusual?
13538    bxeq    lr                                      @ return if not
13539    /*
13540     * One or more interesting events have happened.  Figure out what.
13541     *
13542     * r0 still holds the reentry type.
13543     */
13544    cmp     ip, #0                      @ want suspend?
13545    beq     3f                          @ no, must be something else
13546
13547    stmfd   sp!, {r0, lr}               @ preserve r0 and lr
13548#if defined(WITH_JIT)
13549    /*
13550     * Refresh the Jit's cached copy of profile table pointer.  This pointer
13551     * doubles as the Jit's on/off switch.
13552     */
13553    ldr     r3, [rGLUE, #offGlue_ppJitProfTable] @ r3<-&gDvmJit.pJitProfTable
13554    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
13555    ldr     r3, [r3] @ r3 <- pJitProfTable
13556    EXPORT_PC()                         @ need for precise GC
13557    str     r3, [rGLUE, #offGlue_pJitProfTable] @ refresh Jit's on/off switch
13558#else
13559    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
13560    EXPORT_PC()                         @ need for precise GC
13561#endif
13562    bl      dvmCheckSuspendPending      @ do full check, suspend if necessary
13563    ldmfd   sp!, {r0, lr}               @ restore r0 and lr
13564
13565    /*
13566     * Reload the interpBreak flags - they may have changed while we
13567     * were suspended.
13568     */
13569    ldr     r1, [rGLUE, #offGlue_pInterpBreak]   @ r1<- &interpBreak
13570    ldr     r1, [r1]                    @ r1<- interpBreak
135713:
13572    /*
13573     * TODO: this code is too fragile.  Need a general mechanism
13574     * to identify what actions to take by submode.  Some profiling modes
13575     * (instruction count) need to single-step, while method tracing
13576     * may not.  Debugging with breakpoints can run unfettered, but
13577     * source-level single-stepping requires Dalvik singlestepping.
13578     * GC may require a one-shot action and then full-speed resumption.
13579     */
13580    ands    r1, #(kSubModeDebuggerActive | kSubModeEmulatorTrace | kSubModeInstCounting)
13581    bxeq    lr                          @ nothing to do, return
13582
13583    @ debugger/profiler enabled, bail out; glue->entryPoint was set above
13584    str     r0, [rGLUE, #offGlue_entryPoint]    @ store r0, need for debug/prof
13585    add     rPC, rPC, r9                @ update rPC
13586    mov     r1, #1                      @ "want switch" = true
13587    b       common_gotoBail             @ side exit
13588
13589
13590/*
13591 * The equivalent of "goto bail", this calls through the "bail handler".
13592 *
13593 * State registers will be saved to the "glue" area before bailing.
13594 *
13595 * On entry:
13596 *  r1 is "bool changeInterp", indicating if we want to switch to the
13597 *     other interpreter or just bail all the way out
13598 */
13599common_gotoBail:
13600    SAVE_PC_FP_TO_GLUE()                @ export state to "glue"
13601    mov     r0, rGLUE                   @ r0<- glue ptr
13602    b       dvmMterpStdBail             @ call(glue, changeInterp)
13603
13604    @add     r1, r1, #1                  @ using (boolean+1)
13605    @add     r0, rGLUE, #offGlue_jmpBuf  @ r0<- &glue->jmpBuf
13606    @bl      _longjmp                    @ does not return
13607    @bl      common_abort
13608
13609
13610/*
13611 * Common code for jumbo method invocation.
13612 * NOTE: this adjusts rPC to account for the difference in instruction width.
13613 * As a result, the savedPc in the stack frame will not be wholly accurate. So
13614 * long as that is only used for source file line number calculations, we're
13615 * okay.
13616 *
13617 * On entry:
13618 *  r0 is "Method* methodToCall", the method we're trying to call
13619 */
13620common_invokeMethodJumbo:
13621.LinvokeNewJumbo:
13622    @ prepare to copy args to "outs" area of current frame
13623    add     rPC, rPC, #4                @ adjust pc to make return consistent
13624    FETCH(r2, 1)                        @ r2<- BBBB (arg count)
13625    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
13626    cmp     r2, #0                      @ no args?
13627    beq     .LinvokeArgsDone            @ if no args, skip the rest
13628    FETCH(r1, 2)                        @ r1<- CCCC
13629    b       .LinvokeRangeArgs           @ handle args like invoke range
13630
13631/*
13632 * Common code for method invocation with range.
13633 *
13634 * On entry:
13635 *  r0 is "Method* methodToCall", the method we're trying to call
13636 */
13637common_invokeMethodRange:
13638.LinvokeNewRange:
13639    @ prepare to copy args to "outs" area of current frame
13640    movs    r2, rINST, lsr #8           @ r2<- AA (arg count) -- test for zero
13641    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
13642    beq     .LinvokeArgsDone            @ if no args, skip the rest
13643    FETCH(r1, 2)                        @ r1<- CCCC
13644
13645.LinvokeRangeArgs:
13646    @ r0=methodToCall, r1=CCCC, r2=count, r10=outs
13647    @ (very few methods have > 10 args; could unroll for common cases)
13648    add     r3, rFP, r1, lsl #2         @ r3<- &fp[CCCC]
13649    sub     r10, r10, r2, lsl #2        @ r10<- "outs" area, for call args
136501:  ldr     r1, [r3], #4                @ val = *fp++
13651    subs    r2, r2, #1                  @ count--
13652    str     r1, [r10], #4               @ *outs++ = val
13653    bne     1b                          @ ...while count != 0
13654    b       .LinvokeArgsDone
13655
13656/*
13657 * Common code for method invocation without range.
13658 *
13659 * On entry:
13660 *  r0 is "Method* methodToCall", the method we're trying to call
13661 */
13662common_invokeMethodNoRange:
13663.LinvokeNewNoRange:
13664    @ prepare to copy args to "outs" area of current frame
13665    movs    r2, rINST, lsr #12          @ r2<- B (arg count) -- test for zero
13666    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
13667    FETCH(r1, 2)                        @ r1<- GFED (load here to hide latency)
13668    beq     .LinvokeArgsDone
13669
13670    @ r0=methodToCall, r1=GFED, r2=count, r10=outs
13671.LinvokeNonRange:
13672    rsb     r2, r2, #5                  @ r2<- 5-r2
13673    add     pc, pc, r2, lsl #4          @ computed goto, 4 instrs each
13674    bl      common_abort                @ (skipped due to ARM prefetch)
136755:  and     ip, rINST, #0x0f00          @ isolate A
13676    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vA (shift right 8, left 2)
13677    mov     r0, r0                      @ nop
13678    str     r2, [r10, #-4]!             @ *--outs = vA
136794:  and     ip, r1, #0xf000             @ isolate G
13680    ldr     r2, [rFP, ip, lsr #10]      @ r2<- vG (shift right 12, left 2)
13681    mov     r0, r0                      @ nop
13682    str     r2, [r10, #-4]!             @ *--outs = vG
136833:  and     ip, r1, #0x0f00             @ isolate F
13684    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vF
13685    mov     r0, r0                      @ nop
13686    str     r2, [r10, #-4]!             @ *--outs = vF
136872:  and     ip, r1, #0x00f0             @ isolate E
13688    ldr     r2, [rFP, ip, lsr #2]       @ r2<- vE
13689    mov     r0, r0                      @ nop
13690    str     r2, [r10, #-4]!             @ *--outs = vE
136911:  and     ip, r1, #0x000f             @ isolate D
13692    ldr     r2, [rFP, ip, lsl #2]       @ r2<- vD
13693    mov     r0, r0                      @ nop
13694    str     r2, [r10, #-4]!             @ *--outs = vD
136950:  @ fall through to .LinvokeArgsDone
13696
13697.LinvokeArgsDone: @ r0=methodToCall
13698    ldrh    r9, [r0, #offMethod_registersSize]  @ r9<- methodToCall->regsSize
13699    ldrh    r3, [r0, #offMethod_outsSize]  @ r3<- methodToCall->outsSize
13700    ldr     r2, [r0, #offMethod_insns]  @ r2<- method->insns
13701    ldr     rINST, [r0, #offMethod_clazz]  @ rINST<- method->clazz
13702    @ find space for the new stack frame, check for overflow
13703    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- stack save area
13704    sub     r1, r1, r9, lsl #2          @ r1<- newFp (old savearea - regsSize)
13705    SAVEAREA_FROM_FP(r10, r1)           @ r10<- newSaveArea
13706@    bl      common_dumpRegs
13707    ldr     r9, [rGLUE, #offGlue_interpStackEnd]    @ r9<- interpStackEnd
13708    sub     r3, r10, r3, lsl #2         @ r3<- bottom (newsave - outsSize)
13709    cmp     r3, r9                      @ bottom < interpStackEnd?
13710    ldr     lr, [rGLUE, #offGlue_pInterpBreak]
13711    ldr     r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags
13712    blo     .LstackOverflow             @ yes, this frame will overflow stack
13713
13714    @ set up newSaveArea
13715    ldr     lr, [lr]                    @ lr<- active submodes
13716#ifdef EASY_GDB
13717    SAVEAREA_FROM_FP(ip, rFP)           @ ip<- stack save area
13718    str     ip, [r10, #offStackSaveArea_prevSave]
13719#endif
13720    str     rFP, [r10, #offStackSaveArea_prevFrame]
13721    str     rPC, [r10, #offStackSaveArea_savedPc]
13722#if defined(WITH_JIT)
13723    mov     r9, #0
13724    str     r9, [r10, #offStackSaveArea_returnAddr]
13725#endif
13726    ands    lr, #kSubModeMethodTrace    @ method tracing?
13727    beq     1f                          @ skip if not
13728    stmfd   sp!, {r0-r3}                @ preserve r0-r3
13729    mov     r1, r6
13730    @ r0=methodToCall, r1=rGlue
13731    bl      dvmFastMethodTraceEnter
13732    ldmfd   sp!, {r0-r3}                @ restore r0-r3
137331:
13734    str     r0, [r10, #offStackSaveArea_method]
13735    tst     r3, #ACC_NATIVE
13736    bne     .LinvokeNative
13737
13738    /*
13739    stmfd   sp!, {r0-r3}
13740    bl      common_printNewline
13741    mov     r0, rFP
13742    mov     r1, #0
13743    bl      dvmDumpFp
13744    ldmfd   sp!, {r0-r3}
13745    stmfd   sp!, {r0-r3}
13746    mov     r0, r1
13747    mov     r1, r10
13748    bl      dvmDumpFp
13749    bl      common_printNewline
13750    ldmfd   sp!, {r0-r3}
13751    */
13752
13753    ldrh    r9, [r2]                        @ r9 <- load INST from new PC
13754    ldr     r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
13755    mov     rPC, r2                         @ publish new rPC
13756    ldr     r2, [rGLUE, #offGlue_self]      @ r2<- glue->self
13757
13758    @ Update "glue" values for the new method
13759    @ r0=methodToCall, r1=newFp, r2=self, r3=newMethodClass, r9=newINST
13760    str     r0, [rGLUE, #offGlue_method]    @ glue->method = methodToCall
13761    str     r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ...
13762#if defined(WITH_JIT)
13763    GET_JIT_PROF_TABLE(r0)
13764    mov     rFP, r1                         @ fp = newFp
13765    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
13766    mov     rINST, r9                       @ publish new rINST
13767    str     r1, [r2, #offThread_curFrame]   @ self->curFrame = newFp
13768    cmp     r0,#0
13769    bne     common_updateProfile
13770    GOTO_OPCODE(ip)                         @ jump to next instruction
13771#else
13772    mov     rFP, r1                         @ fp = newFp
13773    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
13774    mov     rINST, r9                       @ publish new rINST
13775    str     r1, [r2, #offThread_curFrame]   @ self->curFrame = newFp
13776    GOTO_OPCODE(ip)                         @ jump to next instruction
13777#endif
13778
13779.LinvokeNative:
13780    @ Prep for the native call
13781    @ r0=methodToCall, r1=newFp, r10=newSaveArea
13782    ldr     r3, [rGLUE, #offGlue_self]      @ r3<- glue->self
13783    ldr     lr, [rGLUE, #offGlue_pInterpBreak]
13784    ldr     r9, [r3, #offThread_jniLocal_topCookie] @ r9<- thread->localRef->...
13785    str     r1, [r3, #offThread_curFrame]   @ self->curFrame = newFp
13786    str     r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top
13787    ldr     lr, [lr]                    @ lr<- active submodes
13788    mov     r9, r3                      @ r9<- glue->self (preserve)
13789
13790    mov     r2, r0                      @ r2<- methodToCall
13791    mov     r0, r1                      @ r0<- newFp (points to args)
13792    add     r1, rGLUE, #offGlue_retval  @ r1<- &retval
13793
13794#ifdef ASSIST_DEBUGGER
13795    /* insert fake function header to help gdb find the stack frame */
13796    b       .Lskip
13797    .type   dalvik_mterp, %function
13798dalvik_mterp:
13799    .fnstart
13800    MTERP_ENTRY1
13801    MTERP_ENTRY2
13802.Lskip:
13803#endif
13804
13805    ands    lr, #kSubModeMethodTrace    @ method tracing?
13806    beq     110f                        @ hop if not
13807    @ r2=JNIMethod, r6=rGLUE
13808    stmfd   sp!, {r2,r6}
13809
13810    mov     lr, pc                      @ set return addr
13811    ldr     pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
13812
13813    @ r0=JNIMethod, r1=rGLUE
13814    ldmfd   sp!, {r0-r1}
13815    bl      dvmFastNativeMethodTraceExit
13816    @ r2=JNIMethod, r6=rGLUE
13817    stmfd   sp!, {r2,r6}
13818    b       220f
13819110:
13820    mov     lr, pc                      @ set return addr
13821    ldr     pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
13822220:
13823#if defined(WITH_JIT)
13824    ldr     r3, [rGLUE, #offGlue_ppJitProfTable] @ Refresh Jit's on/off status
13825#endif
13826
13827    @ native return; r9=self, r10=newSaveArea
13828    @ equivalent to dvmPopJniLocals
13829    ldr     r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top
13830    ldr     r1, [r9, #offThread_exception] @ check for exception
13831#if defined(WITH_JIT)
13832    ldr     r3, [r3]                    @ r3 <- gDvmJit.pProfTable
13833#endif
13834    str     rFP, [r9, #offThread_curFrame]  @ self->curFrame = fp
13835    cmp     r1, #0                      @ null?
13836    str     r0, [r9, #offThread_jniLocal_topCookie] @ new top <- old top
13837#if defined(WITH_JIT)
13838    str     r3, [rGLUE, #offGlue_pJitProfTable] @ refresh cached on/off switch
13839#endif
13840    bne     common_exceptionThrown      @ no, handle exception
13841
13842    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
13843    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13844    GOTO_OPCODE(ip)                     @ jump to next instruction
13845
13846.LstackOverflow:    @ r0=methodToCall
13847    mov     r1, r0                      @ r1<- methodToCall
13848    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- self
13849    bl      dvmHandleStackOverflow
13850    b       common_exceptionThrown
13851#ifdef ASSIST_DEBUGGER
13852    .fnend
13853#endif
13854
13855
13856    /*
13857     * Common code for method invocation, calling through "glue code".
13858     *
13859     * TODO: now that we have range and non-range invoke handlers, this
13860     *       needs to be split into two.  Maybe just create entry points
13861     *       that set r9 and jump here?
13862     *
13863     * On entry:
13864     *  r0 is "Method* methodToCall", the method we're trying to call
13865     *  r9 is "bool methodCallRange", indicating if this is a /range variant
13866     */
13867     .if    0
13868.LinvokeOld:
13869    sub     sp, sp, #8                  @ space for args + pad
13870    FETCH(ip, 2)                        @ ip<- FEDC or CCCC
13871    mov     r2, r0                      @ A2<- methodToCall
13872    mov     r0, rGLUE                   @ A0<- glue
13873    SAVE_PC_FP_TO_GLUE()                @ export state to "glue"
13874    mov     r1, r9                      @ A1<- methodCallRange
13875    mov     r3, rINST, lsr #8           @ A3<- AA
13876    str     ip, [sp, #0]                @ A4<- ip
13877    bl      dvmMterp_invokeMethod       @ call the C invokeMethod
13878    add     sp, sp, #8                  @ remove arg area
13879    b       common_resumeAfterGlueCall  @ continue to next instruction
13880    .endif
13881
13882
13883
13884/*
13885 * Common code for handling a return instruction.
13886 *
13887 * This does not return.
13888 */
13889common_returnFromMethod:
13890.LreturnNew:
13891    mov     r0, #kInterpEntryReturn
13892    mov     r9, #0
13893    bl      common_periodicChecks
13894
13895    ldr     lr, [rGLUE, #offGlue_pInterpBreak]
13896    SAVEAREA_FROM_FP(r0, rFP)
13897    ldr     lr, [lr]                    @ lr<- active submodes
13898    ldr     r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc
13899    ands    lr, #kSubModeMethodTrace    @ method tracing?
13900    beq     333f
13901    stmfd   sp!, {r0-r3}                @ preserve r0-r3
13902    mov     r0, r6
13903    @ r0=rGlue
13904    bl      dvmFastJavaMethodTraceExit
13905    ldmfd   sp!, {r0-r3}                @ restore r0-r3
13906333:
13907    ldr     rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame
13908    ldr     r3, [rGLUE, #offGlue_self]  @ r3<- glue->self
13909    ldr     r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)]
13910                                        @ r2<- method we're returning to
13911    cmp     r2, #0                      @ is this a break frame?
13912#if defined(WORKAROUND_CORTEX_A9_745320)
13913    /* Don't use conditional loads if the HW defect exists */
13914    beq     101f
13915    ldr     r10, [r2, #offMethod_clazz] @ r10<- method->clazz
13916101:
13917#else
13918    ldrne   r10, [r2, #offMethod_clazz] @ r10<- method->clazz
13919#endif
13920    mov     r1, #0                      @ "want switch" = false
13921    beq     common_gotoBail             @ break frame, bail out completely
13922
13923    PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST
13924    str     r2, [rGLUE, #offGlue_method]@ glue->method = newSave->method
13925    ldr     r1, [r10, #offClassObject_pDvmDex]   @ r1<- method->clazz->pDvmDex
13926    str     rFP, [r3, #offThread_curFrame]  @ self->curFrame = fp
13927#if defined(WITH_JIT)
13928    ldr     r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr
13929    mov     rPC, r9                     @ publish new rPC
13930    str     r1, [rGLUE, #offGlue_methodClassDex]
13931    str     r10, [r3, #offThread_inJitCodeCache]  @ may return to JIT'ed land
13932    cmp     r10, #0                      @ caller is compiled code
13933    blxne   r10
13934    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13935    GOTO_OPCODE(ip)                     @ jump to next instruction
13936#else
13937    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13938    mov     rPC, r9                     @ publish new rPC
13939    str     r1, [rGLUE, #offGlue_methodClassDex]
13940    GOTO_OPCODE(ip)                     @ jump to next instruction
13941#endif
13942
13943    /*
13944     * Return handling, calls through "glue code".
13945     */
13946     .if    0
13947.LreturnOld:
13948    SAVE_PC_FP_TO_GLUE()                @ export state
13949    mov     r0, rGLUE                   @ arg to function
13950    bl      dvmMterp_returnFromMethod
13951    b       common_resumeAfterGlueCall
13952    .endif
13953
13954
13955/*
13956 * Somebody has thrown an exception.  Handle it.
13957 *
13958 * If the exception processing code returns to us (instead of falling
13959 * out of the interpreter), continue with whatever the next instruction
13960 * now happens to be.
13961 *
13962 * This does not return.
13963 */
13964     .global dvmMterpCommonExceptionThrown
13965dvmMterpCommonExceptionThrown:
13966common_exceptionThrown:
13967.LexceptionNew:
13968    mov     r0, #kInterpEntryThrow
13969    mov     r9, #0
13970    bl      common_periodicChecks
13971
13972    ldr     r10, [rGLUE, #offGlue_self] @ r10<- glue->self
13973    ldr     r9, [r10, #offThread_exception] @ r9<- self->exception
13974    mov     r1, r10                     @ r1<- self
13975    mov     r0, r9                      @ r0<- exception
13976    bl      dvmAddTrackedAlloc          @ don't let the exception be GCed
13977    mov     r3, #0                      @ r3<- NULL
13978    str     r3, [r10, #offThread_exception] @ self->exception = NULL
13979
13980    /* set up args and a local for "&fp" */
13981    /* (str sp, [sp, #-4]!  would be perfect here, but is discouraged) */
13982    str     rFP, [sp, #-4]!             @ *--sp = fp
13983    mov     ip, sp                      @ ip<- &fp
13984    mov     r3, #0                      @ r3<- false
13985    str     ip, [sp, #-4]!              @ *--sp = &fp
13986    ldr     r1, [rGLUE, #offGlue_method] @ r1<- glue->method
13987    mov     r0, r10                     @ r0<- self
13988    ldr     r1, [r1, #offMethod_insns]  @ r1<- method->insns
13989    mov     r2, r9                      @ r2<- exception
13990    sub     r1, rPC, r1                 @ r1<- pc - method->insns
13991    mov     r1, r1, asr #1              @ r1<- offset in code units
13992
13993    /* call, r0 gets catchRelPc (a code-unit offset) */
13994    bl      dvmFindCatchBlock           @ call(self, relPc, exc, scan?, &fp)
13995
13996    /* fix earlier stack overflow if necessary; may trash rFP */
13997    ldrb    r1, [r10, #offThread_stackOverflowed]
13998    cmp     r1, #0                      @ did we overflow earlier?
13999    beq     1f                          @ no, skip ahead
14000    mov     rFP, r0                     @ save relPc result in rFP
14001    mov     r0, r10                     @ r0<- self
14002    mov     r1, r9                      @ r1<- exception
14003    bl      dvmCleanupStackOverflow     @ call(self)
14004    mov     r0, rFP                     @ restore result
140051:
14006
14007    /* update frame pointer and check result from dvmFindCatchBlock */
14008    ldr     rFP, [sp, #4]               @ retrieve the updated rFP
14009    cmp     r0, #0                      @ is catchRelPc < 0?
14010    add     sp, sp, #8                  @ restore stack
14011    bmi     .LnotCaughtLocally
14012
14013    /* adjust locals to match self->curFrame and updated PC */
14014    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- new save area
14015    ldr     r1, [r1, #offStackSaveArea_method] @ r1<- new method
14016    str     r1, [rGLUE, #offGlue_method]    @ glue->method = new method
14017    ldr     r2, [r1, #offMethod_clazz]      @ r2<- method->clazz
14018    ldr     r3, [r1, #offMethod_insns]      @ r3<- method->insns
14019    ldr     r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex
14020    add     rPC, r3, r0, asl #1             @ rPC<- method->insns + catchRelPc
14021    str     r2, [rGLUE, #offGlue_methodClassDex] @ glue->pDvmDex = meth...
14022
14023    /* release the tracked alloc on the exception */
14024    mov     r0, r9                      @ r0<- exception
14025    mov     r1, r10                     @ r1<- self
14026    bl      dvmReleaseTrackedAlloc      @ release the exception
14027
14028    /* restore the exception if the handler wants it */
14029    FETCH_INST()                        @ load rINST from rPC
14030    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14031    cmp     ip, #OP_MOVE_EXCEPTION      @ is it "move-exception"?
14032    streq   r9, [r10, #offThread_exception] @ yes, restore the exception
14033    GOTO_OPCODE(ip)                     @ jump to next instruction
14034
14035.LnotCaughtLocally: @ r9=exception, r10=self
14036    /* fix stack overflow if necessary */
14037    ldrb    r1, [r10, #offThread_stackOverflowed]
14038    cmp     r1, #0                      @ did we overflow earlier?
14039    movne   r0, r10                     @ if yes: r0<- self
14040    movne   r1, r9                      @ if yes: r1<- exception
14041    blne    dvmCleanupStackOverflow     @ if yes: call(self)
14042
14043    @ may want to show "not caught locally" debug messages here
14044#if DVM_SHOW_EXCEPTION >= 2
14045    /* call __android_log_print(prio, tag, format, ...) */
14046    /* "Exception %s from %s:%d not caught locally" */
14047    @ dvmLineNumFromPC(method, pc - method->insns)
14048    ldr     r0, [rGLUE, #offGlue_method]
14049    ldr     r1, [r0, #offMethod_insns]
14050    sub     r1, rPC, r1
14051    asr     r1, r1, #1
14052    bl      dvmLineNumFromPC
14053    str     r0, [sp, #-4]!
14054    @ dvmGetMethodSourceFile(method)
14055    ldr     r0, [rGLUE, #offGlue_method]
14056    bl      dvmGetMethodSourceFile
14057    str     r0, [sp, #-4]!
14058    @ exception->clazz->descriptor
14059    ldr     r3, [r9, #offObject_clazz]
14060    ldr     r3, [r3, #offClassObject_descriptor]
14061    @
14062    ldr     r2, strExceptionNotCaughtLocally
14063    ldr     r1, strLogTag
14064    mov     r0, #3                      @ LOG_DEBUG
14065    bl      __android_log_print
14066#endif
14067    str     r9, [r10, #offThread_exception] @ restore exception
14068    mov     r0, r9                      @ r0<- exception
14069    mov     r1, r10                     @ r1<- self
14070    bl      dvmReleaseTrackedAlloc      @ release the exception
14071    mov     r1, #0                      @ "want switch" = false
14072    b       common_gotoBail             @ bail out
14073
14074
14075    /*
14076     * Exception handling, calls through "glue code".
14077     */
14078    .if     0
14079.LexceptionOld:
14080    SAVE_PC_FP_TO_GLUE()                @ export state
14081    mov     r0, rGLUE                   @ arg to function
14082    bl      dvmMterp_exceptionThrown
14083    b       common_resumeAfterGlueCall
14084    .endif
14085
14086
14087/*
14088 * After returning from a "glued" function, pull out the updated
14089 * values and start executing at the next instruction.
14090 */
14091common_resumeAfterGlueCall:
14092    LOAD_PC_FP_FROM_GLUE()              @ pull rPC and rFP out of glue
14093    FETCH_INST()                        @ load rINST from rPC
14094    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14095    GOTO_OPCODE(ip)                     @ jump to next instruction
14096
14097/*
14098 * Invalid array index. Note that our calling convention is strange; we use r1
14099 * and r3 because those just happen to be the registers all our callers are
14100 * using. We shuffle them here before calling the C function.
14101 * r1: index
14102 * r3: size
14103 */
14104common_errArrayIndex:
14105    EXPORT_PC()
14106    mov     r0, r1
14107    mov     r1, r3
14108    bl      dvmThrowAIOOBE
14109    b       common_exceptionThrown
14110
14111/*
14112 * Integer divide or mod by zero.
14113 */
14114common_errDivideByZero:
14115    EXPORT_PC()
14116    ldr     r0, strArithmeticException
14117    ldr     r1, strDivideByZero
14118    bl      dvmThrowException
14119    b       common_exceptionThrown
14120
14121/*
14122 * Attempt to allocate an array with a negative size.
14123 */
14124common_errNegativeArraySize:
14125    EXPORT_PC()
14126    ldr     r0, strNegativeArraySizeException
14127    mov     r1, #0
14128    bl      dvmThrowException
14129    b       common_exceptionThrown
14130
14131/*
14132 * Invocation of a non-existent method.
14133 */
14134common_errNoSuchMethod:
14135    EXPORT_PC()
14136    ldr     r0, strNoSuchMethodError
14137    mov     r1, #0
14138    bl      dvmThrowException
14139    b       common_exceptionThrown
14140
14141/*
14142 * We encountered a null object when we weren't expecting one.  We
14143 * export the PC, throw a NullPointerException, and goto the exception
14144 * processing code.
14145 */
14146common_errNullObject:
14147    EXPORT_PC()
14148    ldr     r0, strNullPointerException
14149    mov     r1, #0
14150    bl      dvmThrowException
14151    b       common_exceptionThrown
14152
14153/*
14154 * For debugging, cause an immediate fault.  The source address will
14155 * be in lr (use a bl instruction to jump here).
14156 */
14157common_abort:
14158    ldr     pc, .LdeadFood
14159.LdeadFood:
14160    .word   0xdeadf00d
14161
14162/*
14163 * Spit out a "we were here", preserving all registers.  (The attempt
14164 * to save ip won't work, but we need to save an even number of
14165 * registers for EABI 64-bit stack alignment.)
14166 */
14167    .macro  SQUEAK num
14168common_squeak\num:
14169    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14170    ldr     r0, strSqueak
14171    mov     r1, #\num
14172    bl      printf
14173    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14174    bx      lr
14175    .endm
14176
14177    SQUEAK  0
14178    SQUEAK  1
14179    SQUEAK  2
14180    SQUEAK  3
14181    SQUEAK  4
14182    SQUEAK  5
14183
14184/*
14185 * Spit out the number in r0, preserving registers.
14186 */
14187common_printNum:
14188    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14189    mov     r1, r0
14190    ldr     r0, strSqueak
14191    bl      printf
14192    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14193    bx      lr
14194
14195/*
14196 * Print a newline, preserving registers.
14197 */
14198common_printNewline:
14199    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14200    ldr     r0, strNewline
14201    bl      printf
14202    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14203    bx      lr
14204
14205    /*
14206     * Print the 32-bit quantity in r0 as a hex value, preserving registers.
14207     */
14208common_printHex:
14209    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14210    mov     r1, r0
14211    ldr     r0, strPrintHex
14212    bl      printf
14213    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14214    bx      lr
14215
14216/*
14217 * Print the 64-bit quantity in r0-r1, preserving registers.
14218 */
14219common_printLong:
14220    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14221    mov     r3, r1
14222    mov     r2, r0
14223    ldr     r0, strPrintLong
14224    bl      printf
14225    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14226    bx      lr
14227
14228/*
14229 * Print full method info.  Pass the Method* in r0.  Preserves regs.
14230 */
14231common_printMethod:
14232    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14233    bl      dvmMterpPrintMethod
14234    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14235    bx      lr
14236
14237/*
14238 * Call a C helper function that dumps regs and possibly some
14239 * additional info.  Requires the C function to be compiled in.
14240 */
14241    .if     0
14242common_dumpRegs:
14243    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14244    bl      dvmMterpDumpArmRegs
14245    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14246    bx      lr
14247    .endif
14248
14249#if 0
14250/*
14251 * Experiment on VFP mode.
14252 *
14253 * uint32_t setFPSCR(uint32_t val, uint32_t mask)
14254 *
14255 * Updates the bits specified by "mask", setting them to the values in "val".
14256 */
14257setFPSCR:
14258    and     r0, r0, r1                  @ make sure no stray bits are set
14259    fmrx    r2, fpscr                   @ get VFP reg
14260    mvn     r1, r1                      @ bit-invert mask
14261    and     r2, r2, r1                  @ clear masked bits
14262    orr     r2, r2, r0                  @ set specified bits
14263    fmxr    fpscr, r2                   @ set VFP reg
14264    mov     r0, r2                      @ return new value
14265    bx      lr
14266
14267    .align  2
14268    .global dvmConfigureFP
14269    .type   dvmConfigureFP, %function
14270dvmConfigureFP:
14271    stmfd   sp!, {ip, lr}
14272    /* 0x03000000 sets DN/FZ */
14273    /* 0x00009f00 clears the six exception enable flags */
14274    bl      common_squeak0
14275    mov     r0, #0x03000000             @ r0<- 0x03000000
14276    add     r1, r0, #0x9f00             @ r1<- 0x03009f00
14277    bl      setFPSCR
14278    ldmfd   sp!, {ip, pc}
14279#endif
14280
14281
14282/*
14283 * String references, must be close to the code that uses them.
14284 */
14285    .align  2
14286strArithmeticException:
14287    .word   .LstrArithmeticException
14288strDivideByZero:
14289    .word   .LstrDivideByZero
14290strNegativeArraySizeException:
14291    .word   .LstrNegativeArraySizeException
14292strNoSuchMethodError:
14293    .word   .LstrNoSuchMethodError
14294strNullPointerException:
14295    .word   .LstrNullPointerException
14296
14297strLogTag:
14298    .word   .LstrLogTag
14299strExceptionNotCaughtLocally:
14300    .word   .LstrExceptionNotCaughtLocally
14301
14302strNewline:
14303    .word   .LstrNewline
14304strSqueak:
14305    .word   .LstrSqueak
14306strPrintHex:
14307    .word   .LstrPrintHex
14308strPrintLong:
14309    .word   .LstrPrintLong
14310
14311/*
14312 * Zero-terminated ASCII string data.
14313 *
14314 * On ARM we have two choices: do like gcc does, and LDR from a .word
14315 * with the address, or use an ADR pseudo-op to get the address
14316 * directly.  ADR saves 4 bytes and an indirection, but it's using a
14317 * PC-relative addressing mode and hence has a limited range, which
14318 * makes it not work well with mergeable string sections.
14319 */
14320    .section .rodata.str1.4,"aMS",%progbits,1
14321
14322.LstrBadEntryPoint:
14323    .asciz  "Bad entry point %d\n"
14324.LstrArithmeticException:
14325    .asciz  "Ljava/lang/ArithmeticException;"
14326.LstrDivideByZero:
14327    .asciz  "divide by zero"
14328.LstrFilledNewArrayNotImpl:
14329    .asciz  "filled-new-array only implemented for objects and 'int'"
14330.LstrInternalError:
14331    .asciz  "Ljava/lang/InternalError;"
14332.LstrInstantiationError:
14333    .asciz  "Ljava/lang/InstantiationError;"
14334.LstrNegativeArraySizeException:
14335    .asciz  "Ljava/lang/NegativeArraySizeException;"
14336.LstrNoSuchMethodError:
14337    .asciz  "Ljava/lang/NoSuchMethodError;"
14338.LstrNullPointerException:
14339    .asciz  "Ljava/lang/NullPointerException;"
14340
14341.LstrLogTag:
14342    .asciz  "mterp"
14343.LstrExceptionNotCaughtLocally:
14344    .asciz  "Exception %s from %s:%d not caught locally\n"
14345
14346.LstrNewline:
14347    .asciz  "\n"
14348.LstrSqueak:
14349    .asciz  "<%d>"
14350.LstrPrintHex:
14351    .asciz  "<0x%x>"
14352.LstrPrintLong:
14353    .asciz  "<%lld>"
14354
14355